mutest 0.0.1 → 0.0.2

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 (401) hide show
  1. checksums.yaml +4 -4
  2. data/.buildkite/hooks/pre-command +3 -0
  3. data/.buildkite/pipeline.yml +51 -0
  4. data/.gitattributes +1 -0
  5. data/.gitignore +38 -0
  6. data/.rspec +5 -0
  7. data/Gemfile +13 -0
  8. data/Gemfile.lock +216 -0
  9. data/Gemfile.shared +3 -0
  10. data/LICENSE +21 -0
  11. data/README.md +8 -0
  12. data/Rakefile +24 -0
  13. data/bin/mutest +39 -0
  14. data/build/Dockerfile +71 -0
  15. data/build/docker-bootstrap.sh +85 -0
  16. data/build/docker-exec +29 -0
  17. data/build/make-docker +3 -0
  18. data/build/ruby_matrix +1 -0
  19. data/build/run +5 -0
  20. data/build/strict-mode.sh +16 -0
  21. data/circle.yml +7 -0
  22. data/config/devtools.yml +2 -0
  23. data/config/flay.yml +3 -0
  24. data/config/flog.yml +2 -0
  25. data/config/reek.yml +137 -0
  26. data/config/rubocop.yml +395 -0
  27. data/config/triage.yml +2 -0
  28. data/config/yardstick.yml +2 -0
  29. data/lib/mutest.rb +243 -0
  30. data/lib/mutest/actor.rb +52 -0
  31. data/lib/mutest/actor/env.rb +28 -0
  32. data/lib/mutest/actor/mailbox.rb +31 -0
  33. data/lib/mutest/actor/receiver.rb +39 -0
  34. data/lib/mutest/actor/sender.rb +22 -0
  35. data/lib/mutest/ast.rb +44 -0
  36. data/lib/mutest/ast/meta.rb +7 -0
  37. data/lib/mutest/ast/meta/const.rb +22 -0
  38. data/lib/mutest/ast/meta/optarg.rb +24 -0
  39. data/lib/mutest/ast/meta/resbody.rb +15 -0
  40. data/lib/mutest/ast/meta/restarg.rb +15 -0
  41. data/lib/mutest/ast/meta/send.rb +89 -0
  42. data/lib/mutest/ast/meta/symbol.rb +15 -0
  43. data/lib/mutest/ast/named_children.rb +86 -0
  44. data/lib/mutest/ast/node_predicates.rb +17 -0
  45. data/lib/mutest/ast/nodes.rb +22 -0
  46. data/lib/mutest/ast/regexp.rb +50 -0
  47. data/lib/mutest/ast/regexp/transformer.rb +184 -0
  48. data/lib/mutest/ast/regexp/transformer/alternative.rb +39 -0
  49. data/lib/mutest/ast/regexp/transformer/character_set.rb +46 -0
  50. data/lib/mutest/ast/regexp/transformer/direct.rb +101 -0
  51. data/lib/mutest/ast/regexp/transformer/options_group.rb +65 -0
  52. data/lib/mutest/ast/regexp/transformer/quantifier.rb +112 -0
  53. data/lib/mutest/ast/regexp/transformer/recursive.rb +50 -0
  54. data/lib/mutest/ast/regexp/transformer/root.rb +28 -0
  55. data/lib/mutest/ast/regexp/transformer/text.rb +55 -0
  56. data/lib/mutest/ast/sexp.rb +26 -0
  57. data/lib/mutest/ast/types.rb +140 -0
  58. data/lib/mutest/cli.rb +196 -0
  59. data/lib/mutest/color.rb +39 -0
  60. data/lib/mutest/config.rb +28 -0
  61. data/lib/mutest/context.rb +98 -0
  62. data/lib/mutest/diff.rb +111 -0
  63. data/lib/mutest/env.rb +59 -0
  64. data/lib/mutest/env/bootstrap.rb +159 -0
  65. data/lib/mutest/expression.rb +55 -0
  66. data/lib/mutest/expression/method.rb +54 -0
  67. data/lib/mutest/expression/methods.rb +58 -0
  68. data/lib/mutest/expression/namespace.rb +75 -0
  69. data/lib/mutest/expression/parser.rb +64 -0
  70. data/lib/mutest/integration.rb +75 -0
  71. data/lib/mutest/isolation.rb +11 -0
  72. data/lib/mutest/isolation/fork.rb +72 -0
  73. data/lib/mutest/isolation/none.rb +23 -0
  74. data/lib/mutest/loader.rb +27 -0
  75. data/lib/mutest/matcher.rb +14 -0
  76. data/lib/mutest/matcher/chain.rb +19 -0
  77. data/lib/mutest/matcher/compiler.rb +55 -0
  78. data/lib/mutest/matcher/config.rb +81 -0
  79. data/lib/mutest/matcher/filter.rb +19 -0
  80. data/lib/mutest/matcher/method.rb +138 -0
  81. data/lib/mutest/matcher/method/instance.rb +63 -0
  82. data/lib/mutest/matcher/method/singleton.rb +88 -0
  83. data/lib/mutest/matcher/methods.rb +109 -0
  84. data/lib/mutest/matcher/namespace.rb +41 -0
  85. data/lib/mutest/matcher/null.rb +17 -0
  86. data/lib/mutest/matcher/scope.rb +38 -0
  87. data/lib/mutest/matcher/static.rb +15 -0
  88. data/lib/mutest/meta.rb +33 -0
  89. data/lib/mutest/meta/example.rb +32 -0
  90. data/lib/mutest/meta/example/dsl.rb +107 -0
  91. data/lib/mutest/meta/example/verification.rb +85 -0
  92. data/lib/mutest/mutation.rb +101 -0
  93. data/lib/mutest/mutator.rb +117 -0
  94. data/lib/mutest/mutator/node.rb +166 -0
  95. data/lib/mutest/mutator/node/and_asgn.rb +25 -0
  96. data/lib/mutest/mutator/node/argument.rb +68 -0
  97. data/lib/mutest/mutator/node/arguments.rb +90 -0
  98. data/lib/mutest/mutator/node/begin.rb +21 -0
  99. data/lib/mutest/mutator/node/binary.rb +64 -0
  100. data/lib/mutest/mutator/node/block.rb +51 -0
  101. data/lib/mutest/mutator/node/break.rb +21 -0
  102. data/lib/mutest/mutator/node/case.rb +47 -0
  103. data/lib/mutest/mutator/node/class.rb +21 -0
  104. data/lib/mutest/mutator/node/conditional_loop.rb +25 -0
  105. data/lib/mutest/mutator/node/const.rb +23 -0
  106. data/lib/mutest/mutator/node/define.rb +79 -0
  107. data/lib/mutest/mutator/node/defined.rb +24 -0
  108. data/lib/mutest/mutator/node/dstr.rb +20 -0
  109. data/lib/mutest/mutator/node/dsym.rb +20 -0
  110. data/lib/mutest/mutator/node/generic.rb +77 -0
  111. data/lib/mutest/mutator/node/if.rb +57 -0
  112. data/lib/mutest/mutator/node/kwbegin.rb +20 -0
  113. data/lib/mutest/mutator/node/literal.rb +19 -0
  114. data/lib/mutest/mutator/node/literal/array.rb +37 -0
  115. data/lib/mutest/mutator/node/literal/boolean.rb +27 -0
  116. data/lib/mutest/mutator/node/literal/fixnum.rb +36 -0
  117. data/lib/mutest/mutator/node/literal/float.rb +45 -0
  118. data/lib/mutest/mutator/node/literal/hash.rb +52 -0
  119. data/lib/mutest/mutator/node/literal/nil.rb +20 -0
  120. data/lib/mutest/mutator/node/literal/range.rb +38 -0
  121. data/lib/mutest/mutator/node/literal/regex.rb +76 -0
  122. data/lib/mutest/mutator/node/literal/string.rb +21 -0
  123. data/lib/mutest/mutator/node/literal/symbol.rb +26 -0
  124. data/lib/mutest/mutator/node/masgn.rb +21 -0
  125. data/lib/mutest/mutator/node/match_current_line.rb +22 -0
  126. data/lib/mutest/mutator/node/mlhs.rb +21 -0
  127. data/lib/mutest/mutator/node/named_value/access.rb +54 -0
  128. data/lib/mutest/mutator/node/named_value/constant_assignment.rb +42 -0
  129. data/lib/mutest/mutator/node/named_value/variable_assignment.rb +47 -0
  130. data/lib/mutest/mutator/node/next.rb +22 -0
  131. data/lib/mutest/mutator/node/noop.rb +19 -0
  132. data/lib/mutest/mutator/node/nthref.rb +22 -0
  133. data/lib/mutest/mutator/node/op_asgn.rb +50 -0
  134. data/lib/mutest/mutator/node/or_asgn.rb +26 -0
  135. data/lib/mutest/mutator/node/regexp.rb +33 -0
  136. data/lib/mutest/mutator/node/regexp/alternation_meta.rb +21 -0
  137. data/lib/mutest/mutator/node/regexp/capture_group.rb +26 -0
  138. data/lib/mutest/mutator/node/regexp/character_type.rb +29 -0
  139. data/lib/mutest/mutator/node/regexp/end_of_line_anchor.rb +21 -0
  140. data/lib/mutest/mutator/node/regexp/end_of_string_or_before_end_of_line_anchor.rb +21 -0
  141. data/lib/mutest/mutator/node/regexp/one_or_more.rb +29 -0
  142. data/lib/mutest/mutator/node/regexp/zero_or_more.rb +29 -0
  143. data/lib/mutest/mutator/node/regopt.rb +28 -0
  144. data/lib/mutest/mutator/node/resbody.rb +34 -0
  145. data/lib/mutest/mutator/node/rescue.rb +69 -0
  146. data/lib/mutest/mutator/node/return.rb +24 -0
  147. data/lib/mutest/mutator/node/send.rb +270 -0
  148. data/lib/mutest/mutator/node/send/attribute_assignment.rb +39 -0
  149. data/lib/mutest/mutator/node/send/binary.rb +45 -0
  150. data/lib/mutest/mutator/node/send/conditional.rb +21 -0
  151. data/lib/mutest/mutator/node/send/index.rb +47 -0
  152. data/lib/mutest/mutator/node/splat.rb +23 -0
  153. data/lib/mutest/mutator/node/super.rb +24 -0
  154. data/lib/mutest/mutator/node/when.rb +60 -0
  155. data/lib/mutest/mutator/node/yield.rb +21 -0
  156. data/lib/mutest/mutator/node/zsuper.rb +20 -0
  157. data/lib/mutest/mutator/util.rb +11 -0
  158. data/lib/mutest/mutator/util/array.rb +42 -0
  159. data/lib/mutest/mutator/util/symbol.rb +19 -0
  160. data/lib/mutest/parallel.rb +89 -0
  161. data/lib/mutest/parallel/master.rb +181 -0
  162. data/lib/mutest/parallel/source.rb +57 -0
  163. data/lib/mutest/parallel/worker.rb +76 -0
  164. data/lib/mutest/parser.rb +22 -0
  165. data/lib/mutest/registry.rb +43 -0
  166. data/lib/mutest/reporter.rb +39 -0
  167. data/lib/mutest/reporter/cli.rb +87 -0
  168. data/lib/mutest/reporter/cli/format.rb +135 -0
  169. data/lib/mutest/reporter/cli/printer.rb +124 -0
  170. data/lib/mutest/reporter/cli/printer/config.rb +24 -0
  171. data/lib/mutest/reporter/cli/printer/env_progress.rb +76 -0
  172. data/lib/mutest/reporter/cli/printer/env_result.rb +20 -0
  173. data/lib/mutest/reporter/cli/printer/mutation_progress_result.rb +31 -0
  174. data/lib/mutest/reporter/cli/printer/mutation_result.rb +127 -0
  175. data/lib/mutest/reporter/cli/printer/status.rb +49 -0
  176. data/lib/mutest/reporter/cli/printer/status_progressive.rb +46 -0
  177. data/lib/mutest/reporter/cli/printer/subject_progress.rb +65 -0
  178. data/lib/mutest/reporter/cli/printer/subject_result.rb +23 -0
  179. data/lib/mutest/reporter/cli/printer/test_result.rb +28 -0
  180. data/lib/mutest/reporter/cli/tput.rb +43 -0
  181. data/lib/mutest/reporter/null.rb +14 -0
  182. data/lib/mutest/reporter/sequence.rb +24 -0
  183. data/lib/mutest/repository.rb +80 -0
  184. data/lib/mutest/require_highjack.rb +24 -0
  185. data/lib/mutest/result.rb +212 -0
  186. data/lib/mutest/runner.rb +81 -0
  187. data/lib/mutest/runner/sink.rb +63 -0
  188. data/lib/mutest/scope.rb +6 -0
  189. data/lib/mutest/selector.rb +13 -0
  190. data/lib/mutest/selector/expression.rb +25 -0
  191. data/lib/mutest/source_file.rb +47 -0
  192. data/lib/mutest/subject.rb +94 -0
  193. data/lib/mutest/subject/method.rb +42 -0
  194. data/lib/mutest/subject/method/instance.rb +43 -0
  195. data/lib/mutest/subject/method/singleton.rb +19 -0
  196. data/lib/mutest/test.rb +14 -0
  197. data/lib/mutest/util.rb +18 -0
  198. data/lib/mutest/version.rb +4 -0
  199. data/lib/mutest/warning_filter.rb +58 -0
  200. data/lib/mutest/zombifier.rb +119 -0
  201. data/meta/and.rb +13 -0
  202. data/meta/and_asgn.rb +12 -0
  203. data/meta/array.rb +28 -0
  204. data/meta/begin.rb +19 -0
  205. data/meta/block.rb +104 -0
  206. data/meta/block_pass.rb +6 -0
  207. data/meta/blockarg.rb +8 -0
  208. data/meta/break.rb +8 -0
  209. data/meta/case.rb +221 -0
  210. data/meta/casgn.rb +26 -0
  211. data/meta/cbase.rb +6 -0
  212. data/meta/class.rb +10 -0
  213. data/meta/const.rb +15 -0
  214. data/meta/csend.rb +8 -0
  215. data/meta/cvar.rb +5 -0
  216. data/meta/cvasgn.rb +8 -0
  217. data/meta/date.rb +57 -0
  218. data/meta/def.rb +260 -0
  219. data/meta/defined.rb +7 -0
  220. data/meta/dstr.rb +11 -0
  221. data/meta/dsym.rb +12 -0
  222. data/meta/ensure.rb +7 -0
  223. data/meta/false.rb +6 -0
  224. data/meta/float.rb +35 -0
  225. data/meta/gvar.rb +5 -0
  226. data/meta/gvasgn.rb +8 -0
  227. data/meta/hash.rb +22 -0
  228. data/meta/if.rb +75 -0
  229. data/meta/int.rb +16 -0
  230. data/meta/ivar.rb +6 -0
  231. data/meta/ivasgn.rb +21 -0
  232. data/meta/kwarg.rb +8 -0
  233. data/meta/kwbegin.rb +7 -0
  234. data/meta/kwoptarg.rb +11 -0
  235. data/meta/kwrestarg.rb +17 -0
  236. data/meta/lvar.rb +14 -0
  237. data/meta/lvasgn.rb +8 -0
  238. data/meta/masgn.rb +5 -0
  239. data/meta/match_current_line.rb +13 -0
  240. data/meta/next.rb +9 -0
  241. data/meta/nil.rb +3 -0
  242. data/meta/nthref.rb +12 -0
  243. data/meta/op_assgn.rb +39 -0
  244. data/meta/or.rb +13 -0
  245. data/meta/or_asgn.rb +48 -0
  246. data/meta/range.rb +37 -0
  247. data/meta/redo.rb +3 -0
  248. data/meta/regexp.rb +84 -0
  249. data/meta/regexp/character_types.rb +20 -0
  250. data/meta/regexp/regexp_alternation_meta.rb +11 -0
  251. data/meta/regexp/regexp_bol_anchor.rb +8 -0
  252. data/meta/regexp/regexp_bos_anchor.rb +16 -0
  253. data/meta/regexp/regexp_capture_group.rb +17 -0
  254. data/meta/regexp/regexp_eol_anchor.rb +8 -0
  255. data/meta/regexp/regexp_eos_anchor.rb +6 -0
  256. data/meta/regexp/regexp_eos_ob_eol_anchor.rb +8 -0
  257. data/meta/regexp/regexp_one_or_more.rb +32 -0
  258. data/meta/regexp/regexp_root_expression.rb +8 -0
  259. data/meta/regexp/regexp_zero_or_more.rb +32 -0
  260. data/meta/regopt.rb +8 -0
  261. data/meta/rescue.rb +87 -0
  262. data/meta/restarg.rb +9 -0
  263. data/meta/return.rb +14 -0
  264. data/meta/self.rb +5 -0
  265. data/meta/send.rb +849 -0
  266. data/meta/str.rb +5 -0
  267. data/meta/super.rb +25 -0
  268. data/meta/sym.rb +6 -0
  269. data/meta/true.rb +6 -0
  270. data/meta/until.rb +15 -0
  271. data/meta/while.rb +24 -0
  272. data/meta/yield.rb +8 -0
  273. data/mutest-rspec.gemspec +22 -0
  274. data/mutest.gemspec +45 -0
  275. data/spec/integration/mutest/corpus_spec.rb +18 -0
  276. data/spec/integration/mutest/isolation/fork_spec.rb +8 -0
  277. data/spec/integration/mutest/null_spec.rb +13 -0
  278. data/spec/integration/mutest/rspec_spec.rb +11 -0
  279. data/spec/integration/mutest/test_mutator_handles_types_spec.rb +7 -0
  280. data/spec/integrations.yml +32 -0
  281. data/spec/rcov.opts +7 -0
  282. data/spec/shared/framework_integration_behavior.rb +44 -0
  283. data/spec/shared/method_matcher_behavior.rb +49 -0
  284. data/spec/spec_helper.rb +70 -0
  285. data/spec/support/compress_helper.rb +9 -0
  286. data/spec/support/corpus.rb +331 -0
  287. data/spec/support/fake_actor.rb +107 -0
  288. data/spec/support/file_system.rb +60 -0
  289. data/spec/support/ice_nine_config.rb +8 -0
  290. data/spec/support/rb_bug.rb +15 -0
  291. data/spec/support/ruby_vm.rb +82 -0
  292. data/spec/support/shared_context.rb +125 -0
  293. data/spec/support/test_app.rb +5 -0
  294. data/spec/support/warning.rb +73 -0
  295. data/spec/support/warnings.yml +5 -0
  296. data/spec/support/xspec.rb +175 -0
  297. data/spec/unit/mutest/actor/binding_spec.rb +32 -0
  298. data/spec/unit/mutest/actor/env_spec.rb +29 -0
  299. data/spec/unit/mutest/actor/mailbox_spec.rb +25 -0
  300. data/spec/unit/mutest/actor/message_spec.rb +22 -0
  301. data/spec/unit/mutest/actor/receiver_spec.rb +56 -0
  302. data/spec/unit/mutest/actor/sender_spec.rb +22 -0
  303. data/spec/unit/mutest/ast/meta/optarg_spec.rb +21 -0
  304. data/spec/unit/mutest/ast/meta/send/proc_predicate_spec.rb +28 -0
  305. data/spec/unit/mutest/ast/meta/send/receiver_possible_top_level_const_predicate_spec.rb +37 -0
  306. data/spec/unit/mutest/ast/meta/send_spec.rb +42 -0
  307. data/spec/unit/mutest/ast/named_children_spec.rb +87 -0
  308. data/spec/unit/mutest/ast/regexp/parse_spec.rb +5 -0
  309. data/spec/unit/mutest/ast/regexp/supported_predicate_spec.rb +14 -0
  310. data/spec/unit/mutest/ast/regexp/transformer/lookup_table/table_spec.rb +19 -0
  311. data/spec/unit/mutest/ast/regexp/transformer/lookup_table_spec.rb +33 -0
  312. data/spec/unit/mutest/ast/regexp/transformer_spec.rb +19 -0
  313. data/spec/unit/mutest/ast/regexp_spec.rb +625 -0
  314. data/spec/unit/mutest/ast/sexp_spec.rb +36 -0
  315. data/spec/unit/mutest/ast_spec.rb +55 -0
  316. data/spec/unit/mutest/cli_spec.rb +247 -0
  317. data/spec/unit/mutest/context_spec.rb +141 -0
  318. data/spec/unit/mutest/diff_spec.rb +185 -0
  319. data/spec/unit/mutest/env/bootstrap_spec.rb +188 -0
  320. data/spec/unit/mutest/env_spec.rb +100 -0
  321. data/spec/unit/mutest/expression/method_spec.rb +44 -0
  322. data/spec/unit/mutest/expression/methods_spec.rb +59 -0
  323. data/spec/unit/mutest/expression/namespace/exact_spec.rb +26 -0
  324. data/spec/unit/mutest/expression/namespace/recursive_spec.rb +64 -0
  325. data/spec/unit/mutest/expression/parser_spec.rb +67 -0
  326. data/spec/unit/mutest/expression_spec.rb +45 -0
  327. data/spec/unit/mutest/integration/null_spec.rb +28 -0
  328. data/spec/unit/mutest/integration/rspec_spec.rb +197 -0
  329. data/spec/unit/mutest/integration_spec.rb +26 -0
  330. data/spec/unit/mutest/isolation/fork_spec.rb +155 -0
  331. data/spec/unit/mutest/isolation/none_spec.rb +16 -0
  332. data/spec/unit/mutest/loader_spec.rb +42 -0
  333. data/spec/unit/mutest/matcher/chain_spec.rb +24 -0
  334. data/spec/unit/mutest/matcher/compiler/subject_prefix_spec.rb +24 -0
  335. data/spec/unit/mutest/matcher/compiler_spec.rb +76 -0
  336. data/spec/unit/mutest/matcher/config_spec.rb +45 -0
  337. data/spec/unit/mutest/matcher/filter_spec.rb +20 -0
  338. data/spec/unit/mutest/matcher/method/instance_spec.rb +125 -0
  339. data/spec/unit/mutest/matcher/method/singleton_spec.rb +85 -0
  340. data/spec/unit/mutest/matcher/methods/instance_spec.rb +58 -0
  341. data/spec/unit/mutest/matcher/methods/singleton_spec.rb +54 -0
  342. data/spec/unit/mutest/matcher/namespace_spec.rb +35 -0
  343. data/spec/unit/mutest/matcher/null_spec.rb +10 -0
  344. data/spec/unit/mutest/matcher/scope_spec.rb +33 -0
  345. data/spec/unit/mutest/matcher/static_spec.rb +11 -0
  346. data/spec/unit/mutest/meta/example/dsl_spec.rb +123 -0
  347. data/spec/unit/mutest/meta/example/verification_spec.rb +120 -0
  348. data/spec/unit/mutest/meta/example_spec.rb +32 -0
  349. data/spec/unit/mutest/mutation_spec.rb +129 -0
  350. data/spec/unit/mutest/mutator/node_spec.rb +43 -0
  351. data/spec/unit/mutest/mutator_spec.rb +30 -0
  352. data/spec/unit/mutest/parallel/driver_spec.rb +26 -0
  353. data/spec/unit/mutest/parallel/master_spec.rb +335 -0
  354. data/spec/unit/mutest/parallel/source/array_spec.rb +47 -0
  355. data/spec/unit/mutest/parallel/worker_spec.rb +65 -0
  356. data/spec/unit/mutest/parallel_spec.rb +16 -0
  357. data/spec/unit/mutest/parser_spec.rb +24 -0
  358. data/spec/unit/mutest/registry_spec.rb +45 -0
  359. data/spec/unit/mutest/reporter/cli/printer/config_spec.rb +29 -0
  360. data/spec/unit/mutest/reporter/cli/printer/env_progress_spec.rb +74 -0
  361. data/spec/unit/mutest/reporter/cli/printer/env_result_spec.rb +35 -0
  362. data/spec/unit/mutest/reporter/cli/printer/mutation_progress_result_spec.rb +23 -0
  363. data/spec/unit/mutest/reporter/cli/printer/mutation_result_spec.rb +110 -0
  364. data/spec/unit/mutest/reporter/cli/printer/status_progressive_spec.rb +43 -0
  365. data/spec/unit/mutest/reporter/cli/printer/status_spec.rb +119 -0
  366. data/spec/unit/mutest/reporter/cli/printer/subject_progress_spec.rb +34 -0
  367. data/spec/unit/mutest/reporter/cli/printer/subject_result_spec.rb +37 -0
  368. data/spec/unit/mutest/reporter/cli/printer/test_result_spec.rb +14 -0
  369. data/spec/unit/mutest/reporter/cli/printer_spec.rb +161 -0
  370. data/spec/unit/mutest/reporter/cli/tput_spec.rb +48 -0
  371. data/spec/unit/mutest/reporter/cli_spec.rb +212 -0
  372. data/spec/unit/mutest/reporter/null_spec.rb +12 -0
  373. data/spec/unit/mutest/reporter/sequence_spec.rb +29 -0
  374. data/spec/unit/mutest/repository/diff_spec.rb +106 -0
  375. data/spec/unit/mutest/repository/subject_filter_spec.rb +28 -0
  376. data/spec/unit/mutest/require_highjack_spec.rb +71 -0
  377. data/spec/unit/mutest/result/class_methods_spec.rb +49 -0
  378. data/spec/unit/mutest/result/env_spec.rb +82 -0
  379. data/spec/unit/mutest/result/mutation_spec.rb +37 -0
  380. data/spec/unit/mutest/result/subject_spec.rb +109 -0
  381. data/spec/unit/mutest/result_spec.rb +31 -0
  382. data/spec/unit/mutest/runner/sink_spec.rb +172 -0
  383. data/spec/unit/mutest/runner_spec.rb +69 -0
  384. data/spec/unit/mutest/selector/expression_spec.rb +59 -0
  385. data/spec/unit/mutest/source_file_spec.rb +42 -0
  386. data/spec/unit/mutest/subject/method/instance/memoized_spec.rb +78 -0
  387. data/spec/unit/mutest/subject/method/instance_spec.rb +64 -0
  388. data/spec/unit/mutest/subject/method/singleton_spec.rb +51 -0
  389. data/spec/unit/mutest/subject_spec.rb +87 -0
  390. data/spec/unit/mutest/util/one_spec.rb +20 -0
  391. data/spec/unit/mutest/warning_filter_spec.rb +99 -0
  392. data/spec/unit/mutest/zombifier_spec.rb +120 -0
  393. data/spec/unit/mutest_spec.rb +15 -0
  394. data/test_app/.rspec +1 -0
  395. data/test_app/Gemfile.rspec3.4 +7 -0
  396. data/test_app/Gemfile.rspec3.5 +7 -0
  397. data/test_app/lib/test_app.rb +109 -0
  398. data/test_app/lib/test_app/literal.rb +40 -0
  399. data/test_app/spec/spec_helper.rb +9 -0
  400. data/test_app/spec/unit/test_app/literal_spec.rb +20 -0
  401. metadata +784 -9
@@ -0,0 +1,39 @@
1
+ module Mutest
2
+ module AST
3
+ module Regexp
4
+ class Transformer
5
+ # Transformer for Regexp `alternative` nodes
6
+ #
7
+ # This transformer is very similar to the generic recursive mapper
8
+ # except for the fact that the `Regexp::Expression` class for
9
+ # `alternative` nodes has a unique constructor
10
+ class Alternative < self
11
+ register :regexp_sequence_expression
12
+
13
+ # Mapper from `Regexp::Expression` to `Parser::AST::Node`
14
+ ExpressionToAST = Class.new(Recursive::ExpressionToAST)
15
+
16
+ # Mapper from `Parser::AST::Node` to `Regexp::Expression`
17
+ class ASTToExpression < Transformer::ASTToExpression
18
+ # Alternative instance with dummy values for `level`, `set_level`,
19
+ # and `conditional_level`. These values do not affect unparsing
20
+ ALTERNATIVE = IceNine.deep_freeze(
21
+ ::Regexp::Expression::Alternative.new(0, 0, 0)
22
+ )
23
+
24
+ private
25
+
26
+ # Transform ast into expression
27
+ #
28
+ # @return [Regexp::Expression::Alternative]
29
+ def transform
30
+ ALTERNATIVE.dup.tap do |alt|
31
+ alt.expressions = subexpressions
32
+ end
33
+ end
34
+ end # ASTToExpression
35
+ end # Alternative
36
+ end # Transformer
37
+ end # Regexp
38
+ end # AST
39
+ end # Mutest
@@ -0,0 +1,46 @@
1
+ module Mutest
2
+ module AST
3
+ module Regexp
4
+ class Transformer
5
+ # Transformer for character sets
6
+ #
7
+ # The `Regexp::Expression` representation of a character set
8
+ # is unique due to its usage of the `#members` attribute which
9
+ # is why it gets its own transformer
10
+ class CharacterSet < self
11
+ register :regexp_character_set
12
+
13
+ # Mapper from `Regexp::Expression` to `Parser::AST::Node`
14
+ class ExpressionToAST < Transformer::ExpressionToAST
15
+ # Transform character set expression into node
16
+ #
17
+ # @return [Parser::AST::Node]
18
+ def call
19
+ quantify(ast(*expression.members))
20
+ end
21
+ end # ExpressionToAST
22
+
23
+ # Mapper from `Parser::AST::Node` to `Regexp::Expression`
24
+ class ASTToExpression < Transformer::ASTToExpression
25
+ CHARACTER_SET = IceNine.deep_freeze(
26
+ ::Regexp::Expression::CharacterSet.new(
27
+ ::Regexp::Token.new(:set, :character, '[')
28
+ )
29
+ )
30
+
31
+ private
32
+
33
+ # Transform node into expression
34
+ #
35
+ # @return [Regexp::Expression]
36
+ def transform
37
+ CHARACTER_SET.dup.tap do |expression|
38
+ expression.members = node.children
39
+ end
40
+ end
41
+ end # ASTToExpression
42
+ end # CharacterSet
43
+ end # Transformer
44
+ end # Regexp
45
+ end # AST
46
+ end # Mutest
@@ -0,0 +1,101 @@
1
+ module Mutest
2
+ module AST
3
+ module Regexp
4
+ class Transformer
5
+ # Transformer for nodes which map directly to other domain
6
+ #
7
+ # A node maps "directly" to another domain if the node never
8
+ # has children or text which needs to be preserved for a mapping
9
+ #
10
+ # @example direct mapping
11
+ #
12
+ # input = /\d/
13
+ # expression = Regexp::Parser.parse(input).first
14
+ # node = Transformer::Direct.to_ast(expression)
15
+ #
16
+ # # the digit type always has the same text and no children
17
+ # expression.text # => "\\d"
18
+ # expression.terminal? # => true
19
+ #
20
+ # # therefore the `Parser::AST::Node` is always the same
21
+ # node # => s(:regexp_digit_type)
22
+ class Direct < self
23
+ # Mapper from `Regexp::Expression` to `Parser::AST::Node`
24
+ class ExpressionToAST < Transformer::ExpressionToAST
25
+ # Transform expression into node
26
+ #
27
+ # @return [Parser::AST::Node]
28
+ def call
29
+ quantify(ast)
30
+ end
31
+ end # ExpressionToAST
32
+
33
+ # Mapper from `Parser::AST::Node` to `Regexp::Expression`
34
+ class ASTToExpression < Transformer::ASTToExpression
35
+ include LookupTable
36
+
37
+ # rubocop:disable LineLength
38
+ TABLE = Table.create(
39
+ [:regexp_one_or_more_escape, [:escape, :one_or_more, '\+'], ::Regexp::Expression::EscapeSequence::Literal],
40
+ [:regexp_zero_or_one_escape, [:escape, :zero_or_one, '\?'], ::Regexp::Expression::EscapeSequence::Literal],
41
+ [:regexp_alternation_escape, [:escape, :alternation, '\|'], ::Regexp::Expression::EscapeSequence::Literal],
42
+ [:regexp_group_open_escape, [:escape, :group_open, '\('], ::Regexp::Expression::EscapeSequence::Literal],
43
+ [:regexp_group_close_escape, [:escape, :group_close, '\)'], ::Regexp::Expression::EscapeSequence::Literal],
44
+ [:regexp_interval_open_escape, [:escape, :interval_open, '\{'], ::Regexp::Expression::EscapeSequence::Literal],
45
+ [:regexp_interval_close_escape, [:escape, :interval_close, '\}'], ::Regexp::Expression::EscapeSequence::Literal],
46
+ [:regexp_newline_escape, [:escape, :newline, '\n'], ::Regexp::Expression::EscapeSequence::Literal],
47
+ [:regexp_zero_or_more_escape, [:escape, :zero_or_more, '\*'], ::Regexp::Expression::EscapeSequence::Literal],
48
+ [:regexp_carriage_escape, [:escape, :carriage, '\r'], ::Regexp::Expression::EscapeSequence::Literal],
49
+ [:regexp_dot_escape, [:escape, :dot, '\.'], ::Regexp::Expression::EscapeSequence::Literal],
50
+ [:regexp_set_open_escape, [:escape, :set_open, '\['], ::Regexp::Expression::EscapeSequence::Literal],
51
+ [:regexp_set_close_escape, [:escape, :set_close, '\]'], ::Regexp::Expression::EscapeSequence::Literal],
52
+ [:regexp_eol_escape, [:escape, :eol, '\$'], ::Regexp::Expression::EscapeSequence::Literal],
53
+ [:regexp_bol_escape, [:escape, :bol, '\^'], ::Regexp::Expression::EscapeSequence::Literal],
54
+ [:regexp_bell_escape, [:escape, :bell, '\a'], ::Regexp::Expression::EscapeSequence::Literal],
55
+ [:regexp_escape_escape, [:escape, :escape, '\e'], ::Regexp::Expression::EscapeSequence::AsciiEscape],
56
+ [:regexp_form_feed_escape, [:escape, :form_feed, '\f'], ::Regexp::Expression::EscapeSequence::FormFeed],
57
+ [:regexp_vertical_tab_escape, [:escape, :vertical_tab, '\v'], ::Regexp::Expression::EscapeSequence::VerticalTab],
58
+ [:regexp_mark_keep, [:keep, :mark, '\K'], ::Regexp::Expression::Keep::Mark],
59
+ [:regexp_bos_anchor, [:anchor, :bos, '\\A'], ::Regexp::Expression::Anchor::BeginningOfString],
60
+ [:regexp_match_start_anchor, [:anchor, :match_start, '\\G'], ::Regexp::Expression::Anchor::MatchStart],
61
+ [:regexp_word_boundary_anchor, [:anchor, :word_boundary, '\b'], ::Regexp::Expression::Anchor::WordBoundary],
62
+ [:regexp_eos_ob_eol_anchor, [:anchor, :eos_ob_eol, '\\Z'], ::Regexp::Expression::Anchor::EndOfStringOrBeforeEndOfLine],
63
+ [:regexp_eos_anchor, [:anchor, :eos, '\\z'], ::Regexp::Expression::Anchor::EndOfString],
64
+ [:regexp_bol_anchor, [:anchor, :bol, '^'], ::Regexp::Expression::Anchor::BeginningOfLine],
65
+ [:regexp_eol_anchor, [:anchor, :eol, '$'], ::Regexp::Expression::Anchor::EndOfLine],
66
+ [:regexp_nonword_boundary_anchor, [:anchor, :nonword_boundary, '\\B'], ::Regexp::Expression::Anchor::NonWordBoundary],
67
+ [:regexp_alpha_property, [:property, :alpha, '\p{Alpha}'], ::Regexp::Expression::UnicodeProperty::Alpha],
68
+ [:regexp_script_arabic_property, [:property, :script_arabic, '\p{Arabic}'], ::Regexp::Expression::UnicodeProperty::Script],
69
+ [:regexp_script_hangul_property, [:property, :script_hangul, '\p{Hangul}'], ::Regexp::Expression::UnicodeProperty::Script],
70
+ [:regexp_script_han_property, [:property, :script_han, '\p{Han}'], ::Regexp::Expression::UnicodeProperty::Script],
71
+ [:regexp_script_hiragana_property, [:property, :script_hiragana, '\p{Hiragana}'], ::Regexp::Expression::UnicodeProperty::Script],
72
+ [:regexp_script_katakana_property, [:property, :script_katakana, '\p{Katakana}'], ::Regexp::Expression::UnicodeProperty::Script],
73
+ [:regexp_letter_any_property, [:property, :letter_any, '\p{L}'], ::Regexp::Expression::UnicodeProperty::Letter::Any],
74
+ [:regexp_hex_type, [:type, :hex, '\h'], ::Regexp::Expression::CharacterType::Hex],
75
+ [:regexp_digit_type, [:type, :digit, '\d'], ::Regexp::Expression::CharacterType::Digit],
76
+ [:regexp_space_type, [:type, :space, '\s'], ::Regexp::Expression::CharacterType::Space],
77
+ [:regexp_word_type, [:type, :word, '\w'], ::Regexp::Expression::CharacterType::Word],
78
+ [:regexp_hex_type, [:type, :hex, '\h'], ::Regexp::Expression::CharacterType::Hex],
79
+ [:regexp_nonhex_type, [:type, :nonhex, '\H'], ::Regexp::Expression::CharacterType::NonHex],
80
+ [:regexp_nondigit_type, [:type, :nondigit, '\D'], ::Regexp::Expression::CharacterType::NonDigit],
81
+ [:regexp_nonspace_type, [:type, :nonspace, '\S'], ::Regexp::Expression::CharacterType::NonSpace],
82
+ [:regexp_nonword_type, [:type, :nonword, '\W'], ::Regexp::Expression::CharacterType::NonWord],
83
+ [:regexp_dot_meta, [:meta, :dot, '.'], ::Regexp::Expression::CharacterType::Any]
84
+ )
85
+
86
+ private
87
+
88
+ # Transform ast into expression
89
+ #
90
+ # @return [Regexp::Expression]
91
+ def transform
92
+ expression_class.new(expression_token)
93
+ end
94
+ end # ASTToExpression
95
+
96
+ ASTToExpression::TABLE.types.each(&method(:register))
97
+ end # Direct
98
+ end # Transformer
99
+ end # Regexp
100
+ end # AST
101
+ end # Mutest
@@ -0,0 +1,65 @@
1
+ module Mutest
2
+ module AST
3
+ module Regexp
4
+ class Transformer
5
+ # Transformer for option groups
6
+ class OptionsGroup < self
7
+ register :regexp_options_group
8
+
9
+ # Mapper from `Regexp::Expression` to `Parser::AST::Node`
10
+ class ExpressionToAST < Transformer::ExpressionToAST
11
+ # Transform options group into node
12
+ #
13
+ # @return [Parser::AST::Node]
14
+ def call
15
+ quantify(ast(expression.options, *children))
16
+ end
17
+ end # ExpressionToAST
18
+
19
+ # Mapper from `Parser::AST::Node` to `Regexp::Expression`
20
+ class ASTToExpression < Transformer::ASTToExpression
21
+ include NamedChildren
22
+
23
+ children :options
24
+
25
+ private
26
+
27
+ # Covnert node into expression
28
+ #
29
+ # @return [Regexp::Expression::Group::Options]
30
+ def transform
31
+ options_group.tap do |expression|
32
+ expression.expressions = subexpressions
33
+ end
34
+ end
35
+
36
+ # Recursive mapping of children
37
+ #
38
+ # @return [Array<Regexp::Expression>]
39
+ def subexpressions
40
+ remaining_children.map(&Regexp.public_method(:to_expression))
41
+ end
42
+
43
+ # Options group instance constructed from options text
44
+ #
45
+ # @return [Regexp::Expression::Group::Options]
46
+ def options_group
47
+ ::Regexp::Expression::Group::Options.new(
48
+ ::Regexp::Token.new(:group, :options, text)
49
+ )
50
+ end
51
+
52
+ # Flag text constructed from enabled options
53
+ #
54
+ # @return [String]
55
+ def text
56
+ flags = options.map { |key, value| key if value }.join
57
+
58
+ "(?#{flags}-:"
59
+ end
60
+ end # ASTToExpression
61
+ end # OptionsGroup
62
+ end # Transformer
63
+ end # Regexp
64
+ end # AST
65
+ end # Mutest
@@ -0,0 +1,112 @@
1
+ module Mutest
2
+ module AST
3
+ module Regexp
4
+ class Transformer
5
+ # Transformer for regexp quantifiers
6
+ class Quantifier < self
7
+ # Mapper from `Regexp::Expression` to `Parser::AST::Node`
8
+ class ExpressionToAST < Transformer::ExpressionToAST
9
+ # Transform quantifier into node
10
+ #
11
+ # @return [Parser::AST::Node]
12
+ def call
13
+ ast(expression.min, expression.max)
14
+ end
15
+
16
+ private
17
+
18
+ # Custom `type` for quantifiers which use `mode` instead of `type`
19
+ #
20
+ # @return [Symbol]
21
+ def type
22
+ :"regexp_#{expression.mode}_#{expression.token}"
23
+ end
24
+ end # ExpressionToAST
25
+
26
+ # Mapper from `Parser::AST::Node` to `Regexp::Expression`
27
+ class ASTToExpression < Transformer::ASTToExpression
28
+ include NamedChildren
29
+
30
+ children :min, :max, :subject
31
+
32
+ Quantifier = Class.new.include(Concord::Public.new(:type, :suffix, :mode))
33
+
34
+ QUANTIFIER_MAP = IceNine.deep_freeze({
35
+ regexp_greedy_zero_or_more: [:zero_or_more, '*', :greedy],
36
+ regexp_greedy_one_or_more: [:one_or_more, '+', :greedy],
37
+ regexp_greedy_zero_or_one: [:zero_or_one, '?', :greedy],
38
+ regexp_possessive_zero_or_one: [:zero_or_one, '?+', :possessive],
39
+ regexp_reluctant_zero_or_more: [:zero_or_more, '*?', :reluctant],
40
+ regexp_reluctant_one_or_more: [:one_or_more, '+?', :reluctant],
41
+ regexp_possessive_zero_or_more: [:zero_or_more, '*+', :possessive],
42
+ regexp_possessive_one_or_more: [:one_or_more, '++', :possessive],
43
+ regexp_greedy_interval: [:interval, '', :greedy],
44
+ regexp_reluctant_interval: [:interval, '?', :reluctant],
45
+ regexp_possessive_interval: [:interval, '+', :possessive]
46
+ }.map { |ast_type, arguments| [ast_type, Quantifier.new(*arguments)] }.to_h)
47
+
48
+ private
49
+
50
+ # Transform ast into quantifier attached to expression
51
+ #
52
+ # @return [Regexp::Expression]
53
+ def transform
54
+ Regexp.to_expression(subject).dup.tap do |expression|
55
+ expression.quantify(type, text, min, max, mode)
56
+ end
57
+ end
58
+
59
+ # Quantifier text
60
+ #
61
+ # @return [String]
62
+ def text
63
+ if type.equal?(:interval)
64
+ interval_text + suffix
65
+ else
66
+ suffix
67
+ end
68
+ end
69
+
70
+ # Type of quantifier
71
+ #
72
+ # @return [:zero_or_more,:one_or_more,:interval]
73
+ def type
74
+ quantifier.type
75
+ end
76
+
77
+ # Regexp symbols used to specify quantifier
78
+ #
79
+ # @return [String]
80
+ def suffix
81
+ quantifier.suffix
82
+ end
83
+
84
+ # The quantifier "mode"
85
+ #
86
+ # @return [:greedy,:possessive,:reluctant]
87
+ def mode
88
+ quantifier.mode
89
+ end
90
+
91
+ # Quantifier mapping information for current node
92
+ #
93
+ # @return [Quantifier]
94
+ def quantifier
95
+ QUANTIFIER_MAP.fetch(node.type)
96
+ end
97
+
98
+ # Interval text constructed from min and max
99
+ #
100
+ # @return [String]
101
+ def interval_text
102
+ interval = [min, max].map { |num| num if num > 0 }.uniq
103
+ "{#{interval.join(',')}}"
104
+ end
105
+ end # ASTToExpression
106
+
107
+ ASTToExpression::QUANTIFIER_MAP.keys.each(&method(:register))
108
+ end # Quantifier
109
+ end # Transformer
110
+ end # Regexp
111
+ end # AST
112
+ end # Mutest
@@ -0,0 +1,50 @@
1
+ module Mutest
2
+ module AST
3
+ module Regexp
4
+ class Transformer
5
+ # Transformer for nodes with children
6
+ class Recursive < self
7
+ # Mapper from `Regexp::Expression` to `Parser::AST::Node`
8
+ class ExpressionToAST < Transformer::ExpressionToAST
9
+ # Transform expression and children into nodes
10
+ #
11
+ # @return [Parser::AST::Node]
12
+ def call
13
+ quantify(ast(*children))
14
+ end
15
+ end # ExpressionToAST
16
+
17
+ # Mapper from `Parser::AST::Node` to `Regexp::Expression`
18
+ class ASTToExpression < Transformer::ASTToExpression
19
+ include LookupTable
20
+
21
+ # rubocop:disable LineLength
22
+ TABLE = Table.create(
23
+ [:regexp_alternation_meta, [:meta, :alternation, '|'], ::Regexp::Expression::Alternation],
24
+ [:regexp_nlookahead_assertion, [:assertion, :nlookahead, '(?!'], ::Regexp::Expression::Assertion::NegativeLookahead],
25
+ [:regexp_passive_group, [:group, :passive, '(?:'], ::Regexp::Expression::Group::Passive],
26
+ [:regexp_nlookbehind_assertion, [:assertion, :nlookbehind, '(?<!'], ::Regexp::Expression::Assertion::NegativeLookbehind],
27
+ [:regexp_lookbehind_assertion, [:assertion, :lookbehind, '(?<='], ::Regexp::Expression::Assertion::Lookbehind],
28
+ [:regexp_lookahead_assertion, [:assertion, :lookahead, '(?='], ::Regexp::Expression::Assertion::Lookahead],
29
+ [:regexp_atomic_group, [:group, :atomic, '(?>'], ::Regexp::Expression::Group::Atomic],
30
+ [:regexp_capture_group, [:group, :capture, '('], ::Regexp::Expression::Group::Capture]
31
+ )
32
+
33
+ private
34
+
35
+ # Transform nodes and their children into expressions
36
+ #
37
+ # @return [Regexp::Expression]
38
+ def transform
39
+ expression_class.new(expression_token).tap do |expression|
40
+ expression.expressions = subexpressions
41
+ end
42
+ end
43
+ end # ASTToExpression
44
+
45
+ ASTToExpression::TABLE.types.each(&method(:register))
46
+ end # Recursive
47
+ end # Transformer
48
+ end # Regexp
49
+ end # AST
50
+ end # Mutest
@@ -0,0 +1,28 @@
1
+ module Mutest
2
+ module AST
3
+ module Regexp
4
+ class Transformer
5
+ # Transformer for root nodes
6
+ class Root < self
7
+ register :regexp_root_expression
8
+
9
+ ExpressionToAST = Class.new(Recursive::ExpressionToAST)
10
+
11
+ # Mapper from `Parser::AST::Node` to `Regexp::Expression`
12
+ class ASTToExpression < Transformer::ASTToExpression
13
+ private
14
+
15
+ # Transform node into root expression
16
+ #
17
+ # @return [Regexp::Expression::Root]
18
+ def transform
19
+ ::Regexp::Expression::Root.new.tap do |root|
20
+ root.expressions = subexpressions
21
+ end
22
+ end
23
+ end # ASTToExpression
24
+ end # Root
25
+ end # Transformer
26
+ end # Regexp
27
+ end # AST
28
+ end # Mutest