Fix reports and calculate tests once per subject

This commit is contained in:
Markus Schirp 2014-05-23 01:03:09 +00:00
parent c5f7fd7209
commit 53fa6f447b
7 changed files with 58 additions and 46 deletions

View file

@ -3,8 +3,7 @@
module Mutant
# Mutation killer
class Killer
include Adamantium::Flat
include Anima.new(:test, :mutation)
include Adamantium::Flat, Anima.new(:test, :mutation)
# Report object for kill results
class Report

View file

@ -8,6 +8,18 @@ module Mutant
# Reporter for mutations
class Mutation < self
# Run report printer
#
# @return [self]
#
# @api private
#
def run
puts(object.identification)
puts(details)
self
end
# Reporter for noop mutations
class Noop < self
handle(Mutant::Mutation::Neutral::Noop)
@ -19,16 +31,18 @@ module Mutant
'%s'
].join("\n").freeze
# Run report printer
private
# Return details
#
# @return [self]
#
# @api private
#
def run
puts(MESSAGE % [object.subject.node.inspect, object.original_source])
self
def details
MESSAGE % [object.subject.node.inspect, object.original_source]
end
end # Noop
# Reporter for mutations producing a diff
@ -36,7 +50,7 @@ module Mutant
handle(Mutant::Mutation::Evil)
handle(Mutant::Mutation::Neutral)
delegate :subject
private
# Run report printer
#
@ -44,14 +58,14 @@ module Mutant
#
# @api private
#
def run
def details
original, current = object.original_source, object.source
diff = Mutant::Diff.build(original, current)
puts(color? ? diff.colorized_diff : diff.diff)
self
color? ? diff.colorized_diff : diff.diff
end
end
end
end # Diff
end # Mutation
# Subject report printer
class MutationRunner < self

View file

@ -4,7 +4,7 @@ module Mutant
class Runner
# Mutation runner
class Mutation < self
include Equalizer.new(:config, :mutation)
include Equalizer.new(:config, :mutation, :tests)
register Mutant::Mutation
@ -28,13 +28,14 @@ module Mutant
#
# @param [Config] config
# @param [Mutation] mutation
# @param [Enumerable<Test>] tests
#
# @return [undefined]
#
# @api private
#
def initialize(config, mutation)
@mutation = mutation
def initialize(config, mutation, tests)
@mutation, @tests = mutation, tests
super(config)
end
@ -62,7 +63,12 @@ module Mutant
#
def run
progress(mutation)
@killers = visit_collection(config.strategy.killers(mutation))
@killers = @tests.map do |test|
Mutant::Killer.new(
mutation: mutation,
test: test
)
end.map(&method(:visit))
progress(self)
end

View file

@ -73,7 +73,10 @@ module Mutant
#
def run
progress(subject)
@mutations = visit_collection(subject.mutations)
tests = config.strategy.tests(subject)
@mutations = subject.mutations.map do |mutation|
Runner::Mutation.new(config, mutation, tests)
end
progress(self)
end

View file

@ -62,23 +62,6 @@ module Mutant
#
abstract_method :all_tests
# Return killers for mutation
#
# @param [Mutation] mutation
#
# @return [Enumerable<Killer>]
#
# @api private
#
def killers(mutation)
tests(mutation).map do |test|
Killer.new(
mutation: mutation,
test: test
)
end
end
# Return tests for mutation
#
# TODO: This logic is now centralized but still fucked.
@ -89,8 +72,8 @@ module Mutant
#
# @api private
#
def tests(mutation)
mutation.subject.match_prefixes.map do |match_expression|
def tests(subject)
subject.match_prefixes.map do |match_expression|
tests = all_tests.select do |test|
test.subject_identification.start_with?(match_expression)
end
@ -114,7 +97,7 @@ module Mutant
# @api private
#
def all_tests
[]
EMPTY_ARRAY
end
end # Null

View file

@ -3,13 +3,13 @@
require 'spec_helper'
describe Mutant::Runner::Mutation do
let(:object) { described_class.new(config, mutation) }
let(:object) { described_class.new(config, mutation, tests) }
let(:reporter) { double('Reporter') }
let(:mutation) { double('Mutation', class: Mutant::Mutation) }
let(:strategy) { double('Strategy') }
let(:killer_a) { double('Killer A') }
let(:killer_b) { double('Killer B') }
let(:killer_a) { Mutant::Killer.new(test: test_a, mutation: mutation) }
let(:killer_b) { Mutant::Killer.new(test: test_b, mutation: mutation) }
let(:runner_a) { double('Runner A', success?: success_a, stop?: stop_a) }
let(:runner_b) { double('Runner B', success?: success_b, stop?: stop_b) }
let(:runners) { [runner_a, runner_b] }
@ -19,6 +19,9 @@ describe Mutant::Runner::Mutation do
let(:success_b) { true }
let(:stop_a) { false }
let(:stop_b) { false }
let(:test_a) { double('test a') }
let(:test_b) { double('test b') }
let(:tests) { [test_a, test_b] }
before do
expect(Mutant::Runner).to receive(:run).with(config, killer_a).and_return(runner_a)

View file

@ -15,10 +15,11 @@ describe Mutant::Runner::Subject, '#success?' do
)
end
let(:reporter) { Mutant::Reporter::Trace.new }
let(:config) { double('Config', reporter: reporter) }
let(:mutation_a) { double('Mutation A') }
let(:mutation_b) { double('Mutation B') }
let(:reporter) { Mutant::Reporter::Trace.new }
let(:config) { double('Config', reporter: reporter, strategy: strategy) }
let(:mutation_a) { double('Mutation A') }
let(:mutation_b) { double('Mutation B') }
let(:strategy) { double('Strategy') }
let(:runner_a) do
double('Runner A', success?: success_a, stop?: stop_a)
@ -28,9 +29,12 @@ describe Mutant::Runner::Subject, '#success?' do
double('Runner B', success?: success_b, stop?: stop_b)
end
let(:tests) { [double('test a'), double('test b')] }
before do
expect(Mutant::Runner).to receive(:run).with(config, mutation_a).and_return(runner_a)
expect(Mutant::Runner).to receive(:run).with(config, mutation_b).and_return(runner_b)
expect(strategy).to receive(:tests).with(mutation_subject).and_return(tests)
expect(Mutant::Runner::Mutation).to receive(:new).with(config, mutation_a, tests).and_return(runner_a)
expect(Mutant::Runner::Mutation).to receive(:new).with(config, mutation_b, tests).and_return(runner_b)
end
context 'with failing mutations' do