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
@@ -40,7 +40,7 @@ module Mutant
40
40
  instance_of?(Success)
41
41
  end
42
42
 
43
- # Succesful result producing value
43
+ # Successful result producing value
44
44
  class Success < self
45
45
  include Concord::Public.new(:value, :log)
46
46
 
@@ -10,12 +10,12 @@ module Mutant
10
10
 
11
11
  ATTRIBUTES = %i[block log_pipe result_pipe world].freeze
12
12
 
13
- # Unsucessful result as child exited nonzero
13
+ # Unsuccessful result as child exited nonzero
14
14
  class ChildError < Result
15
15
  include Concord::Public.new(:value, :log)
16
16
  end # ChildError
17
17
 
18
- # Unsucessful result as fork failed
18
+ # Unsuccessful result as fork failed
19
19
  class ForkError < Result
20
20
  include Equalizer.new
21
21
  end # ForkError
@@ -73,9 +73,6 @@ module Mutant
73
73
 
74
74
  private
75
75
 
76
- # Start child process
77
- #
78
- # @return [Integer]
79
76
  def start_child
80
77
  world.process.fork do
81
78
  Child.call(
@@ -87,12 +84,6 @@ module Mutant
87
84
  end
88
85
  end
89
86
 
90
- # Read child result
91
- #
92
- # @param [Integer] pid
93
- #
94
- # @return [undefined]
95
- #
96
87
  # rubocop:disable Metrics/MethodLength
97
88
  def read_child_result(pid)
98
89
  result_fragments = []
@@ -115,11 +106,6 @@ module Mutant
115
106
  end
116
107
  # rubocop:enable Metrics/MethodLength
117
108
 
118
- # Read fragments
119
- #
120
- # @param [Hash{FD => Array<String}] targets
121
- #
122
- # @return [undefined]
123
109
  def read_fragments(targets)
124
110
  until targets.empty?
125
111
  ready, = world.io.select(targets.keys)
@@ -134,11 +120,6 @@ module Mutant
134
120
  end
135
121
  end
136
122
 
137
- # Wait for child process
138
- #
139
- # @param [Integer] pid
140
- #
141
- # @return [undefined]
142
123
  def wait_child(pid, log_fragments)
143
124
  _pid, status = world.process.wait2(pid)
144
125
 
@@ -147,9 +128,6 @@ module Mutant
147
128
  end
148
129
  end
149
130
 
150
- # Add a result
151
- #
152
- # @param [Result]
153
131
  def add_result(result)
154
132
  @result = defined?(@result) ? @result.add_error(result) : result
155
133
  end
@@ -3,7 +3,7 @@
3
3
  module Mutant
4
4
  # Module providing isolation
5
5
  class Isolation
6
- # Absolutly no isolation
6
+ # Absolutely no isolation
7
7
  #
8
8
  # Only useful for debugging.
9
9
  class None < self
@@ -43,6 +43,8 @@ module Mutant
43
43
  def self.load_mutant_license(world)
44
44
  Either
45
45
  .wrap_error(LoadError) { world.gem_method.call(NAME, VERSION) }
46
+ .lmap(&:message)
47
+ .lmap(&method(:check_for_rubygems_mutant_license))
46
48
  .lmap(&method(:unlicensed))
47
49
  end
48
50
 
@@ -50,6 +52,15 @@ module Mutant
50
52
  "[Mutant-License-Error]: #{message}"
51
53
  end
52
54
 
55
+ def self.check_for_rubygems_mutant_license(message)
56
+ if message.include?('already activated mutant-license-0.0.0')
57
+ 'mutant-license gem from rubygems.org is a dummy'
58
+ else
59
+ message
60
+ end
61
+ end
62
+ private_class_method :check_for_rubygems_mutant_license
63
+
53
64
  def self.license_path(world)
54
65
  world
55
66
  .pathname
@@ -25,25 +25,11 @@ module Mutant
25
25
  )
26
26
  end
27
27
 
28
- # Test if subject is allowed do
29
- #
30
- # @param [Config] config
31
- # @param [Subject] subject
32
- #
33
- # @return [Boolean]
34
28
  def self.allowed_subject?(config, subject)
35
29
  select_subject?(config, subject) && !ignore_subject?(config, subject)
36
30
  end
37
31
  private_class_method :allowed_subject?
38
32
 
39
- # Predicate that tests for selected subject
40
- #
41
- # @param [Config] config
42
- # @param [Subject] subject
43
- #
44
- # @return [Boolean]
45
- #
46
- # @api private
47
33
  def self.select_subject?(config, subject)
48
34
  config.subject_filters.all? { |filter| filter.call(subject) }
49
35
  end
@@ -44,16 +44,10 @@ module Mutant
44
44
 
45
45
  private
46
46
 
47
- # Present attributes
48
- #
49
- # @return [Array<Symbol>]
50
47
  def present_attributes
51
48
  to_h.reject { |_key, value| value.empty? }.keys
52
49
  end
53
50
 
54
- # Formatted attributes
55
- #
56
- # @return [String]
57
51
  def inspect_attributes
58
52
  attributes = present_attributes
59
53
  .map(&method(:format_attribute))
@@ -62,11 +56,6 @@ module Mutant
62
56
  attributes.empty? ? EMPTY_ATTRIBUTES : attributes
63
57
  end
64
58
 
65
- # Format attribute
66
- #
67
- # @param [Symbol] attribute_name
68
- #
69
- # @return [String]
70
59
  def format_attribute(attribute_name)
71
60
  ATTRIBUTE_FORMAT %
72
61
  [
@@ -49,9 +49,6 @@ module Mutant
49
49
 
50
50
  private
51
51
 
52
- # Test if method should be skipped
53
- #
54
- # @return [Truthy]
55
52
  def skip?
56
53
  location = source_location
57
54
  if location.nil? || BLACKLIST.include?(location.first)
@@ -61,56 +58,31 @@ module Mutant
61
58
  end
62
59
  end
63
60
 
64
- # Target method name
65
- #
66
- # @return [String]
67
61
  def method_name
68
62
  target_method.name
69
63
  end
70
64
 
71
- # Target context
72
- #
73
- # @return [Context]
74
65
  def context
75
66
  Context.new(scope, source_path)
76
67
  end
77
68
 
78
- # Root source node
79
- #
80
- # @return [Parser::AST::Node]
81
69
  def ast
82
70
  env.parser.call(source_path)
83
71
  end
84
72
 
85
- # Path to source
86
- #
87
- # @return [Pathname]
88
73
  def source_path
89
74
  env.world.pathname.new(source_location.first)
90
75
  end
91
76
  memoize :source_path
92
77
 
93
- # Source file line
94
- #
95
- # @return [Integer]
96
78
  def source_line
97
79
  source_location.last
98
80
  end
99
81
 
100
- # Full source location
101
- #
102
- # @return [Array{String,Integer}]
103
82
  def source_location
104
83
  target_method.source_location
105
84
  end
106
85
 
107
- # Matched subject
108
- #
109
- # @return [Subject]
110
- # if there is a matched node
111
- #
112
- # @return [nil]
113
- # otherwise
114
86
  def subject
115
87
  node = matched_node_path.last || return
116
88
 
@@ -122,9 +94,6 @@ module Mutant
122
94
  end
123
95
  memoize :subject
124
96
 
125
- # Matched node path
126
- #
127
- # @return [Array<Parser::AST::Node>]
128
97
  def matched_node_path
129
98
  AST.find_last_path(ast, &method(:match?))
130
99
  end
@@ -33,11 +33,6 @@ module Mutant
33
33
 
34
34
  private
35
35
 
36
- # Check if node is matched
37
- #
38
- # @param [Parser::AST::Node] node
39
- #
40
- # @return [Boolean]
41
36
  def match?(node)
42
37
  n_def?(node) &&
43
38
  node.location.line.equal?(source_line) &&
@@ -50,9 +45,6 @@ module Mutant
50
45
 
51
46
  private
52
47
 
53
- # Source location
54
- #
55
- # @return [Array{String,Integer}]
56
48
  def source_location
57
49
  scope
58
50
  .unmemoized_instance_method(method_name)
@@ -0,0 +1,86 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Mutant
4
+ class Matcher
5
+ class Method
6
+ # Matcher for metaclass methods
7
+ # i.e. ones defined using class << self or class << CONSTANT. It might??
8
+ # work for methods defined like class << obj, but I don't think the
9
+ # plumbing will be in place in the subject for that to work
10
+ class Metaclass < self
11
+
12
+ # New singleton method matcher
13
+ #
14
+ # @param [Class, Module] scope
15
+ # @param [Symbol] method_name
16
+ #
17
+ # @return [Matcher::Method::Singleton]
18
+ def self.new(scope, method_name)
19
+ super(scope, method_name, Evaluator)
20
+ end
21
+
22
+ # Metaclass method evaluator
23
+ class Evaluator < Evaluator
24
+ # Terminology note: the "receiver" is the `self` in `class << self`
25
+ SUBJECT_CLASS = Subject::Method::Metaclass
26
+ NAME_INDEX = 0
27
+ CONST_NAME_INDEX = 1
28
+ SCLASS_RECEIVER_INDEX = 0
29
+ RECEIVER_WARNING = 'Can only match :def inside :sclass on ' \
30
+ ':self or :const, got :sclass on %p ' \
31
+ 'unable to match'
32
+
33
+ private
34
+
35
+ def match?(node)
36
+ n_def?(node) &&
37
+ name?(node) &&
38
+ line?(node) &&
39
+ metaclass_receiver?(node)
40
+ end
41
+
42
+ def metaclass_receiver?(node)
43
+ candidate = metaclass_containing(node)
44
+ candidate && metaclass_target?(candidate)
45
+ end
46
+
47
+ def metaclass_containing(node)
48
+ AST::FindMetaclassContaining.call(ast, node)
49
+ end
50
+
51
+ def line?(node)
52
+ node
53
+ .location
54
+ .line
55
+ .equal?(source_line)
56
+ end
57
+
58
+ def name?(node)
59
+ node.children.fetch(NAME_INDEX).equal?(method_name)
60
+ end
61
+
62
+ def metaclass_target?(node)
63
+ receiver = node.children.fetch(SCLASS_RECEIVER_INDEX)
64
+ case receiver.type
65
+ when :self
66
+ true
67
+ when :const
68
+ sclass_const_name?(receiver)
69
+ else
70
+ env.warn(RECEIVER_WARNING % receiver.type)
71
+ nil
72
+ end
73
+ end
74
+
75
+ def sclass_const_name?(node)
76
+ name = node.children.fetch(CONST_NAME_INDEX)
77
+ name.to_s.eql?(context.unqualified_name)
78
+ end
79
+
80
+ end # Evaluator
81
+
82
+ private_constant(*constants(false))
83
+ end # Singleton
84
+ end # Method
85
+ end # Matcher
86
+ end # Mutant
@@ -25,20 +25,10 @@ module Mutant
25
25
 
26
26
  private
27
27
 
28
- # Test for node match
29
- #
30
- # @param [Parser::AST::Node] node
31
- #
32
- # @return [Boolean]
33
28
  def match?(node)
34
29
  n_defs?(node) && line?(node) && name?(node) && receiver?(node)
35
30
  end
36
31
 
37
- # Test for line match
38
- #
39
- # @param [Parser::AST::Node] node
40
- #
41
- # @return [Boolean]
42
32
  def line?(node)
43
33
  node
44
34
  .location
@@ -46,20 +36,10 @@ module Mutant
46
36
  .equal?(source_line)
47
37
  end
48
38
 
49
- # Test for name match
50
- #
51
- # @param [Parser::AST::Node] node
52
- #
53
- # @return [Boolean]
54
39
  def name?(node)
55
40
  node.children.fetch(NAME_INDEX).equal?(method_name)
56
41
  end
57
42
 
58
- # Test for receiver match
59
- #
60
- # @param [Parser::AST::Node] node
61
- #
62
- # @return [Boolean]
63
43
  def receiver?(node)
64
44
  receiver = node.children.fetch(RECEIVER_INDEX)
65
45
  case receiver.type
@@ -73,11 +53,6 @@ module Mutant
73
53
  end
74
54
  end
75
55
 
76
- # Test if receiver name matches context
77
- #
78
- # @param [Parser::AST::Node] node
79
- #
80
- # @return [Boolean]
81
56
  def receiver_name?(node)
82
57
  name = node.children.fetch(NAME_INDEX)
83
58
  name.to_s.eql?(context.unqualified_name)
@@ -27,16 +27,10 @@ module Mutant
27
27
 
28
28
  private
29
29
 
30
- # method matcher class
31
- #
32
- # @return [Class:Matcher::Method]
33
30
  def matcher
34
31
  self.class::MATCHER
35
32
  end
36
33
 
37
- # Available methods scope
38
- #
39
- # @return [Enumerable<Method, UnboundMethod>]
40
34
  def methods
41
35
  candidate_names.each_with_object([]) do |name, methods|
42
36
  method = access(name)
@@ -45,9 +39,6 @@ module Mutant
45
39
  end
46
40
  memoize :methods
47
41
 
48
- # Candidate method names on target scope
49
- #
50
- # @return [Enumerable<Symbol>]
51
42
  def candidate_names
52
43
  CANDIDATE_NAMES
53
44
  .map(&candidate_scope.method(:public_send))
@@ -55,10 +46,8 @@ module Mutant
55
46
  .sort
56
47
  end
57
48
 
58
- # Candidate scope
59
- #
60
- # @return [Class, Module]
61
49
  abstract_method :candidate_scope
50
+ private :candidate_scope
62
51
 
63
52
  # Matcher for singleton methods
64
53
  class Singleton < self
@@ -66,18 +55,10 @@ module Mutant
66
55
 
67
56
  private
68
57
 
69
- # Method object on scope
70
- #
71
- # @param [Symbol] method_name
72
- #
73
- # @return [Method]
74
58
  def access(method_name)
75
59
  scope.method(method_name)
76
60
  end
77
61
 
78
- # Candidate scope
79
- #
80
- # @return [Class]
81
62
  def candidate_scope
82
63
  scope.singleton_class
83
64
  end
@@ -85,24 +66,32 @@ module Mutant
85
66
 
86
67
  end # Singleton
87
68
 
69
+ # Matcher for metaclass methods
70
+ class Metaclass < self
71
+ MATCHER = Matcher::Method::Metaclass
72
+
73
+ private
74
+
75
+ def access(method_name)
76
+ scope.method(method_name)
77
+ end
78
+
79
+ def candidate_scope
80
+ scope.singleton_class
81
+ end
82
+ memoize :candidate_scope, freezer: :noop
83
+ end # Metaclass
84
+
88
85
  # Matcher for instance methods
89
86
  class Instance < self
90
87
  MATCHER = Matcher::Method::Instance
91
88
 
92
89
  private
93
90
 
94
- # Method object on scope
95
- #
96
- # @param [Symbol] method_name
97
- #
98
- # @return [UnboundMethod]
99
91
  def access(method_name)
100
92
  scope.instance_method(method_name)
101
93
  end
102
94
 
103
- # Candidate scope
104
- #
105
- # @return [Class, Module]
106
95
  def candidate_scope
107
96
  scope
108
97
  end