mutant 0.8.22 → 0.8.23

Sign up to get free protection for your applications and to get access to all the features.
@@ -4,15 +4,20 @@ RSpec.describe Mutant::Isolation::None do
4
4
  describe '.call' do
5
5
  let(:object) { described_class.new }
6
6
 
7
- it 'return block value' do
8
- expect(object.call { :foo }).to be(:foo)
7
+ context 'without exception' do
8
+ it 'returns success result' do
9
+ expect(object.call { :foo })
10
+ .to eql(Mutant::Isolation::Result::Success.new(:foo))
11
+ end
9
12
  end
10
13
 
11
- it 'wraps *all* exceptions' do
12
- expect { object.call { fail 'foo' } }.to raise_error(
13
- Mutant::Isolation::Error,
14
- 'foo'
15
- )
14
+ context 'with exception' do
15
+ let(:exception) { RuntimeError.new('foo') }
16
+
17
+ it 'returns error result' do
18
+ expect(object.call { fail exception })
19
+ .to eql(Mutant::Isolation::Result::Exception.new(exception))
20
+ end
16
21
  end
17
22
  end
18
23
  end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Mutant::Isolation::Result do
4
+ describe '#success?' do
5
+ let(:value) { double('Object') }
6
+
7
+ def apply
8
+ effective_class.new(value).success?
9
+ end
10
+
11
+ context 'on success instance' do
12
+ let(:effective_class) { described_class::Success }
13
+
14
+ it 'returns true' do
15
+ expect(apply).to be(true)
16
+ end
17
+ end
18
+
19
+ context 'on error instance' do
20
+ let(:effective_class) { described_class::Exception }
21
+
22
+ it 'returns false' do
23
+ expect(apply).to be(false)
24
+ end
25
+ end
26
+ end
27
+
28
+ describe 'add_error' do
29
+ let(:other) { described_class::Success.new(object) }
30
+ let(:value) { double('Object') }
31
+ let(:object) { described_class::Success.new(value) }
32
+
33
+ def apply
34
+ object.add_error(other)
35
+ end
36
+
37
+ it 'returns chain instance' do
38
+ expect(apply).to eql(described_class::ErrorChain.new(other, object))
39
+ end
40
+ end
41
+ end
@@ -5,7 +5,7 @@ RSpec.describe Mutant::Loader, '.call' do
5
5
  described_class.call(
6
6
  binding: binding,
7
7
  kernel: kernel,
8
- node: node,
8
+ source: source,
9
9
  subject: mutation_subject
10
10
  )
11
11
  end
@@ -27,10 +27,6 @@ RSpec.describe Mutant::Loader, '.call' do
27
27
  end
28
28
 
29
29
  it 'performs expected kernel interaction' do
30
- expect(Unparser).to receive(:unparse)
31
- .with(node)
32
- .and_return(source)
33
-
34
30
  expect(kernel).to receive(:eval)
35
31
  .with(
36
32
  source,
@@ -26,8 +26,9 @@ RSpec.describe Mutant::Mutation do
26
26
  describe '#insert' do
27
27
  subject { object.insert(kernel) }
28
28
 
29
- let(:root_node) { s(:foo) }
30
- let(:kernel) { instance_double(Kernel) }
29
+ let(:expected_source) { '1' }
30
+ let(:kernel) { instance_double(Kernel) }
31
+ let(:root_node) { s(:int, 1) }
31
32
 
32
33
  before do
33
34
  expect(context).to receive(:root)
@@ -43,7 +44,7 @@ RSpec.describe Mutant::Mutation do
43
44
  .with(
44
45
  binding: TOPLEVEL_BINDING,
45
46
  kernel: kernel,
46
- node: root_node,
47
+ source: expected_source,
47
48
  subject: mutation_subject
48
49
  )
49
50
  .and_return(Mutant::Loader)
@@ -0,0 +1,124 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Mutant::Reporter::CLI::Printer::IsolationResult do
4
+ setup_shared_context
5
+
6
+ describe '.call' do
7
+ context 'on sucessful isolation' do
8
+ let(:reportable) do
9
+ Mutant::Isolation::Result::Success.new(mutation_a_test_result)
10
+ end
11
+
12
+ it_reports <<~'STR'
13
+ - 1 @ runtime: 1.0
14
+ - test-a
15
+ Test Output:
16
+ mutation a test result output
17
+ STR
18
+ end
19
+
20
+ context 'on exception isolation error' do
21
+ let(:exception) do
22
+ Class.new(RuntimeError) do
23
+ def inspect
24
+ '<TestException>'
25
+ end
26
+
27
+ def backtrace
28
+ %w[first last]
29
+ end
30
+ end.new('foo')
31
+ end
32
+
33
+ let(:reportable) do
34
+ Mutant::Isolation::Result::Exception.new(exception)
35
+ end
36
+
37
+ it_reports <<~'STR'
38
+ Killing the mutation resulted in an integration error.
39
+ This is the case when the tests selected for the current mutation
40
+ did not produce a test result, but instead an exception was raised.
41
+
42
+ This may point to the following problems:
43
+ * Bug in mutant
44
+ * Bug in the ruby interpreter
45
+ * Bug in your test suite
46
+ * Bug in your test suite under concurrency
47
+
48
+ The following exception was raised:
49
+
50
+ ```
51
+ <TestException>
52
+ first
53
+ last
54
+ ```
55
+ STR
56
+ end
57
+
58
+ context 'on fork isolation error' do
59
+ let(:reportable) do
60
+ Mutant::Isolation::Fork::ForkError.new
61
+ end
62
+
63
+ it_reports <<~'STR'
64
+ Forking the child process to isolate the mutation in failed.
65
+ This meant that either the RubyVM or your OS was under too much
66
+ pressure to add another child process.
67
+
68
+ Possible solutions are:
69
+ * Reduce concurrency
70
+ * Reduce locks
71
+ STR
72
+ end
73
+
74
+ context 'on child isolation error' do
75
+ let(:reportable) do
76
+ Mutant::Isolation::Fork::ChildError.new(
77
+ instance_double(
78
+ Process::Status,
79
+ 'unsuccessful status'
80
+ )
81
+ )
82
+ end
83
+
84
+ it_reports <<~'STR'
85
+ Killfork exited nonzero. Its result (if any) was ignored:
86
+ #<InstanceDouble(Process::Status) "unsuccessful status">
87
+ STR
88
+ end
89
+
90
+ context 'on child isolation error' do
91
+ let(:fork_error) do
92
+ Mutant::Isolation::Fork::ForkError.new
93
+ end
94
+
95
+ let(:child_error) do
96
+ Mutant::Isolation::Fork::ChildError.new(
97
+ instance_double(
98
+ Process::Status,
99
+ 'unsuccessful status'
100
+ )
101
+ )
102
+ end
103
+
104
+ let(:reportable) do
105
+ Mutant::Isolation::Result::ErrorChain.new(
106
+ fork_error,
107
+ child_error
108
+ )
109
+ end
110
+
111
+ it_reports <<~'STR'
112
+ Forking the child process to isolate the mutation in failed.
113
+ This meant that either the RubyVM or your OS was under too much
114
+ pressure to add another child process.
115
+
116
+ Possible solutions are:
117
+ * Reduce concurrency
118
+ * Reduce locks
119
+ Killfork exited nonzero. Its result (if any) was ignored:
120
+ #<InstanceDouble(Process::Status) "unsuccessful status">
121
+ STR
122
+ end
123
+ end
124
+ end
@@ -6,7 +6,27 @@ RSpec.describe Mutant::Reporter::CLI::Printer::MutationResult do
6
6
  let(:reportable) { mutation_a_result }
7
7
 
8
8
  describe '.call' do
9
- context 'failed kill' do
9
+ context 'isolation problem' do
10
+ let(:status) do
11
+ instance_double(Process::Status)
12
+ end
13
+
14
+ let(:mutation_a_isolation_result) do
15
+ Mutant::Isolation::Fork::ChildError.new(status)
16
+ end
17
+
18
+ it_reports(<<~'REPORT')
19
+ evil:subject-a:d27d2
20
+ @@ -1,2 +1,2 @@
21
+ -true
22
+ +false
23
+ Killfork exited nonzero. Its result (if any) was ignored:
24
+ #<InstanceDouble(Process::Status) (anonymous)>
25
+ -----------------------
26
+ REPORT
27
+ end
28
+
29
+ context 'unsucessful result' do
10
30
  with(:mutation_a_test_result) { { passed: true } }
11
31
 
12
32
  context 'on evil mutation' do
@@ -80,11 +100,6 @@ RSpec.describe Mutant::Reporter::CLI::Printer::MutationResult do
80
100
  s(:true)
81
101
  Unparsed Source:
82
102
  true
83
- Test Result:
84
- - 1 @ runtime: 1.0
85
- - test-a
86
- Test Output:
87
- mutation a test result output
88
103
  -----------------------
89
104
  REPORT
90
105
  end
@@ -101,11 +116,6 @@ RSpec.describe Mutant::Reporter::CLI::Printer::MutationResult do
101
116
  ---- Noop failure -----
102
117
  No code was inserted. And the test did NOT PASS.
103
118
  This is typically a problem of your specs not passing unmutated.
104
- Test Result:
105
- - 1 @ runtime: 1.0
106
- - test-a
107
- Test Output:
108
- mutation a test result output
109
119
  -----------------------
110
120
  REPORT
111
121
  end
@@ -5,13 +5,16 @@ RSpec.describe Mutant::Result::Env do
5
5
  described_class.new(
6
6
  runtime: instance_double(Float),
7
7
  env: env,
8
- subject_results: [subject_result]
8
+ subject_results: subject_results
9
9
  )
10
10
  end
11
11
 
12
+ let(:subject_results) { [subject_result] }
13
+
12
14
  let(:env) do
13
15
  instance_double(
14
16
  Mutant::Env,
17
+ config: instance_double(Mutant::Config, fail_fast: fail_fast),
15
18
  subjects: [instance_double(Mutant::Subject)],
16
19
  mutations: [instance_double(Mutant::Mutation)]
17
20
  )
@@ -22,12 +25,14 @@ RSpec.describe Mutant::Result::Env do
22
25
  Mutant::Result::Subject,
23
26
  amount_mutation_results: results,
24
27
  amount_mutations_killed: killed,
25
- success?: true
28
+ success?: subject_success?
26
29
  )
27
30
  end
28
31
 
29
- let(:results) { 1 }
30
- let(:killed) { 0 }
32
+ let(:fail_fast) { false }
33
+ let(:killed) { 0 }
34
+ let(:results) { 1 }
35
+ let(:subject_success?) { true }
31
36
 
32
37
  describe '#success?' do
33
38
  subject { object.success? }
@@ -81,4 +86,46 @@ RSpec.describe Mutant::Result::Env do
81
86
 
82
87
  it { should eql(1) }
83
88
  end
89
+
90
+ describe '#stop?' do
91
+ subject { object.stop? }
92
+
93
+ context 'without fail fast' do
94
+ context 'on empty subjects' do
95
+ let(:subject_results) { [] }
96
+
97
+ it { should be(false) }
98
+ end
99
+
100
+ context 'on failed subject' do
101
+ let(:subject_success?) { false }
102
+
103
+ it { should be(false) }
104
+ end
105
+
106
+ context 'on successful subject' do
107
+ it { should be(false) }
108
+ end
109
+ end
110
+
111
+ context 'with fail fast' do
112
+ let(:fail_fast) { true }
113
+
114
+ context 'on empty subjects' do
115
+ let(:subject_results) { [] }
116
+
117
+ it { should be(false) }
118
+ end
119
+
120
+ context 'on failed subject' do
121
+ let(:subject_success?) { false }
122
+
123
+ it { should be(true) }
124
+ end
125
+
126
+ context 'on successful subject' do
127
+ it { should be(false) }
128
+ end
129
+ end
130
+ end
84
131
  end
@@ -3,8 +3,9 @@
3
3
  RSpec.describe Mutant::Result::Mutation do
4
4
  let(:object) do
5
5
  described_class.new(
6
- mutation: mutation,
7
- test_result: test_result
6
+ isolation_result: isolation_result,
7
+ mutation: mutation,
8
+ runtime: 2.0
8
9
  )
9
10
  end
10
11
 
@@ -17,23 +18,53 @@ RSpec.describe Mutant::Result::Mutation do
17
18
  )
18
19
  end
19
20
 
21
+ let(:isolation_result) do
22
+ Mutant::Isolation::Result::Success.new(test_result)
23
+ end
24
+
25
+ shared_examples_for 'unsuccessful isolation' do
26
+ let(:isolation_result) do
27
+ Mutant::Isolation::Result::Exception.new(RuntimeError.new('foo'))
28
+ end
29
+ end
30
+
31
+ describe '#killtime' do
32
+ subject { object.killtime }
33
+
34
+ context 'if isolation is successful' do
35
+ it { should eql(1.0) }
36
+ end
37
+
38
+ context 'if isolation is not successful' do
39
+ include_context 'unsuccessful isolation'
40
+
41
+ it { should eql(0.0) }
42
+ end
43
+ end
44
+
20
45
  describe '#runtime' do
21
46
  subject { object.runtime }
22
47
 
23
- it { should eql(1.0) }
48
+ it { should eql(2.0) }
24
49
  end
25
50
 
26
51
  describe '#success?' do
27
52
  subject { object.success? }
28
53
 
29
- let(:result) { double('result boolean') }
54
+ context 'if isolation is successful' do
55
+ before do
56
+ expect(mutation.class).to receive(:success?)
57
+ .with(test_result)
58
+ .and_return(true)
59
+ end
30
60
 
31
- before do
32
- expect(mutation.class).to receive(:success?)
33
- .with(test_result)
34
- .and_return(result)
61
+ it { should be(true) }
35
62
  end
36
63
 
37
- it { should be(result) }
64
+ context 'if isolation is not successful' do
65
+ include_context 'unsuccessful isolation'
66
+
67
+ it { should be(false) }
68
+ end
38
69
  end
39
70
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mutant
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.22
4
+ version: 0.8.23
5
5
  platform: ruby
6
6
  authors:
7
7
  - Markus Schirp
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-12-04 00:00:00.000000000 Z
11
+ date: 2018-12-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: abstract_type
@@ -412,6 +412,7 @@ files:
412
412
  - lib/mutant/reporter/cli/printer/config.rb
413
413
  - lib/mutant/reporter/cli/printer/env_progress.rb
414
414
  - lib/mutant/reporter/cli/printer/env_result.rb
415
+ - lib/mutant/reporter/cli/printer/isolation_result.rb
415
416
  - lib/mutant/reporter/cli/printer/mutation_progress_result.rb
416
417
  - lib/mutant/reporter/cli/printer/mutation_result.rb
417
418
  - lib/mutant/reporter/cli/printer/status.rb
@@ -570,6 +571,7 @@ files:
570
571
  - spec/unit/mutant/integration_spec.rb
571
572
  - spec/unit/mutant/isolation/fork_spec.rb
572
573
  - spec/unit/mutant/isolation/none_spec.rb
574
+ - spec/unit/mutant/isolation/result_spec.rb
573
575
  - spec/unit/mutant/loader_spec.rb
574
576
  - spec/unit/mutant/matcher/chain_spec.rb
575
577
  - spec/unit/mutant/matcher/compiler/subject_prefix_spec.rb
@@ -600,6 +602,7 @@ files:
600
602
  - spec/unit/mutant/reporter/cli/printer/config_spec.rb
601
603
  - spec/unit/mutant/reporter/cli/printer/env_progress_spec.rb
602
604
  - spec/unit/mutant/reporter/cli/printer/env_result_spec.rb
605
+ - spec/unit/mutant/reporter/cli/printer/isolation_result_spec.rb
603
606
  - spec/unit/mutant/reporter/cli/printer/mutation_progress_result_spec.rb
604
607
  - spec/unit/mutant/reporter/cli/printer/mutation_result_spec.rb
605
608
  - spec/unit/mutant/reporter/cli/printer/status_progressive_spec.rb
@@ -659,7 +662,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
659
662
  version: '0'
660
663
  requirements: []
661
664
  rubyforge_project:
662
- rubygems_version: 2.7.6
665
+ rubygems_version: 3.0.0.beta2
663
666
  signing_key:
664
667
  specification_version: 4
665
668
  summary: Mutation testing tool for ruby under MRI and Rubinius
@@ -704,6 +707,7 @@ test_files:
704
707
  - spec/unit/mutant/integration_spec.rb
705
708
  - spec/unit/mutant/isolation/fork_spec.rb
706
709
  - spec/unit/mutant/isolation/none_spec.rb
710
+ - spec/unit/mutant/isolation/result_spec.rb
707
711
  - spec/unit/mutant/loader_spec.rb
708
712
  - spec/unit/mutant/matcher/chain_spec.rb
709
713
  - spec/unit/mutant/matcher/compiler/subject_prefix_spec.rb
@@ -734,6 +738,7 @@ test_files:
734
738
  - spec/unit/mutant/reporter/cli/printer/config_spec.rb
735
739
  - spec/unit/mutant/reporter/cli/printer/env_progress_spec.rb
736
740
  - spec/unit/mutant/reporter/cli/printer/env_result_spec.rb
741
+ - spec/unit/mutant/reporter/cli/printer/isolation_result_spec.rb
737
742
  - spec/unit/mutant/reporter/cli/printer/mutation_progress_result_spec.rb
738
743
  - spec/unit/mutant/reporter/cli/printer/mutation_result_spec.rb
739
744
  - spec/unit/mutant/reporter/cli/printer/status_progressive_spec.rb