mutant 0.9.9 → 0.9.14

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 (252) hide show
  1. checksums.yaml +4 -4
  2. data/lib/mutant.rb +2 -4
  3. data/lib/mutant/bootstrap.rb +14 -1
  4. data/lib/mutant/cli.rb +6 -0
  5. data/lib/mutant/isolation.rb +1 -1
  6. data/lib/mutant/isolation/fork.rb +2 -2
  7. data/lib/mutant/isolation/none.rb +1 -1
  8. data/lib/mutant/matcher/config.rb +2 -0
  9. data/lib/mutant/meta/example.rb +16 -4
  10. data/lib/mutant/meta/example/dsl.rb +33 -16
  11. data/lib/mutant/meta/example/verification.rb +70 -28
  12. data/lib/mutant/minitest/coverage.rb +53 -0
  13. data/lib/mutant/mutator/node.rb +2 -2
  14. data/lib/mutant/mutator/node/block_pass.rb +29 -0
  15. data/lib/mutant/mutator/node/{dstr.rb → dynamic_literal.rb} +7 -5
  16. data/lib/mutant/mutator/node/index.rb +4 -4
  17. data/lib/mutant/mutator/node/literal/range.rb +4 -1
  18. data/lib/mutant/mutator/node/noop.rb +1 -1
  19. data/lib/mutant/mutator/node/op_asgn.rb +15 -1
  20. data/lib/mutant/mutator/node/send.rb +25 -1
  21. data/lib/mutant/mutator/node/send/attribute_assignment.rb +1 -0
  22. data/lib/mutant/reporter/cli/printer.rb +2 -2
  23. data/lib/mutant/reporter/cli/printer/isolation_result.rb +9 -3
  24. data/lib/mutant/reporter/cli/printer/mutation_result.rb +1 -1
  25. data/lib/mutant/subject/method/instance.rb +41 -2
  26. data/lib/mutant/version.rb +1 -1
  27. metadata +59 -347
  28. data/.github/workflows/ci.yml +0 -121
  29. data/.gitignore +0 -38
  30. data/.rspec +0 -5
  31. data/.rubocop.yml +0 -7
  32. data/Changelog.md +0 -81
  33. data/Gemfile +0 -7
  34. data/Gemfile.lock +0 -167
  35. data/Gemfile.shared +0 -10
  36. data/README.md +0 -178
  37. data/Rakefile +0 -5
  38. data/config/devtools.yml +0 -2
  39. data/config/reek.yml +0 -139
  40. data/config/rubocop.yml +0 -205
  41. data/config/yardstick.yml +0 -2
  42. data/docs/commercial-support.md +0 -14
  43. data/docs/concurrency.md +0 -39
  44. data/docs/incremental.md +0 -76
  45. data/docs/known-problems.md +0 -30
  46. data/docs/limitations.md +0 -50
  47. data/docs/mutant-minitest.md +0 -149
  48. data/docs/mutant-rspec.md +0 -130
  49. data/docs/nomenclature.md +0 -82
  50. data/docs/reading-reports.md +0 -74
  51. data/lib/mutant/color.rb +0 -40
  52. data/lib/mutant/diff.rb +0 -97
  53. data/lib/mutant/mutator/node/dsym.rb +0 -22
  54. data/meta/and.rb +0 -13
  55. data/meta/and_asgn.rb +0 -14
  56. data/meta/array.rb +0 -27
  57. data/meta/begin.rb +0 -20
  58. data/meta/block.rb +0 -199
  59. data/meta/block_pass.rb +0 -8
  60. data/meta/blockarg.rb +0 -10
  61. data/meta/break.rb +0 -9
  62. data/meta/case.rb +0 -217
  63. data/meta/casgn.rb +0 -25
  64. data/meta/cbase.rb +0 -8
  65. data/meta/class.rb +0 -12
  66. data/meta/const.rb +0 -17
  67. data/meta/csend.rb +0 -10
  68. data/meta/cvar.rb +0 -7
  69. data/meta/cvasgn.rb +0 -9
  70. data/meta/date.rb +0 -59
  71. data/meta/def.rb +0 -196
  72. data/meta/defined.rb +0 -9
  73. data/meta/dstr.rb +0 -13
  74. data/meta/dsym.rb +0 -14
  75. data/meta/ensure.rb +0 -8
  76. data/meta/false.rb +0 -7
  77. data/meta/file.rb +0 -5
  78. data/meta/float.rb +0 -37
  79. data/meta/gvar.rb +0 -7
  80. data/meta/gvasgn.rb +0 -9
  81. data/meta/hash.rb +0 -20
  82. data/meta/if.rb +0 -72
  83. data/meta/index.rb +0 -133
  84. data/meta/indexasgn.rb +0 -31
  85. data/meta/int.rb +0 -18
  86. data/meta/ivar.rb +0 -8
  87. data/meta/ivasgn.rb +0 -22
  88. data/meta/kwarg.rb +0 -10
  89. data/meta/kwbegin.rb +0 -8
  90. data/meta/kwoptarg.rb +0 -13
  91. data/meta/lambda.rb +0 -23
  92. data/meta/line.rb +0 -5
  93. data/meta/lvar.rb +0 -16
  94. data/meta/lvasgn.rb +0 -24
  95. data/meta/masgn.rb +0 -7
  96. data/meta/match_current_line.rb +0 -14
  97. data/meta/next.rb +0 -10
  98. data/meta/nil.rb +0 -5
  99. data/meta/nthref.rb +0 -14
  100. data/meta/op_assgn.rb +0 -17
  101. data/meta/or.rb +0 -13
  102. data/meta/or_asgn.rb +0 -50
  103. data/meta/range.rb +0 -39
  104. data/meta/redo.rb +0 -5
  105. data/meta/regexp.rb +0 -80
  106. data/meta/regopt.rb +0 -10
  107. data/meta/rescue.rb +0 -84
  108. data/meta/return.rb +0 -16
  109. data/meta/sclass.rb +0 -12
  110. data/meta/self.rb +0 -7
  111. data/meta/send.rb +0 -600
  112. data/meta/str.rb +0 -7
  113. data/meta/super.rb +0 -27
  114. data/meta/sym.rb +0 -8
  115. data/meta/true.rb +0 -7
  116. data/meta/until.rb +0 -16
  117. data/meta/while.rb +0 -24
  118. data/meta/yield.rb +0 -9
  119. data/mutant-minitest.gemspec +0 -22
  120. data/mutant-rspec.gemspec +0 -22
  121. data/mutant.gemspec +0 -41
  122. data/mutant.sh +0 -12
  123. data/mutant.yml +0 -6
  124. data/spec/integration/mutant/corpus_spec.rb +0 -15
  125. data/spec/integration/mutant/isolation/fork_spec.rb +0 -28
  126. data/spec/integration/mutant/minitest_spec.rb +0 -11
  127. data/spec/integration/mutant/null_spec.rb +0 -16
  128. data/spec/integration/mutant/rspec_spec.rb +0 -15
  129. data/spec/integration/mutant/test_mutator_handles_types_spec.rb +0 -9
  130. data/spec/integrations.yml +0 -63
  131. data/spec/shared/base_behavior.rb +0 -45
  132. data/spec/shared/framework_integration_behavior.rb +0 -70
  133. data/spec/shared/method_matcher_behavior.rb +0 -47
  134. data/spec/spec_helper.rb +0 -75
  135. data/spec/support/corpus.rb +0 -318
  136. data/spec/support/file_system.rb +0 -62
  137. data/spec/support/ice_nine_config.rb +0 -10
  138. data/spec/support/ruby_vm.rb +0 -84
  139. data/spec/support/shared_context.rb +0 -169
  140. data/spec/support/test_app.rb +0 -7
  141. data/spec/support/warnings.yml +0 -6
  142. data/spec/support/xspec.rb +0 -183
  143. data/spec/unit/mutant/ast/find_metaclass_containing_spec.rb +0 -64
  144. data/spec/unit/mutant/ast/meta/optarg_spec.rb +0 -24
  145. data/spec/unit/mutant/ast/meta/send/proc_predicate_spec.rb +0 -30
  146. data/spec/unit/mutant/ast/meta/send/receiver_possible_top_level_const_predicate_spec.rb +0 -39
  147. data/spec/unit/mutant/ast/meta/send_spec.rb +0 -42
  148. data/spec/unit/mutant/ast/named_children_spec.rb +0 -89
  149. data/spec/unit/mutant/ast/sexp_spec.rb +0 -38
  150. data/spec/unit/mutant/ast_spec.rb +0 -57
  151. data/spec/unit/mutant/bootstrap_spec.rb +0 -216
  152. data/spec/unit/mutant/cli_spec.rb +0 -305
  153. data/spec/unit/mutant/clock_monotonic_spec.rb +0 -52
  154. data/spec/unit/mutant/config_spec.rb +0 -126
  155. data/spec/unit/mutant/context_spec.rb +0 -111
  156. data/spec/unit/mutant/diff_spec.rb +0 -189
  157. data/spec/unit/mutant/env_spec.rb +0 -229
  158. data/spec/unit/mutant/expression/method_spec.rb +0 -62
  159. data/spec/unit/mutant/expression/methods_spec.rb +0 -66
  160. data/spec/unit/mutant/expression/namespace/exact_spec.rb +0 -28
  161. data/spec/unit/mutant/expression/namespace/recursive_spec.rb +0 -66
  162. data/spec/unit/mutant/expression/parser_spec.rb +0 -65
  163. data/spec/unit/mutant/expression_spec.rb +0 -45
  164. data/spec/unit/mutant/integration/rspec_spec.rb +0 -201
  165. data/spec/unit/mutant/integration_spec.rb +0 -150
  166. data/spec/unit/mutant/isolation/fork_spec.rb +0 -309
  167. data/spec/unit/mutant/isolation/none_spec.rb +0 -23
  168. data/spec/unit/mutant/isolation/result_spec.rb +0 -73
  169. data/spec/unit/mutant/license_spec.rb +0 -305
  170. data/spec/unit/mutant/loader_spec.rb +0 -79
  171. data/spec/unit/mutant/matcher/chain_spec.rb +0 -26
  172. data/spec/unit/mutant/matcher/compiler_spec.rb +0 -0
  173. data/spec/unit/mutant/matcher/config_spec.rb +0 -47
  174. data/spec/unit/mutant/matcher/filter_spec.rb +0 -22
  175. data/spec/unit/mutant/matcher/method/instance_spec.rb +0 -164
  176. data/spec/unit/mutant/matcher/method/metaclass_spec.rb +0 -108
  177. data/spec/unit/mutant/matcher/method/singleton_spec.rb +0 -90
  178. data/spec/unit/mutant/matcher/methods/instance_spec.rb +0 -54
  179. data/spec/unit/mutant/matcher/methods/metaclass_spec.rb +0 -62
  180. data/spec/unit/mutant/matcher/methods/singleton_spec.rb +0 -51
  181. data/spec/unit/mutant/matcher/namespace_spec.rb +0 -39
  182. data/spec/unit/mutant/matcher/null_spec.rb +0 -12
  183. data/spec/unit/mutant/matcher/scope_spec.rb +0 -45
  184. data/spec/unit/mutant/matcher/static_spec.rb +0 -13
  185. data/spec/unit/mutant/matcher_spec.rb +0 -102
  186. data/spec/unit/mutant/meta/example/dsl_spec.rb +0 -108
  187. data/spec/unit/mutant/meta/example/verification_spec.rb +0 -154
  188. data/spec/unit/mutant/meta/example_spec.rb +0 -34
  189. data/spec/unit/mutant/mutation_spec.rb +0 -140
  190. data/spec/unit/mutant/mutator/node_spec.rb +0 -47
  191. data/spec/unit/mutant/mutator_spec.rb +0 -21
  192. data/spec/unit/mutant/parallel/driver_spec.rb +0 -126
  193. data/spec/unit/mutant/parallel/source/array_spec.rb +0 -57
  194. data/spec/unit/mutant/parallel/worker_spec.rb +0 -206
  195. data/spec/unit/mutant/parallel_spec.rb +0 -115
  196. data/spec/unit/mutant/parser_spec.rb +0 -26
  197. data/spec/unit/mutant/range_spec.rb +0 -141
  198. data/spec/unit/mutant/registry_spec.rb +0 -74
  199. data/spec/unit/mutant/reporter/cli/printer/config_spec.rb +0 -17
  200. data/spec/unit/mutant/reporter/cli/printer/env_progress_spec.rb +0 -85
  201. data/spec/unit/mutant/reporter/cli/printer/env_result_spec.rb +0 -45
  202. data/spec/unit/mutant/reporter/cli/printer/isolation_result_spec.rb +0 -132
  203. data/spec/unit/mutant/reporter/cli/printer/mutation_progress_result_spec.rb +0 -25
  204. data/spec/unit/mutant/reporter/cli/printer/mutation_result_spec.rb +0 -153
  205. data/spec/unit/mutant/reporter/cli/printer/status_progressive_spec.rb +0 -45
  206. data/spec/unit/mutant/reporter/cli/printer/subject_progress_spec.rb +0 -36
  207. data/spec/unit/mutant/reporter/cli/printer/subject_result_spec.rb +0 -44
  208. data/spec/unit/mutant/reporter/cli/printer/test_result_spec.rb +0 -16
  209. data/spec/unit/mutant/reporter/cli/printer_spec.rb +0 -163
  210. data/spec/unit/mutant/reporter/cli_spec.rb +0 -137
  211. data/spec/unit/mutant/reporter/null_spec.rb +0 -14
  212. data/spec/unit/mutant/reporter/sequence_spec.rb +0 -31
  213. data/spec/unit/mutant/repository/diff/ranges_spec.rb +0 -180
  214. data/spec/unit/mutant/repository/diff_spec.rb +0 -122
  215. data/spec/unit/mutant/repository/subject_filter_spec.rb +0 -30
  216. data/spec/unit/mutant/require_highjack_spec.rb +0 -73
  217. data/spec/unit/mutant/result/class_methods_spec.rb +0 -51
  218. data/spec/unit/mutant/result/env_spec.rb +0 -161
  219. data/spec/unit/mutant/result/mutation_spec.rb +0 -70
  220. data/spec/unit/mutant/result/subject_spec.rb +0 -111
  221. data/spec/unit/mutant/result/test_spec.rb +0 -14
  222. data/spec/unit/mutant/result_spec.rb +0 -33
  223. data/spec/unit/mutant/runner/sink_spec.rb +0 -174
  224. data/spec/unit/mutant/runner_spec.rb +0 -121
  225. data/spec/unit/mutant/selector/expression_spec.rb +0 -62
  226. data/spec/unit/mutant/selector/null_spec.rb +0 -17
  227. data/spec/unit/mutant/subject/method/instance_spec.rb +0 -181
  228. data/spec/unit/mutant/subject/method/metaclass_spec.rb +0 -63
  229. data/spec/unit/mutant/subject/method/singleton_spec.rb +0 -61
  230. data/spec/unit/mutant/subject_spec.rb +0 -93
  231. data/spec/unit/mutant/transform/array_spec.rb +0 -92
  232. data/spec/unit/mutant/transform/bool_spec.rb +0 -63
  233. data/spec/unit/mutant/transform/error_spec.rb +0 -132
  234. data/spec/unit/mutant/transform/exception_spec.rb +0 -44
  235. data/spec/unit/mutant/transform/hash_spec.rb +0 -236
  236. data/spec/unit/mutant/transform/index_spec.rb +0 -92
  237. data/spec/unit/mutant/transform/named_spec.rb +0 -49
  238. data/spec/unit/mutant/transform/primitive_spec.rb +0 -56
  239. data/spec/unit/mutant/transform/sequence_spec.rb +0 -98
  240. data/spec/unit/mutant/util/one_spec.rb +0 -22
  241. data/spec/unit/mutant/warnings_spec.rb +0 -89
  242. data/spec/unit/mutant/world_spec.rb +0 -63
  243. data/spec/unit/mutant/zombifier_spec.rb +0 -122
  244. data/test_app/.rspec +0 -1
  245. data/test_app/Gemfile.minitest +0 -4
  246. data/test_app/Gemfile.rspec3.8 +0 -7
  247. data/test_app/lib/test_app.rb +0 -110
  248. data/test_app/lib/test_app/literal.rb +0 -35
  249. data/test_app/lib/test_app/metaclasses.rb +0 -108
  250. data/test_app/spec/spec_helper.rb +0 -9
  251. data/test_app/spec/unit/test_app/literal_spec.rb +0 -20
  252. data/test_app/test/unit/test_app/literal_test.rb +0 -16
@@ -1,150 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.describe Mutant::Integration do
4
- subject { class_under_test.new(Mutant::Config::DEFAULT) }
5
-
6
- let(:class_under_test) do
7
- Class.new(described_class)
8
- end
9
-
10
- describe '#setup' do
11
- def apply
12
- subject.setup
13
- end
14
-
15
- it 'returns self' do
16
- expect(apply).to be(subject)
17
- end
18
- end
19
-
20
- describe '.setup' do
21
- def apply
22
- described_class.setup(env)
23
- end
24
-
25
- let(:kernel) { class_double(Kernel) }
26
- let(:integration) { instance_double(Mutant::Integration::Null) }
27
- let(:integration_name) { 'null' }
28
-
29
- let(:config) do
30
- instance_double(
31
- Mutant::Config,
32
- integration: integration_name
33
- )
34
- end
35
-
36
- let(:env) do
37
- instance_double(
38
- Mutant::Env,
39
- config: config,
40
- world: world
41
- )
42
- end
43
-
44
- let(:world) do
45
- instance_double(
46
- Mutant::World,
47
- kernel: kernel
48
- )
49
- end
50
-
51
- before do
52
- allow(kernel).to receive_messages(require: undefined)
53
- allow(described_class).to receive_messages(const_get: described_class::Null)
54
- allow(described_class::Null).to receive_messages(new: integration)
55
- allow(integration).to receive_messages(setup: integration)
56
- end
57
-
58
- context 'when require fails' do
59
- let(:exception) { LoadError.new('some-load-error') }
60
-
61
- before do
62
- allow(kernel).to receive(:require).and_raise(exception)
63
- end
64
-
65
- it 'returns error' do
66
- expect(apply).to eql(Mutant::Either::Left.new(<<~MESSAGE))
67
- Unable to load integration mutant-null:
68
- #{exception.inspect}
69
- You may have to install the gem mutant-null!
70
- MESSAGE
71
- end
72
- end
73
-
74
- context 'when constant lookup fails' do
75
- let(:exception) { NameError.new('some-name-error') }
76
-
77
- before do
78
- allow(described_class).to receive(:const_get).and_raise(exception)
79
- end
80
-
81
- it 'returns error' do
82
- expect(apply).to eql(Mutant::Either::Left.new(<<~MESSAGE))
83
- Unable to load integration mutant-null:
84
- #{exception.inspect}
85
- This is a bug in the integration you have to report.
86
- The integration is supposed to define Mutant::Integration::Null!
87
- MESSAGE
88
- end
89
- end
90
-
91
- it 'performs actions in expected sequence' do
92
- apply
93
-
94
- expect(kernel)
95
- .to have_received(:require)
96
- .with('mutant/integration/null')
97
- .ordered
98
-
99
- expect(described_class)
100
- .to have_received(:const_get)
101
- .with('Null')
102
- .ordered
103
-
104
- expect(described_class::Null)
105
- .to have_received(:new)
106
- .with(config)
107
- .ordered
108
-
109
- expect(integration)
110
- .to have_received(:setup)
111
- .ordered
112
- end
113
-
114
- it 'returns integration instance' do
115
- expect(apply).to eql(
116
- Mutant::Either::Right.new(integration)
117
- )
118
- end
119
- end
120
- end
121
-
122
- RSpec.describe Mutant::Integration::Null do
123
-
124
- let(:object) { described_class.new(Mutant::Config::DEFAULT) }
125
-
126
- describe '#all_tests' do
127
- subject { object.all_tests }
128
-
129
- it { should eql([]) }
130
-
131
- it_should_behave_like 'an idempotent method'
132
- end
133
-
134
- describe '#call' do
135
- let(:tests) { instance_double(Array) }
136
-
137
- subject { object.call(tests) }
138
-
139
- it 'returns test result' do
140
- should eql(
141
- Mutant::Result::Test.new(
142
- output: '',
143
- passed: true,
144
- runtime: 0.0,
145
- tests: tests
146
- )
147
- )
148
- end
149
- end
150
- end
@@ -1,309 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # The fork isolation is all about managing a series of systemcalls with proper error handling
4
- #
5
- # So creating a unit spec for this is challenging. Especially under mutation testing.
6
- # Hence we even have to implement our own message expectation mechanism, as rspec build in
7
- # expectations are not able to correctly specify a sequence of expectations where a specific
8
- # message is send twice.
9
- #
10
- # Also our replacement for rspec-expectations used here allows easier deduplication.
11
- RSpec.describe Mutant::Isolation::Fork do
12
- let(:block_return) { instance_double(Object, :block_return) }
13
- let(:block_return_blob) { instance_double(String, :block_return_blob) }
14
- let(:io) { class_double(IO) }
15
- let(:isolated_block) { -> { block_return } }
16
- let(:log_fragment) { 'log message' }
17
- let(:log_reader) { instance_double(IO, :log_reader) }
18
- let(:log_writer) { instance_double(IO, :log_writer) }
19
- let(:marshal) { class_double(Marshal) }
20
- let(:pid) { class_double(Integer) }
21
- let(:process) { class_double(Process) }
22
- let(:result_fragment) { 'result body' }
23
- let(:result_reader) { instance_double(IO, :result_reader) }
24
- let(:result_writer) { instance_double(IO, :result_writer) }
25
- let(:stderr) { instance_double(IO, :stderr) }
26
- let(:stdout) { instance_double(IO, :stdout) }
27
-
28
- let(:status_success) do
29
- instance_double(Process::Status, success?: true)
30
- end
31
-
32
- let(:world) do
33
- instance_double(
34
- Mutant::World,
35
- io: io,
36
- marshal: marshal,
37
- process: process,
38
- stderr: stderr,
39
- stdout: stdout
40
- )
41
- end
42
-
43
- let(:fork_success) do
44
- {
45
- receiver: process,
46
- selector: :fork,
47
- reaction: {
48
- yields: [],
49
- return: pid
50
- }
51
- }
52
- end
53
-
54
- let(:child_wait) do
55
- {
56
- receiver: process,
57
- selector: :wait2,
58
- arguments: [pid],
59
- reaction: {
60
- return: [pid, status_success]
61
- }
62
- }
63
- end
64
-
65
- def close(descriptor)
66
- {
67
- receiver: descriptor,
68
- selector: :close
69
- }
70
- end
71
-
72
- let(:load_success) do
73
- {
74
- receiver: marshal,
75
- selector: :load,
76
- arguments: [result_fragment],
77
- reaction: {
78
- return: block_return
79
- }
80
- }
81
- end
82
-
83
- let(:read_fragments) do
84
- [
85
- {
86
- receiver: io,
87
- selector: :select,
88
- arguments: [[log_reader, result_reader]],
89
- reaction: { return: [[log_reader, result_reader], []] }
90
- },
91
- {
92
- receiver: log_reader,
93
- selector: :eof?,
94
- reaction: { return: false }
95
- },
96
- {
97
- receiver: log_reader,
98
- selector: :read_nonblock,
99
- arguments: [4096],
100
- reaction: { return: log_fragment }
101
- },
102
- {
103
- receiver: result_reader,
104
- selector: :eof?,
105
- reaction: { return: false }
106
- },
107
- {
108
- receiver: result_reader,
109
- selector: :read_nonblock,
110
- arguments: [4096],
111
- reaction: { return: result_fragment }
112
- },
113
- {
114
- receiver: io,
115
- selector: :select,
116
- arguments: [[log_reader, result_reader]],
117
- reaction: { return: [[log_reader, result_reader], []] }
118
- },
119
- {
120
- receiver: log_reader,
121
- selector: :eof?,
122
- reaction: { return: true }
123
- },
124
- {
125
- receiver: result_reader,
126
- selector: :eof?,
127
- reaction: { return: true }
128
- }
129
- ]
130
- end
131
-
132
- let(:killfork) do
133
- [
134
- # Inside the killfork
135
- {
136
- receiver: log_reader,
137
- selector: :close
138
- },
139
- {
140
- receiver: result_reader,
141
- selector: :close
142
- },
143
- {
144
- receiver: stderr,
145
- selector: :reopen,
146
- arguments: [log_writer]
147
- },
148
- {
149
- receiver: stdout,
150
- selector: :reopen,
151
- arguments: [log_writer]
152
- },
153
- {
154
- receiver: marshal,
155
- selector: :dump,
156
- arguments: [block_return],
157
- reaction: {
158
- return: block_return_blob
159
- }
160
- },
161
- {
162
- receiver: result_writer,
163
- selector: :syswrite,
164
- arguments: [block_return_blob]
165
- },
166
- close(result_writer),
167
- close(log_writer)
168
- ]
169
- end
170
-
171
- describe '#call' do
172
- subject { described_class.new(world) }
173
-
174
- def apply
175
- subject.call(&isolated_block)
176
- end
177
-
178
- let(:prefork_expectations) do
179
- [
180
- {
181
- receiver: io,
182
- selector: :pipe,
183
- arguments: [binmode: true],
184
- reaction: {
185
- yields: [[result_reader, result_writer]]
186
- }
187
- },
188
- {
189
- receiver: io,
190
- selector: :pipe,
191
- arguments: [binmode: true],
192
- reaction: {
193
- yields: [[log_reader, log_writer]]
194
- }
195
- }
196
- ]
197
- end
198
-
199
- context 'when no IO operation fails' do
200
- let(:expectations) do
201
- [
202
- *prefork_expectations,
203
- fork_success,
204
- *killfork,
205
- close(result_writer),
206
- *read_fragments,
207
- load_success,
208
- child_wait
209
- ].map(&XSpec::MessageExpectation.method(:parse))
210
- end
211
-
212
- specify do
213
- XSpec::ExpectationVerifier.verify(self, expectations) do
214
- expect(apply).to eql(Mutant::Isolation::Result::Success.new(block_return, log_fragment))
215
- end
216
- end
217
- end
218
-
219
- context 'when expected exception was raised when loading result' do
220
- let(:exception) { ArgumentError.new }
221
-
222
- let(:expectations) do
223
- [
224
- *prefork_expectations,
225
- fork_success,
226
- *killfork,
227
- close(result_writer),
228
- *read_fragments,
229
- {
230
- receiver: marshal,
231
- selector: :load,
232
- arguments: [result_fragment],
233
- reaction: {
234
- exception: exception
235
- }
236
- },
237
- child_wait
238
- ].map(&XSpec::MessageExpectation.method(:parse))
239
- end
240
-
241
- specify do
242
- XSpec::ExpectationVerifier.verify(self, expectations) do
243
- expect(apply).to eql(Mutant::Isolation::Result::Exception.new(exception))
244
- end
245
- end
246
- end
247
-
248
- context 'when fork fails' do
249
- let(:result_class) { described_class::ForkError }
250
-
251
- let(:expectations) do
252
- [
253
- *prefork_expectations,
254
- {
255
- receiver: process,
256
- selector: :fork,
257
- reaction: {
258
- return: nil
259
- }
260
- }
261
- ].map(&XSpec::MessageExpectation.method(:parse))
262
- end
263
-
264
- specify do
265
- XSpec::ExpectationVerifier.verify(self, expectations) do
266
- expect(apply).to eql(result_class.new)
267
- end
268
- end
269
- end
270
-
271
- context 'when child exits nonzero' do
272
- let(:status_error) do
273
- instance_double(Process::Status, success?: false)
274
- end
275
-
276
- let(:expected_result) do
277
- Mutant::Isolation::Result::ErrorChain.new(
278
- described_class::ChildError.new(status_error, log_fragment),
279
- Mutant::Isolation::Result::Success.new(block_return, log_fragment)
280
- )
281
- end
282
-
283
- let(:expectations) do
284
- [
285
- *prefork_expectations,
286
- fork_success,
287
- *killfork,
288
- close(result_writer),
289
- *read_fragments,
290
- load_success,
291
- {
292
- receiver: process,
293
- selector: :wait2,
294
- arguments: [pid],
295
- reaction: {
296
- return: [pid, status_error]
297
- }
298
- }
299
- ].map(&XSpec::MessageExpectation.method(:parse))
300
- end
301
-
302
- specify do
303
- XSpec::ExpectationVerifier.verify(self, expectations) do
304
- expect(apply).to eql(expected_result)
305
- end
306
- end
307
- end
308
- end
309
- end