mutant 0.2.20 → 0.3.0.beta2

Sign up to get free protection for your applications and to get access to all the features.
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