mutant 0.9.8 → 0.9.9

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 (161) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +2 -2
  3. data/Changelog.md +6 -0
  4. data/README.md +63 -23
  5. data/config/reek.yml +1 -0
  6. data/lib/mutant.rb +4 -0
  7. data/lib/mutant/ast.rb +0 -9
  8. data/lib/mutant/ast/find_metaclass_containing.rb +48 -0
  9. data/lib/mutant/ast/meta/send.rb +0 -6
  10. data/lib/mutant/bootstrap.rb +0 -36
  11. data/lib/mutant/cli.rb +5 -49
  12. data/lib/mutant/color.rb +0 -3
  13. data/lib/mutant/config.rb +0 -8
  14. data/lib/mutant/context.rb +0 -3
  15. data/lib/mutant/diff.rb +0 -17
  16. data/lib/mutant/env.rb +0 -6
  17. data/lib/mutant/expression/method.rb +6 -6
  18. data/lib/mutant/expression/methods.rb +6 -6
  19. data/lib/mutant/expression/parser.rb +0 -6
  20. data/lib/mutant/integration.rb +0 -18
  21. data/lib/mutant/isolation/fork.rb +0 -22
  22. data/lib/mutant/license.rb +11 -0
  23. data/lib/mutant/matcher.rb +0 -14
  24. data/lib/mutant/matcher/config.rb +0 -11
  25. data/lib/mutant/matcher/method.rb +0 -31
  26. data/lib/mutant/matcher/method/instance.rb +0 -8
  27. data/lib/mutant/matcher/method/metaclass.rb +86 -0
  28. data/lib/mutant/matcher/method/singleton.rb +0 -25
  29. data/lib/mutant/matcher/methods.rb +17 -28
  30. data/lib/mutant/matcher/namespace.rb +0 -10
  31. data/lib/mutant/matcher/scope.rb +2 -4
  32. data/lib/mutant/meta/example/dsl.rb +0 -21
  33. data/lib/mutant/meta/example/verification.rb +0 -20
  34. data/lib/mutant/mutation.rb +0 -3
  35. data/lib/mutant/mutator.rb +1 -29
  36. data/lib/mutant/mutator/node.rb +1 -66
  37. data/lib/mutant/mutator/node/and_asgn.rb +0 -3
  38. data/lib/mutant/mutator/node/argument.rb +0 -15
  39. data/lib/mutant/mutator/node/arguments.rb +0 -20
  40. data/lib/mutant/mutator/node/begin.rb +0 -3
  41. data/lib/mutant/mutator/node/binary.rb +0 -23
  42. data/lib/mutant/mutator/node/block.rb +0 -15
  43. data/lib/mutant/mutator/node/break.rb +0 -3
  44. data/lib/mutant/mutator/node/case.rb +0 -9
  45. data/lib/mutant/mutator/node/class.rb +0 -3
  46. data/lib/mutant/mutator/node/conditional_loop.rb +0 -3
  47. data/lib/mutant/mutator/node/const.rb +0 -3
  48. data/lib/mutant/mutator/node/define.rb +0 -11
  49. data/lib/mutant/mutator/node/defined.rb +0 -3
  50. data/lib/mutant/mutator/node/dstr.rb +0 -3
  51. data/lib/mutant/mutator/node/dsym.rb +0 -3
  52. data/lib/mutant/mutator/node/generic.rb +0 -3
  53. data/lib/mutant/mutator/node/if.rb +0 -12
  54. data/lib/mutant/mutator/node/index.rb +0 -27
  55. data/lib/mutant/mutator/node/kwbegin.rb +0 -3
  56. data/lib/mutant/mutator/node/literal.rb +0 -3
  57. data/lib/mutant/mutator/node/literal/array.rb +0 -6
  58. data/lib/mutant/mutator/node/literal/boolean.rb +0 -4
  59. data/lib/mutant/mutator/node/literal/float.rb +0 -9
  60. data/lib/mutant/mutator/node/literal/hash.rb +0 -9
  61. data/lib/mutant/mutator/node/literal/integer.rb +0 -9
  62. data/lib/mutant/mutator/node/literal/nil.rb +0 -3
  63. data/lib/mutant/mutator/node/literal/range.rb +0 -6
  64. data/lib/mutant/mutator/node/literal/regex.rb +0 -6
  65. data/lib/mutant/mutator/node/literal/string.rb +0 -3
  66. data/lib/mutant/mutator/node/literal/symbol.rb +0 -3
  67. data/lib/mutant/mutator/node/masgn.rb +0 -3
  68. data/lib/mutant/mutator/node/match_current_line.rb +0 -3
  69. data/lib/mutant/mutator/node/mlhs.rb +0 -3
  70. data/lib/mutant/mutator/node/named_value/access.rb +2 -14
  71. data/lib/mutant/mutator/node/named_value/constant_assignment.rb +0 -9
  72. data/lib/mutant/mutator/node/named_value/variable_assignment.rb +0 -6
  73. data/lib/mutant/mutator/node/next.rb +0 -3
  74. data/lib/mutant/mutator/node/noop.rb +0 -3
  75. data/lib/mutant/mutator/node/nthref.rb +0 -3
  76. data/lib/mutant/mutator/node/op_asgn.rb +0 -3
  77. data/lib/mutant/mutator/node/or_asgn.rb +0 -3
  78. data/lib/mutant/mutator/node/procarg_zero.rb +0 -3
  79. data/lib/mutant/mutator/node/regopt.rb +0 -6
  80. data/lib/mutant/mutator/node/resbody.rb +0 -6
  81. data/lib/mutant/mutator/node/rescue.rb +2 -19
  82. data/lib/mutant/mutator/node/return.rb +0 -3
  83. data/lib/mutant/mutator/node/sclass.rb +20 -0
  84. data/lib/mutant/mutator/node/send.rb +2 -61
  85. data/lib/mutant/mutator/node/send/attribute_assignment.rb +0 -9
  86. data/lib/mutant/mutator/node/send/binary.rb +0 -11
  87. data/lib/mutant/mutator/node/send/conditional.rb +0 -3
  88. data/lib/mutant/mutator/node/splat.rb +0 -3
  89. data/lib/mutant/mutator/node/super.rb +0 -3
  90. data/lib/mutant/mutator/node/when.rb +0 -19
  91. data/lib/mutant/mutator/node/yield.rb +0 -3
  92. data/lib/mutant/mutator/node/zsuper.rb +0 -3
  93. data/lib/mutant/mutator/util/array.rb +0 -6
  94. data/lib/mutant/mutator/util/symbol.rb +0 -3
  95. data/lib/mutant/parallel.rb +0 -13
  96. data/lib/mutant/parallel/driver.rb +0 -10
  97. data/lib/mutant/parallel/worker.rb +0 -22
  98. data/lib/mutant/reporter/cli.rb +0 -5
  99. data/lib/mutant/reporter/cli/format.rb +0 -9
  100. data/lib/mutant/reporter/cli/printer.rb +0 -40
  101. data/lib/mutant/reporter/cli/printer/env_progress.rb +0 -15
  102. data/lib/mutant/reporter/cli/printer/isolation_result.rb +0 -18
  103. data/lib/mutant/reporter/cli/printer/mutation_progress_result.rb +0 -5
  104. data/lib/mutant/reporter/cli/printer/mutation_result.rb +0 -21
  105. data/lib/mutant/reporter/cli/printer/status_progressive.rb +0 -8
  106. data/lib/mutant/reporter/cli/printer/subject_progress.rb +0 -9
  107. data/lib/mutant/repository/diff.rb +1 -13
  108. data/lib/mutant/repository/diff/ranges.rb +0 -11
  109. data/lib/mutant/result.rb +0 -3
  110. data/lib/mutant/runner.rb +0 -18
  111. data/lib/mutant/runner/sink.rb +0 -5
  112. data/lib/mutant/subject.rb +0 -8
  113. data/lib/mutant/subject/method.rb +0 -3
  114. data/lib/mutant/subject/method/instance.rb +0 -5
  115. data/lib/mutant/subject/method/metaclass.rb +30 -0
  116. data/lib/mutant/transform.rb +0 -92
  117. data/lib/mutant/version.rb +1 -1
  118. data/lib/mutant/warnings.rb +0 -6
  119. data/lib/mutant/zombifier.rb +2 -34
  120. data/meta/and.rb +0 -2
  121. data/meta/array.rb +0 -3
  122. data/meta/begin.rb +0 -3
  123. data/meta/block.rb +0 -3
  124. data/meta/break.rb +0 -1
  125. data/meta/case.rb +0 -6
  126. data/meta/casgn.rb +0 -3
  127. data/meta/cvasgn.rb +0 -1
  128. data/meta/def.rb +0 -7
  129. data/meta/ensure.rb +0 -1
  130. data/meta/false.rb +0 -1
  131. data/meta/gvasgn.rb +0 -1
  132. data/meta/hash.rb +0 -4
  133. data/meta/if.rb +0 -5
  134. data/meta/ivasgn.rb +0 -1
  135. data/meta/kwbegin.rb +0 -1
  136. data/meta/lvasgn.rb +0 -1
  137. data/meta/match_current_line.rb +0 -1
  138. data/meta/next.rb +0 -1
  139. data/meta/or.rb +0 -2
  140. data/meta/regexp.rb +0 -1
  141. data/meta/rescue.rb +0 -6
  142. data/meta/sclass.rb +12 -0
  143. data/meta/send.rb +0 -4
  144. data/meta/true.rb +0 -1
  145. data/meta/until.rb +0 -1
  146. data/meta/while.rb +0 -2
  147. data/meta/yield.rb +0 -1
  148. data/mutant.sh +12 -0
  149. data/spec/unit/mutant/ast/find_metaclass_containing_spec.rb +64 -0
  150. data/spec/unit/mutant/expression/methods_spec.rb +7 -2
  151. data/spec/unit/mutant/license_spec.rb +15 -3
  152. data/spec/unit/mutant/matcher/method/metaclass_spec.rb +108 -0
  153. data/spec/unit/mutant/matcher/methods/metaclass_spec.rb +62 -0
  154. data/spec/unit/mutant/matcher/namespace_spec.rb +3 -1
  155. data/spec/unit/mutant/matcher/scope_spec.rb +11 -1
  156. data/spec/unit/mutant/meta/example_spec.rb +3 -3
  157. data/spec/unit/mutant/mutator/node_spec.rb +1 -6
  158. data/spec/unit/mutant/subject/method/metaclass_spec.rb +63 -0
  159. data/test_app/lib/test_app.rb +1 -0
  160. data/test_app/lib/test_app/metaclasses.rb +108 -0
  161. metadata +17 -2
@@ -25,18 +25,12 @@ module Mutant
25
25
 
26
26
  private
27
27
 
28
- # Emit mutations
29
- #
30
- # @return [undefined]
31
28
  def dispatch
32
29
  emit_singletons
33
30
  mutate_name
34
31
  emit_value_mutations if value # op asgn!
35
32
  end
36
33
 
37
- # Emit name mutations
38
- #
39
- # @return [undefined]
40
34
  def mutate_name
41
35
  prefix, regexp = MAP.fetch(node.type)
42
36
  stripped = name.to_s.sub(regexp, EMPTY_STRING)
@@ -11,9 +11,6 @@ module Mutant
11
11
 
12
12
  private
13
13
 
14
- # Emit mutations
15
- #
16
- # @return [undefined]
17
14
  def dispatch
18
15
  super()
19
16
  emit_singletons
@@ -11,9 +11,6 @@ module Mutant
11
11
 
12
12
  private
13
13
 
14
- # Emit mutations
15
- #
16
- # @return [undefined]
17
14
  def dispatch
18
15
  # noop
19
16
  end
@@ -12,9 +12,6 @@ module Mutant
12
12
 
13
13
  private
14
14
 
15
- # Emit mutations
16
- #
17
- # @return [undefined]
18
15
  def dispatch
19
16
  unless number.equal?(1)
20
17
  emit_number(number - 1)
@@ -13,9 +13,6 @@ module Mutant
13
13
 
14
14
  private
15
15
 
16
- # Emit mutations
17
- #
18
- # @return [undefined]
19
16
  def dispatch
20
17
  emit_singletons
21
18
  emit_left_mutations do |node|
@@ -13,9 +13,6 @@ module Mutant
13
13
 
14
14
  private
15
15
 
16
- # Emit mutations
17
- #
18
- # @return [undefined]
19
16
  def dispatch
20
17
  emit_singletons
21
18
  emit_right_mutations
@@ -17,9 +17,6 @@ module Mutant
17
17
 
18
18
  private
19
19
 
20
- # Emit mutations
21
- #
22
- # @return [undefined]
23
20
  def dispatch
24
21
  name = Mutant::Util.one(argument.children)
25
22
 
@@ -13,16 +13,10 @@ module Mutant
13
13
 
14
14
  private
15
15
 
16
- # Emit mutations
17
- #
18
- # @return [undefined]
19
16
  def dispatch
20
17
  emit_type(*mutated_flags)
21
18
  end
22
19
 
23
- # Altered flags array excluding case insensitive flag
24
- #
25
- # @return [Array<Symbol>]
26
20
  def mutated_flags
27
21
  (children - MUTATED_FLAGS)
28
22
  end
@@ -12,18 +12,12 @@ module Mutant
12
12
 
13
13
  private
14
14
 
15
- # Emit mutations
16
- #
17
- # @return [undefined]
18
15
  def dispatch
19
16
  emit_assignment(nil)
20
17
  emit_body_mutations if body
21
18
  mutate_captures
22
19
  end
23
20
 
24
- # Mutate captures
25
- #
26
- # @return [undefined]
27
21
  def mutate_captures
28
22
  return unless captures
29
23
  Util::Array::Element.call(captures.children).each do |matchers|
@@ -14,20 +14,14 @@ module Mutant
14
14
 
15
15
  RESCUE_INDICES = (1..-2).freeze
16
16
 
17
- # Emit mutations
18
- #
19
- # @return [undefined]
17
+ private
18
+
20
19
  def dispatch
21
20
  mutate_body
22
21
  mutate_rescue_bodies
23
22
  mutate_else_body
24
23
  end
25
24
 
26
- private
27
-
28
- # Mutate child by name
29
- #
30
- # @return [undefined]
31
25
  def mutate_rescue_bodies
32
26
  children_indices(RESCUE_INDICES).each do |index|
33
27
  mutate_child(index)
@@ -36,11 +30,6 @@ module Mutant
36
30
  end
37
31
  end
38
32
 
39
- # Emit concatenation with body
40
- #
41
- # @param [Parser::AST::Node] child
42
- #
43
- # @return [undefined]
44
33
  def emit_concat(child)
45
34
  if body
46
35
  emit(s(:begin, body, child))
@@ -49,18 +38,12 @@ module Mutant
49
38
  end
50
39
  end
51
40
 
52
- # Emit body mutations
53
- #
54
- # @return [undefined]
55
41
  def mutate_body
56
42
  return unless body
57
43
  emit_body_mutations
58
44
  emit(body)
59
45
  end
60
46
 
61
- # Emit else body mutations
62
- #
63
- # @return [undefined]
64
47
  def mutate_else_body
65
48
  return unless else_body
66
49
  emit_else_body_mutations
@@ -12,9 +12,6 @@ module Mutant
12
12
 
13
13
  private
14
14
 
15
- # Emit mutations
16
- #
17
- # @return [undefined]
18
15
  def dispatch
19
16
  emit_singletons
20
17
  return unless value
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Mutant
4
+ class Mutator
5
+ class Node
6
+ # Namespace for singleton class mutations (class << some_obj)
7
+ class Sclass < self
8
+ handle :sclass
9
+
10
+ children :expr, :body
11
+
12
+ private
13
+
14
+ def dispatch
15
+ emit_body_mutations if body
16
+ end
17
+ end # Class
18
+ end # Node
19
+ end # Mutator
20
+ end # Mutant
@@ -36,8 +36,8 @@ module Mutant
36
36
  :== => %i[eql? equal?],
37
37
  :>= => %i[> == eql? equal?],
38
38
  :<= => %i[< == eql? equal?],
39
- :> => %i[== >= eql? equal?],
40
- :< => %i[== <= eql? equal?]
39
+ :> => %i[== eql? equal?],
40
+ :< => %i[== eql? equal?]
41
41
  )
42
42
 
43
43
  RECEIVER_SELECTOR_REPLACEMENTS = IceNine.deep_freeze(
@@ -48,9 +48,6 @@ module Mutant
48
48
 
49
49
  private
50
50
 
51
- # Emit mutations
52
- #
53
- # @return [undefined]
54
51
  def dispatch
55
52
  emit_singletons
56
53
 
@@ -63,23 +60,14 @@ module Mutant
63
60
  end
64
61
  end
65
62
 
66
- # AST metadata for node
67
- #
68
- # @return [AST::Meta::Send]
69
63
  def meta
70
64
  AST::Meta::Send.new(node)
71
65
  end
72
66
  memoize :meta
73
67
 
74
- # Arguments being send
75
- #
76
- # @return [Enumerable<Parser::AST::Node>]
77
68
  alias_method :arguments, :remaining_children
78
69
  private :arguments
79
70
 
80
- # Perform normal, non special case dispatch
81
- #
82
- # @return [undefined]
83
71
  def normal_dispatch
84
72
  emit_naked_receiver
85
73
  emit_selector_replacement
@@ -90,9 +78,6 @@ module Mutant
90
78
  mutate_arguments
91
79
  end
92
80
 
93
- # Emit mutations which only correspond to one selector
94
- #
95
- # @return [undefined]
96
81
  def emit_selector_specific_mutations
97
82
  emit_const_get_mutation
98
83
  emit_integer_mutation
@@ -101,9 +86,6 @@ module Mutant
101
86
  emit_lambda_mutation
102
87
  end
103
88
 
104
- # Emit selector mutations specific to top level constants
105
- #
106
- # @return [undefined]
107
89
  def emit_receiver_selector_mutations
108
90
  return unless meta.receiver_possible_top_level_const?
109
91
 
@@ -113,9 +95,6 @@ module Mutant
113
95
  .each(&method(:emit_selector))
114
96
  end
115
97
 
116
- # Emit mutation from `!!foo` to `foo`
117
- #
118
- # @return [undefined]
119
98
  def emit_double_negation_mutation
120
99
  return unless selector.equal?(:!) && n_send?(receiver)
121
100
 
@@ -123,19 +102,10 @@ module Mutant
123
102
  emit(negated.receiver) if negated.selector.equal?(:!)
124
103
  end
125
104
 
126
- # Emit mutation from proc definition to lambda
127
- #
128
- # @return [undefined]
129
105
  def emit_lambda_mutation
130
106
  emit(s(:send, nil, :lambda)) if meta.proc?
131
107
  end
132
108
 
133
- # Emit mutation for `#dig`
134
- #
135
- # - Mutates `foo.dig(a, b)` to `foo.fetch(a).dig(b)`
136
- # - Mutates `foo.dig(a)` to `foo.fetch(a)`
137
- #
138
- # @return [undefined]
139
109
  def emit_dig_mutation
140
110
  return if !selector.equal?(:dig) || arguments.none?
141
111
 
@@ -148,41 +118,26 @@ module Mutant
148
118
  emit(s(:send, fetch_mutation, :dig, *tail))
149
119
  end
150
120
 
151
- # Emit mutation from `to_i` to `Integer(...)`
152
- #
153
- # @return [undefined]
154
121
  def emit_integer_mutation
155
122
  return unless selector.equal?(:to_i)
156
123
 
157
124
  emit(s(:send, nil, :Integer, receiver))
158
125
  end
159
126
 
160
- # Emit mutation from `const_get` to const literal
161
- #
162
- # @return [undefined]
163
127
  def emit_const_get_mutation
164
128
  return unless selector.equal?(:const_get) && n_sym?(arguments.first)
165
129
 
166
130
  emit(s(:const, receiver, AST::Meta::Symbol.new(arguments.first).name))
167
131
  end
168
132
 
169
- # Emit selector replacement
170
- #
171
- # @return [undefined]
172
133
  def emit_selector_replacement
173
134
  SELECTOR_REPLACEMENTS.fetch(selector, EMPTY_ARRAY).each(&method(:emit_selector))
174
135
  end
175
136
 
176
- # Emit naked receiver mutation
177
- #
178
- # @return [undefined]
179
137
  def emit_naked_receiver
180
138
  emit(receiver) if receiver
181
139
  end
182
140
 
183
- # Mutate arguments
184
- #
185
- # @return [undefined]
186
141
  def mutate_arguments
187
142
  emit_type(receiver, selector)
188
143
  remaining_children_with_index.each do |_node, index|
@@ -191,25 +146,14 @@ module Mutant
191
146
  end
192
147
  end
193
148
 
194
- # Mutate argument
195
- #
196
- # @param [Integer] index
197
- #
198
- # @return [undefined]
199
149
  def mutate_argument_index(index)
200
150
  mutate_child(index) { |node| !n_begin?(node) }
201
151
  end
202
152
 
203
- # Emit argument propagation
204
- #
205
- # @return [undefined]
206
153
  def emit_argument_propagation
207
154
  emit_propagation(Mutant::Util.one(arguments)) if arguments.one?
208
155
  end
209
156
 
210
- # Emit receiver mutations
211
- #
212
- # @return [undefined]
213
157
  def mutate_receiver
214
158
  return unless receiver
215
159
  emit_implicit_self
@@ -218,9 +162,6 @@ module Mutant
218
162
  end
219
163
  end
220
164
 
221
- # Emit implicit self mutation
222
- #
223
- # @return [undefined]
224
165
  def emit_implicit_self
225
166
  emit_receiver(nil) if n_self?(receiver) && !(
226
167
  KEYWORDS.include?(selector) ||
@@ -12,26 +12,17 @@ module Mutant
12
12
 
13
13
  private
14
14
 
15
- # Emit mutations
16
- #
17
- # @return [undefined]
18
15
  def dispatch
19
16
  normal_dispatch
20
17
  emit_attribute_read
21
18
  end
22
19
 
23
- # Mutate arguments
24
- #
25
- # @return [undefined]
26
20
  def mutate_arguments
27
21
  remaining_children_indices.each do |index|
28
22
  mutate_child(index)
29
23
  end
30
24
  end
31
25
 
32
- # Emit attribute read
33
- #
34
- # @return [undefined]
35
26
  def emit_attribute_read
36
27
  emit_type(receiver, selector[ATTRIBUTE_RANGE].to_sym)
37
28
  end
@@ -12,9 +12,6 @@ module Mutant
12
12
 
13
13
  private
14
14
 
15
- # Emit mutations
16
- #
17
- # @return [undefined]
18
15
  def dispatch
19
16
  emit(left)
20
17
  emit_left_mutations
@@ -24,9 +21,6 @@ module Mutant
24
21
  emit_not_equality_mutations
25
22
  end
26
23
 
27
- # Emit mutations for `!=`
28
- #
29
- # @return [undefined]
30
24
  def emit_not_equality_mutations
31
25
  return unless operator.equal?(:'!=')
32
26
 
@@ -34,11 +28,6 @@ module Mutant
34
28
  emit_not_equality_mutation(:equal?)
35
29
  end
36
30
 
37
- # Emit negated method sends with specified operator
38
- #
39
- # @param new_operator [Symbol] selector to be negated
40
- #
41
- # @return [undefined]
42
31
  def emit_not_equality_mutation(new_operator)
43
32
  emit(n_not(s(:send, left, new_operator, right)))
44
33
  end
@@ -10,9 +10,6 @@ module Mutant
10
10
 
11
11
  private
12
12
 
13
- # Emit mutations
14
- #
15
- # @return [undefined]
16
13
  def dispatch
17
14
  super()
18
15
  emit(s(:send, *children))
@@ -12,9 +12,6 @@ module Mutant
12
12
 
13
13
  private
14
14
 
15
- # Emit mutations
16
- #
17
- # @return [undefined]
18
15
  def dispatch
19
16
  emit_singletons
20
17
  emit_expression_mutations