mutant 0.2.20 → 0.3.0.beta2

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 (201) hide show
  1. checksums.yaml +7 -0
  2. data/.travis.yml +10 -11
  3. data/Changelog.md +93 -38
  4. data/Gemfile +3 -1
  5. data/Gemfile.devtools +16 -20
  6. data/Guardfile +1 -1
  7. data/README.md +36 -16
  8. data/Rakefile +21 -2
  9. data/TODO +11 -7
  10. data/bin/mutant +4 -0
  11. data/bin/zombie +4 -0
  12. data/config/devtools.yml +2 -0
  13. data/config/flay.yml +2 -2
  14. data/config/flog.yml +1 -1
  15. data/config/{site.reek → reek.yml} +94 -70
  16. data/lib/mutant/cli/classifier/method.rb +100 -0
  17. data/lib/mutant/cli/classifier/namespace.rb +47 -0
  18. data/lib/mutant/cli/classifier/scope.rb +35 -0
  19. data/lib/mutant/cli/classifier.rb +141 -0
  20. data/lib/mutant/cli.rb +115 -162
  21. data/lib/mutant/color.rb +2 -2
  22. data/lib/mutant/config.rb +27 -0
  23. data/lib/mutant/constants.rb +32 -17
  24. data/lib/mutant/context/scope.rb +33 -51
  25. data/lib/mutant/context.rb +8 -19
  26. data/lib/mutant/differ.rb +5 -5
  27. data/lib/mutant/helper.rb +2 -17
  28. data/lib/mutant/killer/forked.rb +44 -0
  29. data/lib/mutant/killer/forking.rb +3 -57
  30. data/lib/mutant/killer/rspec.rb +16 -20
  31. data/lib/mutant/killer/static.rb +6 -7
  32. data/lib/mutant/killer.rb +48 -74
  33. data/lib/mutant/loader.rb +6 -6
  34. data/lib/mutant/matcher/chain.rb +4 -25
  35. data/lib/mutant/matcher/method/instance.rb +14 -24
  36. data/lib/mutant/matcher/method/singleton.rb +35 -46
  37. data/lib/mutant/matcher/method.rb +95 -83
  38. data/lib/mutant/matcher/{scope_methods.rb → methods.rb} +53 -76
  39. data/lib/mutant/matcher/namespace.rb +71 -0
  40. data/lib/mutant/matcher/scope.rb +34 -0
  41. data/lib/mutant/matcher.rb +24 -34
  42. data/lib/mutant/mutation/evil.rb +35 -0
  43. data/lib/mutant/mutation/filter/code.rb +7 -28
  44. data/lib/mutant/mutation/filter/regexp.rb +6 -18
  45. data/lib/mutant/mutation/filter/whitelist.rb +5 -4
  46. data/lib/mutant/mutation/filter.rb +10 -9
  47. data/lib/mutant/mutation/neutral.rb +35 -0
  48. data/lib/mutant/mutation.rb +21 -61
  49. data/lib/mutant/mutator/node/argument.rb +88 -0
  50. data/lib/mutant/mutator/node/arguments.rb +52 -0
  51. data/lib/mutant/mutator/node/assignment.rb +34 -38
  52. data/lib/mutant/mutator/node/begin.rb +33 -0
  53. data/lib/mutant/mutator/node/block.rb +14 -14
  54. data/lib/mutant/mutator/node/case.rb +59 -0
  55. data/lib/mutant/mutator/node/define.rb +26 -22
  56. data/lib/mutant/mutator/node/if.rb +31 -71
  57. data/lib/mutant/mutator/node/literal/array.rb +25 -9
  58. data/lib/mutant/mutator/node/literal/boolean.rb +13 -30
  59. data/lib/mutant/mutator/node/literal/dynamic.rb +6 -5
  60. data/lib/mutant/mutator/node/literal/fixnum.rb +18 -7
  61. data/lib/mutant/mutator/node/literal/float.rb +15 -8
  62. data/lib/mutant/mutator/node/literal/hash.rb +33 -52
  63. data/lib/mutant/mutator/node/literal/nil.rb +8 -7
  64. data/lib/mutant/mutator/node/literal/range.rb +25 -50
  65. data/lib/mutant/mutator/node/literal/regex.rb +15 -23
  66. data/lib/mutant/mutator/node/literal/string.rb +7 -6
  67. data/lib/mutant/mutator/node/literal/symbol.rb +7 -6
  68. data/lib/mutant/mutator/node/literal.rb +4 -46
  69. data/lib/mutant/mutator/node/mlhs.rb +27 -0
  70. data/lib/mutant/mutator/node/noop.rb +18 -43
  71. data/lib/mutant/mutator/node/return.rb +8 -8
  72. data/lib/mutant/mutator/node/send/binary.rb +31 -0
  73. data/lib/mutant/mutator/node/send.rb +106 -72
  74. data/lib/mutant/mutator/node/super.rb +15 -20
  75. data/lib/mutant/mutator/node/when.rb +32 -7
  76. data/lib/mutant/mutator/node/while.rb +9 -7
  77. data/lib/mutant/mutator/node.rb +116 -66
  78. data/lib/mutant/mutator/registry.rb +14 -11
  79. data/lib/mutant/mutator/util/array.rb +9 -9
  80. data/lib/mutant/mutator/util/symbol.rb +6 -20
  81. data/lib/mutant/mutator/util.rb +6 -3
  82. data/lib/mutant/mutator.rb +12 -28
  83. data/lib/mutant/node_helpers.rb +28 -0
  84. data/lib/mutant/random.rb +3 -2
  85. data/lib/mutant/reporter/cli/printer/config.rb +174 -0
  86. data/lib/mutant/reporter/cli/printer/killer.rb +42 -0
  87. data/lib/mutant/reporter/cli/printer/mutation.rb +55 -0
  88. data/lib/mutant/reporter/cli/printer/subject.rb +147 -0
  89. data/lib/mutant/reporter/cli/printer.rb +165 -0
  90. data/lib/mutant/reporter/cli.rb +9 -277
  91. data/lib/mutant/reporter/null.rb +6 -30
  92. data/lib/mutant/reporter.rb +6 -73
  93. data/lib/mutant/runner/config.rb +82 -0
  94. data/lib/mutant/runner/mutation.rb +58 -0
  95. data/lib/mutant/runner/subject.rb +81 -0
  96. data/lib/mutant/runner.rb +42 -92
  97. data/lib/mutant/singleton_methods.rb +2 -2
  98. data/lib/mutant/strategy/method_expansion.rb +51 -0
  99. data/lib/mutant/strategy/rspec/dm2/lookup/method.rb +142 -0
  100. data/lib/mutant/strategy/rspec/dm2/lookup.rb +61 -0
  101. data/lib/mutant/strategy/rspec/dm2.rb +22 -0
  102. data/lib/mutant/strategy/rspec.rb +20 -22
  103. data/lib/mutant/strategy/static.rb +18 -0
  104. data/lib/mutant/strategy.rb +15 -50
  105. data/lib/mutant/subject/method.rb +100 -0
  106. data/lib/mutant/subject.rb +18 -49
  107. data/lib/mutant/support/method_object.rb +4 -2
  108. data/lib/mutant.rb +40 -35
  109. data/mutant.gemspec +9 -8
  110. data/spec/integration/mutant/rspec_killer_spec.rb +3 -3
  111. data/spec/integration/mutant/test_mutator_handles_types_spec.rb +9 -0
  112. data/spec/integration/mutant/zombie_spec.rb +1 -1
  113. data/spec/shared/method_matcher_behavior.rb +35 -0
  114. data/spec/shared/mutator_behavior.rb +63 -32
  115. data/spec/spec_helper.rb +13 -3
  116. data/spec/support/ice_nine_config.rb +8 -0
  117. data/spec/support/rspec.rb +1 -1
  118. data/spec/support/zombie.rb +1 -1
  119. data/spec/unit/mutant/cli/class_methods/new_spec.rb +42 -28
  120. data/spec/unit/mutant/cli/class_methods/run_spec.rb +15 -13
  121. data/spec/unit/mutant/cli/classifier/class_methods/build_spec.rb +44 -0
  122. data/spec/unit/mutant/context/scope/root_spec.rb +4 -4
  123. data/spec/unit/mutant/killer/rspec/class_methods/new_spec.rb +6 -5
  124. data/spec/unit/mutant/killer/success_predicate_spec.rb +28 -0
  125. data/spec/unit/mutant/loader/eval/class_methods/run_spec.rb +1 -1
  126. data/spec/unit/mutant/matcher/chain/each_spec.rb +1 -1
  127. data/spec/unit/mutant/matcher/chain/matchers_spec.rb +1 -1
  128. data/spec/unit/mutant/matcher/method/instance/each_spec.rb +112 -0
  129. data/spec/unit/mutant/matcher/method/singleton/each_spec.rb +93 -0
  130. data/spec/unit/mutant/matcher/methods/instance/each_spec.rb +59 -0
  131. data/spec/unit/mutant/matcher/methods/singleton/each_spec.rb +53 -0
  132. data/spec/unit/mutant/matcher/namespace/each_spec.rb +37 -0
  133. data/spec/unit/mutant/mutator/node/begin/mutation_spec.rb +33 -0
  134. data/spec/unit/mutant/mutator/node/block/mutation_spec.rb +42 -14
  135. data/spec/unit/mutant/mutator/node/case/mutation_spec.rb +319 -0
  136. data/spec/unit/mutant/mutator/node/define/mutation_spec.rb +31 -27
  137. data/spec/unit/mutant/mutator/node/if/mutation_spec.rb +75 -0
  138. data/spec/unit/mutant/mutator/node/literal/fixnum_spec.rb +1 -1
  139. data/spec/unit/mutant/mutator/node/literal/hash_spec.rb +2 -2
  140. data/spec/unit/mutant/mutator/node/literal/nil_spec.rb +1 -3
  141. data/spec/unit/mutant/mutator/node/literal/regex_spec.rb +1 -9
  142. data/spec/unit/mutant/mutator/node/return/mutation_spec.rb +6 -2
  143. data/spec/unit/mutant/mutator/node/send/mutation_spec.rb +111 -108
  144. data/spec/unit/mutant/mutator/node/super/mutation_spec.rb +0 -33
  145. data/spec/unit/mutant/mutator/node/while/mutation_spec.rb +2 -2
  146. data/spec/unit/mutant/runner/config/subjects_spec.rb +38 -0
  147. data/spec/unit/mutant/runner/config/success_predicate_spec.rb +53 -0
  148. data/spec/unit/mutant/runner/failed_predicte_spec.rb +33 -0
  149. data/spec/unit/mutant/runner/mutation/killer_spec.rb +39 -0
  150. data/spec/unit/mutant/runner/subject/success_predicate_spec.rb +49 -0
  151. data/spec/unit/mutant/strategy/method_expansion/class_methods/run_spec.rb +49 -0
  152. data/spec/unit/mutant/strategy/rspec/dm2/lookup/method/instance/spec_files_spec.rb +52 -0
  153. data/spec/unit/mutant/strategy/rspec/dm2/lookup/method/singleton/spec_files_spec.rb +42 -0
  154. data/spec/unit/mutant/subject/context_spec.rb +6 -3
  155. data/spec/unit/mutant/subject/each_spec.rb +11 -8
  156. data/spec/unit/mutant/subject/node_spec.rb +6 -2
  157. data/test_app/spec/shared/method_filter_parse_behavior.rb +0 -2
  158. data/test_app/spec/shared/method_match_behavior.rb +1 -1
  159. data/test_app/spec/spec_helper.rb +4 -2
  160. metadata +101 -109
  161. data/config/roodi.yml +0 -26
  162. data/lib/mutant/matcher/method/classifier.rb +0 -141
  163. data/lib/mutant/matcher/object_space.rb +0 -114
  164. data/lib/mutant/mutator/node/actual_arguments.rb +0 -25
  165. data/lib/mutant/mutator/node/default_arguments.rb +0 -25
  166. data/lib/mutant/mutator/node/formal_arguments_19/default_mutations.rb +0 -33
  167. data/lib/mutant/mutator/node/formal_arguments_19/pattern_argument_expansion.rb +0 -35
  168. data/lib/mutant/mutator/node/formal_arguments_19/require_defaults.rb +0 -37
  169. data/lib/mutant/mutator/node/formal_arguments_19.rb +0 -41
  170. data/lib/mutant/mutator/node/iter_19.rb +0 -27
  171. data/lib/mutant/mutator/node/literal/empty_array.rb +0 -26
  172. data/lib/mutant/mutator/node/pattern_arguments.rb +0 -41
  173. data/lib/mutant/mutator/node/pattern_variable.rb +0 -23
  174. data/lib/mutant/mutator/node/receiver_case.rb +0 -122
  175. data/lib/mutant/mutator/node/send/binary_operator_method.rb +0 -61
  176. data/lib/mutant/mutator/node/send/with_arguments.rb +0 -81
  177. data/lib/mutant/reporter/stats.rb +0 -120
  178. data/lib/mutant/strategy/rspec/example_lookup.rb +0 -163
  179. data/spec/integration/mutant/method_matching_spec.rb +0 -269
  180. data/spec/shared/method_match_behavior.rb +0 -39
  181. data/spec/unit/mutant/killer/fail_ques_spec.rb +0 -39
  182. data/spec/unit/mutant/matcher/class_methods/from_string_spec.rb +0 -49
  183. data/spec/unit/mutant/matcher/class_methods/parse_spec.rb +0 -12
  184. data/spec/unit/mutant/matcher/method/class_methods/parse_spec.rb +0 -21
  185. data/spec/unit/mutant/matcher/method/classifier/class_methods/run_spec.rb +0 -52
  186. data/spec/unit/mutant/matcher/object_space/class_methods/parse_spec.rb +0 -24
  187. data/spec/unit/mutant/matcher/object_space/each_spec.rb +0 -31
  188. data/spec/unit/mutant/mutator/node/if_statement/mutation_spec.rb +0 -60
  189. data/spec/unit/mutant/mutator/node/receiver_case/mutation_spec.rb +0 -27
  190. data/spec/unit/mutant/strategy/rspec/example_lookup/spec_file_spec.rb +0 -236
  191. data/spec/unit/mutant/subject/class_methods/new_spec.rb +0 -13
  192. data/tasks/metrics/ci.rake +0 -7
  193. data/tasks/metrics/flay.rake +0 -41
  194. data/tasks/metrics/flog.rake +0 -43
  195. data/tasks/metrics/heckle.rake +0 -216
  196. data/tasks/metrics/metric_fu.rake +0 -31
  197. data/tasks/metrics/reek.rake +0 -15
  198. data/tasks/metrics/roodi.rake +0 -15
  199. data/tasks/metrics/yardstick.rake +0 -23
  200. data/tasks/spec.rake +0 -45
  201. data/tasks/yard.rake +0 -9
@@ -4,7 +4,11 @@ module Mutant
4
4
 
5
5
  # Mutator for super with parantheses
6
6
  class Super < self
7
- handle(Rubinius::AST::Super)
7
+
8
+ handle(:super)
9
+
10
+ Z_SUPER = NodeHelpers.s(:zsuper)
11
+ EMPTY_SUPER = NodeHelpers.s(:super)
8
12
 
9
13
  private
10
14
 
@@ -15,24 +19,15 @@ module Mutant
15
19
  # @api private
16
20
  #
17
21
  def dispatch
18
- emit_node(Rubinius::AST::ZSuper)
19
- emit_without_block
20
- emit_attribute_mutations(:block) if node.block
21
- emit_attribute_mutations(:arguments)
22
+ emit(Z_SUPER)
23
+ emit(EMPTY_SUPER)
24
+ children.each_index do |index|
25
+ mutate_child(index)
26
+ delete_child(index)
27
+ end
22
28
  end
23
29
 
24
- # Emit without block mutation
25
- #
26
- # @return [undefined]
27
- #
28
- # @api private
29
- #
30
- def emit_without_block
31
- dup = dup_node
32
- dup.block = nil
33
- emit(dup)
34
- end
35
- end
36
- end
37
- end
38
- end
30
+ end # Super
31
+ end # Node
32
+ end # Mutator
33
+ end # Mutant
@@ -2,10 +2,10 @@ module Mutant
2
2
  class Mutator
3
3
  class Node
4
4
 
5
- # Mutator for Rubinius::AST::When nodes
5
+ # Mutator for when nodes
6
6
  class When < self
7
7
 
8
- handle(Rubinius::AST::When)
8
+ handle(:when)
9
9
 
10
10
  private
11
11
 
@@ -16,10 +16,35 @@ module Mutant
16
16
  # @api private
17
17
  #
18
18
  def dispatch
19
- emit_attribute_mutations(:body)
19
+ mutate_body
20
+ mutate_conditions
20
21
  end
21
22
 
22
- end
23
- end
24
- end
25
- end
23
+ # Emit condition mutations
24
+ #
25
+ # @return [undefined]
26
+ #
27
+ # @api private
28
+ #
29
+ def mutate_conditions
30
+ conditions = children.length - 1
31
+ children[0..-2].each_index do |index|
32
+ delete_child(index) if conditions > 1
33
+ mutate_child(index)
34
+ end
35
+ end
36
+
37
+ # Emit body mutations
38
+ #
39
+ # @return [undefined]
40
+ #
41
+ # @api private
42
+ #
43
+ def mutate_body
44
+ mutate_child(children.length-1)
45
+ end
46
+
47
+ end # When
48
+ end # Node
49
+ end # Mutator
50
+ end # Mutant
@@ -5,7 +5,9 @@ module Mutant
5
5
  # Mutator for while expressions
6
6
  class While < self
7
7
 
8
- handle(Rubinius::AST::While)
8
+ handle(:while)
9
+
10
+ children :condition, :body
9
11
 
10
12
  private
11
13
 
@@ -16,11 +18,11 @@ module Mutant
16
18
  # @api private
17
19
  #
18
20
  def dispatch
19
- emit_attribute_mutations(:condition)
20
- emit_attribute_mutations(:body)
21
+ emit_condition_mutations
22
+ emit_body_mutations
21
23
  end
22
24
 
23
- end
24
- end
25
- end
26
- end
25
+ end # While
26
+ end # Node
27
+ end # Mutator
28
+ end # Mutant
@@ -3,25 +3,82 @@ module Mutant
3
3
  class Mutator
4
4
  # Abstract base class for node mutators
5
5
  class Node < self
6
- include AbstractType
6
+ include AbstractType, NodeHelpers, Unparser::Constants
7
7
 
8
8
  # Return identity of node
9
9
  #
10
- # @param [Rubinius::AST::Node] node
10
+ # @param [Parser::AST::Node] node
11
11
  #
12
12
  # @return [String]
13
13
  #
14
14
  # @api private
15
15
  #
16
16
  def self.identity(node)
17
- ToSource.to_source(node)
17
+ Unparser.unparse(node)
18
18
  end
19
19
 
20
+ # Define named child
21
+ #
22
+ # @param [Symbol] name
23
+ # @param [Fixnum] index
24
+ #
25
+ # @return [undefined]
26
+ #
27
+ # @api private
28
+ #
29
+ def self.define_named_child(name, index)
30
+ define_method("#{name}") do
31
+ children.at(index)
32
+ end
33
+
34
+ define_method("emit_#{name}_mutations") do
35
+ mutate_child(index)
36
+ end
37
+
38
+ define_method("emit_#{name}") do |node|
39
+ emit_child_update(index, node)
40
+ end
41
+ end
42
+ private_class_method :define_named_child
43
+
44
+ # Define remaining children
45
+ #
46
+ # @param [Array<Symbol>] names
47
+ #
48
+ # @return [undefined]
49
+ #
50
+ # @api private
51
+ #
52
+ def self.define_remaining_children(names)
53
+ define_method(:remaining_children_with_index) do
54
+ children.each_with_index.drop(names.length)
55
+ end
56
+
57
+ define_method(:remaining_children) do
58
+ children.drop(names.length)
59
+ end
60
+ end
61
+ private_class_method :define_remaining_children
62
+
63
+ # Create name helpers
64
+ #
65
+ # @return [undefined]
66
+ #
67
+ # @api private
68
+ #
69
+ def self.children(*names)
70
+ names.each_with_index do |name, index|
71
+ define_named_child(name, index)
72
+ end
73
+ define_remaining_children(names)
74
+ end
75
+ private_class_method :children
76
+
20
77
  private
21
78
 
22
79
  # Return mutated node
23
80
  #
24
- # @return [Rubinius::AST::Node]
81
+ # @return [Parser::AST::Node]
25
82
  #
26
83
  # @api private
27
84
  #
@@ -29,85 +86,89 @@ module Mutant
29
86
 
30
87
  # Return duplicated node
31
88
  #
32
- # @return [Rubinius::AST::Node]
89
+ # @return [Parser::AST::Node]
33
90
  #
34
91
  # @api private
35
92
  #
36
93
  alias_method :dup_node, :dup_input
37
94
 
38
- # Emit a new AST node
95
+ # Emit children mutations
39
96
  #
40
- # @param [Rubinis::AST::Node:Class] node_class
41
- #
42
- # @return [Rubinius::AST::Node]
97
+ # @return [undefined]
43
98
  #
44
99
  # @api private
45
100
  #
46
- def emit_node(node_class, *arguments)
47
- emit(new(node_class, *arguments))
101
+ def emit_children_mutations
102
+ Mutator::Util::Array.each(children) do |children|
103
+ emit_self(*children)
104
+ end
48
105
  end
49
106
 
50
- # Create a new AST node with same class as wrapped node
107
+ # Return children
51
108
  #
52
- # @return [Rubinius::AST::Node]
109
+ # @return [Array<Parser::AST::Node>]
53
110
  #
54
111
  # @api private
55
112
  #
56
- def new_self(*arguments)
57
- new(node.class, *arguments)
113
+ def children
114
+ node.children
58
115
  end
59
116
 
60
- # Create a new AST node with Rubnius::AST::NilLiteral class
117
+ # Dispatch on child index
61
118
  #
62
- # @return [Rubinius::AST::Node]
119
+ # @param [Fixnum] index
120
+ #
121
+ # @return [undefined]
63
122
  #
64
123
  # @api private
65
124
  #
66
- def new_nil
67
- new(Rubinius::AST::NilLiteral)
125
+ def mutate_child(index, mutator = Mutator)
126
+ children = node.children
127
+ child = children[index]
128
+ mutator.each(child) do |mutation|
129
+ emit_child_update(index, mutation)
130
+ end
68
131
  end
69
132
 
70
- # Create a new AST node with the same line as wrapped node
133
+ # Emit delete child mutation
71
134
  #
72
- # @param [Class:Rubinius::AST::Node] node_class
135
+ # @param [Fixnum] index
73
136
  #
74
- # @return [Rubinius::AST::Node]
137
+ # @return [undefined]
75
138
  #
76
139
  # @api private
77
140
  #
78
- def new(node_class, *arguments)
79
- node_class.new(node.line, *arguments)
141
+ def delete_child(index)
142
+ dup_children = children.dup
143
+ dup_children.delete_at(index)
144
+ emit_self(*dup_children)
80
145
  end
81
146
 
82
- # Emit a new AST node with same class as wrapped node
147
+ # Emit updated child
148
+ #
149
+ # @param [Fixnum] index
150
+ # @param [Object] update
83
151
  #
84
152
  # @return [undefined]
85
153
  #
86
154
  # @api private
87
155
  #
88
- def emit_self(*arguments)
89
- emit(new_self(*arguments))
156
+ def emit_child_update(index, update)
157
+ new_children = children.dup
158
+ new_children[index]=update
159
+ emit_self(*new_children)
90
160
  end
91
161
 
92
- # Emit body mutations
162
+ # Emit a new AST node with same class as wrapped node
93
163
  #
94
- # @param [Symbol] name
164
+ # @param [Array<Parser::AST::Node>] children
95
165
  #
96
166
  # @return [undefined]
97
167
  #
98
168
  # @api private
99
169
  #
100
- def emit_attribute_mutations(name, mutator = Mutator)
101
- value = node.public_send(name)
102
-
103
- mutator.each(value) do |mutation|
104
- dup = dup_node
105
- dup.public_send(:"#{name}=", mutation)
106
- if block_given?
107
- dup = yield(dup)
108
- end
109
- emit(dup)
110
- end
170
+ def emit_self(*children)
171
+ emit(new_self(*children))
111
172
  end
112
173
 
113
174
  # Emit a new AST node with NilLiteral class
@@ -117,44 +178,33 @@ module Mutant
117
178
  # @api private
118
179
  #
119
180
  def emit_nil
120
- emit(new_nil)
181
+ emit(N_NIL)
121
182
  end
122
183
 
123
- # Return new Rubiinius::AST::SendWithArguments node
184
+ # Return new self typed child
124
185
  #
125
- # @param [Rubnius::AST::Node] receiver
126
- # @param [Symbol] name
127
- # @param [Object] arguments
128
- #
129
- # @return [Rubinius::AST::SendWithArguments]
186
+ # @return [Parser::AST::Node]
130
187
  #
131
188
  # @api private
132
189
  #
133
- def new_send_with_arguments(receiver, name, arguments)
134
- new(Rubinius::AST::SendWithArguments, receiver, name, arguments)
190
+ def new_self(*children)
191
+ Parser::AST::Node.new(node.type, children)
135
192
  end
136
193
 
137
- # Return AST representing send
194
+ # Emit values
138
195
  #
139
- # @param [Rubinius::AST::Node] receiver
140
- # @param [Symbol] name
196
+ # @param [Array<Object>] values
141
197
  #
142
- # @return [Rubnius::AST::Send]
198
+ # @return [undefined]
143
199
  #
144
200
  # @api private
145
201
  #
146
- def new_send(receiver, name)
147
- new(Rubinius::AST::Send, receiver, name)
202
+ def emit_values(values)
203
+ values.each do |value|
204
+ emit_self(value)
205
+ end
148
206
  end
149
207
 
150
- # Return duplicated (unfrozen) node each call
151
- #
152
- # @return [Rubinius::AST::Node]
153
- #
154
- # @api private
155
- #
156
- alias_method :dup_node, :dup_input
157
-
158
- end
159
- end
160
- end
208
+ end # Node
209
+ end # Mutator
210
+ end # Mutant
@@ -15,21 +15,22 @@ module Mutant
15
15
 
16
16
  # Register mutator class for AST node class
17
17
  #
18
- # @param [Class] ast_class
18
+ # @param [Symbol] type
19
19
  # @param [Class] mutator_class
20
20
  #
21
21
  # @api private
22
22
  #
23
23
  # @return [self]
24
24
  #
25
- def self.register(ast_class,mutator_class)
26
- registry[ast_class]=mutator_class
25
+ def self.register(type, mutator_class)
26
+ raise "duplicate type registration: #{type}" if registry.key?(type)
27
+ registry[type]=mutator_class
27
28
  self
28
29
  end
29
30
 
30
- # Lookup mutator class for AST node class
31
+ # Lookup mutator class for node
31
32
  #
32
- # @param [Class] ast_class
33
+ # @param [Parser::AST::Node] node
33
34
  #
34
35
  # @return [Class]
35
36
  #
@@ -38,11 +39,13 @@ module Mutant
38
39
  #
39
40
  # @api private
40
41
  #
41
- def self.lookup(ast_class)
42
- registry.fetch(ast_class) do
43
- raise ArgumentError,"No mutator to handle: #{ast_class.inspect}"
42
+ def self.lookup(node)
43
+ type = node.type
44
+ registry.fetch(type) do
45
+ raise ArgumentError,"No mutator to handle: #{type.inspect}"
44
46
  end
45
47
  end
46
- end
47
- end
48
- end
48
+
49
+ end # Registry
50
+ end # Mutator
51
+ end # Mutant
@@ -26,7 +26,7 @@ module Mutant
26
26
  end
27
27
  end
28
28
 
29
- end
29
+ end # Presence
30
30
 
31
31
  # Array element mutator
32
32
  class Element < Util
@@ -34,27 +34,27 @@ module Mutant
34
34
  private
35
35
 
36
36
  # Emit mutations
37
- #
37
+ #
38
38
  # @return [undefined]
39
39
  #
40
40
  # @api private
41
41
  #
42
42
  def dispatch
43
43
  input.each_with_index do |element, index|
44
- dup = dup_input
45
44
  Mutator.each(element).each do |mutation|
45
+ dup = dup_input
46
46
  dup[index]=mutation
47
47
  emit(dup)
48
48
  end
49
49
  end
50
50
  end
51
51
 
52
- end
52
+ end # Element
53
53
 
54
54
  private
55
55
 
56
56
  # Emit mutations
57
- #
57
+ #
58
58
  # @return [undefined]
59
59
  #
60
60
  # @api private
@@ -65,7 +65,7 @@ module Mutant
65
65
  emit([])
66
66
  end
67
67
 
68
- end
69
- end
70
- end
71
- end
68
+ end # Array
69
+ end # Node
70
+ end # Mutant
71
+ end # Mutator
@@ -2,7 +2,7 @@ module Mutant
2
2
  class Mutator
3
3
  class Util
4
4
 
5
- # Mutators that mutates symbol inputs
5
+ # Utility symbol mutator
6
6
  class Symbol < self
7
7
 
8
8
  handle(::Symbol)
@@ -16,24 +16,10 @@ module Mutant
16
16
  # @api private
17
17
  #
18
18
  def dispatch
19
- emit_new { :"s#{Random.hex_string}" } unless ignore?
19
+ emit_new { :"s#{Random.hex_string}" }
20
20
  end
21
21
 
22
- # Test if symbol is ignored
23
- #
24
- # @return [true]
25
- # if symbol begins with an underscore
26
- #
27
- # @return [false]
28
- # otherwise
29
- #
30
- # @api private
31
- #
32
- def ignore?
33
- input.to_s[0] == '_'
34
- end
35
-
36
- end
37
- end
38
- end
39
- end
22
+ end # Symbol
23
+ end # Util
24
+ end # Mutator
25
+ end # Mutant
@@ -23,6 +23,8 @@ module Mutant
23
23
  self
24
24
  end
25
25
 
26
+ private
27
+
26
28
  # Test if mutation is new
27
29
  #
28
30
  # @param [Object] generated
@@ -38,6 +40,7 @@ module Mutant
38
40
  def new?(generated)
39
41
  input != generated
40
42
  end
41
- end
42
- end
43
- end
43
+
44
+ end # Util
45
+ end # Mutator
46
+ end # Mutant
@@ -5,30 +5,30 @@ module Mutant
5
5
 
6
6
  # Run mutator on input
7
7
  #
8
- # @param [Object] input
8
+ # @param [Parser::AST::Node] node
9
9
  # @param [#call] block
10
10
  #
11
11
  # @return [self]
12
12
  #
13
13
  # @api private
14
14
  #
15
- def self.each(input, &block)
16
- return to_enum(__method__, input) unless block_given?
17
- Registry.lookup(input.class).new(input, block)
15
+ def self.each(node, &block)
16
+ return to_enum(__method__, node) unless block_given?
17
+ Registry.lookup(node).new(node, block)
18
18
 
19
19
  self
20
20
  end
21
21
 
22
22
  # Register node class handler
23
23
  #
24
- # @param [Class:Rubinius::AST::Node] node_class
25
- #
26
24
  # @return [undefined]
27
25
  #
28
26
  # @api private
29
27
  #
30
- def self.handle(node_class)
31
- Registry.register(node_class,self)
28
+ def self.handle(*types)
29
+ types.each do |type|
30
+ Registry.register(type, self)
31
+ end
32
32
  end
33
33
  private_class_method :handle
34
34
 
@@ -97,22 +97,6 @@ module Mutant
97
97
  @seen << self.class.identity(object)
98
98
  end
99
99
 
100
- # Test if generated mutation is allowed
101
- #
102
- # @param [Object] object
103
- #
104
- # @return [true]
105
- # if mutation is allowed
106
- #
107
- # @return [false]
108
- # otherwise
109
- #
110
- # @api private
111
- #
112
- def allow?(object)
113
- true
114
- end
115
-
116
100
  # Dispatch node generations
117
101
  #
118
102
  # @return [undefined]
@@ -130,7 +114,7 @@ module Mutant
130
114
  # @api private
131
115
  #
132
116
  def emit(object)
133
- return unless new?(object) and allow?(object)
117
+ return unless new?(object)
134
118
 
135
119
  guard(object)
136
120
 
@@ -171,7 +155,7 @@ module Mutant
171
155
 
172
156
  # Call block with node
173
157
  #
174
- # @param [Rubinius::AST::Node] node
158
+ # @param [Parser::AST::Node] node
175
159
  #
176
160
  # @return [self]
177
161
  #
@@ -202,5 +186,5 @@ module Mutant
202
186
  Helper.deep_clone(input)
203
187
  end
204
188
 
205
- end
206
- end
189
+ end # Mutator
190
+ end # Mutant
@@ -0,0 +1,28 @@
1
+ module Mutant
2
+ # Mixin for node helpers
3
+ module NodeHelpers
4
+
5
+ # Build node
6
+ #
7
+ # @param [Symbol] type
8
+ #
9
+ # @return [Parser::AST::Node]
10
+ #
11
+ # @api private
12
+ #
13
+ def s(type, *children)
14
+ Parser::AST::Node.new(type, children)
15
+ end
16
+ module_function :s
17
+
18
+
19
+ NAN = s(:send, s(:float, 0.0), :/, s(:args, s(:float, 0.0)))
20
+ NEGATIVE_INFINITY = s(:send, s(:float, -1.0), :/, s(:args, s(:float, 0.0)))
21
+ INFINITY = s(:send, s(:float, 1.0), :/, s(:args, s(:float, 0.0)))
22
+ NEW_OBJECT = s(:send, s(:const, s(:cbase), :Object), :new)
23
+
24
+ N_NIL = s(:nil)
25
+ N_EMPTY = s(:empty)
26
+
27
+ end # NodeHelpers
28
+ end # Mutant
data/lib/mutant/random.rb CHANGED
@@ -31,5 +31,6 @@ module Mutant
31
31
  def self.float
32
32
  ::Random.rand
33
33
  end
34
- end
35
- end
34
+
35
+ end # Random
36
+ end # Mutant