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 'to_source'
|
||||||
require 'ice_nine'
|
require 'ice_nine'
|
||||||
require 'backports'
|
require 'backports'
|
||||||
|
require 'diff/lcs'
|
||||||
|
require 'diff/lcs/hunk'
|
||||||
|
require 'pp'
|
||||||
|
|
||||||
# Library namespace
|
# Library namespace
|
||||||
module Mutant
|
module Mutant
|
||||||
|
@ -72,6 +75,8 @@ require 'mutant/matcher/method/classifier'
|
||||||
require 'mutant/killer'
|
require 'mutant/killer'
|
||||||
require 'mutant/killer/rspec'
|
require 'mutant/killer/rspec'
|
||||||
require 'mutant/runner'
|
require 'mutant/runner'
|
||||||
|
require 'mutant/color'
|
||||||
|
require 'mutant/differ'
|
||||||
require 'mutant/reporter'
|
require 'mutant/reporter'
|
||||||
require 'mutant/reporter/null'
|
require 'mutant/reporter/null'
|
||||||
require 'mutant/reporter/cli'
|
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
|
# @api private
|
||||||
#
|
#
|
||||||
def subject(subject)
|
def subject(subject)
|
||||||
@io.puts("Found subject: #{subject.identification}")
|
@io.puts("Subject: #{subject.identification}")
|
||||||
end
|
end
|
||||||
|
|
||||||
# Report mutations
|
# Report mutations
|
||||||
|
@ -35,14 +35,15 @@ module Mutant
|
||||||
# @api private
|
# @api private
|
||||||
#
|
#
|
||||||
def killer(killer)
|
def killer(killer)
|
||||||
@io.puts('Killer: %s / %02.2fs' % [killer.identification,killer.runtime])
|
|
||||||
|
|
||||||
if killer.fail?
|
if killer.fail?
|
||||||
@io.puts "Uncovered mutation"
|
@io.puts(colorize(Color::RED, "!!! Uncovered Mutation !!!"))
|
||||||
@io.puts "=== Original ===\n#{killer.original_source}"
|
differ = Differ.new(killer.original_source,killer.mutation_source)
|
||||||
|
diff = color? ? differ.colorized_diff : color
|
||||||
|
@io.puts(diff)
|
||||||
@io.puts
|
@io.puts
|
||||||
@io.puts "=== Mutation ===\n#{killer.mutation_source}"
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
self
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
@ -58,6 +59,47 @@ module Mutant
|
||||||
def initialize(io)
|
def initialize(io)
|
||||||
@io = io
|
@io = io
|
||||||
end
|
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
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -21,4 +21,5 @@ Gem::Specification.new do |gem|
|
||||||
gem.add_runtime_dependency('backports', '~> 2.6')
|
gem.add_runtime_dependency('backports', '~> 2.6')
|
||||||
gem.add_runtime_dependency('immutable', '~> 0.0.1')
|
gem.add_runtime_dependency('immutable', '~> 0.0.1')
|
||||||
gem.add_runtime_dependency('abstract', '~> 0.0.1')
|
gem.add_runtime_dependency('abstract', '~> 0.0.1')
|
||||||
|
gem.add_runtime_dependency('diff-lcs', '~> 1.1.3')
|
||||||
end
|
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'
|
require 'mutant'
|
||||||
|
|
||||||
RSpec.configure do |config|
|
RSpec.configure do |config|
|
||||||
|
config.include(CompressHelper)
|
||||||
end
|
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