Add colorized diffs to cli reporter
This commit is contained in:
parent
42e6fe84e5
commit
cee1d3943c
8 changed files with 161 additions and 6 deletions
|
@ -4,6 +4,9 @@ require 'securerandom'
|
|||
require 'to_source'
|
||||
require 'ice_nine'
|
||||
require 'backports'
|
||||
require 'diff/lcs'
|
||||
require 'diff/lcs/hunk'
|
||||
require 'pp'
|
||||
|
||||
# Library namespace
|
||||
module Mutant
|
||||
|
@ -72,6 +75,8 @@ require 'mutant/matcher/method/classifier'
|
|||
require 'mutant/killer'
|
||||
require 'mutant/killer/rspec'
|
||||
require 'mutant/runner'
|
||||
require 'mutant/color'
|
||||
require 'mutant/differ'
|
||||
require 'mutant/reporter'
|
||||
require 'mutant/reporter/null'
|
||||
require 'mutant/reporter/cli'
|
||||
|
|
27
lib/mutant/color.rb
Normal file
27
lib/mutant/color.rb
Normal file
|
@ -0,0 +1,27 @@
|
|||
module Mutant
|
||||
# Class to colorize strings
|
||||
class Color
|
||||
include Immutable
|
||||
|
||||
def initialize(code)
|
||||
@code = code
|
||||
end
|
||||
|
||||
def format(text)
|
||||
"\e[#{@code}m#{text}\e[0m"
|
||||
end
|
||||
|
||||
NONE = Class.new(self) do
|
||||
def initialize(*)
|
||||
end
|
||||
|
||||
def format(text)
|
||||
text
|
||||
end
|
||||
end.new.freeze
|
||||
|
||||
RED = Color.new(31)
|
||||
GREEN = Color.new(32)
|
||||
BLUE = Color.new(34)
|
||||
end
|
||||
end
|
54
lib/mutant/differ.rb
Normal file
54
lib/mutant/differ.rb
Normal file
|
@ -0,0 +1,54 @@
|
|||
module Mutant
|
||||
class Differ
|
||||
include Immutable
|
||||
|
||||
def initialize(old, new)
|
||||
@new, @old = new.lines.map(&:chomp), old.lines.map(&:chomp)
|
||||
@diffs = Diff::LCS.diff(@old, @new)
|
||||
end
|
||||
|
||||
def format
|
||||
:unified
|
||||
end
|
||||
|
||||
def context_lines
|
||||
3
|
||||
end
|
||||
|
||||
def length_difference
|
||||
@new.size - @old.size
|
||||
end
|
||||
|
||||
def diff
|
||||
output = ''
|
||||
@diffs.each do |piece|
|
||||
hunk = Diff::LCS::Hunk.new(@old, @new, piece, context_lines, length_difference)
|
||||
output << hunk.diff(format)
|
||||
output << "\n"
|
||||
end
|
||||
output
|
||||
end
|
||||
memoize :diff
|
||||
|
||||
def colorized_diff
|
||||
diff.lines.map do |line|
|
||||
self.class.colorize_line(line)
|
||||
end.join
|
||||
end
|
||||
memoize :colorized_diff
|
||||
|
||||
def self.colorize_line(line)
|
||||
case line[0].chr
|
||||
when '+'
|
||||
Color::GREEN
|
||||
when '-'
|
||||
Color::RED
|
||||
when '@'
|
||||
line[1].chr == '@' ? Color::BLUE : Color::NONE
|
||||
else
|
||||
Color::NONE
|
||||
end.format(line)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -11,7 +11,7 @@ module Mutant
|
|||
# @api private
|
||||
#
|
||||
def subject(subject)
|
||||
@io.puts("Found subject: #{subject.identification}")
|
||||
@io.puts("Subject: #{subject.identification}")
|
||||
end
|
||||
|
||||
# Report mutations
|
||||
|
@ -35,14 +35,15 @@ module Mutant
|
|||
# @api private
|
||||
#
|
||||
def killer(killer)
|
||||
@io.puts('Killer: %s / %02.2fs' % [killer.identification,killer.runtime])
|
||||
|
||||
if killer.fail?
|
||||
@io.puts "Uncovered mutation"
|
||||
@io.puts "=== Original ===\n#{killer.original_source}"
|
||||
@io.puts(colorize(Color::RED, "!!! Uncovered Mutation !!!"))
|
||||
differ = Differ.new(killer.original_source,killer.mutation_source)
|
||||
diff = color? ? differ.colorized_diff : color
|
||||
@io.puts(diff)
|
||||
@io.puts
|
||||
@io.puts "=== Mutation ===\n#{killer.mutation_source}"
|
||||
end
|
||||
|
||||
self
|
||||
end
|
||||
|
||||
private
|
||||
|
@ -58,6 +59,47 @@ module Mutant
|
|||
def initialize(io)
|
||||
@io = io
|
||||
end
|
||||
|
||||
# Test for colored output
|
||||
#
|
||||
# @return [true]
|
||||
# returns true if output is colored
|
||||
#
|
||||
# @return [false]
|
||||
# returns false otherwise
|
||||
#
|
||||
# @api private
|
||||
#
|
||||
def color?
|
||||
tty?
|
||||
end
|
||||
|
||||
# Colorize message
|
||||
#
|
||||
# @param [Color] color
|
||||
# @param [String] message
|
||||
#
|
||||
# @api private
|
||||
#
|
||||
def colorize(color, message)
|
||||
color = Color::NONE unless color?
|
||||
color.format(message)
|
||||
end
|
||||
|
||||
# Test for output to tty
|
||||
#
|
||||
# @return [true]
|
||||
# returns true if output is a tty
|
||||
#
|
||||
# @return [false]
|
||||
# returns false otherwise
|
||||
#
|
||||
# @api private
|
||||
#
|
||||
def tty?
|
||||
@io.respond_to?(:tty?) && @io.tty?
|
||||
end
|
||||
memoize :tty?
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -21,4 +21,5 @@ Gem::Specification.new do |gem|
|
|||
gem.add_runtime_dependency('backports', '~> 2.6')
|
||||
gem.add_runtime_dependency('immutable', '~> 0.0.1')
|
||||
gem.add_runtime_dependency('abstract', '~> 0.0.1')
|
||||
gem.add_runtime_dependency('diff-lcs', '~> 1.1.3')
|
||||
end
|
||||
|
|
15
spec/integration/mutant/differ_spec.rb
Normal file
15
spec/integration/mutant/differ_spec.rb
Normal file
|
@ -0,0 +1,15 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe Mutant,'differ' do
|
||||
specify 'allows to create diffs from text' do
|
||||
a = "Foo\nBar\n"
|
||||
b = "Foo\nBaz\n"
|
||||
differ = Mutant::Differ.new(a,b)
|
||||
differ.diff.should == strip_indent(<<-RUBY)
|
||||
@@ -1,3 +1,3 @@
|
||||
Foo
|
||||
-Bar
|
||||
+Baz
|
||||
RUBY
|
||||
end
|
||||
end
|
|
@ -11,4 +11,5 @@ require 'test_app'
|
|||
require 'mutant'
|
||||
|
||||
RSpec.configure do |config|
|
||||
config.include(CompressHelper)
|
||||
end
|
||||
|
|
10
spec/support/compress_helper.rb
Normal file
10
spec/support/compress_helper.rb
Normal file
|
@ -0,0 +1,10 @@
|
|||
module CompressHelper
|
||||
def strip_indent(string)
|
||||
lines = string.lines
|
||||
match = /\A( *)/.match(lines.first)
|
||||
whitespaces = match[1].to_s.length
|
||||
stripped = lines.map do |line|
|
||||
line[whitespaces..-1]
|
||||
end.join
|
||||
end
|
||||
end
|
Loading…
Add table
Reference in a new issue