Add colorized diffs to cli reporter

This commit is contained in:
Markus Schirp 2012-08-16 18:02:03 +02:00
parent 42e6fe84e5
commit cee1d3943c
8 changed files with 161 additions and 6 deletions

View file

@ -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
View 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
View 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

View file

@ -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

View file

@ -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

View 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

View file

@ -11,4 +11,5 @@ require 'test_app'
require 'mutant'
RSpec.configure do |config|
config.include(CompressHelper)
end

View 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