mutant 0.8.8 → 0.8.9

Sign up to get free protection for your applications and to get access to all the features.
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