mutant 0.8.8 → 0.8.9

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.
Files changed (211) hide show
  1. checksums.yaml +4 -4
  2. data/Changelog.md +9 -0
  3. data/README.md +1 -1
  4. data/Rakefile +12 -8
  5. data/bin/mutant +5 -1
  6. data/config/flay.yml +1 -1
  7. data/lib/mutant.rb +18 -17
  8. data/lib/mutant/actor.rb +1 -7
  9. data/lib/mutant/actor/env.rb +0 -4
  10. data/lib/mutant/actor/mailbox.rb +0 -4
  11. data/lib/mutant/actor/receiver.rb +0 -4
  12. data/lib/mutant/actor/sender.rb +0 -2
  13. data/lib/mutant/ast.rb +1 -5
  14. data/lib/mutant/ast/meta/const.rb +0 -2
  15. data/lib/mutant/ast/meta/optarg.rb +0 -2
  16. data/lib/mutant/ast/meta/send.rb +0 -12
  17. data/lib/mutant/ast/named_children.rb +0 -10
  18. data/lib/mutant/ast/sexp.rb +1 -5
  19. data/lib/mutant/cli.rb +19 -38
  20. data/lib/mutant/color.rb +1 -7
  21. data/lib/mutant/config.rb +11 -7
  22. data/lib/mutant/context.rb +0 -4
  23. data/lib/mutant/context/scope.rb +0 -18
  24. data/lib/mutant/delegator.rb +0 -6
  25. data/lib/mutant/diff.rb +0 -18
  26. data/lib/mutant/env.rb +8 -24
  27. data/lib/mutant/env/bootstrap.rb +18 -41
  28. data/lib/mutant/expression.rb +0 -8
  29. data/lib/mutant/expression/method.rb +6 -7
  30. data/lib/mutant/expression/methods.rb +5 -9
  31. data/lib/mutant/expression/namespace.rb +0 -13
  32. data/lib/mutant/expression/parser.rb +0 -6
  33. data/lib/mutant/integration.rb +2 -20
  34. data/lib/mutant/isolation.rb +0 -4
  35. data/lib/mutant/loader.rb +20 -35
  36. data/lib/mutant/matcher.rb +1 -1
  37. data/lib/mutant/matcher/chain.rb +1 -3
  38. data/lib/mutant/matcher/compiler.rb +0 -8
  39. data/lib/mutant/matcher/config.rb +2 -10
  40. data/lib/mutant/matcher/filter.rb +1 -3
  41. data/lib/mutant/matcher/method.rb +4 -26
  42. data/lib/mutant/matcher/method/instance.rb +1 -7
  43. data/lib/mutant/matcher/method/singleton.rb +0 -12
  44. data/lib/mutant/matcher/methods.rb +1 -19
  45. data/lib/mutant/matcher/namespace.rb +1 -7
  46. data/lib/mutant/matcher/null.rb +1 -3
  47. data/lib/mutant/matcher/scope.rb +1 -5
  48. data/lib/mutant/matcher/static.rb +0 -2
  49. data/lib/mutant/meta.rb +0 -2
  50. data/lib/mutant/meta/example.rb +0 -28
  51. data/lib/mutant/meta/example/dsl.rb +2 -16
  52. data/lib/mutant/mutation.rb +9 -18
  53. data/lib/mutant/mutator.rb +0 -24
  54. data/lib/mutant/mutator/node.rb +1 -33
  55. data/lib/mutant/mutator/node/and_asgn.rb +0 -2
  56. data/lib/mutant/mutator/node/argument.rb +0 -10
  57. data/lib/mutant/mutator/node/arguments.rb +0 -12
  58. data/lib/mutant/mutator/node/begin.rb +0 -4
  59. data/lib/mutant/mutator/node/binary.rb +2 -11
  60. data/lib/mutant/mutator/node/block.rb +0 -6
  61. data/lib/mutant/mutator/node/break.rb +0 -2
  62. data/lib/mutant/mutator/node/case.rb +0 -6
  63. data/lib/mutant/mutator/node/conditional_loop.rb +0 -2
  64. data/lib/mutant/mutator/node/const.rb +1 -3
  65. data/lib/mutant/mutator/node/define.rb +4 -11
  66. data/lib/mutant/mutator/node/defined.rb +0 -2
  67. data/lib/mutant/mutator/node/dstr.rb +0 -2
  68. data/lib/mutant/mutator/node/dsym.rb +0 -2
  69. data/lib/mutant/mutator/node/generic.rb +1 -3
  70. data/lib/mutant/mutator/node/if.rb +0 -8
  71. data/lib/mutant/mutator/node/kwbegin.rb +0 -2
  72. data/lib/mutant/mutator/node/literal/array.rb +0 -4
  73. data/lib/mutant/mutator/node/literal/boolean.rb +0 -2
  74. data/lib/mutant/mutator/node/literal/fixnum.rb +0 -6
  75. data/lib/mutant/mutator/node/literal/float.rb +0 -6
  76. data/lib/mutant/mutator/node/literal/hash.rb +0 -6
  77. data/lib/mutant/mutator/node/literal/nil.rb +0 -2
  78. data/lib/mutant/mutator/node/literal/range.rb +0 -8
  79. data/lib/mutant/mutator/node/literal/regex.rb +0 -4
  80. data/lib/mutant/mutator/node/literal/string.rb +0 -2
  81. data/lib/mutant/mutator/node/literal/symbol.rb +0 -2
  82. data/lib/mutant/mutator/node/masgn.rb +0 -2
  83. data/lib/mutant/mutator/node/match_current_line.rb +0 -2
  84. data/lib/mutant/mutator/node/mlhs.rb +0 -2
  85. data/lib/mutant/mutator/node/named_value/access.rb +0 -8
  86. data/lib/mutant/mutator/node/named_value/constant_assignment.rb +1 -7
  87. data/lib/mutant/mutator/node/named_value/variable_assignment.rb +0 -4
  88. data/lib/mutant/mutator/node/next.rb +0 -2
  89. data/lib/mutant/mutator/node/noop.rb +0 -2
  90. data/lib/mutant/mutator/node/nthref.rb +0 -2
  91. data/lib/mutant/mutator/node/op_asgn.rb +0 -2
  92. data/lib/mutant/mutator/node/or_asgn.rb +0 -2
  93. data/lib/mutant/mutator/node/resbody.rb +0 -4
  94. data/lib/mutant/mutator/node/rescue.rb +0 -10
  95. data/lib/mutant/mutator/node/return.rb +0 -2
  96. data/lib/mutant/mutator/node/send.rb +4 -32
  97. data/lib/mutant/mutator/node/send/attribute_assignment.rb +0 -6
  98. data/lib/mutant/mutator/node/send/binary.rb +0 -6
  99. data/lib/mutant/mutator/node/send/index.rb +0 -6
  100. data/lib/mutant/mutator/node/splat.rb +0 -2
  101. data/lib/mutant/mutator/node/super.rb +0 -2
  102. data/lib/mutant/mutator/node/when.rb +0 -10
  103. data/lib/mutant/mutator/node/yield.rb +0 -2
  104. data/lib/mutant/mutator/node/zsuper.rb +0 -2
  105. data/lib/mutant/mutator/registry.rb +0 -6
  106. data/lib/mutant/mutator/util.rb +0 -4
  107. data/lib/mutant/mutator/util/array.rb +0 -6
  108. data/lib/mutant/mutator/util/symbol.rb +0 -2
  109. data/lib/mutant/parallel.rb +21 -17
  110. data/lib/mutant/parallel/master.rb +0 -28
  111. data/lib/mutant/parallel/source.rb +0 -10
  112. data/lib/mutant/parallel/worker.rb +15 -10
  113. data/lib/mutant/parser.rb +23 -0
  114. data/lib/mutant/reporter.rb +5 -8
  115. data/lib/mutant/reporter/cli.rb +1 -15
  116. data/lib/mutant/reporter/cli/format.rb +3 -25
  117. data/lib/mutant/reporter/cli/printer.rb +0 -18
  118. data/lib/mutant/reporter/cli/printer/config.rb +0 -2
  119. data/lib/mutant/reporter/cli/printer/env_progress.rb +0 -2
  120. data/lib/mutant/reporter/cli/printer/env_result.rb +0 -2
  121. data/lib/mutant/reporter/cli/printer/mutation_progress_result.rb +0 -4
  122. data/lib/mutant/reporter/cli/printer/mutation_result.rb +0 -16
  123. data/lib/mutant/reporter/cli/printer/status.rb +0 -6
  124. data/lib/mutant/reporter/cli/printer/status_progressive.rb +0 -4
  125. data/lib/mutant/reporter/cli/printer/subject_progress.rb +0 -8
  126. data/lib/mutant/reporter/cli/printer/subject_result.rb +0 -2
  127. data/lib/mutant/reporter/cli/printer/test_result.rb +0 -2
  128. data/lib/mutant/reporter/cli/tput.rb +0 -4
  129. data/lib/mutant/repository.rb +4 -22
  130. data/lib/mutant/require_highjack.rb +0 -2
  131. data/lib/mutant/result.rb +23 -43
  132. data/lib/mutant/runner.rb +7 -20
  133. data/lib/mutant/runner/sink.rb +43 -86
  134. data/lib/mutant/selector.rb +0 -2
  135. data/lib/mutant/selector/expression.rb +0 -2
  136. data/lib/mutant/subject.rb +0 -22
  137. data/lib/mutant/subject/method.rb +2 -10
  138. data/lib/mutant/subject/method/instance.rb +0 -6
  139. data/lib/mutant/subject/method/singleton.rb +0 -2
  140. data/lib/mutant/test.rb +4 -3
  141. data/lib/mutant/version.rb +1 -1
  142. data/lib/mutant/warning_filter.rb +0 -10
  143. data/lib/mutant/zombifier.rb +5 -20
  144. data/meta/or_asgn.rb +6 -0
  145. data/meta/send.rb +29 -0
  146. data/mutant-rspec.gemspec +1 -1
  147. data/spec/integration/mutant/rspec_spec.rb +1 -1
  148. data/spec/integrations.yml +2 -3
  149. data/spec/shared/method_matcher_behavior.rb +7 -7
  150. data/spec/spec_helper.rb +2 -9
  151. data/spec/support/corpus.rb +37 -30
  152. data/spec/support/rb_bug.rb +1 -2
  153. data/spec/support/ruby_vm.rb +6 -3
  154. data/spec/support/shared_context.rb +19 -20
  155. data/spec/unit/mutant/actor/binding_spec.rb +6 -6
  156. data/spec/unit/mutant/actor/env_spec.rb +2 -2
  157. data/spec/unit/mutant/actor/mailbox_spec.rb +6 -6
  158. data/spec/unit/mutant/actor/message_spec.rb +2 -2
  159. data/spec/unit/mutant/actor/receiver_spec.rb +4 -4
  160. data/spec/unit/mutant/actor/sender_spec.rb +6 -6
  161. data/spec/unit/mutant/ast_spec.rb +9 -0
  162. data/spec/unit/mutant/cli_spec.rb +16 -10
  163. data/spec/unit/mutant/context/scope/root_spec.rb +1 -1
  164. data/spec/unit/mutant/context/scope/unqualified_name_spec.rb +1 -1
  165. data/spec/unit/mutant/context/scope_spec.rb +3 -3
  166. data/spec/unit/mutant/context_spec.rb +0 -22
  167. data/spec/unit/mutant/env/boostrap_spec.rb +34 -41
  168. data/spec/unit/mutant/env_spec.rb +74 -32
  169. data/spec/unit/mutant/integration/rspec_spec.rb +23 -17
  170. data/spec/unit/mutant/integration_spec.rb +4 -4
  171. data/spec/unit/mutant/isolation_spec.rb +4 -4
  172. data/spec/unit/mutant/loader_spec.rb +42 -0
  173. data/spec/unit/mutant/matcher/compiler_spec.rb +3 -3
  174. data/spec/unit/mutant/matcher/config_spec.rb +1 -1
  175. data/spec/unit/mutant/matcher/method/instance_spec.rb +8 -1
  176. data/spec/unit/mutant/matcher/method/singleton_spec.rb +8 -1
  177. data/spec/unit/mutant/matcher/namespace_spec.rb +7 -8
  178. data/spec/unit/mutant/matcher/null_spec.rb +3 -2
  179. data/spec/unit/mutant/mutation_spec.rb +11 -5
  180. data/spec/unit/mutant/mutator/registry_spec.rb +1 -1
  181. data/spec/unit/mutant/parallel/master_spec.rb +9 -9
  182. data/spec/unit/mutant/parallel/source/array_spec.rb +3 -3
  183. data/spec/unit/mutant/parallel/worker_spec.rb +5 -5
  184. data/spec/unit/mutant/parallel_spec.rb +4 -4
  185. data/spec/unit/mutant/parser_spec.rb +24 -0
  186. data/spec/unit/mutant/reporter/cli/printer_spec.rb +3 -3
  187. data/spec/unit/mutant/reporter/cli/tput_spec.rb +2 -2
  188. data/spec/unit/mutant/reporter/cli_spec.rb +7 -7
  189. data/spec/unit/mutant/reporter/null_spec.rb +5 -4
  190. data/spec/unit/mutant/repository/diff_spec.rb +30 -18
  191. data/spec/unit/mutant/repository/subject_filter_spec.rb +5 -5
  192. data/spec/unit/mutant/require_highjack_spec.rb +1 -1
  193. data/spec/unit/mutant/result/env_spec.rb +9 -9
  194. data/spec/unit/mutant/result/subject_spec.rb +5 -5
  195. data/spec/unit/mutant/runner/driver_spec.rb +4 -4
  196. data/spec/unit/mutant/runner/{sink/mutation_spec.rb → sink_spec.rb} +16 -4
  197. data/spec/unit/mutant/runner_spec.rb +31 -31
  198. data/spec/unit/mutant/selector/expression_spec.rb +8 -8
  199. data/spec/unit/mutant/subject/method/instance_spec.rb +9 -3
  200. data/spec/unit/mutant/subject/method/singleton_spec.rb +1 -1
  201. data/spec/unit/mutant/subject_spec.rb +1 -5
  202. data/spec/unit/mutant_spec.rb +3 -3
  203. metadata +9 -15
  204. data/config/mutant.yml +0 -14
  205. data/lib/mutant/cache.rb +0 -29
  206. data/lib/mutant/reporter/trace.rb +0 -36
  207. data/spec/support/rspec.rb +0 -21
  208. data/spec/unit/mutant/cache_spec.rb +0 -22
  209. data/spec/unit/mutant/loader/eval_spec.rb +0 -44
  210. data/spec/unit/mutant/reporter/trace_spec.rb +0 -21
  211. data/test_app/Gemfile.rspec3.2 +0 -7
@@ -1,6 +1,6 @@
1
1
  RSpec.describe Mutant::Actor::Env do
2
- let(:thread) { double('Thread') }
3
- let(:thread_root) { double('Thread Root') }
2
+ let(:thread) { instance_double(Thread) }
3
+ let(:thread_root) { instance_double(Thread.singleton_class) }
4
4
 
5
5
  let(:object) { described_class.new(thread_root) }
6
6
 
@@ -1,6 +1,6 @@
1
1
  RSpec.describe Mutant::Actor::Mailbox do
2
- let(:mutex) { double('Mutex') }
3
- let(:condition_variable) { double('Mutex') }
2
+ let(:mutex) { instance_double(Mutex) }
3
+ let(:condition_variable) { instance_double(ConditionVariable) }
4
4
 
5
5
  before do
6
6
  allow(Mutex).to receive(:new).and_return(mutex)
@@ -10,8 +10,8 @@ RSpec.describe Mutant::Actor::Mailbox do
10
10
  describe '.new' do
11
11
  subject { described_class.new }
12
12
 
13
- let(:object) { described_class.new }
14
- let(:thread) { double('Thread') }
13
+ let(:object) { described_class.new }
14
+ let(:thread) { instance_double(Thread) }
15
15
 
16
16
  its(:sender) { should eql(Mutant::Actor::Sender.new(condition_variable, mutex, [])) }
17
17
  its(:receiver) { should eql(Mutant::Actor::Receiver.new(condition_variable, mutex, [])) }
@@ -19,8 +19,8 @@ RSpec.describe Mutant::Actor::Mailbox do
19
19
  end
20
20
 
21
21
  describe '#bind' do
22
- let(:object) { described_class.new }
23
- let(:other) { double('Sender') }
22
+ let(:object) { described_class.new }
23
+ let(:other) { instance_double(Mutant::Actor::Sender) }
24
24
 
25
25
  subject { object.bind(other) }
26
26
 
@@ -1,7 +1,7 @@
1
1
  RSpec.describe Mutant::Actor::Message do
2
2
 
3
- let(:type) { double('Type') }
4
- let(:payload) { double('Payload') }
3
+ let(:type) { instance_double(Symbol) }
4
+ let(:payload) { instance_double(Object) }
5
5
 
6
6
  describe '.new' do
7
7
  subject { described_class.new(*arguments) }
@@ -1,8 +1,8 @@
1
1
  RSpec.describe Mutant::Actor::Receiver do
2
- let(:messages) { double('Messages') }
3
- let(:mutex) { double('Mutex') }
4
- let(:condition_variable) { double('Condition Variable') }
5
- let(:message) { double('Message') }
2
+ let(:messages) { instance_double(Array) }
3
+ let(:mutex) { instance_double(Mutex) }
4
+ let(:condition_variable) { instance_double(ConditionVariable) }
5
+ let(:message) { instance_double(Object) }
6
6
 
7
7
  let(:object) { described_class.new(condition_variable, mutex, messages) }
8
8
 
@@ -1,12 +1,12 @@
1
1
  RSpec.describe Mutant::Actor::Sender do
2
2
  let(:object) { described_class.new(condition_variable, mutex, messages) }
3
3
 
4
- let(:condition_variable) { double('Condition Variable') }
5
- let(:mutex) { double('Mutex') }
6
- let(:messages) { double('Messages') }
7
- let(:type) { double('Type') }
8
- let(:payload) { double('Payload') }
9
- let(:_message) { message(type, payload) }
4
+ let(:condition_variable) { instance_double(ConditionVariable) }
5
+ let(:mutex) { instance_double(Mutex) }
6
+ let(:messages) { instance_double(Array) }
7
+ let(:type) { instance_double(Symbol) }
8
+ let(:payload) { instance_double(Object) }
9
+ let(:_message) { message(type, payload) }
10
10
 
11
11
  describe '#call' do
12
12
  subject { object.call(_message) }
@@ -27,6 +27,15 @@ RSpec.describe Mutant::AST do
27
27
  end
28
28
  end
29
29
 
30
+ context 'on non Parser::AST::Node child' do
31
+ let(:block) { ->(node) { fail if node.equal?(child_a) } }
32
+ let(:child_a) { AST::Node.new(:foo) }
33
+
34
+ it 'does not yield that node' do
35
+ expect(path).to eql([])
36
+ end
37
+ end
38
+
30
39
  context 'when one node matches' do
31
40
  let(:block) { ->(node) { node.equal?(child_a) } }
32
41
 
@@ -18,10 +18,10 @@ RSpec.describe Mutant::CLI do
18
18
  describe '.run' do
19
19
  subject { object.run(arguments) }
20
20
 
21
- let(:arguments) { double('arguments') }
22
- let(:report) { double('Report', success?: report_success) }
23
- let(:config) { double('Config') }
24
- let(:env) { double('env') }
21
+ let(:arguments) { instance_double(Array) }
22
+ let(:report) { instance_double(Mutant::Result::Env, success?: report_success) }
23
+ let(:config) { instance_double(Mutant::Config) }
24
+ let(:env) { instance_double(Mutant::Env) }
25
25
 
26
26
  before do
27
27
  expect(Mutant::CLI).to receive(:call).with(arguments).and_return(config)
@@ -33,7 +33,7 @@ RSpec.describe Mutant::CLI do
33
33
  let(:report_success) { true }
34
34
 
35
35
  it 'exits failure' do
36
- expect(subject).to be(0)
36
+ expect(subject).to be(true)
37
37
  end
38
38
  end
39
39
 
@@ -41,7 +41,7 @@ RSpec.describe Mutant::CLI do
41
41
  let(:report_success) { false }
42
42
 
43
43
  it 'exits failure' do
44
- expect(subject).to be(1)
44
+ expect(subject).to be(false)
45
45
  end
46
46
  end
47
47
 
@@ -55,7 +55,7 @@ RSpec.describe Mutant::CLI do
55
55
 
56
56
  it 'exits failure' do
57
57
  expect($stderr).to receive(:puts).with('test-error')
58
- expect(subject).to be(1)
58
+ expect(subject).to be(false)
59
59
  end
60
60
  end
61
61
  end
@@ -110,7 +110,7 @@ RSpec.describe Mutant::CLI do
110
110
 
111
111
  before do
112
112
  expect($stdout).to receive(:puts).with(expected_message)
113
- expect(Kernel).to receive(:exit).with(0)
113
+ expect(Kernel).to receive(:exit)
114
114
  end
115
115
 
116
116
  it_should_behave_like 'a cli parser'
@@ -172,7 +172,7 @@ Options:
172
172
  let(:flags) { %w[--version] }
173
173
 
174
174
  before do
175
- expect(Kernel).to receive(:exit).with(0)
175
+ expect(Kernel).to receive(:exit)
176
176
  expect($stdout).to receive(:puts).with("mutant-#{Mutant::VERSION}")
177
177
  end
178
178
 
@@ -237,7 +237,13 @@ Options:
237
237
  let(:expected_matcher_config) do
238
238
  default_matcher_config.with(
239
239
  subject_filters: [
240
- Mutant::Repository::SubjectFilter.new(Mutant::Repository::Diff.new('HEAD', 'master'))
240
+ Mutant::Repository::SubjectFilter.new(
241
+ Mutant::Repository::Diff.new(
242
+ config: Mutant::Config::DEFAULT,
243
+ from: 'HEAD',
244
+ to: 'master'
245
+ )
246
+ )
241
247
  ]
242
248
  )
243
249
  end
@@ -2,7 +2,7 @@ RSpec.describe Mutant::Context::Scope, '#root' do
2
2
  subject { object.root(node) }
3
3
 
4
4
  let(:object) { described_class.new(TestApp::Literal, path) }
5
- let(:path) { double('Path') }
5
+ let(:path) { instance_double(Pathname) }
6
6
  let(:node) { parse(':node') }
7
7
 
8
8
  let(:scope) { subject.body }
@@ -1,7 +1,7 @@
1
1
  RSpec.describe Mutant::Context::Scope, '#unqualified_name' do
2
2
  subject { object.unqualified_name }
3
3
 
4
- let(:path) { double('Path') }
4
+ let(:path) { instance_double(Pathname) }
5
5
 
6
6
  context 'with top level constant name' do
7
7
  let(:object) { described_class.new(TestApp, path) }
@@ -1,7 +1,7 @@
1
1
  RSpec.describe Mutant::Context::Scope do
2
- let(:object) { described_class.new(scope, source_path) }
3
- let(:scope) { double('scope', name: double('name')) }
4
- let(:source_path) { double('source path') }
2
+ let(:object) { described_class.new(scope, source_path) }
3
+ let(:scope) { instance_double(Class, name: instance_double(String)) }
4
+ let(:source_path) { instance_double(Pathname) }
5
5
 
6
6
  describe '#identification' do
7
7
  subject { object.identification }
@@ -31,27 +31,5 @@ RSpec.describe Mutant::Context::Scope do
31
31
 
32
32
  it { should eql(expected) }
33
33
  end
34
-
35
- context 'with Class as scope' do
36
- let(:scope) { Mutant::Context }
37
-
38
- let(:expected) do
39
- s(:class,
40
- s(:const, nil, :Context),
41
- nil,
42
- s(:str, 'test')
43
- )
44
- end
45
-
46
- it { should eql(expected) }
47
- end
48
-
49
- context 'with anything else as scope' do
50
- let(:scope) { double(name: 'Foo') }
51
-
52
- it 'raises exception' do
53
- expect { subject }.to raise_error(RuntimeError, "Cannot wrap scope: #{scope.inspect}")
54
- end
55
- end
56
34
  end
57
35
  end
@@ -15,25 +15,25 @@ RSpec.describe Mutant::Env::Bootstrap do
15
15
 
16
16
  let(:config) do
17
17
  Mutant::Config::DEFAULT.with(
18
- jobs: 1,
19
- reporter: Mutant::Reporter::Trace.new,
20
18
  includes: [],
21
- requires: [],
22
19
  integration: integration_class,
23
- matcher: matcher_config
20
+ jobs: 1,
21
+ matcher: matcher_config,
22
+ reporter: instance_double(Mutant::Reporter),
23
+ requires: []
24
24
  )
25
25
  end
26
26
 
27
27
  let(:expected_env) do
28
28
  Mutant::Env.new(
29
- cache: Mutant::Cache.new,
30
- subjects: [],
29
+ actor_env: Mutant::Actor::Env.new(Thread),
30
+ config: config,
31
+ integration: integration,
31
32
  matchable_scopes: [],
32
33
  mutations: [],
33
- config: config,
34
+ parser: Mutant::Parser.new,
34
35
  selector: Mutant::Selector::Expression.new(integration),
35
- actor_env: Mutant::Actor::Env.new(Thread),
36
- integration: integration
36
+ subjects: []
37
37
  )
38
38
  end
39
39
 
@@ -41,12 +41,18 @@ RSpec.describe Mutant::Env::Bootstrap do
41
41
  it { should eql(expected_env) }
42
42
  end
43
43
 
44
+ def expect_warning
45
+ expect(config.reporter).to receive(:warn)
46
+ .with(expected_warning)
47
+ .and_return(config.reporter)
48
+ end
49
+
44
50
  before do
45
51
  expect(integration_class).to receive(:new)
46
52
  .with(config)
47
53
  .and_return(integration)
48
54
 
49
- expect(integration).to receive(:setup).and_return(integration)
55
+ expect(integration).to receive_messages(setup: integration)
50
56
 
51
57
  expect(ObjectSpace).to receive(:each_object)
52
58
  .with(Module)
@@ -54,17 +60,12 @@ RSpec.describe Mutant::Env::Bootstrap do
54
60
  end
55
61
 
56
62
  describe '#warn' do
57
- let(:object) { described_class.new(config) }
58
- let(:message) { instance_double(String) }
63
+ let(:object) { described_class.new(config) }
64
+ let(:expected_warning) { instance_double(String) }
59
65
 
60
- subject { object.warn(message) }
66
+ subject { object.warn(expected_warning) }
61
67
 
62
- it 'reports a warning' do
63
- expect { subject }
64
- .to change { object.config.reporter.warn_calls }
65
- .from([])
66
- .to([message])
67
- end
68
+ before { expect_warning }
68
69
 
69
70
  it_behaves_like 'a command method'
70
71
  end
@@ -75,6 +76,11 @@ RSpec.describe Mutant::Env::Bootstrap do
75
76
  context 'when Module#name calls result in exceptions' do
76
77
  let(:object_space_modules) { [invalid_class] }
77
78
 
79
+ let(:expected_warning) do
80
+ "Class#name from: #{invalid_class} raised an error: " \
81
+ "RuntimeError. #{Mutant::Env::SEMANTICS_MESSAGE}"
82
+ end
83
+
78
84
  let(:invalid_class) do
79
85
  Class.new do
80
86
  def self.name
@@ -92,17 +98,7 @@ RSpec.describe Mutant::Env::Bootstrap do
92
98
  end
93
99
  end
94
100
 
95
- it 'warns via reporter' do
96
- expected_warnings = [
97
- "Class#name from: #{invalid_class} raised an error: " \
98
- "RuntimeError. #{Mutant::Env::SEMANTICS_MESSAGE}"
99
- ]
100
-
101
- expect { subject }
102
- .to change { config.reporter.warn_calls }
103
- .from([])
104
- .to(expected_warnings)
105
- end
101
+ before { expect_warning }
106
102
 
107
103
  include_examples 'bootstrap call'
108
104
  end
@@ -146,6 +142,11 @@ RSpec.describe Mutant::Env::Bootstrap do
146
142
  end
147
143
  end
148
144
 
145
+ let(:expected_warning) do
146
+ "Class#name from: #{invalid_class} " \
147
+ "returned Object. #{Mutant::Env::SEMANTICS_MESSAGE}"
148
+ end
149
+
149
150
  after do
150
151
  # Fix Class#name so other specs do not see this one
151
152
  class << invalid_class
@@ -155,15 +156,7 @@ RSpec.describe Mutant::Env::Bootstrap do
155
156
  end
156
157
  end
157
158
 
158
- it 'warns via reporter' do
159
- expected_warnings = [
160
- "Class#name from: #{invalid_class.inspect} returned Object. #{Mutant::Env::SEMANTICS_MESSAGE}"
161
- ]
162
-
163
- expect { subject }
164
- .to change { config.reporter.warn_calls }
165
- .from([]).to(expected_warnings)
166
- end
159
+ before { expect_warning }
167
160
 
168
161
  include_examples 'bootstrap call'
169
162
  end
@@ -184,8 +177,8 @@ RSpec.describe Mutant::Env::Bootstrap do
184
177
  Mutant::Scope.new(TestApp::Empty, match_expressions.last),
185
178
  Mutant::Scope.new(TestApp::Literal, match_expressions.first)
186
179
  ],
187
- subjects: subjects,
188
- mutations: subjects.flat_map(&:mutations)
180
+ mutations: subjects.flat_map(&:mutations),
181
+ subjects: subjects
189
182
  )
190
183
  end
191
184
 
@@ -2,62 +2,96 @@ RSpec.describe Mutant::Env do
2
2
  context '#kill' do
3
3
  let(:object) do
4
4
  described_class.new(
5
- config: config,
6
5
  actor_env: Mutant::Actor::Env.new(Thread),
7
- cache: Mutant::Cache.new,
6
+ config: config,
7
+ integration: integration,
8
+ matchable_scopes: [],
9
+ mutations: [],
8
10
  selector: selector,
9
11
  subjects: [],
10
- mutations: [],
11
- matchable_scopes: [],
12
- integration: integration
12
+ parser: Mutant::Parser.new
13
13
  )
14
14
  end
15
15
 
16
- let(:integration) { integration_class.new(config) }
16
+ let(:integration) { instance_double(Mutant::Integration) }
17
+ let(:wrapped_node) { instance_double(Parser::AST::Node) }
18
+ let(:context) { instance_double(Mutant::Context) }
19
+ let(:test_a) { instance_double(Mutant::Test) }
20
+ let(:test_b) { instance_double(Mutant::Test) }
21
+ let(:tests) { [test_a, test_b] }
22
+ let(:selector) { instance_double(Mutant::Selector) }
23
+ let(:integration_class) { Mutant::Integration::Null }
17
24
 
18
- let(:config) do
19
- Mutant::Config::DEFAULT.with(isolation: isolation, integration: integration_class)
25
+ let(:isolation) do
26
+ instance_double(Mutant::Isolation::Fork.singleton_class)
20
27
  end
21
28
 
22
- let(:isolation) { double('Isolation') }
23
- let(:mutation) { Mutant::Mutation::Evil.new(mutation_subject, Mutant::AST::Nodes::N_NIL) }
24
- let(:wrapped_node) { double('Wrapped Node') }
25
- let(:context) { double('Context') }
26
- let(:test_a) { double('Test A') }
27
- let(:test_b) { double('Test B') }
28
- let(:tests) { [test_a, test_b] }
29
- let(:selector) { double('Selector') }
30
- let(:integration_class) { Mutant::Integration::Null }
29
+ let(:mutation) do
30
+ instance_double(
31
+ Mutant::Mutation,
32
+ subject: mutation_subject
33
+ )
34
+ end
35
+
36
+ let(:config) do
37
+ Mutant::Config::DEFAULT.with(
38
+ isolation: isolation,
39
+ integration: integration_class,
40
+ kernel: instance_double(Kernel.singleton_class)
41
+ )
42
+ end
31
43
 
32
44
  let(:mutation_subject) do
33
- double(
34
- 'Subject',
35
- identification: 'subject',
45
+ instance_double(
46
+ Mutant::Subject,
36
47
  context: context,
37
- source: 'original',
38
- tests: tests
48
+ identification: 'subject',
49
+ source: 'original'
39
50
  )
40
51
  end
41
52
 
42
53
  subject { object.kill(mutation) }
43
54
 
44
55
  shared_examples_for 'mutation kill' do
45
- it { should eql(Mutant::Result::Mutation.new(mutation: mutation, test_result: test_result)) }
56
+ specify do
57
+ should eql(
58
+ Mutant::Result::Mutation.new(
59
+ mutation: mutation,
60
+ test_result: test_result
61
+ )
62
+ )
63
+ end
46
64
  end
47
65
 
48
66
  before do
49
- expect(selector).to receive(:call).with(mutation_subject).and_return(tests)
50
- allow(Time).to receive(:now).and_return(Time.at(0))
67
+ expect(selector).to receive(:call)
68
+ .with(mutation_subject)
69
+ .and_return(tests)
70
+
71
+ allow(Time).to receive_messages(now: Time.at(0))
51
72
  end
52
73
 
53
74
  context 'when isolation does not raise error' do
54
- let(:test_result) { double('Test Result A', passed: false) }
75
+ let(:test_result) do
76
+ instance_double(
77
+ Mutant::Result::Test,
78
+ passed: false
79
+ )
80
+ end
55
81
 
56
82
  before do
57
- expect(isolation).to receive(:call).and_yield.and_return(test_result)
58
- expect(mutation_subject).to receive(:prepare).and_return(mutation_subject).ordered
59
- expect(context).to receive(:root).with(s(:nil)).and_return(wrapped_node).ordered
60
- expect(Mutant::Loader::Eval).to receive(:call).with(wrapped_node, mutation_subject).and_return(nil).ordered
83
+ expect(isolation).to receive(:call)
84
+ .ordered
85
+ .and_yield
86
+
87
+ expect(mutation).to receive(:insert)
88
+ .ordered
89
+ .with(config.kernel)
90
+
91
+ expect(integration).to receive(:call)
92
+ .ordered
93
+ .with(tests)
94
+ .and_return(test_result)
61
95
  end
62
96
 
63
97
  include_examples 'mutation kill'
@@ -65,10 +99,18 @@ RSpec.describe Mutant::Env do
65
99
 
66
100
  context 'when isolation does raise error' do
67
101
  before do
68
- expect(isolation).to receive(:call).and_raise(Mutant::Isolation::Error, 'test-error')
102
+ expect(isolation).to receive(:call)
103
+ .and_raise(Mutant::Isolation::Error, 'test-error')
69
104
  end
70
105
 
71
- let(:test_result) { Mutant::Result::Test.new(tests: tests, output: 'test-error', passed: false, runtime: 0.0) }
106
+ let(:test_result) do
107
+ Mutant::Result::Test.new(
108
+ output: 'test-error',
109
+ passed: false,
110
+ runtime: 0.0,
111
+ tests: tests
112
+ )
113
+ end
72
114
 
73
115
  include_examples 'mutation kill'
74
116
  end