Always build valid result objects

* Before Mutant::Expression was not marshallable resulting in the need
  to build "partial" result objects from killforks.
* Fixes an adjacent bug in spec selection
This commit is contained in:
Markus Schirp 2014-12-22 17:54:18 +00:00
parent 7dff1d1904
commit 207c159c23
14 changed files with 56 additions and 13 deletions

View file

@ -64,7 +64,7 @@ module Mutant
config.isolation.call do
mutation.insert
config.integration.call(tests)
end.update(tests: tests)
end
rescue Isolation::Error => error
Result::Test.new(
tests: tests,

View file

@ -66,7 +66,7 @@ module Mutant
cache: cache,
subjects: subjects,
matchable_scopes: matchable_scopes,
selector: Selector::Expression.new(config.integration.all_tests),
selector: Selector::Expression.new(config.integration),
mutations: subjects.flat_map(&:mutations)
)
end

View file

@ -37,6 +37,33 @@ module Mutant
@inspect = format(INSPECT_FORMAT, syntax)
end
# Return marshallable representation
#
# FIXME: Remove the need for this.
#
# Refactoring Expression objects not to reference a MatchData instance.
# This will make this hack unneeded.
#
# @return [String]
#
# @api private
#
def _dump(_level)
syntax
end
# Load serializable representation
#
# @return [String]
#
# @return [Expression]
#
# @api private
#
def self._load(syntax)
parse(syntax)
end
# Return inspection
#
# @return [String]

View file

@ -54,7 +54,7 @@ module Mutant
passed = @runner.run_specs(RSpec.world.ordered_example_groups).equal?(EXIT_SUCCESS)
@output.rewind
Result::Test.new(
tests: nil,
tests: tests,
output: @output.read,
runtime: Time.now - start,
passed: passed

View file

@ -295,7 +295,7 @@ module Mutant
# Subject report printer
class SubjectResult < self
delegate :subject, :failed_mutations
delegate :subject, :failed_mutations, :tests
# Run report printer
#
@ -305,7 +305,7 @@ module Mutant
#
def run
status(subject.identification)
subject.tests.each do |test|
tests.each do |test|
puts("- #{test.identification}")
end
visit_collection(MutationResult, object.alive_mutation_results)

View file

@ -147,7 +147,7 @@ module Mutant
# Subject result
class Subject
include Coverage, Result, Anima.new(:subject, :mutation_results)
include Coverage, Result, Anima.new(:subject, :tests, :mutation_results)
sum :killtime, :mutation_results
sum :runtime, :mutation_results

View file

@ -46,6 +46,7 @@ module Mutant
@subject_results = Hash.new do |_hash, subject|
Result::Subject.new(
subject: subject,
tests: [],
mutation_results: []
)
end
@ -85,7 +86,8 @@ module Mutant
original = @subject_results[mutation.subject]
@subject_results[mutation.subject] = original.update(
mutation_results: (original.mutation_results.dup << mutation_result)
mutation_results: (original.mutation_results.dup << mutation_result),
tests: mutation_result.test_result.tests
)
self

View file

@ -2,7 +2,7 @@ module Mutant
class Selector
# Expression based test selector
class Expression < self
include Concord.new(:tests)
include Concord.new(:integration)
# Return tests for subject
#
@ -14,7 +14,7 @@ module Mutant
#
def call(subject)
subject.match_expressions.each do |match_expression|
subject_tests = tests.select do |test|
subject_tests = integration.all_tests.select do |test|
match_expression.prefix?(test.expression)
end
return subject_tests if subject_tests.any?

View file

@ -111,6 +111,7 @@ module SharedContext
let(:subject_a_result) do
Mutant::Result::Subject.new(
subject: subject_a,
tests: [test_a],
mutation_results: [mutation_a_result, mutation_b_result]
)
end

View file

@ -16,7 +16,7 @@ RSpec.describe Mutant::Env::Bootstrap do
matchable_scopes: [],
mutations: [],
config: config,
selector: Mutant::Selector::Expression.new(config.integration.all_tests),
selector: Mutant::Selector::Expression.new(config.integration),
actor_env: Mutant::Actor::Env.new(Thread)
)
end

View file

@ -61,7 +61,6 @@ RSpec.describe Mutant::Env do
expect(context).to receive(:root).with(s(:nil)).and_return(wrapped_node).ordered
expect(Mutant::Loader::Eval).to receive(:call).with(wrapped_node, mutation_subject).and_return(nil).ordered
expect(integration).to receive(:call).with(tests).and_return(test_result).ordered
expect(test_result).to receive(:update).with(tests: tests).and_return(test_result).ordered
end
include_examples 'mutation kill'

View file

@ -44,6 +44,13 @@ RSpec.describe Mutant::Expression do
it_should_behave_like 'an idempotent method'
end
describe '#_dump' do
let(:object) { described_class.parse('Foo') }
subject { object._dump(double('Level')) }
it { should eql('Foo') }
end
describe '.parse' do
subject { object.parse(input) }
@ -64,4 +71,10 @@ RSpec.describe Mutant::Expression do
it { should eql(Mutant::Expression::Namespace::Exact.new('Foo')) }
end
end
describe '._load' do
subject { described_class._load('Foo') }
it { should eql(described_class.parse('Foo')) }
end
end

View file

@ -2,7 +2,8 @@ RSpec.describe Mutant::Result::Subject do
let(:object) do
described_class.new(
subject: mutation_subject,
mutation_results: mutation_results
mutation_results: mutation_results,
tests: []
)
end

View file

@ -1,6 +1,6 @@
RSpec.describe Mutant::Selector::Expression do
describe '#call' do
let(:object) { described_class.new(all_tests) }
let(:object) { described_class.new(integration) }
let(:subject_class) do
Class.new(Mutant::Subject) do