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,55 @@
1
+ module Mutest
2
+ module AST
3
+ module Regexp
4
+ class Transformer
5
+ # Regexp AST transformer for nodes that encode a text value
6
+ class Text < self
7
+ # Mapper from `Regexp::Expression` to `Parser::AST::Node`
8
+ class ExpressionToAST < Transformer::ExpressionToAST
9
+ # Transform expression into node preserving text value
10
+ #
11
+ # @return [Parser::AST::Node]
12
+ def call
13
+ quantify(ast(expression.text))
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
+ TABLE = Table.create(
22
+ [:regexp_literal_literal, %i[literal literal], ::Regexp::Expression::Literal],
23
+ [:regexp_comment_group, %i[group comment], ::Regexp::Expression::Group::Comment],
24
+ [:regexp_named_group, %i[group named], ::Regexp::Expression::Group::Named],
25
+ [:regexp_number_backref, %i[backref number], ::Regexp::Expression::Backreference::Number],
26
+ [:regexp_name_call_backref, %i[backref name_call], ::Regexp::Expression::Backreference::NameCall],
27
+ [:regexp_whitespace_free_space, %i[free_space whitespace], ::Regexp::Expression::WhiteSpace],
28
+ [:regexp_comment_free_space, %i[free_space comment], ::Regexp::Expression::WhiteSpace],
29
+ [:regexp_hex_escape, %i[escape hex], ::Regexp::Expression::EscapeSequence::Literal],
30
+ [:regexp_literal_escape, %i[escape literal], ::Regexp::Expression::EscapeSequence::Literal],
31
+ [:regexp_backslash_escape, %i[escape backslash], ::Regexp::Expression::EscapeSequence::Literal],
32
+ [:regexp_tab_escape, %i[escape tab], ::Regexp::Expression::EscapeSequence::Literal],
33
+ [:regexp_codepoint_list_escape, %i[escape codepoint_list], ::Regexp::Expression::EscapeSequence::Literal],
34
+ [:regexp_control_escape, %i[escape control], ::Regexp::Expression::EscapeSequence::Control],
35
+ [:regexp_meta_sequence_escape, %i[escape meta_sequence], ::Regexp::Expression::EscapeSequence::Control]
36
+ )
37
+
38
+ private
39
+
40
+ # Transform node to expression with text value
41
+ #
42
+ # @return [Regexp::Expression]
43
+ def transform
44
+ token = expression_token.dup
45
+ token.text = Util.one(node.children)
46
+ expression_class.new(token)
47
+ end
48
+ end # ASTToExpression
49
+
50
+ ASTToExpression::TABLE.types.each(&method(:register))
51
+ end # Text
52
+ end # Transformer
53
+ end # Regexp
54
+ end # AST
55
+ end # Mutest
@@ -0,0 +1,26 @@
1
+ module Mutest
2
+ module AST
3
+ # Mixin for node sexp syntax
4
+ module Sexp
5
+ private
6
+
7
+ # Build node
8
+ #
9
+ # @param [Symbol] type
10
+ #
11
+ # @return [Parser::AST::Node]
12
+ def s(type, *children)
13
+ ::Parser::AST::Node.new(type, children)
14
+ end
15
+
16
+ # Build a negated boolean node
17
+ #
18
+ # @param [Parser::AST::Node] node
19
+ #
20
+ # @return [Parser::AST::Node]
21
+ def n_not(node)
22
+ s(:send, node, :!)
23
+ end
24
+ end # Sexp
25
+ end # AST
26
+ end # Mutest
@@ -0,0 +1,140 @@
1
+ module Mutest
2
+ module AST
3
+ # Groups of node types
4
+ #
5
+ # :reek:TooManyConstants
6
+ # rubocop:disable Metrics/ModuleLength
7
+ module Types
8
+ symbolset = ->(strings) { strings.map(&:to_sym).to_set.freeze }
9
+
10
+ ASSIGNABLE_VARIABLES = symbolset.(%w[ivasgn lvasgn cvasgn gvasgn])
11
+
12
+ INDEX_ASSIGN_OPERATOR = :[]=
13
+
14
+ # Set of nodes that cannot be on the LHS of an assignment
15
+ NOT_ASSIGNABLE = symbolset.(%w[int float str dstr class module self nil])
16
+
17
+ # Set of op-assign types
18
+ OP_ASSIGN = symbolset.(%w[or_asgn and_asgn op_asgn])
19
+ # Set of node types that are not valid when emitted standalone
20
+ NOT_STANDALONE = symbolset.(%w[splat restarg block_pass])
21
+ INDEX_OPERATORS = symbolset.(%w[[] []=])
22
+ UNARY_METHOD_OPERATORS = symbolset.(%w[~@ +@ -@ !])
23
+
24
+ # Operators ruby implements as methods
25
+ METHOD_OPERATORS = symbolset.(%w[
26
+ <=> === []= [] <= >= == !~ != =~ <<
27
+ >> ** * % / | ^ & < > + - ~@ +@ -@ !
28
+ ])
29
+
30
+ BINARY_METHOD_OPERATORS = symbolset.(
31
+ METHOD_OPERATORS - (INDEX_OPERATORS + UNARY_METHOD_OPERATORS)
32
+ )
33
+
34
+ OPERATOR_METHODS = symbolset.(
35
+ METHOD_OPERATORS + INDEX_OPERATORS + UNARY_METHOD_OPERATORS
36
+ )
37
+
38
+ # Nodes that are NOT handled by mutest.
39
+ #
40
+ # not - 1.8 only, mutest does not support 1.8
41
+ #
42
+ BLACKLIST = symbolset.(%w[not])
43
+
44
+ # Nodes generated by regular expression body parsing
45
+ REGEXP = symbolset.(%w[
46
+ regexp_alpha_property
47
+ regexp_alternation_escape
48
+ regexp_alternation_meta
49
+ regexp_atomic_group
50
+ regexp_backslash_escape
51
+ regexp_bell_escape
52
+ regexp_bol_anchor
53
+ regexp_bol_escape
54
+ regexp_bos_anchor
55
+ regexp_capture_group
56
+ regexp_carriage_escape
57
+ regexp_character_set
58
+ regexp_character_set
59
+ regexp_codepoint_list_escape
60
+ regexp_comment_free_space
61
+ regexp_comment_group
62
+ regexp_control_escape
63
+ regexp_digit_type
64
+ regexp_dot_escape
65
+ regexp_dot_meta
66
+ regexp_eol_anchor
67
+ regexp_eol_escape
68
+ regexp_eos_anchor
69
+ regexp_eos_ob_eol_anchor
70
+ regexp_escape_escape
71
+ regexp_form_feed_escape
72
+ regexp_greedy_interval
73
+ regexp_greedy_one_or_more
74
+ regexp_greedy_zero_or_more
75
+ regexp_greedy_zero_or_one
76
+ regexp_group_close_escape
77
+ regexp_group_open_escape
78
+ regexp_hex_escape
79
+ regexp_hex_type
80
+ regexp_interval_close_escape
81
+ regexp_interval_open_escape
82
+ regexp_letter_any_property
83
+ regexp_literal_escape
84
+ regexp_literal_literal
85
+ regexp_lookahead_assertion
86
+ regexp_lookbehind_assertion
87
+ regexp_mark_keep
88
+ regexp_match_start_anchor
89
+ regexp_meta_sequence_escape
90
+ regexp_name_call_backref
91
+ regexp_named_group
92
+ regexp_newline_escape
93
+ regexp_nlookahead_assertion
94
+ regexp_nlookbehind_assertion
95
+ regexp_nondigit_type
96
+ regexp_nonspace_type
97
+ regexp_nonword_boundary_anchor
98
+ regexp_nonword_type
99
+ regexp_nonhex_type
100
+ regexp_number_backref
101
+ regexp_one_or_more_escape
102
+ regexp_open_conditional
103
+ regexp_options_group
104
+ regexp_passive_group
105
+ regexp_possessive_interval
106
+ regexp_possessive_one_or_more
107
+ regexp_possessive_zero_or_more
108
+ regexp_possessive_zero_or_one
109
+ regexp_reluctant_interval
110
+ regexp_reluctant_one_or_more
111
+ regexp_reluctant_zero_or_more
112
+ regexp_root_expression
113
+ regexp_script_arabic_property
114
+ regexp_script_han_property
115
+ regexp_script_hangul_property
116
+ regexp_script_hiragana_property
117
+ regexp_script_katakana_property
118
+ regexp_sequence_expression
119
+ regexp_set_close_escape
120
+ regexp_set_open_escape
121
+ regexp_space_type
122
+ regexp_tab_escape
123
+ regexp_vertical_tab_escape
124
+ regexp_whitespace_free_space
125
+ regexp_word_boundary_anchor
126
+ regexp_word_type
127
+ regexp_zero_or_more_escape
128
+ regexp_zero_or_one_escape
129
+ ])
130
+
131
+ # Nodes that are NOT generated by parser but used by mutest / unparser.
132
+ GENERATED = symbolset.(%w[empty])
133
+
134
+ EXTRA = symbolset.(GENERATED + REGEXP)
135
+
136
+ # All node types mutest handles
137
+ ALL = symbolset.((Parser::Meta::NODE_TYPES + EXTRA) - BLACKLIST)
138
+ end # Types
139
+ end # AST
140
+ end # Mutest
data/lib/mutest/cli.rb ADDED
@@ -0,0 +1,196 @@
1
+ module Mutest
2
+ # Commandline parser / runner
3
+ class CLI
4
+ include Adamantium::Flat, Equalizer.new(:config), Procto.call(:config)
5
+
6
+ # Error failed when CLI argv is invalid
7
+ Error = Class.new(RuntimeError)
8
+
9
+ # Run cli with arguments
10
+ #
11
+ # @param [Array<String>] arguments
12
+ #
13
+ # @return [Boolean]
14
+ def self.run(arguments)
15
+ Runner.call(Env::Bootstrap.call(call(arguments))).success?
16
+ rescue Error => exception
17
+ $stderr.puts(exception.message)
18
+ false
19
+ end
20
+
21
+ # Initialize object
22
+ #
23
+ # @param [Array<String>]
24
+ #
25
+ # @return [undefined]
26
+ def initialize(arguments)
27
+ @config = Config::DEFAULT
28
+
29
+ parse(arguments)
30
+ end
31
+
32
+ # Config parsed from CLI
33
+ #
34
+ # @return [Config]
35
+ attr_reader :config
36
+
37
+ private
38
+
39
+ # Parse the command-line options
40
+ #
41
+ # @param [Array<String>] arguments
42
+ # Command-line options and arguments to be parsed.
43
+ #
44
+ # @fail [Error]
45
+ # An error occurred while parsing the options.
46
+ #
47
+ # @return [undefined]
48
+ def parse(arguments)
49
+ opts =
50
+ OptionParser.new do |builder|
51
+ builder.banner = 'usage: mutest [options] MATCH_EXPRESSION ...'
52
+ %i[add_environment_options add_mutation_options add_filter_options add_debug_options].each do |name|
53
+ __send__(name, builder)
54
+ end
55
+ end
56
+
57
+ parse_match_expressions(opts.parse!(arguments))
58
+ rescue OptionParser::ParseError => error
59
+ raise(Error, error)
60
+ end
61
+
62
+ # Parse matchers
63
+ #
64
+ # @param [Array<String>] expressions
65
+ #
66
+ # @return [undefined]
67
+ def parse_match_expressions(expressions)
68
+ expressions.each do |expression|
69
+ add_matcher(:match_expressions, config.expression_parser.(expression))
70
+ end
71
+ end
72
+
73
+ # Add environmental options
74
+ #
75
+ # @param [Object] opts
76
+ #
77
+ # @return [undefined]
78
+ #
79
+ # rubocop:disable MethodLength
80
+ def add_environment_options(opts)
81
+ opts.separator('Environment:')
82
+ opts.on('--zombie', 'Run mutest zombified') do
83
+ with(zombie: true)
84
+ end
85
+ opts.on('-I', '--include DIRECTORY', 'Add DIRECTORY to $LOAD_PATH') do |directory|
86
+ add(:includes, directory)
87
+ end
88
+ opts.on('-r', '--require NAME', 'Require file with NAME') do |name|
89
+ add(:requires, name)
90
+ end
91
+ opts.on('-j', '--jobs NUMBER', 'Number of kill jobs. Defaults to number of processors.') do |number|
92
+ with(jobs: Integer(number))
93
+ end
94
+ end
95
+
96
+ # Use integration
97
+ #
98
+ # @param [String] name
99
+ #
100
+ # @return [undefined]
101
+ def setup_integration(name)
102
+ with(integration: Integration.setup(config.kernel, name))
103
+ rescue LoadError
104
+ raise Error, "Could not load integration #{name.inspect} (you may want to try installing the gem mutest-#{name})"
105
+ end
106
+
107
+ # Add mutation options
108
+ #
109
+ # @param [OptionParser] opts
110
+ #
111
+ # @return [undefined]
112
+ def add_mutation_options(opts)
113
+ opts.separator(nil)
114
+ opts.separator('Options:')
115
+
116
+ opts.on('--use INTEGRATION', 'Use INTEGRATION to kill mutations', &method(:setup_integration))
117
+ end
118
+
119
+ # Add filter options
120
+ #
121
+ # @param [OptionParser] opts
122
+ #
123
+ # @return [undefined]
124
+ def add_filter_options(opts)
125
+ opts.on('--ignore-subject EXPRESSION', 'Ignore subjects that match EXPRESSION as prefix') do |pattern|
126
+ add_matcher(:ignore_expressions, config.expression_parser.(pattern))
127
+ end
128
+ opts.on('--since REVISION', 'Only select subjects touched since REVISION') do |revision|
129
+ add_matcher(
130
+ :subject_filters,
131
+ Repository::SubjectFilter.new(
132
+ Repository::Diff.new(
133
+ config: config,
134
+ from: Repository::Diff::HEAD,
135
+ to: revision
136
+ )
137
+ )
138
+ )
139
+ end
140
+ end
141
+
142
+ # Add debug options
143
+ #
144
+ # @param [OptionParser] opts
145
+ #
146
+ # @return [undefined]
147
+ def add_debug_options(opts)
148
+ opts.on('--fail-fast', 'Fail fast') do
149
+ with(fail_fast: true)
150
+ end
151
+ opts.on('--version', 'Print mutests version') do
152
+ puts("mutest-#{VERSION}")
153
+ config.kernel.exit
154
+ end
155
+ opts.on_tail('-h', '--help', 'Show this message') do
156
+ puts(opts.to_s)
157
+ config.kernel.exit
158
+ end
159
+ end
160
+
161
+ # With configuration
162
+ #
163
+ # @param [Hash<Symbol, Object>] attributes
164
+ #
165
+ # @return [undefined]
166
+ def with(attributes)
167
+ @config = config.with(attributes)
168
+ end
169
+
170
+ # Add configuration
171
+ #
172
+ # @param [Symbol] attribute
173
+ # the attribute to add to
174
+ #
175
+ # @param [Object] value
176
+ # the value to add
177
+ #
178
+ # @return [undefined]
179
+ def add(attribute, value)
180
+ with(attribute => config.public_send(attribute) + [value])
181
+ end
182
+
183
+ # Add matcher configuration
184
+ #
185
+ # @param [Symbol] attribute
186
+ # the attribute to add to
187
+ #
188
+ # @param [Object] value
189
+ # the value to add
190
+ #
191
+ # @return [undefined]
192
+ def add_matcher(attribute, value)
193
+ with(matcher: config.matcher.add(attribute, value))
194
+ end
195
+ end # CLI
196
+ end # Mutest
@@ -0,0 +1,39 @@
1
+ module Mutest
2
+ # Class to colorize strings
3
+ class Color
4
+ include Adamantium::Flat, Concord.new(:code)
5
+
6
+ # Format text with color
7
+ #
8
+ # @param [String] text
9
+ #
10
+ # @return [String]
11
+ def format(text)
12
+ "\e[#{code}m#{text}\e[0m"
13
+ end
14
+
15
+ NONE = Class.new(self) do
16
+ # Format null color
17
+ #
18
+ # @param [String] text
19
+ #
20
+ # @return [String]
21
+ # the argument string
22
+ def format(text)
23
+ text
24
+ end
25
+
26
+ private # rubocop:disable AccessModifierIndentation
27
+
28
+ # Initialize null color
29
+ #
30
+ # @return [undefined]
31
+ def initialize
32
+ end
33
+ end.new
34
+
35
+ RED = Color.new(31)
36
+ GREEN = Color.new(32)
37
+ BLUE = Color.new(34)
38
+ end # Color
39
+ end # Mutest