mutant 0.1.1 → 0.2.0

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 (225) hide show
  1. data/.gitignore +5 -11
  2. data/.rspec +0 -1
  3. data/.travis.yml +14 -3
  4. data/Changelog.md +3 -0
  5. data/Gemfile +5 -1
  6. data/Gemfile.devtools +49 -0
  7. data/Guardfile +18 -0
  8. data/README.md +67 -0
  9. data/Rakefile +4 -1
  10. data/TODO +13 -0
  11. data/bin/mutant +14 -0
  12. data/bin/zombie +14 -0
  13. data/config/flay.yml +3 -0
  14. data/config/flog.yml +2 -0
  15. data/config/roodi.yml +26 -0
  16. data/config/site.reek +93 -0
  17. data/config/yardstick.yml +2 -0
  18. data/lib/inflector.rb +7 -0
  19. data/lib/inflector/defaults.rb +62 -0
  20. data/lib/inflector/inflections.rb +209 -0
  21. data/lib/inflector/methods.rb +149 -0
  22. data/lib/inflector/version.rb +3 -0
  23. data/lib/mutant.rb +96 -21
  24. data/lib/mutant/cli.rb +309 -0
  25. data/lib/mutant/color.rb +61 -0
  26. data/lib/mutant/context.rb +36 -0
  27. data/lib/mutant/context/scope.rb +138 -0
  28. data/lib/mutant/differ.rb +100 -0
  29. data/lib/mutant/helper.rb +38 -0
  30. data/lib/mutant/killer.rb +136 -0
  31. data/lib/mutant/killer/forking.rb +41 -0
  32. data/lib/mutant/killer/rspec.rb +49 -0
  33. data/lib/mutant/killer/static.rb +19 -0
  34. data/lib/mutant/loader.rb +129 -0
  35. data/lib/mutant/matcher.rb +55 -0
  36. data/lib/mutant/matcher/chain.rb +66 -0
  37. data/lib/mutant/matcher/method.rb +173 -0
  38. data/lib/mutant/matcher/method/classifier.rb +126 -0
  39. data/lib/mutant/matcher/method/instance.rb +67 -0
  40. data/lib/mutant/matcher/method/singleton.rb +141 -0
  41. data/lib/mutant/matcher/object_space.rb +114 -0
  42. data/lib/mutant/matcher/scope_methods.rb +127 -0
  43. data/lib/mutant/mutation.rb +101 -12
  44. data/lib/mutant/mutation/filter.rb +75 -0
  45. data/lib/mutant/mutation/filter/code.rb +68 -0
  46. data/lib/mutant/mutation/filter/regexp.rb +39 -0
  47. data/lib/mutant/mutation/filter/whitelist.rb +47 -0
  48. data/lib/mutant/mutator.rb +134 -30
  49. data/lib/mutant/mutator/node.rb +163 -0
  50. data/lib/mutant/mutator/node/arguments.rb +24 -0
  51. data/lib/mutant/mutator/node/block.rb +24 -0
  52. data/lib/mutant/mutator/node/define.rb +24 -0
  53. data/lib/mutant/mutator/node/if_statement.rb +93 -0
  54. data/lib/mutant/mutator/node/literal.rb +54 -0
  55. data/lib/mutant/mutator/node/literal/array.rb +28 -0
  56. data/lib/mutant/mutator/node/literal/boolean.rb +49 -0
  57. data/lib/mutant/mutator/node/literal/dynamic.rb +24 -0
  58. data/lib/mutant/mutator/node/literal/empty_array.rb +26 -0
  59. data/lib/mutant/mutator/node/literal/fixnum.rb +37 -0
  60. data/lib/mutant/mutator/node/literal/float.rb +48 -0
  61. data/lib/mutant/mutator/node/literal/hash.rb +89 -0
  62. data/lib/mutant/mutator/node/literal/nil.rb +25 -0
  63. data/lib/mutant/mutator/node/literal/range.rb +94 -0
  64. data/lib/mutant/mutator/node/literal/regex.rb +43 -0
  65. data/lib/mutant/mutator/node/literal/string.rb +26 -0
  66. data/lib/mutant/mutator/node/literal/symbol.rb +26 -0
  67. data/lib/mutant/mutator/node/noop.rb +55 -0
  68. data/lib/mutant/mutator/node/receiver_case.rb +140 -0
  69. data/lib/mutant/mutator/node/return.rb +31 -0
  70. data/lib/mutant/mutator/node/send.rb +112 -0
  71. data/lib/mutant/mutator/registry.rb +48 -0
  72. data/lib/mutant/mutator/util.rb +87 -0
  73. data/lib/mutant/random.rb +24 -27
  74. data/lib/mutant/reporter.rb +48 -30
  75. data/lib/mutant/reporter/cli.rb +221 -0
  76. data/lib/mutant/reporter/null.rb +42 -0
  77. data/lib/mutant/reporter/stats.rb +64 -0
  78. data/lib/mutant/runner.rb +112 -0
  79. data/lib/mutant/strategy.rb +42 -0
  80. data/lib/mutant/strategy/rspec.rb +59 -0
  81. data/lib/mutant/strategy/rspec/example_lookup.rb +122 -0
  82. data/lib/mutant/subject.rb +115 -0
  83. data/lib/mutant/support/method_object.rb +31 -0
  84. data/locator.rb +87 -0
  85. data/mutant.gemspec +21 -21
  86. data/spec/integration/mutant/differ_spec.rb +15 -0
  87. data/spec/integration/mutant/loader_spec.rb +21 -0
  88. data/spec/integration/mutant/method_matching_spec.rb +269 -0
  89. data/spec/integration/mutant/rspec_killer_spec.rb +24 -0
  90. data/spec/integration/mutant/runner_spec.rb +26 -0
  91. data/spec/integration/mutant/zombie_spec.rb +8 -0
  92. data/spec/rcov.opts +7 -0
  93. data/spec/shared/command_method_behavior.rb +7 -0
  94. data/spec/shared/each_method_behaviour.rb +15 -0
  95. data/spec/shared/hash_method_behavior.rb +17 -0
  96. data/spec/shared/idempotent_method_behavior.rb +7 -0
  97. data/spec/shared/invertible_method_behaviour.rb +9 -0
  98. data/spec/shared/method_filter_parse_behavior.rb +16 -0
  99. data/spec/shared/method_match_behavior.rb +39 -0
  100. data/spec/shared/mutator_behavior.rb +46 -0
  101. data/spec/spec_helper.rb +11 -14
  102. data/spec/support/compress_helper.rb +10 -0
  103. data/spec/support/rspec.rb +22 -0
  104. data/spec/support/test_app.rb +5 -0
  105. data/spec/support/zombie.rb +141 -0
  106. data/spec/unit/mutant/cli/class_methods/new_spec.rb +87 -0
  107. data/spec/unit/mutant/cli/class_methods/run_spec.rb +38 -0
  108. data/spec/unit/mutant/context/root_spec.rb +11 -0
  109. data/spec/unit/mutant/context/scope/class_methods/build_spec.rb +29 -0
  110. data/spec/unit/mutant/context/scope/root_spec.rb +22 -0
  111. data/spec/unit/mutant/context/scope/unqualified_name_spec.rb +27 -0
  112. data/spec/unit/mutant/killer/fail_ques_spec.rb +39 -0
  113. data/spec/unit/mutant/killer/rspec/class_methods/new_spec.rb +32 -0
  114. data/spec/unit/mutant/loader/eval/class_methods/run_spec.rb +33 -0
  115. data/spec/unit/mutant/loader/rubinius/class_methods/run_spec.rb +42 -0
  116. data/spec/unit/mutant/matcher/chain/each_spec.rb +37 -0
  117. data/spec/unit/mutant/matcher/chain/matchers_spec.rb +12 -0
  118. data/spec/unit/mutant/matcher/class_methods/from_string_spec.rb +49 -0
  119. data/spec/unit/mutant/matcher/class_methods/parse_spec.rb +12 -0
  120. data/spec/unit/mutant/matcher/each_spec.rb +14 -0
  121. data/spec/unit/mutant/matcher/method/class_methods/parse_spec.rb +21 -0
  122. data/spec/unit/mutant/matcher/method/classifier/class_methods/run_spec.rb +34 -0
  123. data/spec/unit/mutant/matcher/method/method_spec.rb +11 -0
  124. data/spec/unit/mutant/matcher/object_space/class_methods/parse_spec.rb +24 -0
  125. data/spec/unit/mutant/matcher/object_space/each_spec.rb +31 -0
  126. data/spec/unit/mutant/mutator/each_spec.rb +25 -0
  127. data/spec/unit/mutant/mutator/emit_new_spec.rb +51 -0
  128. data/spec/unit/mutant/mutator/emit_spec.rb +52 -0
  129. data/spec/unit/mutant/mutator/node/block/mutation_spec.rb +36 -0
  130. data/spec/unit/mutant/mutator/node/define/mutation_spec.rb +47 -0
  131. data/spec/unit/mutant/mutator/node/if_statement/mutation_spec.rb +30 -0
  132. data/spec/unit/mutant/mutator/node/literal/array_spec.rb +30 -0
  133. data/spec/unit/mutant/mutator/node/literal/boolean/mutation_spec.rb +23 -0
  134. data/spec/unit/mutant/mutator/node/literal/empty_array_spec.rb +17 -0
  135. data/spec/unit/mutant/mutator/node/literal/fixnum_spec.rb +17 -0
  136. data/spec/unit/mutant/mutator/node/literal/float_spec.rb +25 -0
  137. data/spec/unit/mutant/mutator/node/literal/hash_spec.rb +34 -0
  138. data/spec/unit/mutant/mutator/node/literal/nil_spec.rb +13 -0
  139. data/spec/unit/mutant/mutator/node/literal/range_spec.rb +35 -0
  140. data/spec/unit/mutant/mutator/node/literal/regex_spec.rb +23 -0
  141. data/spec/unit/mutant/mutator/node/literal/string_spec.rb +17 -0
  142. data/spec/unit/mutant/mutator/node/literal/symbol_spec.rb +17 -0
  143. data/spec/unit/mutant/mutator/node/receiver_case/mutation_spec.rb +27 -0
  144. data/spec/unit/mutant/mutator/node/return/mutation_spec.rb +21 -0
  145. data/spec/unit/mutant/mutator/node/send/mutation_spec.rb +78 -0
  146. data/spec/unit/mutant/mutator/self_spec.rb +7 -0
  147. data/spec/unit/mutant/subject/class_methods/new_spec.rb +13 -0
  148. data/spec/unit/mutant/subject/context_spec.rb +14 -0
  149. data/spec/unit/mutant/subject/each_spec.rb +35 -0
  150. data/spec/unit/mutant/subject/node_spec.rb +13 -0
  151. data/tasks/metrics/ci.rake +7 -0
  152. data/tasks/metrics/flay.rake +41 -0
  153. data/tasks/metrics/flog.rake +43 -0
  154. data/tasks/metrics/heckle.rake +216 -0
  155. data/tasks/metrics/metric_fu.rake +31 -0
  156. data/tasks/metrics/reek.rake +15 -0
  157. data/tasks/metrics/roodi.rake +15 -0
  158. data/tasks/metrics/yardstick.rake +23 -0
  159. data/tasks/spec.rake +45 -0
  160. data/tasks/yard.rake +9 -0
  161. data/test_app/.rspec +1 -0
  162. data/test_app/lib/test_app.rb +5 -0
  163. data/test_app/lib/test_app/literal.rb +32 -0
  164. data/test_app/spec/shared/command_method_behavior.rb +7 -0
  165. data/test_app/spec/shared/each_method_behaviour.rb +15 -0
  166. data/test_app/spec/shared/hash_method_behavior.rb +17 -0
  167. data/test_app/spec/shared/idempotent_method_behavior.rb +7 -0
  168. data/test_app/spec/shared/invertible_method_behaviour.rb +9 -0
  169. data/test_app/spec/shared/method_filter_parse_behavior.rb +16 -0
  170. data/test_app/spec/shared/method_match_behavior.rb +39 -0
  171. data/test_app/spec/shared/mutator_behavior.rb +44 -0
  172. data/test_app/spec/spec_helper.rb +7 -0
  173. data/test_app/spec/unit/test_app/literal/command_spec.rb +9 -0
  174. data/test_app/spec/unit/test_app/literal/string_spec.rb +9 -0
  175. metadata +346 -124
  176. data/.rvmrc +0 -1
  177. data/Readme.md +0 -13
  178. data/exe/mutate +0 -6
  179. data/lib/mutant/extensions.rb +0 -8
  180. data/lib/mutant/formatter.rb +0 -19
  181. data/lib/mutant/implementation.rb +0 -70
  182. data/lib/mutant/literal.rb +0 -147
  183. data/lib/mutant/method.rb +0 -31
  184. data/lib/mutant/mutatee.rb +0 -61
  185. data/lib/mutant/node.rb +0 -26
  186. data/lib/mutant/runners/rspec.rb +0 -34
  187. data/lib/mutant/version.rb +0 -3
  188. data/spec/functional/class_spec.rb +0 -46
  189. data/spec/functional/instance_method/array_spec.rb +0 -53
  190. data/spec/functional/instance_method/boolean_spec.rb +0 -101
  191. data/spec/functional/instance_method/call_spec.rb +0 -161
  192. data/spec/functional/instance_method/fixnum_spec.rb +0 -53
  193. data/spec/functional/instance_method/float_spec.rb +0 -53
  194. data/spec/functional/instance_method/hash_spec.rb +0 -53
  195. data/spec/functional/instance_method/if_spec.rb +0 -57
  196. data/spec/functional/instance_method/ivar_assign_spec.rb +0 -62
  197. data/spec/functional/instance_method/range_spec.rb +0 -53
  198. data/spec/functional/instance_method/regex_spec.rb +0 -55
  199. data/spec/functional/instance_method/string_spec.rb +0 -53
  200. data/spec/functional/instance_method/symbol_spec.rb +0 -53
  201. data/spec/functional/reporter/method_loaded_spec.rb +0 -62
  202. data/spec/functional/reporter/running_mutations_spec.rb +0 -60
  203. data/spec/functional/runners/rspec_spec.rb +0 -26
  204. data/spec/functional/singleton_method/array_spec.rb +0 -53
  205. data/spec/functional/singleton_method/boolean_spec.rb +0 -101
  206. data/spec/functional/singleton_method/call_spec.rb +0 -161
  207. data/spec/functional/singleton_method/fixnum_spec.rb +0 -53
  208. data/spec/functional/singleton_method/float_spec.rb +0 -53
  209. data/spec/functional/singleton_method/hash_spec.rb +0 -53
  210. data/spec/functional/singleton_method/if_spec.rb +0 -57
  211. data/spec/functional/singleton_method/ivar_assign_spec.rb +0 -60
  212. data/spec/functional/singleton_method/range_spec.rb +0 -53
  213. data/spec/functional/singleton_method/regex_spec.rb +0 -55
  214. data/spec/functional/singleton_method/string_spec.rb +0 -53
  215. data/spec/functional/singleton_method/symbol_spec.rb +0 -53
  216. data/spec/mutant/extensions_spec.rb +0 -13
  217. data/spec/mutant/implementation_spec.rb +0 -223
  218. data/spec/mutant/literal_spec.rb +0 -129
  219. data/spec/mutant/mutatee_spec.rb +0 -28
  220. data/spec/mutant/node_spec.rb +0 -41
  221. data/spec/mutant/random_spec.rb +0 -33
  222. data/spec/mutant/reporter_spec.rb +0 -17
  223. data/spec/mutant_spec.rb +0 -28
  224. data/spec/support/example_group_helpers.rb +0 -11
  225. data/spec/support/example_helpers.rb +0 -5
@@ -0,0 +1,25 @@
1
+ module Mutant
2
+ class Mutator
3
+ class Node
4
+ class Literal
5
+ # Mutator for nil literals
6
+ class Nil < self
7
+
8
+ handle(Rubinius::AST::NilLiteral)
9
+
10
+ private
11
+
12
+ # Emit mutants
13
+ #
14
+ # @return [undefined]
15
+ #
16
+ # @api private
17
+ #
18
+ def dispatch
19
+ emit('Object.new'.to_ast)
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,94 @@
1
+ module Mutant
2
+ class Mutator
3
+ class Node
4
+ class Literal
5
+ # Abstract literal range mutator
6
+ class Range < self
7
+ include AbstractType
8
+
9
+ private
10
+
11
+ # Emit mutants
12
+ #
13
+ # @return [undefined]
14
+ #
15
+ # @api private
16
+ #
17
+ def dispatch
18
+ emit_nil
19
+ emit(inverse)
20
+ emit_range
21
+ end
22
+
23
+ # Return inverse node
24
+ #
25
+ # @return [Rubinius::AST::Node]
26
+ #
27
+ # @api private
28
+ #
29
+ def inverse
30
+ new(inverse_class,node.start, node.finish)
31
+ end
32
+
33
+ # Emit range specific mutants
34
+ #
35
+ # @return [undefined]
36
+ #
37
+ # @api private
38
+ #
39
+ def emit_range
40
+ emit_finish_mutations
41
+ emit_start_mutations
42
+ end
43
+
44
+ # Emit range start mutations
45
+ #
46
+ # @return [undefined]
47
+ #
48
+ # @api private
49
+ #
50
+ def emit_finish_mutations
51
+ finish = node.finish
52
+ emit_self(negative_infinity, finish)
53
+ emit_self(nan, finish)
54
+ end
55
+
56
+ # Emit start mutations
57
+ #
58
+ # @return [undefined]
59
+ #
60
+ # @api private
61
+ #
62
+ def emit_start_mutations
63
+ start = node.start
64
+ emit_self(start, infinity)
65
+ emit_self(start, nan)
66
+ end
67
+
68
+ # Return inverse AST node class
69
+ #
70
+ # @return [Class:Rubinius::AST::Node]
71
+ #
72
+ # @api private
73
+ #
74
+ def inverse_class
75
+ self.class::INVERSE_CLASS
76
+ end
77
+
78
+ # Mutator for range exclude literals
79
+ class Exclude < self
80
+ INVERSE_CLASS = Rubinius::AST::Range
81
+ handle(Rubinius::AST::RangeExclude)
82
+
83
+ end
84
+
85
+ # Mutator for range include literals
86
+ class Include < self
87
+ INVERSE_CLASS = Rubinius::AST::RangeExclude
88
+ handle(Rubinius::AST::Range)
89
+ end
90
+ end
91
+ end
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,43 @@
1
+ module Mutant
2
+ class Mutator
3
+ class Node
4
+ class Literal < self
5
+ # Mutator for regexp literals
6
+ class Regex < self
7
+
8
+ handle(Rubinius::AST::RegexLiteral)
9
+
10
+ private
11
+
12
+ # Emit mutants
13
+ #
14
+ # @return [undefined]
15
+ #
16
+ # @api private
17
+ #
18
+ def dispatch
19
+ emit_nil
20
+ emit_self('') # match all
21
+ emit_self('a\A') # match nothing
22
+ emit_new { new_self(Random.hex_string) }
23
+ end
24
+
25
+ # Return new Rubinius::AST::Regex
26
+ #
27
+ # @param [String] source
28
+ #
29
+ # @param [Integer] options
30
+ # options of regexp, defaults to mutation subject node options
31
+ #
32
+ # @return [undefined]
33
+ #
34
+ # @api private
35
+ #
36
+ def new_self(source,options=nil)
37
+ super(source,options || node.options)
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,26 @@
1
+ module Mutant
2
+ class Mutator
3
+ class Node
4
+ class Literal
5
+ # Mutator for string literals
6
+ class String < self
7
+
8
+ handle(Rubinius::AST::StringLiteral)
9
+
10
+ private
11
+
12
+ # Emit mutants
13
+ #
14
+ # @return [undefined]
15
+ #
16
+ # @api private
17
+ #
18
+ def dispatch
19
+ emit_nil
20
+ emit_new { new_self(Random.hex_string) }
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,26 @@
1
+ module Mutant
2
+ class Mutator
3
+ class Node
4
+ class Literal < self
5
+ # Mutator for symbol literals
6
+ class Symbol < self
7
+
8
+ handle(Rubinius::AST::SymbolLiteral)
9
+
10
+ private
11
+
12
+ # Emit mutatns
13
+ #
14
+ # @return [undefined]
15
+ #
16
+ # @api private
17
+ #
18
+ def dispatch
19
+ emit_nil
20
+ emit_new { new_self(('s'+Random.hex_string).to_sym) }
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,55 @@
1
+ module Mutant
2
+ class Mutator
3
+ class Node
4
+ # Mutator that does not do mutations on ast
5
+ class Noop < self
6
+
7
+ # Literal references to self do not need to be mutated?
8
+ handle(Rubinius::AST::Self)
9
+
10
+
11
+ # Currently unhandled node classes. Feel free to contribute your mutator!
12
+ handle(Rubinius::AST::While)
13
+ handle(Rubinius::AST::ElementAssignment)
14
+ handle(Rubinius::AST::AttributeAssignment)
15
+ handle(Rubinius::AST::Not)
16
+ handle(Rubinius::AST::And)
17
+ handle(Rubinius::AST::Defined)
18
+ handle(Rubinius::AST::Super)
19
+ handle(Rubinius::AST::Match3)
20
+ handle(Rubinius::AST::ZSuper)
21
+ handle(Rubinius::AST::MultipleAssignment)
22
+ handle(Rubinius::AST::ScopedConstant)
23
+ handle(Rubinius::AST::LocalVariableAssignment)
24
+ handle(Rubinius::AST::LocalVariableAccess)
25
+ handle(Rubinius::AST::InstanceVariableAssignment)
26
+ handle(Rubinius::AST::InstanceVariableAccess)
27
+ handle(Rubinius::AST::GlobalVariableAssignment)
28
+ handle(Rubinius::AST::GlobalVariableAccess)
29
+ handle(Rubinius::AST::ToplevelConstant)
30
+ handle(Rubinius::AST::Ensure)
31
+ handle(Rubinius::AST::Rescue)
32
+ handle(Rubinius::AST::DynamicString)
33
+ handle(Rubinius::AST::DynamicSymbol)
34
+ handle(Rubinius::AST::File)
35
+ handle(Rubinius::AST::DynamicRegex)
36
+ handle(Rubinius::AST::OpAssignOr19)
37
+ handle(Rubinius::AST::OpAssign1)
38
+ handle(Rubinius::AST::Or)
39
+ handle(Rubinius::AST::ConstantAccess)
40
+
41
+ private
42
+
43
+ # Emit mutations
44
+ #
45
+ # @return [undefined]
46
+ #
47
+ # @api private
48
+ #
49
+ def dispatch
50
+ # noop
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,140 @@
1
+ module Mutant
2
+ class Mutator
3
+ class Node
4
+ # Mutator for Rubinius::AST::When nodes
5
+ class When < self
6
+
7
+ handle(Rubinius::AST::When)
8
+
9
+ private
10
+
11
+ # Emit mutations
12
+ #
13
+ # @return [undefined]
14
+ #
15
+ # @api private
16
+ #
17
+ def dispatch
18
+ emit_attribute_mutations(:body)
19
+ end
20
+
21
+ end
22
+
23
+ # Mutator for Rubinius::AST::ReceiverCase nodes
24
+ class ReceiverCase < self
25
+
26
+ handle(Rubinius::AST::ReceiverCase)
27
+
28
+ private
29
+
30
+ # Emit mutations
31
+ #
32
+ # @return [undefined]
33
+ #
34
+ # @api private
35
+ #
36
+ def dispatch
37
+ emit_attribute_mutations(:receiver)
38
+ emit_when_branch_presence_mutations
39
+ emit_else_branch_presence_mutation
40
+ emit_when_branch_mutations
41
+ end
42
+
43
+ # Emit else branch presence mutation
44
+ #
45
+ # @return [undefined]
46
+ #
47
+ # @api private
48
+ #
49
+ def emit_else_branch_presence_mutation
50
+ emit_self(receiver, when_branches, nil)
51
+ end
52
+
53
+ # Emit when branch body mutations
54
+ #
55
+ # @return [undefined]
56
+ #
57
+ # @api private
58
+ #
59
+ def emit_when_branch_mutations
60
+ when_branches.each_with_index do |branch,index|
61
+ Mutator.each(branch) do |mutant|
62
+ branches = dup_when_branches
63
+ branches[index]=mutant
64
+ emit_self(receiver, branches, else_branch)
65
+ end
66
+ end
67
+ end
68
+
69
+ # Emit when branch presence mutations
70
+ #
71
+ # @return [undefined]
72
+ #
73
+ # @api private
74
+ #
75
+ def emit_when_branch_presence_mutations
76
+ return if one?
77
+ when_branches.each_index do |index|
78
+ dup_branches = dup_when_branches
79
+ dup_branches.delete_at(index)
80
+ emit_self(receiver, dup_branches, else_branch)
81
+ end
82
+ end
83
+
84
+ # Check for case there is only one when branch
85
+ #
86
+ # @return [true]
87
+ # returns true when there is only one when branch
88
+ #
89
+ # @return [false]
90
+ # returns false otherwise
91
+ #
92
+ # @api private
93
+ #
94
+ def one?
95
+ when_branches.one?
96
+ end
97
+
98
+ # Return duplicate of when branches
99
+ #
100
+ # @return [Array]
101
+ #
102
+ # @api private
103
+ #
104
+ def dup_when_branches
105
+ when_branches.dup
106
+ end
107
+
108
+ # Return when branches
109
+ #
110
+ # @return [Array]
111
+ #
112
+ # @api private
113
+ #
114
+ def when_branches
115
+ node.whens
116
+ end
117
+
118
+ # Return receiver
119
+ #
120
+ # @return [Rubinius::AST::Node]
121
+ #
122
+ # @api private
123
+ #
124
+ def receiver
125
+ node.receiver
126
+ end
127
+
128
+ # Return else branch
129
+ #
130
+ # @return [Rubinius::AST::Node]
131
+ #
132
+ # @api private
133
+ #
134
+ def else_branch
135
+ node.else
136
+ end
137
+ end
138
+ end
139
+ end
140
+ end
@@ -0,0 +1,31 @@
1
+ module Mutant
2
+ class Mutator
3
+ class Node
4
+ # Mutator for return statements
5
+ class Return < self
6
+
7
+ handle(Rubinius::AST::Return)
8
+
9
+ private
10
+
11
+
12
+ # Emit mutants
13
+ #
14
+ # @return [undefined]
15
+ #
16
+ # @api private
17
+ #
18
+ def dispatch
19
+ value = node.value
20
+ if value
21
+ emit(value)
22
+ else
23
+ emit_nil
24
+ end
25
+ end
26
+
27
+ end
28
+ end
29
+ end
30
+
31
+ end