mutant 0.14.2 → 0.15.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.
- checksums.yaml +4 -4
- data/VERSION +1 -1
- data/lib/mutant/ast/named_children.rb +0 -4
- data/lib/mutant/ast/nodes.rb +5 -0
- data/lib/mutant/ast/pattern/lexer.rb +0 -1
- data/lib/mutant/ast/structure.rb +10 -0
- data/lib/mutant/context.rb +2 -6
- data/lib/mutant/env.rb +8 -27
- data/lib/mutant/hooks.rb +2 -6
- data/lib/mutant/integration/null.rb +1 -3
- data/lib/mutant/integration.rb +2 -6
- data/lib/mutant/isolation/fork.rb +0 -2
- data/lib/mutant/matcher/method/instance.rb +2 -2
- data/lib/mutant/matcher/method.rb +0 -1
- data/lib/mutant/meta/example/verification.rb +0 -1
- data/lib/mutant/mutation/operators.rb +141 -44
- data/lib/mutant/mutation.rb +6 -18
- data/lib/mutant/mutator/node/and_asgn.rb +1 -0
- data/lib/mutant/mutator/node/binary.rb +5 -0
- data/lib/mutant/mutator/node/block.rb +10 -0
- data/lib/mutant/mutator/node/case_match.rb +46 -0
- data/lib/mutant/mutator/node/conditional_loop.rb +30 -1
- data/lib/mutant/mutator/node/define.rb +26 -0
- data/lib/mutant/mutator/node/defined.rb +1 -0
- data/lib/mutant/mutator/node/ensure.rb +24 -0
- data/lib/mutant/mutator/node/guard.rb +23 -0
- data/lib/mutant/mutator/node/in_pattern.rb +25 -0
- data/lib/mutant/mutator/node/literal/complex.rb +31 -0
- data/lib/mutant/mutator/node/literal/rational.rb +31 -0
- data/lib/mutant/mutator/node/literal/string.rb +1 -0
- data/lib/mutant/mutator/node/match_alt.rb +26 -0
- data/lib/mutant/mutator/node/match_pattern_p.rb +25 -0
- data/lib/mutant/mutator/node/op_asgn.rb +21 -1
- data/lib/mutant/mutator/node/or_asgn.rb +1 -4
- data/lib/mutant/mutator/node/regopt.rb +4 -6
- data/lib/mutant/mutator/node/rescue.rb +27 -0
- data/lib/mutant/mutator/node/send/binary.rb +45 -0
- data/lib/mutant/mutator/node/send.rb +23 -7
- data/lib/mutant/mutator/node/super.rb +2 -0
- data/lib/mutant/mutator/node/zsuper.rb +17 -0
- data/lib/mutant/mutator/node.rb +3 -9
- data/lib/mutant/mutator.rb +1 -3
- data/lib/mutant/parallel/connection.rb +9 -23
- data/lib/mutant/parallel/driver.rb +1 -5
- data/lib/mutant/parallel/source.rb +2 -1
- data/lib/mutant/parallel/worker.rb +8 -14
- data/lib/mutant/registry.rb +2 -1
- data/lib/mutant/reporter/cli/format.rb +4 -12
- data/lib/mutant/reporter/cli/printer.rb +2 -6
- data/lib/mutant/reporter/cli/progress_bar.rb +4 -12
- data/lib/mutant/reporter/cli.rb +6 -23
- data/lib/mutant/reporter/sequence.rb +1 -3
- data/lib/mutant/repository/diff.rb +1 -3
- data/lib/mutant/result.rb +16 -48
- data/lib/mutant/scope.rb +2 -6
- data/lib/mutant/segment.rb +1 -3
- data/lib/mutant/subject/method/instance.rb +3 -9
- data/lib/mutant/subject/method/metaclass.rb +1 -4
- data/lib/mutant/subject/method/singleton.rb +2 -8
- data/lib/mutant/subject/method.rb +3 -9
- data/lib/mutant/subject.rb +6 -18
- data/lib/mutant/timer.rb +2 -6
- data/lib/mutant/transform.rb +11 -33
- data/lib/mutant/usage.rb +6 -18
- data/lib/mutant/variable.rb +2 -6
- data/lib/mutant/world.rb +1 -3
- data/lib/mutant/zombifier.rb +3 -1
- data/lib/mutant.rb +8 -0
- metadata +39 -13
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: cdcb7051e04dfb3ff669e6f673f13837725981be61745b633fda8c00122bb439
|
|
4
|
+
data.tar.gz: bc51f9a72c0163a1bae7f56f56ce10a06cf825281d1248b380048237394e404c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 6482d04cf00047a75531c116439726545e2955b0a0df5a9104f855b29720d30d61cc7779b4adaca2982596544bf5b46dc7f34f9d42eb2f187c973bf4288051dc
|
|
7
|
+
data.tar.gz: a805ae81a1f767004c37305555778aab712f58684f0cee50bfe9428f6dd9ab8979796ffdcaa4436510e579752b2a7c2e6331b37dc4af3ced942f3ae67536c906
|
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.
|
|
1
|
+
0.15.0
|
|
@@ -55,10 +55,6 @@ module Mutant
|
|
|
55
55
|
#
|
|
56
56
|
# @return [undefined]
|
|
57
57
|
def define_remaining_children(names)
|
|
58
|
-
define_private_method(:remaining_children_with_index) do
|
|
59
|
-
children.each_with_index.drop(names.length)
|
|
60
|
-
end
|
|
61
|
-
|
|
62
58
|
define_private_method(:remaining_children_indices) do
|
|
63
59
|
children.each_index.drop(names.length)
|
|
64
60
|
end
|
data/lib/mutant/ast/nodes.rb
CHANGED
|
@@ -17,6 +17,11 @@ module Mutant
|
|
|
17
17
|
N_SELF = s(:self)
|
|
18
18
|
N_ZSUPER = s(:zsuper)
|
|
19
19
|
N_EMPTY_SUPER = s(:super)
|
|
20
|
+
N_EMPTY_ARRAY = s(:array)
|
|
21
|
+
N_EMPTY_HASH = s(:hash)
|
|
22
|
+
N_EMPTY_STRING = s(:str, '')
|
|
23
|
+
N_ZERO_INTEGER = s(:int, 0)
|
|
24
|
+
N_ZERO_FLOAT = s(:float, 0.0)
|
|
20
25
|
|
|
21
26
|
end # Nodes
|
|
22
27
|
end # AST
|
data/lib/mutant/ast/structure.rb
CHANGED
|
@@ -463,6 +463,11 @@ module Mutant
|
|
|
463
463
|
),
|
|
464
464
|
variable: nil
|
|
465
465
|
),
|
|
466
|
+
Node.new(
|
|
467
|
+
type: :if_guard,
|
|
468
|
+
fixed: Node.fixed([[Node::Fixed::Descendant, :condition]]),
|
|
469
|
+
variable: nil
|
|
470
|
+
),
|
|
466
471
|
Node.new(
|
|
467
472
|
type: :in_pattern,
|
|
468
473
|
fixed: Node.fixed(
|
|
@@ -849,6 +854,11 @@ module Mutant
|
|
|
849
854
|
),
|
|
850
855
|
variable: nil
|
|
851
856
|
),
|
|
857
|
+
Node.new(
|
|
858
|
+
type: :unless_guard,
|
|
859
|
+
fixed: Node.fixed([[Node::Fixed::Descendant, :condition]]),
|
|
860
|
+
variable: nil
|
|
861
|
+
),
|
|
852
862
|
Node.new(
|
|
853
863
|
type: :when,
|
|
854
864
|
fixed: [Node::Fixed::Descendant.new(index: -1, name: :body)],
|
data/lib/mutant/context.rb
CHANGED
|
@@ -33,9 +33,7 @@ module Mutant
|
|
|
33
33
|
end
|
|
34
34
|
end
|
|
35
35
|
|
|
36
|
-
def match_expressions
|
|
37
|
-
scope.match_expressions
|
|
38
|
-
end
|
|
36
|
+
def match_expressions = scope.match_expressions
|
|
39
37
|
|
|
40
38
|
# Return root node for mutation
|
|
41
39
|
#
|
|
@@ -47,9 +45,7 @@ module Mutant
|
|
|
47
45
|
# Identification string
|
|
48
46
|
#
|
|
49
47
|
# @return [String]
|
|
50
|
-
def identification
|
|
51
|
-
scope.raw.name
|
|
52
|
-
end
|
|
48
|
+
def identification = scope.raw.name
|
|
53
49
|
|
|
54
50
|
end # Context
|
|
55
51
|
end # Mutant
|
data/lib/mutant/env.rb
CHANGED
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
module Mutant
|
|
4
4
|
# Mutation testing execution environment
|
|
5
|
-
# rubocop:disable Metrics/ClassLength
|
|
6
5
|
class Env
|
|
7
6
|
include Adamantium, Anima.new(
|
|
8
7
|
:config,
|
|
@@ -93,57 +92,42 @@ module Mutant
|
|
|
93
92
|
# @param [String] warning
|
|
94
93
|
#
|
|
95
94
|
# @return [self]
|
|
96
|
-
def warn(message)
|
|
97
|
-
config.reporter.warn(message)
|
|
98
|
-
self
|
|
99
|
-
end
|
|
95
|
+
def warn(message) = tap { config.reporter.warn(message) }
|
|
100
96
|
|
|
101
97
|
# Selected tests
|
|
102
98
|
#
|
|
103
99
|
# @return [Set<Test>]
|
|
104
|
-
def selected_tests
|
|
105
|
-
selections.values.flatten.to_set
|
|
106
|
-
end
|
|
100
|
+
def selected_tests = selections.values.flatten.to_set
|
|
107
101
|
memoize :selected_tests
|
|
108
102
|
|
|
109
103
|
# Amount of mutations
|
|
110
104
|
#
|
|
111
105
|
# @return [Integer]
|
|
112
|
-
def amount_mutations
|
|
113
|
-
mutations.length
|
|
114
|
-
end
|
|
106
|
+
def amount_mutations = mutations.length
|
|
115
107
|
memoize :amount_mutations
|
|
116
108
|
|
|
117
109
|
# Amount of all tests the integration provides
|
|
118
110
|
#
|
|
119
111
|
# @return [Integer]
|
|
120
|
-
def amount_all_tests
|
|
121
|
-
integration.all_tests.length
|
|
122
|
-
end
|
|
112
|
+
def amount_all_tests = integration.all_tests.length
|
|
123
113
|
memoize :amount_all_tests
|
|
124
114
|
|
|
125
115
|
# Amount of tests available for mutation testing
|
|
126
116
|
#
|
|
127
117
|
# @return [Integer]
|
|
128
|
-
def amount_available_tests
|
|
129
|
-
integration.available_tests.length
|
|
130
|
-
end
|
|
118
|
+
def amount_available_tests = integration.available_tests.length
|
|
131
119
|
memoize :amount_available_tests
|
|
132
120
|
|
|
133
121
|
# Amount of selected subjects
|
|
134
122
|
#
|
|
135
123
|
# @return [Integer]
|
|
136
|
-
def amount_subjects
|
|
137
|
-
subjects.length
|
|
138
|
-
end
|
|
124
|
+
def amount_subjects = subjects.length
|
|
139
125
|
memoize :amount_subjects
|
|
140
126
|
|
|
141
127
|
# Amount of selected tests
|
|
142
128
|
#
|
|
143
129
|
# @return [Integer]
|
|
144
|
-
def amount_selected_tests
|
|
145
|
-
selected_tests.length
|
|
146
|
-
end
|
|
130
|
+
def amount_selected_tests = selected_tests.length
|
|
147
131
|
memoize :amount_selected_tests
|
|
148
132
|
|
|
149
133
|
# Ratio between selected tests and subjects
|
|
@@ -180,9 +164,6 @@ module Mutant
|
|
|
180
164
|
end
|
|
181
165
|
end
|
|
182
166
|
|
|
183
|
-
def timer
|
|
184
|
-
world.timer
|
|
185
|
-
end
|
|
167
|
+
def timer = world.timer
|
|
186
168
|
end # Env
|
|
187
|
-
# rubocop:enable Metrics/ClassLength
|
|
188
169
|
end # Mutant
|
data/lib/mutant/hooks.rb
CHANGED
|
@@ -45,9 +45,7 @@ module Mutant
|
|
|
45
45
|
end
|
|
46
46
|
|
|
47
47
|
class Builder
|
|
48
|
-
def initialize
|
|
49
|
-
@map = DEFAULTS.transform_values(&:dup)
|
|
50
|
-
end
|
|
48
|
+
def initialize = @map = DEFAULTS.transform_values(&:dup)
|
|
51
49
|
|
|
52
50
|
def register(name, &block)
|
|
53
51
|
Hooks.assert_name(name)
|
|
@@ -57,9 +55,7 @@ module Mutant
|
|
|
57
55
|
self
|
|
58
56
|
end
|
|
59
57
|
|
|
60
|
-
def to_hooks
|
|
61
|
-
Hooks.new(map: @map.transform_values(&:freeze).freeze)
|
|
62
|
-
end
|
|
58
|
+
def to_hooks = Hooks.new(map: @map.transform_values(&:freeze).freeze)
|
|
63
59
|
end # Builder
|
|
64
60
|
|
|
65
61
|
# rubocop:disable Security/Eval
|
data/lib/mutant/integration.rb
CHANGED
|
@@ -110,9 +110,7 @@ module Mutant
|
|
|
110
110
|
# Perform integration setup
|
|
111
111
|
#
|
|
112
112
|
# @return [self]
|
|
113
|
-
def setup
|
|
114
|
-
self
|
|
115
|
-
end
|
|
113
|
+
def setup = self
|
|
116
114
|
|
|
117
115
|
# Run a collection of tests
|
|
118
116
|
#
|
|
@@ -138,8 +136,6 @@ module Mutant
|
|
|
138
136
|
|
|
139
137
|
private
|
|
140
138
|
|
|
141
|
-
def timer
|
|
142
|
-
world.timer
|
|
143
|
-
end
|
|
139
|
+
def timer = world.timer
|
|
144
140
|
end # Integration
|
|
145
141
|
end # Mutant
|
|
@@ -64,7 +64,6 @@ module Mutant
|
|
|
64
64
|
end
|
|
65
65
|
end # Pipe
|
|
66
66
|
|
|
67
|
-
# rubocop:disable Metrics/ClassLength
|
|
68
67
|
class Parent
|
|
69
68
|
include(Anima.new(*ATTRIBUTES), Procto)
|
|
70
69
|
|
|
@@ -206,7 +205,6 @@ module Mutant
|
|
|
206
205
|
status
|
|
207
206
|
end
|
|
208
207
|
end # Parent
|
|
209
|
-
# rubocop:enable Metrics/ClassLength
|
|
210
208
|
|
|
211
209
|
class Child
|
|
212
210
|
include(Adamantium, Anima.new(*ATTRIBUTES), Procto)
|
|
@@ -52,9 +52,9 @@ module Mutant
|
|
|
52
52
|
end
|
|
53
53
|
|
|
54
54
|
def visibility
|
|
55
|
-
if scope.raw.
|
|
55
|
+
if scope.raw.private_method_defined?(method_name)
|
|
56
56
|
:private
|
|
57
|
-
elsif scope.raw.
|
|
57
|
+
elsif scope.raw.protected_method_defined?(method_name)
|
|
58
58
|
:protected
|
|
59
59
|
else
|
|
60
60
|
:public
|
|
@@ -10,47 +10,146 @@ module Mutant
|
|
|
10
10
|
NAME = :full
|
|
11
11
|
|
|
12
12
|
SELECTOR_REPLACEMENTS = {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
13
|
+
:!= => %i[==],
|
|
14
|
+
:** => %i[*],
|
|
15
|
+
:% => %i[/],
|
|
16
|
+
:& => %i[| ^],
|
|
17
|
+
:* => %i[/],
|
|
18
|
+
:+ => %i[-],
|
|
19
|
+
:- => %i[+],
|
|
20
|
+
:/ => %i[*],
|
|
21
|
+
:< => %i[== eql? equal?],
|
|
22
|
+
:<< => %i[>>],
|
|
23
|
+
:<= => %i[< == eql? equal?],
|
|
24
|
+
:== => %i[!= eql? equal?],
|
|
25
|
+
:=== => %i[is_a?],
|
|
26
|
+
:=~ => %i[match?],
|
|
27
|
+
:> => %i[== eql? equal?],
|
|
28
|
+
:>= => %i[> == eql? equal?],
|
|
29
|
+
:>> => %i[<<],
|
|
30
|
+
:^ => %i[& |],
|
|
31
|
+
:| => %i[& ^],
|
|
32
|
+
__send__: %i[public_send],
|
|
33
|
+
all?: %i[any? none?],
|
|
34
|
+
any?: %i[all? empty? none?],
|
|
35
|
+
append: %i[prepend],
|
|
36
|
+
assoc: %i[rassoc],
|
|
37
|
+
at: %i[fetch key?],
|
|
38
|
+
bytes: %i[chars],
|
|
39
|
+
# Bang to non-bang mutations (Array methods)
|
|
40
|
+
capitalize!: %i[capitalize],
|
|
41
|
+
chars: %i[bytes],
|
|
42
|
+
chomp!: %i[chomp],
|
|
43
|
+
chop!: %i[chop],
|
|
44
|
+
chunk: %i[each],
|
|
45
|
+
chunk_while: %i[each],
|
|
46
|
+
collect: %i[each],
|
|
47
|
+
collect!: %i[collect],
|
|
48
|
+
collect_concat: %i[collect],
|
|
49
|
+
compact!: %i[compact],
|
|
50
|
+
ceil: %i[floor],
|
|
51
|
+
count: %i[size length],
|
|
52
|
+
delete!: %i[delete],
|
|
53
|
+
delete_if: %i[reject],
|
|
54
|
+
detect: %i[first last],
|
|
55
|
+
downcase: %i[upcase],
|
|
56
|
+
downcase!: %i[downcase],
|
|
57
|
+
drop: %i[take],
|
|
58
|
+
each_key: %i[each_value],
|
|
59
|
+
each_cons: %i[each],
|
|
60
|
+
each_slice: %i[each],
|
|
61
|
+
each_with_index: %i[each],
|
|
62
|
+
each_value: %i[each_key],
|
|
63
|
+
each_with_object: %i[each],
|
|
64
|
+
empty?: %i[any?],
|
|
65
|
+
encode!: %i[encode],
|
|
66
|
+
end_with?: %i[start_with?],
|
|
67
|
+
even?: %i[odd?],
|
|
68
|
+
fetch: %i[key?],
|
|
69
|
+
filter: %i[reject],
|
|
70
|
+
filter!: %i[filter],
|
|
71
|
+
filter_map: %i[map],
|
|
72
|
+
find: %i[first last],
|
|
73
|
+
first: %i[last],
|
|
74
|
+
flat_map: %i[map],
|
|
75
|
+
flatten!: %i[flatten],
|
|
76
|
+
floor: %i[ceil],
|
|
77
|
+
grep: %i[grep_v],
|
|
78
|
+
grep_v: %i[grep],
|
|
79
|
+
gsub: %i[sub],
|
|
80
|
+
gsub!: %i[gsub],
|
|
81
|
+
is_a?: %i[instance_of?],
|
|
82
|
+
keep_if: %i[select],
|
|
83
|
+
keys: %i[values],
|
|
84
|
+
kind_of?: %i[instance_of?],
|
|
85
|
+
last: %i[first],
|
|
86
|
+
lstrip!: %i[lstrip],
|
|
87
|
+
map: %i[each],
|
|
88
|
+
map!: %i[map],
|
|
89
|
+
match: %i[match?],
|
|
90
|
+
max: %i[first last min],
|
|
91
|
+
max_by: %i[first last min_by],
|
|
92
|
+
merge!: %i[merge],
|
|
93
|
+
method: %i[public_method],
|
|
94
|
+
min: %i[first last max],
|
|
95
|
+
min_by: %i[first last max_by],
|
|
96
|
+
negative?: %i[positive?],
|
|
97
|
+
none?: %i[any? all?],
|
|
98
|
+
odd?: %i[even?],
|
|
99
|
+
pop: %i[shift],
|
|
100
|
+
positive?: %i[negative?],
|
|
101
|
+
pred: %i[succ],
|
|
102
|
+
prepend: %i[append],
|
|
103
|
+
push: %i[unshift],
|
|
104
|
+
reject: %i[select],
|
|
105
|
+
reject!: %i[reject],
|
|
106
|
+
reverse!: %i[reverse],
|
|
107
|
+
reverse_each: %i[each],
|
|
108
|
+
reverse_map: %i[map each],
|
|
109
|
+
reverse_merge: %i[merge],
|
|
110
|
+
rotate!: %i[rotate],
|
|
111
|
+
rstrip!: %i[rstrip],
|
|
112
|
+
sample: %i[first last],
|
|
113
|
+
scrub!: %i[scrub],
|
|
114
|
+
rassoc: %i[assoc],
|
|
115
|
+
select: %i[reject],
|
|
116
|
+
select!: %i[select],
|
|
117
|
+
send: %i[public_send __send__],
|
|
118
|
+
shift: %i[pop],
|
|
119
|
+
shuffle!: %i[shuffle],
|
|
120
|
+
slice_after: %i[each],
|
|
121
|
+
slice_before: %i[each],
|
|
122
|
+
slice_when: %i[each],
|
|
123
|
+
sort!: %i[sort],
|
|
124
|
+
sort_by: %i[sort],
|
|
125
|
+
sort_by!: %i[sort_by],
|
|
126
|
+
squeeze!: %i[squeeze],
|
|
127
|
+
start_with?: %i[end_with?],
|
|
128
|
+
strip: %i[lstrip rstrip],
|
|
129
|
+
strip!: %i[strip],
|
|
130
|
+
sub!: %i[sub],
|
|
131
|
+
succ: %i[pred],
|
|
132
|
+
swapcase!: %i[swapcase],
|
|
133
|
+
take: %i[drop],
|
|
134
|
+
to_a: %i[to_ary],
|
|
135
|
+
to_f: %i[to_i],
|
|
136
|
+
to_h: %i[to_hash],
|
|
137
|
+
to_i: %i[to_int],
|
|
138
|
+
to_s: %i[to_str],
|
|
139
|
+
tr!: %i[tr],
|
|
140
|
+
tr_s!: %i[tr_s],
|
|
141
|
+
transform_keys: %i[transform_values],
|
|
142
|
+
transform_keys!: %i[transform_keys],
|
|
143
|
+
transform_values: %i[transform_keys],
|
|
144
|
+
transform_values!: %i[transform_values],
|
|
145
|
+
unicode_normalize!: %i[unicode_normalize],
|
|
146
|
+
uniq!: %i[uniq],
|
|
147
|
+
unshift: %i[push],
|
|
148
|
+
upcase: %i[downcase],
|
|
149
|
+
upcase!: %i[upcase],
|
|
150
|
+
values: %i[keys],
|
|
151
|
+
values_at: %i[fetch_values],
|
|
152
|
+
zero?: %i[nonzero?]
|
|
54
153
|
}.freeze.tap { |hash| hash.each_value(&:freeze) }
|
|
55
154
|
end
|
|
56
155
|
|
|
@@ -72,9 +171,7 @@ module Mutant
|
|
|
72
171
|
self::NAME
|
|
73
172
|
end
|
|
74
173
|
|
|
75
|
-
def selector_replacements
|
|
76
|
-
self.class::SELECTOR_REPLACEMENTS
|
|
77
|
-
end
|
|
174
|
+
def selector_replacements = self.class::SELECTOR_REPLACEMENTS
|
|
78
175
|
|
|
79
176
|
def self.parse(value)
|
|
80
177
|
klass = [Light, Full].detect { |candidate| candidate.operators_name.to_s.eql?(value) }
|
data/lib/mutant/mutation.rb
CHANGED
|
@@ -70,33 +70,25 @@ module Mutant
|
|
|
70
70
|
# Mutation identification code
|
|
71
71
|
#
|
|
72
72
|
# @return [String]
|
|
73
|
-
def code
|
|
74
|
-
sha1[CODE_RANGE]
|
|
75
|
-
end
|
|
73
|
+
def code = sha1[CODE_RANGE]
|
|
76
74
|
memoize :code
|
|
77
75
|
|
|
78
76
|
# Identification string
|
|
79
77
|
#
|
|
80
78
|
# @return [String]
|
|
81
|
-
def identification
|
|
82
|
-
"#{self.class::SYMBOL}:#{subject.identification}:#{code}"
|
|
83
|
-
end
|
|
79
|
+
def identification = "#{self.class::SYMBOL}:#{subject.identification}:#{code}"
|
|
84
80
|
memoize :identification
|
|
85
81
|
|
|
86
82
|
# The monkeypatch to insert the mutation
|
|
87
83
|
#
|
|
88
84
|
# @return [String]
|
|
89
|
-
def monkeypatch
|
|
90
|
-
Unparser.unparse(subject.context.root(node))
|
|
91
|
-
end
|
|
85
|
+
def monkeypatch = Unparser.unparse(subject.context.root(node))
|
|
92
86
|
memoize :monkeypatch
|
|
93
87
|
|
|
94
88
|
# Normalized original source
|
|
95
89
|
#
|
|
96
90
|
# @return [String]
|
|
97
|
-
def original_source
|
|
98
|
-
subject.source
|
|
99
|
-
end
|
|
91
|
+
def original_source = subject.source
|
|
100
92
|
|
|
101
93
|
# Test if mutation is killed by test reports
|
|
102
94
|
#
|
|
@@ -125,16 +117,12 @@ module Mutant
|
|
|
125
117
|
end
|
|
126
118
|
end
|
|
127
119
|
|
|
128
|
-
def diff
|
|
129
|
-
Unparser::Diff.build(original_source, source)
|
|
130
|
-
end
|
|
120
|
+
def diff = Unparser::Diff.build(original_source, source)
|
|
131
121
|
memoize :diff
|
|
132
122
|
|
|
133
123
|
private
|
|
134
124
|
|
|
135
|
-
def sha1
|
|
136
|
-
Digest::SHA1.hexdigest(subject.identification + CODE_DELIMITER + source)
|
|
137
|
-
end
|
|
125
|
+
def sha1 = Digest::SHA1.hexdigest(subject.identification + CODE_DELIMITER + source)
|
|
138
126
|
|
|
139
127
|
# Evil mutation that should case mutations to fail tests
|
|
140
128
|
class Evil < self
|
|
@@ -20,6 +20,7 @@ module Mutant
|
|
|
20
20
|
def dispatch
|
|
21
21
|
emit_singletons unless left_lvasgn?
|
|
22
22
|
emit_promotions
|
|
23
|
+
emit_operator_swap
|
|
23
24
|
|
|
24
25
|
emit_left_mutations do |mutation|
|
|
25
26
|
!(n_irange?(mutation) || n_erange?(mutation)) || !mutation.children.fetch(1).nil?
|
|
@@ -28,6 +29,10 @@ module Mutant
|
|
|
28
29
|
emit_right_mutations
|
|
29
30
|
end
|
|
30
31
|
|
|
32
|
+
def emit_operator_swap
|
|
33
|
+
emit(s(INVERSE.fetch(node.type), left, right))
|
|
34
|
+
end
|
|
35
|
+
|
|
31
36
|
def emit_promotions
|
|
32
37
|
emit(left)
|
|
33
38
|
emit(right) unless left_lvasgn?
|
|
@@ -14,12 +14,22 @@ module Mutant
|
|
|
14
14
|
def dispatch
|
|
15
15
|
emit_singletons
|
|
16
16
|
emit(send) unless n_lambda?(send)
|
|
17
|
+
emit_receiver_promotion
|
|
17
18
|
emit_send_mutations(&method(:valid_send_mutation?))
|
|
18
19
|
emit_arguments_mutations
|
|
19
20
|
|
|
20
21
|
mutate_body
|
|
21
22
|
end
|
|
22
23
|
|
|
24
|
+
def emit_receiver_promotion
|
|
25
|
+
return unless n_send?(send)
|
|
26
|
+
|
|
27
|
+
send_meta = AST::Meta::Send.new(node: send)
|
|
28
|
+
return unless send_meta.receiver
|
|
29
|
+
|
|
30
|
+
emit(send_meta.receiver)
|
|
31
|
+
end
|
|
32
|
+
|
|
23
33
|
def mutate_body
|
|
24
34
|
emit_body(nil) unless unconditional_loop?
|
|
25
35
|
emit_body(N_RAISE)
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Mutant
|
|
4
|
+
class Mutator
|
|
5
|
+
class Node
|
|
6
|
+
|
|
7
|
+
# Mutator for case/in pattern matching nodes
|
|
8
|
+
class CaseMatch < self
|
|
9
|
+
|
|
10
|
+
handle(:case_match)
|
|
11
|
+
|
|
12
|
+
children :condition
|
|
13
|
+
|
|
14
|
+
define_named_child(:else_branch, -1)
|
|
15
|
+
|
|
16
|
+
PATTERNS = (1..-2)
|
|
17
|
+
|
|
18
|
+
private
|
|
19
|
+
|
|
20
|
+
def dispatch
|
|
21
|
+
emit_condition_mutations
|
|
22
|
+
emit_in_pattern_mutations
|
|
23
|
+
emit_else_mutations
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def emit_in_pattern_mutations
|
|
27
|
+
indices = children_indices(PATTERNS)
|
|
28
|
+
one = indices.one?
|
|
29
|
+
|
|
30
|
+
indices.each do |index|
|
|
31
|
+
mutate_child(index)
|
|
32
|
+
delete_child(index) unless one
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def emit_else_mutations
|
|
37
|
+
return unless else_branch
|
|
38
|
+
|
|
39
|
+
emit_else_branch_mutations
|
|
40
|
+
emit_else_branch(nil)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
end # CaseMatch
|
|
44
|
+
end # Node
|
|
45
|
+
end # Mutator
|
|
46
|
+
end # Mutant
|