mutant 0.8.3 → 0.8.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Changelog.md +8 -0
- data/Gemfile +1 -4
- data/Gemfile.shared +3 -0
- data/Rakefile +0 -2
- data/config/flay.yml +1 -1
- data/config/rubocop.yml +8 -0
- data/lib/mutant.rb +2 -0
- data/lib/mutant/ast/meta/restarg.rb +15 -0
- data/lib/mutant/ast/meta/symbol.rb +15 -0
- data/lib/mutant/cli.rb +11 -11
- data/lib/mutant/config.rb +1 -1
- data/lib/mutant/env.rb +1 -1
- data/lib/mutant/matcher/config.rb +2 -2
- data/lib/mutant/mutator/node/block.rb +16 -0
- data/lib/mutant/mutator/node/define.rb +14 -0
- data/lib/mutant/mutator/node/send.rb +12 -1
- data/lib/mutant/mutator/node/send/binary.rb +25 -1
- data/lib/mutant/parallel.rb +2 -2
- data/lib/mutant/result.rb +1 -1
- data/lib/mutant/runner/sink.rb +2 -2
- data/lib/mutant/version.rb +1 -1
- data/meta/begin.rb +0 -2
- data/meta/block.rb +15 -0
- data/meta/def.rb +25 -0
- data/meta/or_asgn.rb +9 -0
- data/meta/send.rb +41 -1
- data/mutant-rspec.gemspec +0 -2
- data/mutant.gemspec +5 -6
- data/spec/spec_helper.rb +1 -1
- data/spec/support/corpus.rb +1 -0
- data/spec/support/shared_context.rb +5 -5
- data/spec/unit/mutant/cli_spec.rb +6 -6
- data/spec/unit/mutant/env/boostrap_spec.rb +3 -3
- data/spec/unit/mutant/env_spec.rb +1 -1
- data/spec/unit/mutant/matcher/compiler_spec.rb +1 -1
- data/spec/unit/mutant/parallel/master_spec.rb +2 -2
- data/spec/unit/mutant/reporter/cli/printer/config_spec.rb +1 -1
- data/spec/unit/mutant/reporter/cli/printer/env_progress_spec.rb +3 -3
- data/spec/unit/mutant/reporter/cli/printer/env_result_spec.rb +1 -1
- data/spec/unit/mutant/reporter/cli/printer/mutation_progress_result_spec.rb +2 -2
- data/spec/unit/mutant/reporter/cli/printer/mutation_result_spec.rb +3 -3
- data/spec/unit/mutant/reporter/cli/printer/status_progressive_spec.rb +5 -5
- data/spec/unit/mutant/reporter/cli/printer/status_spec.rb +5 -5
- data/spec/unit/mutant/reporter/cli/printer/subject_progress_spec.rb +2 -2
- data/spec/unit/mutant/reporter/cli/printer/subject_result_spec.rb +2 -2
- data/spec/unit/mutant/reporter/cli_spec.rb +6 -4
- data/spec/unit/mutant/result_spec.rb +23 -0
- data/spec/unit/mutant/runner/sink/mutation_spec.rb +8 -8
- data/spec/unit/mutant/selector/expression_spec.rb +1 -1
- data/test_app/Gemfile.rspec3.2 +1 -0
- data/test_app/Gemfile.rspec3.3 +1 -0
- data/test_app/spec/unit/test_app/literal_spec.rb +0 -2
- metadata +27 -18
- data/Guardfile +0 -16
- data/test_app/Gemfile.rspec3.0 +0 -6
- data/test_app/Gemfile.rspec3.1 +0 -6
data/meta/or_asgn.rb
CHANGED
@@ -21,6 +21,15 @@ Mutant::Meta::Example.add do
|
|
21
21
|
mutation '@a ||= 2'
|
22
22
|
end
|
23
23
|
|
24
|
+
Mutant::Meta::Example.add do
|
25
|
+
source '@a ||= self.bar'
|
26
|
+
|
27
|
+
singleton_mutations
|
28
|
+
mutation '@a ||= nil'
|
29
|
+
mutation '@a ||= self'
|
30
|
+
mutation '@a ||= bar'
|
31
|
+
end
|
32
|
+
|
24
33
|
Mutant::Meta::Example.add do
|
25
34
|
source 'foo[:bar] ||= 1'
|
26
35
|
|
data/meta/send.rb
CHANGED
@@ -14,6 +14,32 @@ Mutant::Meta::Example.add do
|
|
14
14
|
mutation 'b'
|
15
15
|
end
|
16
16
|
|
17
|
+
Mutant::Meta::Example.add do
|
18
|
+
source 'A.const_get(:B)'
|
19
|
+
|
20
|
+
singleton_mutations
|
21
|
+
mutation 'A::B'
|
22
|
+
mutation 'A.const_get'
|
23
|
+
mutation 'A'
|
24
|
+
mutation ':B'
|
25
|
+
mutation 'A.const_get(nil)'
|
26
|
+
mutation 'A.const_get(self)'
|
27
|
+
mutation 'A.const_get(:B__mutant__)'
|
28
|
+
mutation 'self.const_get(:B)'
|
29
|
+
end
|
30
|
+
|
31
|
+
Mutant::Meta::Example.add do
|
32
|
+
source 'A.const_get(bar)'
|
33
|
+
|
34
|
+
singleton_mutations
|
35
|
+
mutation 'A.const_get'
|
36
|
+
mutation 'A'
|
37
|
+
mutation 'bar'
|
38
|
+
mutation 'A.const_get(nil)'
|
39
|
+
mutation 'A.const_get(self)'
|
40
|
+
mutation 'self.const_get(bar)'
|
41
|
+
end
|
42
|
+
|
17
43
|
Mutant::Meta::Example.add do
|
18
44
|
source 'a >= b'
|
19
45
|
|
@@ -425,7 +451,7 @@ Mutant::Meta::Example.add do
|
|
425
451
|
mutation 'self[*bar]'
|
426
452
|
end
|
427
453
|
|
428
|
-
(Mutant::AST::Types::BINARY_METHOD_OPERATORS - %i[<= >= < > == eql?]).each do |operator|
|
454
|
+
(Mutant::AST::Types::BINARY_METHOD_OPERATORS - %i[<= >= < > == != eql?]).each do |operator|
|
429
455
|
Mutant::Meta::Example.add do
|
430
456
|
source "true #{operator} false"
|
431
457
|
|
@@ -438,3 +464,17 @@ end
|
|
438
464
|
mutation "true #{operator} nil"
|
439
465
|
end
|
440
466
|
end
|
467
|
+
|
468
|
+
Mutant::Meta::Example.add do
|
469
|
+
source 'a != b'
|
470
|
+
|
471
|
+
singleton_mutations
|
472
|
+
mutation 'nil != b'
|
473
|
+
mutation 'self != b'
|
474
|
+
mutation 'a'
|
475
|
+
mutation 'b'
|
476
|
+
mutation 'a != nil'
|
477
|
+
mutation 'a != self'
|
478
|
+
mutation '!a.eql?(b)'
|
479
|
+
mutation '!a.equal?(b)'
|
480
|
+
end
|
data/mutant-rspec.gemspec
CHANGED
data/mutant.gemspec
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
#
|
3
1
|
require File.expand_path('../lib/mutant/version', __FILE__)
|
4
2
|
|
5
3
|
Gem::Specification.new do |gem|
|
@@ -27,7 +25,7 @@ Gem::Specification.new do |gem|
|
|
27
25
|
gem.add_runtime_dependency('ast', '~> 2.1')
|
28
26
|
gem.add_runtime_dependency('diff-lcs', '~> 1.2')
|
29
27
|
gem.add_runtime_dependency('parallel', '~> 1.3')
|
30
|
-
gem.add_runtime_dependency('morpher', '~> 0.2.
|
28
|
+
gem.add_runtime_dependency('morpher', '~> 0.2.5')
|
31
29
|
gem.add_runtime_dependency('procto', '~> 0.0.2')
|
32
30
|
gem.add_runtime_dependency('abstract_type', '~> 0.0.7')
|
33
31
|
gem.add_runtime_dependency('unparser', '~> 0.2.4')
|
@@ -35,9 +33,10 @@ Gem::Specification.new do |gem|
|
|
35
33
|
gem.add_runtime_dependency('adamantium', '~> 0.2.0')
|
36
34
|
gem.add_runtime_dependency('memoizable', '~> 0.4.2')
|
37
35
|
gem.add_runtime_dependency('equalizer', '~> 0.0.9')
|
38
|
-
gem.add_runtime_dependency('anima', '~> 0.
|
36
|
+
gem.add_runtime_dependency('anima', '~> 0.3.0')
|
39
37
|
gem.add_runtime_dependency('concord', '~> 0.1.5')
|
40
38
|
|
41
|
-
gem.add_development_dependency('
|
42
|
-
gem.add_development_dependency('
|
39
|
+
gem.add_development_dependency('devtools', '~> 0.1.1')
|
40
|
+
gem.add_development_dependency('bundler', '~> 1.10')
|
41
|
+
gem.add_development_dependency('ffi', '~> 1.9.6')
|
43
42
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -33,7 +33,7 @@ $LOAD_PATH << File.join(TestApp.root, 'lib')
|
|
33
33
|
require 'test_app'
|
34
34
|
|
35
35
|
module Fixtures
|
36
|
-
TEST_CONFIG = Mutant::Config::DEFAULT.
|
36
|
+
TEST_CONFIG = Mutant::Config::DEFAULT.with(reporter: Mutant::Reporter::Trace.new)
|
37
37
|
TEST_CACHE = Mutant::Cache.new
|
38
38
|
TEST_ENV = Mutant::Env::Bootstrap.(TEST_CONFIG, TEST_CACHE)
|
39
39
|
end # Fixtures
|
data/spec/support/corpus.rb
CHANGED
@@ -134,6 +134,7 @@ module MutantSpec
|
|
134
134
|
repo_path.join('Gemfile').open('a') do |file|
|
135
135
|
file << "gem 'mutant', path: '#{relative}'\n"
|
136
136
|
file << "gem 'mutant-rspec', path: '#{relative}'\n"
|
137
|
+
file << "eval_gemfile File.expand_path('#{relative.join('Gemfile.shared')}')\n"
|
137
138
|
end
|
138
139
|
lockfile = repo_path.join('Gemfile.lock')
|
139
140
|
lockfile.delete if lockfile.exist?
|
@@ -1,8 +1,8 @@
|
|
1
1
|
# rubocop:disable ModuleLength
|
2
2
|
module SharedContext
|
3
|
-
def
|
3
|
+
def with(name, &block)
|
4
4
|
define_method(name) do
|
5
|
-
super().
|
5
|
+
super().with(instance_eval(&block))
|
6
6
|
end
|
7
7
|
end
|
8
8
|
|
@@ -51,7 +51,7 @@ module SharedContext
|
|
51
51
|
end
|
52
52
|
|
53
53
|
let(:config) do
|
54
|
-
Mutant::Config::DEFAULT.
|
54
|
+
Mutant::Config::DEFAULT.with(
|
55
55
|
jobs: 1,
|
56
56
|
reporter: Mutant::Reporter::Trace.new
|
57
57
|
)
|
@@ -120,11 +120,11 @@ module SharedContext
|
|
120
120
|
end
|
121
121
|
|
122
122
|
let(:empty_subject_a_result) do
|
123
|
-
subject_a_result.
|
123
|
+
subject_a_result.with(mutation_results: [])
|
124
124
|
end
|
125
125
|
|
126
126
|
let(:partial_subject_a_result) do
|
127
|
-
subject_a_result.
|
127
|
+
subject_a_result.with(mutation_results: [mutation_a_result])
|
128
128
|
end
|
129
129
|
end
|
130
130
|
end
|
@@ -73,7 +73,7 @@ RSpec.describe Mutant::CLI do
|
|
73
73
|
|
74
74
|
let(:default_matcher_config) do
|
75
75
|
Mutant::Matcher::Config::DEFAULT
|
76
|
-
.
|
76
|
+
.with(match_expressions: expressions.map(&method(:parse_expression)))
|
77
77
|
end
|
78
78
|
|
79
79
|
let(:flags) { [] }
|
@@ -221,13 +221,13 @@ Options:
|
|
221
221
|
end
|
222
222
|
end
|
223
223
|
|
224
|
-
context 'with require
|
225
|
-
let(:flags) { %w[--require foo] }
|
224
|
+
context 'with require flags' do
|
225
|
+
let(:flags) { %w[--require foo --require bar] }
|
226
226
|
|
227
227
|
it_should_behave_like 'a cli parser'
|
228
228
|
|
229
229
|
it 'configures requires' do
|
230
|
-
expect(subject.config.requires).to eql(%w[foo])
|
230
|
+
expect(subject.config.requires).to eql(%w[foo bar])
|
231
231
|
end
|
232
232
|
end
|
233
233
|
|
@@ -235,7 +235,7 @@ Options:
|
|
235
235
|
let(:flags) { %w[--since master] }
|
236
236
|
|
237
237
|
let(:expected_matcher_config) do
|
238
|
-
default_matcher_config.
|
238
|
+
default_matcher_config.with(
|
239
239
|
subject_filters: [
|
240
240
|
Mutant::Repository::SubjectFilter.new(Mutant::Repository::Diff.new('HEAD', 'master'))
|
241
241
|
]
|
@@ -249,7 +249,7 @@ Options:
|
|
249
249
|
let(:flags) { %w[--ignore-subject Foo::Bar] }
|
250
250
|
|
251
251
|
let(:expected_matcher_config) do
|
252
|
-
default_matcher_config.
|
252
|
+
default_matcher_config.with(ignore_expressions: [parse_expression('Foo::Bar')])
|
253
253
|
end
|
254
254
|
|
255
255
|
it_should_behave_like 'a cli parser'
|
@@ -1,6 +1,6 @@
|
|
1
1
|
RSpec.describe Mutant::Env::Bootstrap do
|
2
2
|
let(:config) do
|
3
|
-
Mutant::Config::DEFAULT.
|
3
|
+
Mutant::Config::DEFAULT.with(
|
4
4
|
jobs: 1,
|
5
5
|
reporter: Mutant::Reporter::Trace.new,
|
6
6
|
includes: [],
|
@@ -69,7 +69,7 @@ RSpec.describe Mutant::Env::Bootstrap do
|
|
69
69
|
end
|
70
70
|
|
71
71
|
context 'when includes are present' do
|
72
|
-
let(:config) { super().
|
72
|
+
let(:config) { super().with(includes: %w[foo bar]) }
|
73
73
|
|
74
74
|
before do
|
75
75
|
%w[foo bar].each do |component|
|
@@ -121,7 +121,7 @@ RSpec.describe Mutant::Env::Bootstrap do
|
|
121
121
|
end
|
122
122
|
|
123
123
|
let(:expected_env) do
|
124
|
-
super().
|
124
|
+
super().with(
|
125
125
|
subjects: subjects,
|
126
126
|
mutations: mutations
|
127
127
|
)
|
@@ -16,7 +16,7 @@ RSpec.describe Mutant::Env do
|
|
16
16
|
let(:integration) { integration_class.new(config) }
|
17
17
|
|
18
18
|
let(:config) do
|
19
|
-
Mutant::Config::DEFAULT.
|
19
|
+
Mutant::Config::DEFAULT.with(isolation: isolation, integration: integration_class)
|
20
20
|
end
|
21
21
|
|
22
22
|
let(:isolation) { double('Isolation') }
|
@@ -18,7 +18,7 @@ RSpec.describe Mutant::Matcher::Compiler do
|
|
18
18
|
end
|
19
19
|
|
20
20
|
describe '.call' do
|
21
|
-
subject { object.call(env, matcher_config.
|
21
|
+
subject { object.call(env, matcher_config.with(attributes)) }
|
22
22
|
|
23
23
|
let(:matcher_config) { Mutant::Matcher::Config::DEFAULT }
|
24
24
|
|
@@ -92,8 +92,8 @@ RSpec.describe Mutant::Parallel::Master do
|
|
92
92
|
subject { described_class.call(config) }
|
93
93
|
|
94
94
|
context 'with multiple workers configured' do
|
95
|
-
let(:config) { super().
|
96
|
-
let(:expected_results) { []
|
95
|
+
let(:config) { super().with(jobs: 2) }
|
96
|
+
let(:expected_results) { [] }
|
97
97
|
|
98
98
|
before do
|
99
99
|
expect(Mutant::Parallel::Worker).to receive(:run).with(
|
@@ -17,7 +17,7 @@ RSpec.describe Mutant::Reporter::CLI::Printer::Config do
|
|
17
17
|
end
|
18
18
|
|
19
19
|
context 'with non default coverage expectation' do
|
20
|
-
|
20
|
+
with(:config) { { expected_coverage: 0.1r } }
|
21
21
|
|
22
22
|
it_reports(<<-REPORT)
|
23
23
|
Mutant configuration:
|
@@ -1,13 +1,13 @@
|
|
1
1
|
RSpec.describe Mutant::Reporter::CLI::Printer::EnvProgress do
|
2
2
|
setup_shared_context
|
3
3
|
|
4
|
-
|
4
|
+
with(:config) { { expected_coverage: 0.1r } }
|
5
5
|
|
6
6
|
let(:reportable) { env_result }
|
7
7
|
|
8
8
|
describe '.call' do
|
9
9
|
context 'without progress' do
|
10
|
-
|
10
|
+
with(:subject_a_result) { { mutation_results: [] } }
|
11
11
|
|
12
12
|
it_reports <<-'STR'
|
13
13
|
Mutant configuration:
|
@@ -51,7 +51,7 @@ RSpec.describe Mutant::Reporter::CLI::Printer::EnvProgress do
|
|
51
51
|
end
|
52
52
|
|
53
53
|
context 'on partial coverage' do
|
54
|
-
|
54
|
+
with(:mutation_a_test_result) { { passed: true } }
|
55
55
|
|
56
56
|
it_reports <<-'STR'
|
57
57
|
Mutant configuration:
|
@@ -9,13 +9,13 @@ RSpec.describe Mutant::Reporter::CLI::Printer::MutationProgressResult do
|
|
9
9
|
|
10
10
|
describe '.run' do
|
11
11
|
context 'on killed mutant' do
|
12
|
-
|
12
|
+
with(:mutation_a_test_result) { { passed: true } }
|
13
13
|
|
14
14
|
it_reports Mutant::Color::RED.format('F')
|
15
15
|
end
|
16
16
|
|
17
17
|
context 'on alive mutant' do
|
18
|
-
|
18
|
+
with(:mutation_a_test_result) { { passed: false } }
|
19
19
|
|
20
20
|
it_reports Mutant::Color::GREEN.format('.')
|
21
21
|
end
|
@@ -5,7 +5,7 @@ RSpec.describe Mutant::Reporter::CLI::Printer::MutationResult do
|
|
5
5
|
|
6
6
|
describe '.call' do
|
7
7
|
context 'failed kill' do
|
8
|
-
|
8
|
+
with(:mutation_a_test_result) { { passed: true } }
|
9
9
|
|
10
10
|
context 'on evil mutation' do
|
11
11
|
context 'with a diff' do
|
@@ -61,7 +61,7 @@ RSpec.describe Mutant::Reporter::CLI::Printer::MutationResult do
|
|
61
61
|
end
|
62
62
|
|
63
63
|
context 'on neutral mutation' do
|
64
|
-
|
64
|
+
with(:mutation_a_test_result) { { passed: false } }
|
65
65
|
|
66
66
|
let(:mutation_a) do
|
67
67
|
Mutant::Mutation::Neutral.new(subject_a, s(:true))
|
@@ -86,7 +86,7 @@ RSpec.describe Mutant::Reporter::CLI::Printer::MutationResult do
|
|
86
86
|
end
|
87
87
|
|
88
88
|
context 'on noop mutation' do
|
89
|
-
|
89
|
+
with(:mutation_a_test_result) { { passed: false } }
|
90
90
|
|
91
91
|
let(:mutation_a) do
|
92
92
|
Mutant::Mutation::Noop.new(subject_a, s(:true))
|
@@ -5,14 +5,14 @@ RSpec.describe Mutant::Reporter::CLI::Printer::StatusProgressive do
|
|
5
5
|
|
6
6
|
describe '.call' do
|
7
7
|
context 'with empty scheduler' do
|
8
|
-
|
8
|
+
with(:env_result) { { subject_results: [] } }
|
9
9
|
|
10
10
|
it_reports <<-REPORT
|
11
11
|
(00/02) 100% - killtime: 0.00s runtime: 4.00s overhead: 4.00s
|
12
12
|
REPORT
|
13
13
|
|
14
14
|
context 'on non default coverage expectation' do
|
15
|
-
|
15
|
+
with(:config) { { expected_coverage: 0.1r } }
|
16
16
|
|
17
17
|
it_reports <<-REPORT
|
18
18
|
(00/02) 100% - killtime: 0.00s runtime: 4.00s overhead: 4.00s
|
@@ -22,7 +22,7 @@ RSpec.describe Mutant::Reporter::CLI::Printer::StatusProgressive do
|
|
22
22
|
|
23
23
|
context 'with scheduler active on one subject' do
|
24
24
|
context 'without progress' do
|
25
|
-
|
25
|
+
with(:status) { { active_jobs: [].to_set } }
|
26
26
|
|
27
27
|
it_reports(<<-REPORT)
|
28
28
|
(02/02) 100% - killtime: 2.00s runtime: 4.00s overhead: 2.00s
|
@@ -30,10 +30,10 @@ RSpec.describe Mutant::Reporter::CLI::Printer::StatusProgressive do
|
|
30
30
|
end
|
31
31
|
|
32
32
|
context 'with progress' do
|
33
|
-
|
33
|
+
with(:status) { { active_jobs: [job_b, job_a].to_set } }
|
34
34
|
|
35
35
|
context 'on failure' do
|
36
|
-
|
36
|
+
with(:mutation_a_test_result) { { passed: true } }
|
37
37
|
|
38
38
|
it_reports(<<-REPORT)
|
39
39
|
(01/02) 50% - killtime: 2.00s runtime: 4.00s overhead: 2.00s
|
@@ -5,7 +5,7 @@ RSpec.describe Mutant::Reporter::CLI::Printer::Status do
|
|
5
5
|
|
6
6
|
describe '.call' do
|
7
7
|
context 'with empty scheduler' do
|
8
|
-
|
8
|
+
with(:env_result) { { subject_results: [] } }
|
9
9
|
|
10
10
|
it_reports <<-REPORT
|
11
11
|
Mutant configuration:
|
@@ -28,7 +28,7 @@ RSpec.describe Mutant::Reporter::CLI::Printer::Status do
|
|
28
28
|
REPORT
|
29
29
|
|
30
30
|
context 'on non default coverage expectation' do
|
31
|
-
|
31
|
+
with(:config) { { expected_coverage: 0.1r } }
|
32
32
|
|
33
33
|
it_reports <<-REPORT
|
34
34
|
Mutant configuration:
|
@@ -54,7 +54,7 @@ RSpec.describe Mutant::Reporter::CLI::Printer::Status do
|
|
54
54
|
|
55
55
|
context 'with scheduler active on one subject' do
|
56
56
|
context 'without progress' do
|
57
|
-
|
57
|
+
with(:status) { { active_jobs: [].to_set } }
|
58
58
|
|
59
59
|
it_reports(<<-REPORT)
|
60
60
|
Mutant configuration:
|
@@ -78,10 +78,10 @@ RSpec.describe Mutant::Reporter::CLI::Printer::Status do
|
|
78
78
|
end
|
79
79
|
|
80
80
|
context 'with progress' do
|
81
|
-
|
81
|
+
with(:status) { { active_jobs: [job_b, job_a].to_set } }
|
82
82
|
|
83
83
|
context 'on failure' do
|
84
|
-
|
84
|
+
with(:mutation_a_test_result) { { passed: true } }
|
85
85
|
|
86
86
|
it_reports(<<-REPORT)
|
87
87
|
Mutant configuration:
|
@@ -13,7 +13,7 @@ RSpec.describe Mutant::Reporter::CLI::Printer::SubjectProgress do
|
|
13
13
|
end
|
14
14
|
|
15
15
|
context 'on partial coverage' do
|
16
|
-
|
16
|
+
with(:mutation_a_test_result) { { passed: true } }
|
17
17
|
|
18
18
|
it_reports <<-'STR'
|
19
19
|
subject-a mutations: 2
|
@@ -23,7 +23,7 @@ RSpec.describe Mutant::Reporter::CLI::Printer::SubjectProgress do
|
|
23
23
|
end
|
24
24
|
|
25
25
|
context 'without results' do
|
26
|
-
|
26
|
+
with(:subject_a_result) { { mutation_results: [] } }
|
27
27
|
|
28
28
|
it_reports <<-'STR'
|
29
29
|
subject-a mutations: 2
|