mutant 0.9.7 → 0.9.12

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 (336) hide show
  1. checksums.yaml +4 -4
  2. data/lib/mutant.rb +5 -2
  3. data/lib/mutant/ast.rb +0 -9
  4. data/lib/mutant/ast/find_metaclass_containing.rb +48 -0
  5. data/lib/mutant/ast/meta/send.rb +0 -6
  6. data/lib/mutant/bootstrap.rb +0 -36
  7. data/lib/mutant/cli.rb +5 -49
  8. data/lib/mutant/config.rb +0 -8
  9. data/lib/mutant/context.rb +0 -3
  10. data/lib/mutant/env.rb +0 -6
  11. data/lib/mutant/expression/method.rb +6 -6
  12. data/lib/mutant/expression/methods.rb +6 -6
  13. data/lib/mutant/expression/parser.rb +0 -6
  14. data/lib/mutant/integration.rb +0 -18
  15. data/lib/mutant/isolation.rb +1 -1
  16. data/lib/mutant/isolation/fork.rb +2 -24
  17. data/lib/mutant/isolation/none.rb +1 -1
  18. data/lib/mutant/license.rb +11 -0
  19. data/lib/mutant/matcher.rb +0 -14
  20. data/lib/mutant/matcher/config.rb +0 -11
  21. data/lib/mutant/matcher/method.rb +0 -31
  22. data/lib/mutant/matcher/method/instance.rb +0 -8
  23. data/lib/mutant/matcher/method/metaclass.rb +86 -0
  24. data/lib/mutant/matcher/method/singleton.rb +0 -25
  25. data/lib/mutant/matcher/methods.rb +17 -28
  26. data/lib/mutant/matcher/namespace.rb +0 -10
  27. data/lib/mutant/matcher/scope.rb +2 -4
  28. data/lib/mutant/meta/example/dsl.rb +0 -21
  29. data/lib/mutant/meta/example/verification.rb +0 -20
  30. data/lib/mutant/minitest/coverage.rb +53 -0
  31. data/lib/mutant/mutation.rb +0 -3
  32. data/lib/mutant/mutator.rb +1 -29
  33. data/lib/mutant/mutator/node.rb +1 -66
  34. data/lib/mutant/mutator/node/and_asgn.rb +0 -3
  35. data/lib/mutant/mutator/node/argument.rb +0 -15
  36. data/lib/mutant/mutator/node/arguments.rb +0 -20
  37. data/lib/mutant/mutator/node/begin.rb +0 -3
  38. data/lib/mutant/mutator/node/binary.rb +0 -23
  39. data/lib/mutant/mutator/node/block.rb +0 -15
  40. data/lib/mutant/mutator/node/block_pass.rb +29 -0
  41. data/lib/mutant/mutator/node/break.rb +0 -3
  42. data/lib/mutant/mutator/node/case.rb +0 -9
  43. data/lib/mutant/mutator/node/class.rb +0 -3
  44. data/lib/mutant/mutator/node/conditional_loop.rb +0 -3
  45. data/lib/mutant/mutator/node/const.rb +0 -3
  46. data/lib/mutant/mutator/node/define.rb +0 -11
  47. data/lib/mutant/mutator/node/defined.rb +0 -3
  48. data/lib/mutant/mutator/node/dstr.rb +0 -3
  49. data/lib/mutant/mutator/node/dsym.rb +0 -3
  50. data/lib/mutant/mutator/node/generic.rb +0 -74
  51. data/lib/mutant/mutator/node/if.rb +0 -12
  52. data/lib/mutant/mutator/node/index.rb +0 -27
  53. data/lib/mutant/mutator/node/kwbegin.rb +0 -3
  54. data/lib/mutant/mutator/node/literal.rb +0 -3
  55. data/lib/mutant/mutator/node/literal/array.rb +0 -6
  56. data/lib/mutant/mutator/node/literal/boolean.rb +0 -4
  57. data/lib/mutant/mutator/node/literal/float.rb +0 -9
  58. data/lib/mutant/mutator/node/literal/hash.rb +0 -9
  59. data/lib/mutant/mutator/node/literal/integer.rb +0 -9
  60. data/lib/mutant/mutator/node/literal/nil.rb +0 -3
  61. data/lib/mutant/mutator/node/literal/range.rb +4 -7
  62. data/lib/mutant/mutator/node/literal/regex.rb +0 -6
  63. data/lib/mutant/mutator/node/literal/string.rb +0 -3
  64. data/lib/mutant/mutator/node/literal/symbol.rb +0 -3
  65. data/lib/mutant/mutator/node/masgn.rb +0 -3
  66. data/lib/mutant/mutator/node/match_current_line.rb +0 -3
  67. data/lib/mutant/mutator/node/mlhs.rb +0 -3
  68. data/lib/mutant/mutator/node/named_value/access.rb +2 -14
  69. data/lib/mutant/mutator/node/named_value/constant_assignment.rb +0 -9
  70. data/lib/mutant/mutator/node/named_value/variable_assignment.rb +0 -6
  71. data/lib/mutant/mutator/node/next.rb +0 -3
  72. data/lib/mutant/mutator/node/noop.rb +1 -4
  73. data/lib/mutant/mutator/node/nthref.rb +0 -3
  74. data/lib/mutant/mutator/node/op_asgn.rb +0 -3
  75. data/lib/mutant/mutator/node/or_asgn.rb +0 -3
  76. data/lib/mutant/mutator/node/procarg_zero.rb +0 -3
  77. data/lib/mutant/mutator/node/regopt.rb +0 -6
  78. data/lib/mutant/mutator/node/resbody.rb +0 -6
  79. data/lib/mutant/mutator/node/rescue.rb +2 -19
  80. data/lib/mutant/mutator/node/return.rb +0 -3
  81. data/lib/mutant/mutator/node/sclass.rb +20 -0
  82. data/lib/mutant/mutator/node/send.rb +26 -61
  83. data/lib/mutant/mutator/node/send/attribute_assignment.rb +0 -9
  84. data/lib/mutant/mutator/node/send/binary.rb +0 -11
  85. data/lib/mutant/mutator/node/send/conditional.rb +0 -3
  86. data/lib/mutant/mutator/node/splat.rb +0 -3
  87. data/lib/mutant/mutator/node/super.rb +0 -3
  88. data/lib/mutant/mutator/node/when.rb +0 -19
  89. data/lib/mutant/mutator/node/yield.rb +0 -3
  90. data/lib/mutant/mutator/node/zsuper.rb +0 -3
  91. data/lib/mutant/mutator/util/array.rb +0 -6
  92. data/lib/mutant/mutator/util/symbol.rb +0 -3
  93. data/lib/mutant/parallel.rb +0 -13
  94. data/lib/mutant/parallel/driver.rb +0 -10
  95. data/lib/mutant/parallel/worker.rb +0 -22
  96. data/lib/mutant/registry.rb +2 -7
  97. data/lib/mutant/reporter/cli.rb +0 -5
  98. data/lib/mutant/reporter/cli/format.rb +0 -9
  99. data/lib/mutant/reporter/cli/printer.rb +2 -42
  100. data/lib/mutant/reporter/cli/printer/env_progress.rb +0 -15
  101. data/lib/mutant/reporter/cli/printer/isolation_result.rb +0 -18
  102. data/lib/mutant/reporter/cli/printer/mutation_progress_result.rb +0 -5
  103. data/lib/mutant/reporter/cli/printer/mutation_result.rb +1 -22
  104. data/lib/mutant/reporter/cli/printer/status_progressive.rb +0 -8
  105. data/lib/mutant/reporter/cli/printer/subject_progress.rb +0 -9
  106. data/lib/mutant/repository/diff.rb +1 -13
  107. data/lib/mutant/repository/diff/ranges.rb +0 -11
  108. data/lib/mutant/result.rb +0 -3
  109. data/lib/mutant/runner.rb +0 -18
  110. data/lib/mutant/runner/sink.rb +0 -5
  111. data/lib/mutant/subject.rb +0 -8
  112. data/lib/mutant/subject/method.rb +0 -3
  113. data/lib/mutant/subject/method/instance.rb +40 -6
  114. data/lib/mutant/subject/method/metaclass.rb +30 -0
  115. data/lib/mutant/transform.rb +0 -92
  116. data/lib/mutant/version.rb +1 -1
  117. data/lib/mutant/warnings.rb +0 -6
  118. data/lib/mutant/zombifier.rb +2 -34
  119. metadata +61 -333
  120. data/.circleci/config.yml +0 -53
  121. data/.gitignore +0 -38
  122. data/.rspec +0 -5
  123. data/.rubocop.yml +0 -7
  124. data/Changelog.md +0 -71
  125. data/Gemfile +0 -14
  126. data/Gemfile.lock +0 -167
  127. data/Gemfile.shared +0 -3
  128. data/README.md +0 -138
  129. data/Rakefile +0 -5
  130. data/config/devtools.yml +0 -2
  131. data/config/reek.yml +0 -138
  132. data/config/rubocop.yml +0 -205
  133. data/config/yardstick.yml +0 -2
  134. data/docs/commercial-support.md +0 -14
  135. data/docs/concurrency.md +0 -39
  136. data/docs/incremental.md +0 -76
  137. data/docs/known-problems.md +0 -30
  138. data/docs/limitations.md +0 -50
  139. data/docs/mutant-minitest.md +0 -149
  140. data/docs/mutant-rspec.md +0 -130
  141. data/docs/nomenclature.md +0 -82
  142. data/docs/reading-reports.md +0 -74
  143. data/lib/mutant/color.rb +0 -43
  144. data/lib/mutant/diff.rb +0 -114
  145. data/meta/and.rb +0 -15
  146. data/meta/and_asgn.rb +0 -14
  147. data/meta/array.rb +0 -30
  148. data/meta/begin.rb +0 -23
  149. data/meta/block.rb +0 -202
  150. data/meta/block_pass.rb +0 -8
  151. data/meta/blockarg.rb +0 -10
  152. data/meta/break.rb +0 -10
  153. data/meta/case.rb +0 -223
  154. data/meta/casgn.rb +0 -28
  155. data/meta/cbase.rb +0 -8
  156. data/meta/class.rb +0 -12
  157. data/meta/const.rb +0 -17
  158. data/meta/csend.rb +0 -10
  159. data/meta/cvar.rb +0 -7
  160. data/meta/cvasgn.rb +0 -10
  161. data/meta/date.rb +0 -59
  162. data/meta/def.rb +0 -203
  163. data/meta/defined.rb +0 -9
  164. data/meta/dstr.rb +0 -13
  165. data/meta/dsym.rb +0 -14
  166. data/meta/ensure.rb +0 -9
  167. data/meta/false.rb +0 -8
  168. data/meta/file.rb +0 -5
  169. data/meta/float.rb +0 -37
  170. data/meta/gvar.rb +0 -7
  171. data/meta/gvasgn.rb +0 -10
  172. data/meta/hash.rb +0 -24
  173. data/meta/if.rb +0 -77
  174. data/meta/index.rb +0 -133
  175. data/meta/indexasgn.rb +0 -31
  176. data/meta/int.rb +0 -18
  177. data/meta/ivar.rb +0 -8
  178. data/meta/ivasgn.rb +0 -23
  179. data/meta/kwarg.rb +0 -10
  180. data/meta/kwbegin.rb +0 -9
  181. data/meta/kwoptarg.rb +0 -13
  182. data/meta/lambda.rb +0 -23
  183. data/meta/line.rb +0 -5
  184. data/meta/lvar.rb +0 -16
  185. data/meta/lvasgn.rb +0 -25
  186. data/meta/masgn.rb +0 -7
  187. data/meta/match_current_line.rb +0 -15
  188. data/meta/next.rb +0 -11
  189. data/meta/nil.rb +0 -5
  190. data/meta/nthref.rb +0 -14
  191. data/meta/op_assgn.rb +0 -17
  192. data/meta/or.rb +0 -15
  193. data/meta/or_asgn.rb +0 -50
  194. data/meta/range.rb +0 -39
  195. data/meta/redo.rb +0 -5
  196. data/meta/regexp.rb +0 -81
  197. data/meta/regopt.rb +0 -10
  198. data/meta/rescue.rb +0 -90
  199. data/meta/return.rb +0 -16
  200. data/meta/self.rb +0 -7
  201. data/meta/send.rb +0 -604
  202. data/meta/str.rb +0 -7
  203. data/meta/super.rb +0 -27
  204. data/meta/sym.rb +0 -8
  205. data/meta/true.rb +0 -8
  206. data/meta/until.rb +0 -17
  207. data/meta/while.rb +0 -26
  208. data/meta/yield.rb +0 -10
  209. data/mutant-minitest.gemspec +0 -22
  210. data/mutant-rspec.gemspec +0 -22
  211. data/mutant.gemspec +0 -41
  212. data/mutant.yml +0 -6
  213. data/spec/integration/mutant/corpus_spec.rb +0 -15
  214. data/spec/integration/mutant/isolation/fork_spec.rb +0 -28
  215. data/spec/integration/mutant/minitest_spec.rb +0 -11
  216. data/spec/integration/mutant/null_spec.rb +0 -16
  217. data/spec/integration/mutant/rspec_spec.rb +0 -15
  218. data/spec/integration/mutant/test_mutator_handles_types_spec.rb +0 -9
  219. data/spec/integrations.yml +0 -63
  220. data/spec/shared/base_behavior.rb +0 -45
  221. data/spec/shared/framework_integration_behavior.rb +0 -70
  222. data/spec/shared/method_matcher_behavior.rb +0 -47
  223. data/spec/spec_helper.rb +0 -75
  224. data/spec/support/corpus.rb +0 -318
  225. data/spec/support/file_system.rb +0 -62
  226. data/spec/support/ice_nine_config.rb +0 -10
  227. data/spec/support/ruby_vm.rb +0 -84
  228. data/spec/support/shared_context.rb +0 -169
  229. data/spec/support/test_app.rb +0 -7
  230. data/spec/support/warnings.yml +0 -6
  231. data/spec/support/xspec.rb +0 -183
  232. data/spec/unit/mutant/ast/meta/optarg_spec.rb +0 -24
  233. data/spec/unit/mutant/ast/meta/send/proc_predicate_spec.rb +0 -30
  234. data/spec/unit/mutant/ast/meta/send/receiver_possible_top_level_const_predicate_spec.rb +0 -39
  235. data/spec/unit/mutant/ast/meta/send_spec.rb +0 -42
  236. data/spec/unit/mutant/ast/named_children_spec.rb +0 -89
  237. data/spec/unit/mutant/ast/sexp_spec.rb +0 -38
  238. data/spec/unit/mutant/ast_spec.rb +0 -57
  239. data/spec/unit/mutant/bootstrap_spec.rb +0 -216
  240. data/spec/unit/mutant/cli_spec.rb +0 -305
  241. data/spec/unit/mutant/clock_monotonic_spec.rb +0 -52
  242. data/spec/unit/mutant/config_spec.rb +0 -126
  243. data/spec/unit/mutant/context_spec.rb +0 -111
  244. data/spec/unit/mutant/diff_spec.rb +0 -189
  245. data/spec/unit/mutant/env_spec.rb +0 -229
  246. data/spec/unit/mutant/expression/method_spec.rb +0 -62
  247. data/spec/unit/mutant/expression/methods_spec.rb +0 -61
  248. data/spec/unit/mutant/expression/namespace/exact_spec.rb +0 -28
  249. data/spec/unit/mutant/expression/namespace/recursive_spec.rb +0 -66
  250. data/spec/unit/mutant/expression/parser_spec.rb +0 -65
  251. data/spec/unit/mutant/expression_spec.rb +0 -45
  252. data/spec/unit/mutant/integration/rspec_spec.rb +0 -201
  253. data/spec/unit/mutant/integration_spec.rb +0 -150
  254. data/spec/unit/mutant/isolation/fork_spec.rb +0 -309
  255. data/spec/unit/mutant/isolation/none_spec.rb +0 -23
  256. data/spec/unit/mutant/isolation/result_spec.rb +0 -73
  257. data/spec/unit/mutant/license_spec.rb +0 -293
  258. data/spec/unit/mutant/loader_spec.rb +0 -79
  259. data/spec/unit/mutant/matcher/chain_spec.rb +0 -26
  260. data/spec/unit/mutant/matcher/compiler_spec.rb +0 -0
  261. data/spec/unit/mutant/matcher/config_spec.rb +0 -47
  262. data/spec/unit/mutant/matcher/filter_spec.rb +0 -22
  263. data/spec/unit/mutant/matcher/method/instance_spec.rb +0 -164
  264. data/spec/unit/mutant/matcher/method/singleton_spec.rb +0 -90
  265. data/spec/unit/mutant/matcher/methods/instance_spec.rb +0 -54
  266. data/spec/unit/mutant/matcher/methods/singleton_spec.rb +0 -51
  267. data/spec/unit/mutant/matcher/namespace_spec.rb +0 -37
  268. data/spec/unit/mutant/matcher/null_spec.rb +0 -12
  269. data/spec/unit/mutant/matcher/scope_spec.rb +0 -35
  270. data/spec/unit/mutant/matcher/static_spec.rb +0 -13
  271. data/spec/unit/mutant/matcher_spec.rb +0 -102
  272. data/spec/unit/mutant/meta/example/dsl_spec.rb +0 -108
  273. data/spec/unit/mutant/meta/example/verification_spec.rb +0 -154
  274. data/spec/unit/mutant/meta/example_spec.rb +0 -34
  275. data/spec/unit/mutant/mutation_spec.rb +0 -140
  276. data/spec/unit/mutant/mutator/node_spec.rb +0 -52
  277. data/spec/unit/mutant/mutator_spec.rb +0 -21
  278. data/spec/unit/mutant/parallel/driver_spec.rb +0 -126
  279. data/spec/unit/mutant/parallel/source/array_spec.rb +0 -57
  280. data/spec/unit/mutant/parallel/worker_spec.rb +0 -206
  281. data/spec/unit/mutant/parallel_spec.rb +0 -115
  282. data/spec/unit/mutant/parser_spec.rb +0 -26
  283. data/spec/unit/mutant/range_spec.rb +0 -141
  284. data/spec/unit/mutant/registry_spec.rb +0 -47
  285. data/spec/unit/mutant/reporter/cli/printer/config_spec.rb +0 -17
  286. data/spec/unit/mutant/reporter/cli/printer/env_progress_spec.rb +0 -85
  287. data/spec/unit/mutant/reporter/cli/printer/env_result_spec.rb +0 -45
  288. data/spec/unit/mutant/reporter/cli/printer/isolation_result_spec.rb +0 -132
  289. data/spec/unit/mutant/reporter/cli/printer/mutation_progress_result_spec.rb +0 -25
  290. data/spec/unit/mutant/reporter/cli/printer/mutation_result_spec.rb +0 -153
  291. data/spec/unit/mutant/reporter/cli/printer/status_progressive_spec.rb +0 -45
  292. data/spec/unit/mutant/reporter/cli/printer/subject_progress_spec.rb +0 -36
  293. data/spec/unit/mutant/reporter/cli/printer/subject_result_spec.rb +0 -44
  294. data/spec/unit/mutant/reporter/cli/printer/test_result_spec.rb +0 -16
  295. data/spec/unit/mutant/reporter/cli/printer_spec.rb +0 -163
  296. data/spec/unit/mutant/reporter/cli_spec.rb +0 -137
  297. data/spec/unit/mutant/reporter/null_spec.rb +0 -14
  298. data/spec/unit/mutant/reporter/sequence_spec.rb +0 -31
  299. data/spec/unit/mutant/repository/diff/ranges_spec.rb +0 -180
  300. data/spec/unit/mutant/repository/diff_spec.rb +0 -122
  301. data/spec/unit/mutant/repository/subject_filter_spec.rb +0 -30
  302. data/spec/unit/mutant/require_highjack_spec.rb +0 -73
  303. data/spec/unit/mutant/result/class_methods_spec.rb +0 -51
  304. data/spec/unit/mutant/result/env_spec.rb +0 -161
  305. data/spec/unit/mutant/result/mutation_spec.rb +0 -70
  306. data/spec/unit/mutant/result/subject_spec.rb +0 -111
  307. data/spec/unit/mutant/result/test_spec.rb +0 -14
  308. data/spec/unit/mutant/result_spec.rb +0 -33
  309. data/spec/unit/mutant/runner/sink_spec.rb +0 -174
  310. data/spec/unit/mutant/runner_spec.rb +0 -121
  311. data/spec/unit/mutant/selector/expression_spec.rb +0 -62
  312. data/spec/unit/mutant/selector/null_spec.rb +0 -17
  313. data/spec/unit/mutant/subject/method/instance_spec.rb +0 -181
  314. data/spec/unit/mutant/subject/method/singleton_spec.rb +0 -61
  315. data/spec/unit/mutant/subject_spec.rb +0 -93
  316. data/spec/unit/mutant/transform/array_spec.rb +0 -92
  317. data/spec/unit/mutant/transform/bool_spec.rb +0 -63
  318. data/spec/unit/mutant/transform/error_spec.rb +0 -132
  319. data/spec/unit/mutant/transform/exception_spec.rb +0 -44
  320. data/spec/unit/mutant/transform/hash_spec.rb +0 -236
  321. data/spec/unit/mutant/transform/index_spec.rb +0 -92
  322. data/spec/unit/mutant/transform/named_spec.rb +0 -49
  323. data/spec/unit/mutant/transform/primitive_spec.rb +0 -56
  324. data/spec/unit/mutant/transform/sequence_spec.rb +0 -98
  325. data/spec/unit/mutant/util/one_spec.rb +0 -22
  326. data/spec/unit/mutant/warnings_spec.rb +0 -89
  327. data/spec/unit/mutant/world_spec.rb +0 -63
  328. data/spec/unit/mutant/zombifier_spec.rb +0 -122
  329. data/test_app/.rspec +0 -1
  330. data/test_app/Gemfile.minitest +0 -4
  331. data/test_app/Gemfile.rspec3.8 +0 -7
  332. data/test_app/lib/test_app.rb +0 -109
  333. data/test_app/lib/test_app/literal.rb +0 -35
  334. data/test_app/spec/spec_helper.rb +0 -9
  335. data/test_app/spec/unit/test_app/literal_spec.rb +0 -20
  336. data/test_app/test/unit/test_app/literal_test.rb +0 -16
@@ -1,47 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.shared_examples_for 'a method matcher' do
4
- let(:node) { mutation_subject.node }
5
- let(:context) { mutation_subject.context }
6
- let(:mutation_subject) { subject.first }
7
-
8
- it 'returns one subject' do
9
- expect(subject.size).to be(1)
10
- end
11
-
12
- it 'has expected method name' do
13
- expect(name).to eql(method_name)
14
- end
15
-
16
- it 'has expected line number' do
17
- expect(node.location.expression.line).to eql(method_line)
18
- end
19
-
20
- it 'has expected arity' do
21
- expect(arguments.children.length).to eql(method_arity)
22
- end
23
-
24
- it 'has expected scope in context' do
25
- expect(context.scope).to eql(scope)
26
- end
27
-
28
- it 'has source path in context' do
29
- expect(context.source_path).to eql(source_path)
30
- end
31
-
32
- it 'has the correct node type' do
33
- expect(node.type).to be(type)
34
- end
35
- end
36
-
37
- RSpec.shared_examples_for 'skipped candidate' do
38
- before do
39
- expected_warnings.each do |warning|
40
- expect(env).to receive(:warn).with(warning).and_return(env)
41
- end
42
- end
43
-
44
- it 'does not emit matcher' do
45
- expect(subject).to eql([])
46
- end
47
- end
@@ -1,75 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- if ENV['COVERAGE'] == 'true'
4
- require 'simplecov'
5
-
6
- SimpleCov.start do
7
- command_name 'spec:unit'
8
-
9
- add_filter 'config'
10
- add_filter 'spec'
11
- add_filter 'vendor'
12
- add_filter 'test_app'
13
- add_filter 'lib/mutant.rb' # simplecov bug not seeing default block is executed
14
-
15
- minimum_coverage 100
16
- end
17
- end
18
-
19
- require 'tempfile'
20
- require 'concord'
21
- require 'anima'
22
- require 'adamantium'
23
- require 'devtools/spec_helper'
24
- require 'unparser/cli'
25
- require 'mutant'
26
- require 'mutant/meta'
27
-
28
- $LOAD_PATH << File.join(TestApp.root, 'lib')
29
-
30
- require 'test_app'
31
-
32
- module Fixtures
33
- TEST_CONFIG = Mutant::Config::DEFAULT
34
- .with(reporter: Mutant::Reporter::Null.new)
35
-
36
- TEST_ENV = Mutant::Bootstrap
37
- .apply(Mutant::WORLD, TEST_CONFIG).from_right
38
-
39
- end # Fixtures
40
-
41
- module ParserHelper
42
- def generate(node)
43
- Unparser.unparse(node)
44
- end
45
-
46
- def parse(string)
47
- Unparser::Preprocessor.run(Unparser.parse(string))
48
- end
49
-
50
- def parse_expression(string)
51
- Mutant::Config::DEFAULT.expression_parser.apply(string).from_right
52
- end
53
- end # ParserHelper
54
-
55
- module XSpecHelper
56
- def verify_events
57
- expectations = raw_expectations
58
- .map(&XSpec::MessageExpectation.method(:parse))
59
-
60
- XSpec::ExpectationVerifier.verify(self, expectations) do
61
- yield
62
- end
63
- end
64
-
65
- def undefined
66
- double('undefined')
67
- end
68
- end # XSpecHelper
69
-
70
- RSpec.configure do |config|
71
- config.extend(SharedContext)
72
- config.include(ParserHelper)
73
- config.include(Mutant::AST::Sexp)
74
- config.include(XSpecHelper)
75
- end
@@ -1,318 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'anima'
4
- require 'mutant'
5
- require 'parallel'
6
-
7
- # @api private
8
- module MutantSpec
9
- ROOT = Pathname.new(__FILE__).parent.parent.parent
10
-
11
- # Namespace module for corpus testing
12
- #
13
- # rubocop:disable Metrics/MethodLength
14
- module Corpus
15
- TMP = ROOT.join('tmp').freeze
16
- EXCLUDE_GLOB_FORMAT = '{%s}'
17
-
18
- # Not in the docs. Number from chatting with their support.
19
- # 2 processors allocated per container, 4 processes works well.
20
- CIRCLE_CI_CONTAINER_PROCESSES = 4
21
-
22
- private_constant(*constants(false))
23
-
24
- # Project under corpus test
25
- # rubocop:disable Metrics/ClassLength
26
- class Project
27
- MUTEX = Mutex.new
28
-
29
- MUTATION_GENERATION_MESSAGE = 'Total Mutations/Time/Parse-Errors: %s/%0.2fs - %0.2f/s'
30
- START_MESSAGE = 'Starting - %s'
31
- FINISH_MESSAGE = 'Mutations - %4i - %s'
32
- RUBY_GLOB_PATTERN = '**/*.rb'
33
-
34
- DEFAULT_MUTATION_COUNT = 0
35
-
36
- include Adamantium, Anima.new(
37
- :mutation_coverage,
38
- :mutation_generation,
39
- :integration,
40
- :name,
41
- :namespace,
42
- :repo_uri,
43
- :repo_ref,
44
- :exclude
45
- )
46
-
47
- # Verify mutation coverage
48
- #
49
- # @return [self]
50
- # if successful
51
- #
52
- # @raise [Exception]
53
- def verify_mutation_coverage
54
- checkout
55
- Dir.chdir(repo_path) do
56
- Bundler.with_clean_env do
57
- install_mutant
58
- system(
59
- %W[
60
- bundle exec mutant
61
- --use #{integration}
62
- --include lib
63
- --require #{name}
64
- #{namespace}*
65
- ] + concurrency_limits
66
- )
67
- end
68
- end
69
- end
70
-
71
- # The concurrency limits, if any
72
- #
73
- # @return [Array<String>]
74
- def concurrency_limits
75
- if ENV.key?('MUTANT_JOBS')
76
- %W[--jobs #{ENV.fetch('MUTANT_JOBS')}]
77
- else
78
- []
79
- end
80
- end
81
-
82
- # Verify mutation generation
83
- #
84
- # @return [self]
85
- # if successful
86
- #
87
- # @raise [Exception]
88
- # otherwise
89
- def verify_mutation_generation
90
- checkout
91
- start = Mutant::Timer.now
92
-
93
- options = {
94
- finish: method(:finish),
95
- start: method(:start),
96
- in_processes: parallel_processes
97
- }
98
-
99
- total = Parallel.map(effective_ruby_paths, options, &method(:check_generation))
100
- .inject(DEFAULT_MUTATION_COUNT, :+)
101
-
102
- took = Mutant::Timer.now - start
103
- puts MUTATION_GENERATION_MESSAGE % [total, took, total / took]
104
- self
105
- end
106
-
107
- # Checkout repository
108
- #
109
- # @return [self]
110
- def checkout
111
- return self if noinstall?
112
- TMP.mkdir unless TMP.directory?
113
-
114
- if repo_path.exist?
115
- Dir.chdir(repo_path) do
116
- system(%w[git fetch origin])
117
- system(%w[git reset --hard])
118
- system(%w[git clean -f -d -x])
119
- end
120
- else
121
- system(%W[git clone #{repo_uri} #{repo_path}])
122
- end
123
-
124
- Dir.chdir(repo_path) do
125
- system(%W[git checkout #{repo_ref}])
126
- system(%w[git reset --hard])
127
- system(%w[git clean -f -d -x])
128
- end
129
-
130
- self
131
- end
132
- memoize :checkout
133
-
134
- private
135
-
136
- # Count mutations and check error results against whitelist
137
- #
138
- # @param path [Pathname] path responsible for exception
139
- #
140
- # @return [Integer] mutations generated
141
- def check_generation(path)
142
- node = Parser::CurrentRuby.parse(path.read)
143
- fail "Cannot parse: #{path}" unless node
144
-
145
- mutations = Mutant::Mutator.mutate(node)
146
-
147
- mutations.each do |mutation|
148
- check_generation_invariants(node, mutation)
149
- end
150
-
151
- mutations.length
152
- end
153
-
154
- # Check generation invariants
155
- #
156
- # @param [Parser::AST::Node] original
157
- # @param [Parser::AST::Node] mutation
158
- #
159
- # @return [undefined]
160
- #
161
- # @raise [Exception]
162
- def check_generation_invariants(original, mutation)
163
- return unless ENV['MUTANT_CORPUS_EXPENSIVE']
164
-
165
- original_source = Unparser.unparse(original)
166
- mutation_source = Unparser.unparse(mutation)
167
-
168
- Mutant::Diff.build(original_source, mutation_source) and return
169
-
170
- fail Mutant::Reporter::CLI::NO_DIFF_MESSAGE % [
171
- original_source,
172
- original.inspect,
173
- mutation_source,
174
- mutation.inspect
175
- ]
176
- end
177
-
178
- # Install mutant
179
- #
180
- # @return [undefined]
181
- def install_mutant
182
- return if noinstall?
183
- relative = ROOT.relative_path_from(repo_path)
184
- repo_path.join('Gemfile').open('a') do |file|
185
- file << "gem 'mutant', path: '#{relative}'\n"
186
- file << "gem 'mutant-rspec', path: '#{relative}'\n"
187
- file << "gem 'mutant-minitest', path: '#{relative}'\n"
188
- file << "eval_gemfile File.expand_path('#{relative.join('Gemfile.shared')}')\n"
189
- end
190
- lockfile = repo_path.join('Gemfile.lock')
191
- lockfile.delete if lockfile.exist?
192
- system(%w[bundle])
193
- end
194
-
195
- # The effective ruby file paths
196
- #
197
- # @return [Array<Pathname>]
198
- def effective_ruby_paths
199
- Pathname
200
- .glob(repo_path.join(RUBY_GLOB_PATTERN))
201
- .sort_by(&:size)
202
- .reverse
203
- .reject { |path| exclude.include?(path.relative_path_from(repo_path).to_s) }
204
- end
205
-
206
- # Number of parallel processes to use
207
- #
208
- # @return [Integer]
209
- def parallel_processes
210
- if ENV.key?('CI')
211
- CIRCLE_CI_CONTAINER_PROCESSES
212
- else
213
- Etc.nprocessors
214
- end
215
- end
216
-
217
- # Repository path
218
- #
219
- # @return [Pathname]
220
- def repo_path
221
- TMP.join(name)
222
- end
223
-
224
- # Test if installation should be skipped
225
- #
226
- # @return [Boolean]
227
- def noinstall?
228
- ENV.key?('NOINSTALL')
229
- end
230
-
231
- # Print start progress
232
- #
233
- # @param [Pathname] path
234
- # @param [Integer] _index
235
- #
236
- # @return [undefined]
237
- #
238
- def start(path, _index)
239
- MUTEX.synchronize do
240
- puts START_MESSAGE % path
241
- end
242
- end
243
-
244
- # Print finish progress
245
- #
246
- # @param [Pathname] path
247
- # @param [Integer] _index
248
- # @param [Integer] count
249
- #
250
- # @return [undefined]
251
- #
252
- def finish(path, _index, count)
253
- MUTEX.synchronize do
254
- puts FINISH_MESSAGE % [count, path]
255
- end
256
- end
257
-
258
- # Helper method to execute system commands
259
- #
260
- # @param [Array<String>] arguments
261
- #
262
- # rubocop:disable Style/GuardClause - guard clause without else does not make sense
263
- def system(arguments)
264
- return if Kernel.system(*arguments)
265
-
266
- if block_given?
267
- yield
268
- else
269
- fail "System command failed!: #{arguments.join(' ')}"
270
- end
271
- end
272
-
273
- Transform = Mutant::Transform
274
-
275
- boolean = Transform::Boolean.new
276
- string = Transform::Primitive.new(String)
277
- string_array = Transform::Array.new(string)
278
-
279
- integration = Transform::Sequence.new(
280
- [
281
- Transform::Hash.new(
282
- optional: [],
283
- required: [
284
- Transform::Hash::Key.new('exclude', string_array),
285
- Transform::Hash::Key.new('integration', string),
286
- Transform::Hash::Key.new('mutation_coverage', boolean),
287
- Transform::Hash::Key.new('mutation_generation', boolean),
288
- Transform::Hash::Key.new('name', string),
289
- Transform::Hash::Key.new('namespace', string),
290
- Transform::Hash::Key.new('repo_ref', string),
291
- Transform::Hash::Key.new('repo_uri', string)
292
- ]
293
- ),
294
- Transform::Hash::Symbolize.new,
295
- Transform::Exception.new(RuntimeError, Project.method(:new))
296
- ]
297
- )
298
-
299
- transform =
300
- Transform::Sequence.new(
301
- [
302
- Transform::Exception.new(SystemCallError, :read.to_proc),
303
- Transform::Exception.new(YAML::SyntaxError, YAML.method(:safe_load)),
304
- Transform::Array.new(integration)
305
- ]
306
- )
307
-
308
- path = ROOT.join('spec', 'integrations.yml')
309
-
310
- ALL = Transform::Named
311
- .new(path, transform)
312
- .apply(path)
313
- .lmap(&:compact_message)
314
- .lmap(&method(:fail))
315
- .from_right
316
- end # Project
317
- end # Corpus
318
- end # MutantSpec
@@ -1,62 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module MutantSpec
4
- class FileState
5
- DEFAULTS = IceNine.deep_freeze(
6
- file: false,
7
- contents: nil,
8
- requires: []
9
- )
10
-
11
- include Adamantium, Anima.new(*DEFAULTS.keys)
12
-
13
- def self.new(attributes = DEFAULTS)
14
- super(DEFAULTS.merge(attributes))
15
- end
16
-
17
- DOES_NOT_EXIST = new
18
-
19
- alias_method :file?, :file
20
- end # FileState
21
-
22
- class FakePathname
23
- include Adamantium, Concord.new(:file_system, :pathname)
24
-
25
- def join(*arguments)
26
- self.class.new(
27
- file_system,
28
- pathname.join(*arguments)
29
- )
30
- end
31
-
32
- def read
33
- state.contents
34
- end
35
-
36
- def to_s
37
- pathname.to_s
38
- end
39
-
40
- def file?
41
- state.file?
42
- end
43
-
44
- private
45
-
46
- def state
47
- file_system.state(pathname.to_s)
48
- end
49
- end # FakePathname
50
-
51
- class FileSystem
52
- include Adamantium, Concord.new(:file_states)
53
-
54
- def state(filename)
55
- file_states.fetch(filename, FileState::DOES_NOT_EXIST)
56
- end
57
-
58
- def path(filename)
59
- FakePathname.new(self, Pathname.new(filename))
60
- end
61
- end # FileSystem
62
- end # MutantSpec