mutant 0.14.2 → 0.15.1
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/bin/mutant +0 -7
- 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/env_result.rb +9 -0
- 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/version.rb +8 -14
- data/lib/mutant/world.rb +1 -3
- data/lib/mutant/zombifier.rb +3 -1
- data/lib/mutant.rb +8 -0
- metadata +39 -13
|
@@ -5,7 +5,8 @@ module Mutant
|
|
|
5
5
|
class Connection
|
|
6
6
|
include Anima.new(:marshal, :reader, :writer)
|
|
7
7
|
|
|
8
|
-
Error
|
|
8
|
+
class Error < RuntimeError
|
|
9
|
+
end
|
|
9
10
|
|
|
10
11
|
HEADER_FORMAT = 'N'
|
|
11
12
|
HEADER_SIZE = 4
|
|
@@ -21,13 +22,9 @@ module Mutant
|
|
|
21
22
|
|
|
22
23
|
attr_reader :log
|
|
23
24
|
|
|
24
|
-
def error
|
|
25
|
-
Util.max_one(@errors)
|
|
26
|
-
end
|
|
25
|
+
def error = Util.max_one(@errors)
|
|
27
26
|
|
|
28
|
-
def result
|
|
29
|
-
Util.max_one(@results)
|
|
30
|
-
end
|
|
27
|
+
def result = Util.max_one(@results)
|
|
31
28
|
|
|
32
29
|
def initialize(*)
|
|
33
30
|
super
|
|
@@ -81,9 +78,7 @@ module Mutant
|
|
|
81
78
|
|
|
82
79
|
private
|
|
83
80
|
|
|
84
|
-
def timeout
|
|
85
|
-
@errors << Timeout::Error
|
|
86
|
-
end
|
|
81
|
+
def timeout = @errors << Timeout::Error
|
|
87
82
|
|
|
88
83
|
def advance_result
|
|
89
84
|
if length
|
|
@@ -96,9 +91,7 @@ module Mutant
|
|
|
96
91
|
end
|
|
97
92
|
end
|
|
98
93
|
|
|
99
|
-
def length
|
|
100
|
-
Util.max_one(@lengths)
|
|
101
|
-
end
|
|
94
|
+
def length = Util.max_one(@lengths)
|
|
102
95
|
|
|
103
96
|
def advance_log
|
|
104
97
|
while with_nonblock_read(io: log_reader, max_bytes: MAX_LOG_CHUNK, &@log.public_method(:<<))
|
|
@@ -138,9 +131,7 @@ module Mutant
|
|
|
138
131
|
class Frame
|
|
139
132
|
include Anima.new(:io)
|
|
140
133
|
|
|
141
|
-
def receive_value
|
|
142
|
-
read(Util.one(read(HEADER_SIZE).unpack(HEADER_FORMAT)))
|
|
143
|
-
end
|
|
134
|
+
def receive_value = read(Util.one(read(HEADER_SIZE).unpack(HEADER_FORMAT)))
|
|
144
135
|
|
|
145
136
|
def send_value(body)
|
|
146
137
|
bytesize = body.bytesize
|
|
@@ -160,14 +151,9 @@ module Mutant
|
|
|
160
151
|
end
|
|
161
152
|
end
|
|
162
153
|
|
|
163
|
-
def receive_value
|
|
164
|
-
marshal.load(reader.receive_value)
|
|
165
|
-
end
|
|
154
|
+
def receive_value = marshal.load(reader.receive_value)
|
|
166
155
|
|
|
167
|
-
def send_value(value)
|
|
168
|
-
writer.send_value(marshal.dump(value))
|
|
169
|
-
self
|
|
170
|
-
end
|
|
156
|
+
def send_value(value) = tap { writer.send_value(marshal.dump(value)) }
|
|
171
157
|
|
|
172
158
|
def self.from_pipes(marshal:, reader:, writer:)
|
|
173
159
|
new(
|
|
@@ -40,6 +40,10 @@ module Mutant
|
|
|
40
40
|
world.stderr.reopen(log_writer)
|
|
41
41
|
world.stdout.reopen(log_writer)
|
|
42
42
|
|
|
43
|
+
# Ensure output from background threads is immediately flushed
|
|
44
|
+
world.stderr.sync = true
|
|
45
|
+
world.stdout.sync = true
|
|
46
|
+
|
|
43
47
|
run_child(
|
|
44
48
|
config:,
|
|
45
49
|
connection: Connection.from_pipes(marshal:, reader: request, writer: response),
|
|
@@ -77,9 +81,7 @@ module Mutant
|
|
|
77
81
|
end
|
|
78
82
|
private_class_method :run_child
|
|
79
83
|
|
|
80
|
-
def index
|
|
81
|
-
config.index
|
|
82
|
-
end
|
|
84
|
+
def index = config.index
|
|
83
85
|
|
|
84
86
|
# Run worker loop
|
|
85
87
|
#
|
|
@@ -116,21 +118,13 @@ module Mutant
|
|
|
116
118
|
# rubocop:enable Metrics/AbcSize
|
|
117
119
|
# rubocop:enable Metrics/MethodLength
|
|
118
120
|
|
|
119
|
-
def signal
|
|
120
|
-
process.kill('TERM', pid)
|
|
121
|
-
self
|
|
122
|
-
end
|
|
121
|
+
def signal = tap { process.kill('TERM', pid) }
|
|
123
122
|
|
|
124
|
-
def join
|
|
125
|
-
process.wait(pid)
|
|
126
|
-
self
|
|
127
|
-
end
|
|
123
|
+
def join = tap { process.wait(pid) }
|
|
128
124
|
|
|
129
125
|
private
|
|
130
126
|
|
|
131
|
-
def process
|
|
132
|
-
config.world.process
|
|
133
|
-
end
|
|
127
|
+
def process = config.world.process
|
|
134
128
|
|
|
135
129
|
def next_job
|
|
136
130
|
config.var_source.with do |source|
|
data/lib/mutant/registry.rb
CHANGED
|
@@ -44,9 +44,7 @@ module Mutant
|
|
|
44
44
|
# Report delay in seconds
|
|
45
45
|
#
|
|
46
46
|
# @return [Float]
|
|
47
|
-
def delay
|
|
48
|
-
self.class::REPORT_DELAY
|
|
49
|
-
end
|
|
47
|
+
def delay = self.class::REPORT_DELAY
|
|
50
48
|
|
|
51
49
|
# Output abstraction to decouple tty? from buffer
|
|
52
50
|
class Output
|
|
@@ -118,17 +116,11 @@ module Mutant
|
|
|
118
116
|
|
|
119
117
|
private
|
|
120
118
|
|
|
121
|
-
def new_buffer
|
|
122
|
-
StringIO.new
|
|
123
|
-
end
|
|
119
|
+
def new_buffer = StringIO.new
|
|
124
120
|
|
|
125
|
-
def status_progressive_printer
|
|
126
|
-
tty ? Printer::StatusProgressive::Tty : Printer::StatusProgressive::Pipe
|
|
127
|
-
end
|
|
121
|
+
def status_progressive_printer = tty ? Printer::StatusProgressive::Tty : Printer::StatusProgressive::Pipe
|
|
128
122
|
|
|
129
|
-
def test_status_progressive_printer
|
|
130
|
-
tty ? Printer::Test::StatusProgressive::Tty : Printer::Test::StatusProgressive::Pipe
|
|
131
|
-
end
|
|
123
|
+
def test_status_progressive_printer = tty ? Printer::Test::StatusProgressive::Tty : Printer::Test::StatusProgressive::Pipe
|
|
132
124
|
|
|
133
125
|
# Wrap progress output with TTY-specific line handling
|
|
134
126
|
#
|
|
@@ -8,10 +8,19 @@ module Mutant
|
|
|
8
8
|
class EnvResult < self
|
|
9
9
|
delegate(:failed_subject_results)
|
|
10
10
|
|
|
11
|
+
ALIVE_EXPLANATION = <<~'MESSAGE'
|
|
12
|
+
Alive mutations require one of two actions:
|
|
13
|
+
A) Keep the mutated code: Your tests specify the correct semantics,
|
|
14
|
+
and the original code is redundant. Accept the mutation.
|
|
15
|
+
B) Add a missing test: The original code is correct, but the tests
|
|
16
|
+
do not verify the behavior the mutation removed.
|
|
17
|
+
MESSAGE
|
|
18
|
+
|
|
11
19
|
# Run printer
|
|
12
20
|
#
|
|
13
21
|
# @return [undefined]
|
|
14
22
|
def run
|
|
23
|
+
puts(ALIVE_EXPLANATION) if failed_subject_results.any?
|
|
15
24
|
visit_collection(SubjectResult, failed_subject_results)
|
|
16
25
|
visit(EnvProgress, object)
|
|
17
26
|
end
|
|
@@ -14,9 +14,7 @@ module Mutant
|
|
|
14
14
|
|
|
15
15
|
private_class_method :new
|
|
16
16
|
|
|
17
|
-
def call
|
|
18
|
-
run
|
|
19
|
-
end
|
|
17
|
+
def call = run
|
|
20
18
|
|
|
21
19
|
# Create delegators to object
|
|
22
20
|
#
|
|
@@ -50,9 +48,7 @@ module Mutant
|
|
|
50
48
|
|
|
51
49
|
private
|
|
52
50
|
|
|
53
|
-
def status_color
|
|
54
|
-
success? ? Unparser::Color::GREEN : Unparser::Color::RED
|
|
55
|
-
end
|
|
51
|
+
def status_color = success? ? Unparser::Color::GREEN : Unparser::Color::RED
|
|
56
52
|
|
|
57
53
|
def visit_collection(printer, collection)
|
|
58
54
|
collection.each do |object|
|
|
@@ -24,9 +24,7 @@ module Mutant
|
|
|
24
24
|
# Render the progress bar string
|
|
25
25
|
#
|
|
26
26
|
# @return [String]
|
|
27
|
-
def render
|
|
28
|
-
"#{filled}#{empty}"
|
|
29
|
-
end
|
|
27
|
+
def render = "#{filled}#{empty}"
|
|
30
28
|
|
|
31
29
|
# Calculate percentage completion
|
|
32
30
|
#
|
|
@@ -62,17 +60,11 @@ module Mutant
|
|
|
62
60
|
[((current.to_f / total) * width).round, width].min
|
|
63
61
|
end
|
|
64
62
|
|
|
65
|
-
def empty_width
|
|
66
|
-
width - filled_width
|
|
67
|
-
end
|
|
63
|
+
def empty_width = width - filled_width
|
|
68
64
|
|
|
69
|
-
def filled
|
|
70
|
-
filled_char * filled_width
|
|
71
|
-
end
|
|
65
|
+
def filled = filled_char * filled_width
|
|
72
66
|
|
|
73
|
-
def empty
|
|
74
|
-
empty_char * empty_width
|
|
75
|
-
end
|
|
67
|
+
def empty = empty_char * empty_width
|
|
76
68
|
end # ProgressBar
|
|
77
69
|
end # CLI
|
|
78
70
|
end # Reporter
|
data/lib/mutant/reporter/cli.rb
CHANGED
|
@@ -26,55 +26,38 @@ module Mutant
|
|
|
26
26
|
# @param [Env] env
|
|
27
27
|
#
|
|
28
28
|
# @return [self]
|
|
29
|
-
def start(env)
|
|
30
|
-
write(format.start(env))
|
|
31
|
-
self
|
|
32
|
-
end
|
|
29
|
+
def start(env) = tap { write(format.start(env)) }
|
|
33
30
|
|
|
34
31
|
# Report test start
|
|
35
32
|
#
|
|
36
33
|
# @param [Env] env
|
|
37
34
|
#
|
|
38
35
|
# @return [self]
|
|
39
|
-
def test_start(env)
|
|
40
|
-
write(format.test_start(env))
|
|
41
|
-
self
|
|
42
|
-
end
|
|
36
|
+
def test_start(env) = tap { write(format.test_start(env)) }
|
|
43
37
|
|
|
44
38
|
# Report progress object
|
|
45
39
|
#
|
|
46
40
|
# @param [Parallel::Status] status
|
|
47
41
|
#
|
|
48
42
|
# @return [self]
|
|
49
|
-
def progress(status)
|
|
50
|
-
write(format.progress(status))
|
|
51
|
-
self
|
|
52
|
-
end
|
|
43
|
+
def progress(status) = tap { write(format.progress(status)) }
|
|
53
44
|
|
|
54
45
|
# Report progress object
|
|
55
46
|
#
|
|
56
47
|
# @return [self]
|
|
57
|
-
def test_progress(status)
|
|
58
|
-
write(format.test_progress(status))
|
|
59
|
-
self
|
|
60
|
-
end
|
|
48
|
+
def test_progress(status) = tap { write(format.test_progress(status)) }
|
|
61
49
|
|
|
62
50
|
# Report delay in seconds
|
|
63
51
|
#
|
|
64
52
|
# @return [Float]
|
|
65
|
-
def delay
|
|
66
|
-
format.delay
|
|
67
|
-
end
|
|
53
|
+
def delay = format.delay
|
|
68
54
|
|
|
69
55
|
# Report warning
|
|
70
56
|
#
|
|
71
57
|
# @param [String] message
|
|
72
58
|
#
|
|
73
59
|
# @return [self]
|
|
74
|
-
def warn(message)
|
|
75
|
-
output.puts(message) if print_warnings
|
|
76
|
-
self
|
|
77
|
-
end
|
|
60
|
+
def warn(message) = tap { output.puts(message) if print_warnings }
|
|
78
61
|
|
|
79
62
|
# Report env
|
|
80
63
|
#
|
|
@@ -44,9 +44,7 @@ module Mutant
|
|
|
44
44
|
touched_paths.from_right { |message| fail Error, message }.fetch(path, &)
|
|
45
45
|
end
|
|
46
46
|
|
|
47
|
-
def touched_paths
|
|
48
|
-
repository_root.bind(&method(:diff_index))
|
|
49
|
-
end
|
|
47
|
+
def touched_paths = repository_root.bind(&method(:diff_index))
|
|
50
48
|
memoize :touched_paths
|
|
51
49
|
|
|
52
50
|
def diff_index(root)
|
data/lib/mutant/result.rb
CHANGED
|
@@ -81,9 +81,7 @@ module Mutant
|
|
|
81
81
|
# Failed subject results
|
|
82
82
|
#
|
|
83
83
|
# @return [Array<Result::Subject>]
|
|
84
|
-
def failed_subject_results
|
|
85
|
-
subject_results.reject(&:success?)
|
|
86
|
-
end
|
|
84
|
+
def failed_subject_results = subject_results.reject(&:success?)
|
|
87
85
|
|
|
88
86
|
sum :amount_mutation_results, :subject_results
|
|
89
87
|
sum :amount_mutations_alive, :subject_results
|
|
@@ -94,9 +92,7 @@ module Mutant
|
|
|
94
92
|
# Amount of mutations
|
|
95
93
|
#
|
|
96
94
|
# @return [Integer]
|
|
97
|
-
def amount_mutations
|
|
98
|
-
env.mutations.length
|
|
99
|
-
end
|
|
95
|
+
def amount_mutations = env.mutations.length
|
|
100
96
|
|
|
101
97
|
# Test if processing needs to stop
|
|
102
98
|
#
|
|
@@ -126,34 +122,22 @@ module Mutant
|
|
|
126
122
|
# Failed subject results
|
|
127
123
|
#
|
|
128
124
|
# @return [Array<Result::Test>]
|
|
129
|
-
def failed_test_results
|
|
130
|
-
test_results.reject(&:success?)
|
|
131
|
-
end
|
|
125
|
+
def failed_test_results = test_results.reject(&:success?)
|
|
132
126
|
memoize :failed_test_results
|
|
133
127
|
|
|
134
128
|
def stop?
|
|
135
129
|
env.config.fail_fast && !test_results.all?(&:success?)
|
|
136
130
|
end
|
|
137
131
|
|
|
138
|
-
def testtime
|
|
139
|
-
test_results.map(&:runtime).sum(0.0)
|
|
140
|
-
end
|
|
132
|
+
def testtime = test_results.map(&:runtime).sum(0.0)
|
|
141
133
|
|
|
142
|
-
def amount_tests
|
|
143
|
-
env.integration.all_tests.length
|
|
144
|
-
end
|
|
134
|
+
def amount_tests = env.integration.all_tests.length
|
|
145
135
|
|
|
146
|
-
def amount_test_results
|
|
147
|
-
test_results.length
|
|
148
|
-
end
|
|
136
|
+
def amount_test_results = test_results.length
|
|
149
137
|
|
|
150
|
-
def amount_tests_failed
|
|
151
|
-
failed_test_results.length
|
|
152
|
-
end
|
|
138
|
+
def amount_tests_failed = failed_test_results.length
|
|
153
139
|
|
|
154
|
-
def amount_tests_success
|
|
155
|
-
test_results.count(&:passed)
|
|
156
|
-
end
|
|
140
|
+
def amount_tests_success = test_results.count(&:passed)
|
|
157
141
|
end # TestEnv
|
|
158
142
|
|
|
159
143
|
# Test result
|
|
@@ -200,51 +184,37 @@ module Mutant
|
|
|
200
184
|
# Alive mutations
|
|
201
185
|
#
|
|
202
186
|
# @return [Array<Result::Coverage>]
|
|
203
|
-
def uncovered_results
|
|
204
|
-
coverage_results.reject(&:success?)
|
|
205
|
-
end
|
|
187
|
+
def uncovered_results = coverage_results.reject(&:success?)
|
|
206
188
|
memoize :uncovered_results
|
|
207
189
|
|
|
208
190
|
# Amount of mutations
|
|
209
191
|
#
|
|
210
192
|
# @return [Integer]
|
|
211
|
-
def amount_mutation_results
|
|
212
|
-
coverage_results.length
|
|
213
|
-
end
|
|
193
|
+
def amount_mutation_results = coverage_results.length
|
|
214
194
|
|
|
215
195
|
# Amount of mutations
|
|
216
196
|
#
|
|
217
197
|
# @return [Integer]
|
|
218
|
-
def amount_timeouts
|
|
219
|
-
coverage_results.count(&:timeout?)
|
|
220
|
-
end
|
|
198
|
+
def amount_timeouts = coverage_results.count(&:timeout?)
|
|
221
199
|
|
|
222
200
|
# Amount of mutations
|
|
223
201
|
#
|
|
224
202
|
# @return [Integer]
|
|
225
|
-
def amount_mutations
|
|
226
|
-
subject.mutations.length
|
|
227
|
-
end
|
|
203
|
+
def amount_mutations = subject.mutations.length
|
|
228
204
|
|
|
229
205
|
# Number of killed mutations
|
|
230
206
|
#
|
|
231
207
|
# @return [Integer]
|
|
232
|
-
def amount_mutations_killed
|
|
233
|
-
covered_results.length
|
|
234
|
-
end
|
|
208
|
+
def amount_mutations_killed = covered_results.length
|
|
235
209
|
|
|
236
210
|
# Number of alive mutations
|
|
237
211
|
#
|
|
238
212
|
# @return [Integer]
|
|
239
|
-
def amount_mutations_alive
|
|
240
|
-
uncovered_results.length
|
|
241
|
-
end
|
|
213
|
+
def amount_mutations_alive = uncovered_results.length
|
|
242
214
|
|
|
243
215
|
private
|
|
244
216
|
|
|
245
|
-
def covered_results
|
|
246
|
-
coverage_results.select(&:success?)
|
|
247
|
-
end
|
|
217
|
+
def covered_results = coverage_results.select(&:success?)
|
|
248
218
|
memoize :covered_results
|
|
249
219
|
|
|
250
220
|
end # Subject
|
|
@@ -303,9 +273,7 @@ module Mutant
|
|
|
303
273
|
# Time the tests had been running
|
|
304
274
|
#
|
|
305
275
|
# @return [Float]
|
|
306
|
-
def killtime
|
|
307
|
-
isolation_result.value&.runtime || 0.0
|
|
308
|
-
end
|
|
276
|
+
def killtime = isolation_result.value&.runtime || 0.0
|
|
309
277
|
|
|
310
278
|
# Test for timeout
|
|
311
279
|
#
|
data/lib/mutant/scope.rb
CHANGED
|
@@ -21,9 +21,7 @@ module Mutant
|
|
|
21
21
|
# Unqualified name of scope
|
|
22
22
|
#
|
|
23
23
|
# @return [String]
|
|
24
|
-
def unqualified_name
|
|
25
|
-
name_nesting.last
|
|
26
|
-
end
|
|
24
|
+
def unqualified_name = name_nesting.last
|
|
27
25
|
|
|
28
26
|
# Match expressions for scope
|
|
29
27
|
#
|
|
@@ -39,9 +37,7 @@ module Mutant
|
|
|
39
37
|
|
|
40
38
|
private
|
|
41
39
|
|
|
42
|
-
def name_nesting
|
|
43
|
-
raw.name.split(NAMESPACE_DELIMITER)
|
|
44
|
-
end
|
|
40
|
+
def name_nesting = raw.name.split(NAMESPACE_DELIMITER)
|
|
45
41
|
memoize :name_nesting
|
|
46
42
|
|
|
47
43
|
end # Scope
|
data/lib/mutant/segment.rb
CHANGED
|
@@ -12,15 +12,9 @@ module Mutant
|
|
|
12
12
|
# Prepare subject for mutation insertion
|
|
13
13
|
#
|
|
14
14
|
# @return [self]
|
|
15
|
-
def prepare
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
def post_insert
|
|
21
|
-
scope.raw.__send__(visibility, name)
|
|
22
|
-
self
|
|
23
|
-
end
|
|
15
|
+
def prepare = tap { scope.raw.undef_method(name) }
|
|
16
|
+
|
|
17
|
+
def post_insert = tap { scope.raw.__send__(visibility, name) }
|
|
24
18
|
|
|
25
19
|
# Mutator for memoizable memoized instance methods
|
|
26
20
|
class Memoized < self
|
|
@@ -12,15 +12,9 @@ module Mutant
|
|
|
12
12
|
# Prepare subject for mutation insertion
|
|
13
13
|
#
|
|
14
14
|
# @return [self]
|
|
15
|
-
def prepare
|
|
16
|
-
scope.raw.singleton_class.undef_method(name)
|
|
17
|
-
self
|
|
18
|
-
end
|
|
15
|
+
def prepare = tap { scope.raw.singleton_class.undef_method(name) }
|
|
19
16
|
|
|
20
|
-
def post_insert
|
|
21
|
-
scope.raw.singleton_class.__send__(visibility, name)
|
|
22
|
-
self
|
|
23
|
-
end
|
|
17
|
+
def post_insert = tap { scope.raw.singleton_class.__send__(visibility, name) }
|
|
24
18
|
|
|
25
19
|
end # Singleton
|
|
26
20
|
end # Method
|
|
@@ -9,9 +9,7 @@ module Mutant
|
|
|
9
9
|
# Method name
|
|
10
10
|
#
|
|
11
11
|
# @return [Expression]
|
|
12
|
-
def name
|
|
13
|
-
node.children.fetch(self.class::NAME_INDEX)
|
|
14
|
-
end
|
|
12
|
+
def name = node.children.fetch(self.class::NAME_INDEX)
|
|
15
13
|
|
|
16
14
|
# Match expression
|
|
17
15
|
#
|
|
@@ -28,16 +26,12 @@ module Mutant
|
|
|
28
26
|
# Match expressions
|
|
29
27
|
#
|
|
30
28
|
# @return [Array<Expression>]
|
|
31
|
-
def match_expressions
|
|
32
|
-
[expression].concat(context.match_expressions)
|
|
33
|
-
end
|
|
29
|
+
def match_expressions = [expression].concat(context.match_expressions)
|
|
34
30
|
memoize :match_expressions
|
|
35
31
|
|
|
36
32
|
private
|
|
37
33
|
|
|
38
|
-
def scope
|
|
39
|
-
context.scope
|
|
40
|
-
end
|
|
34
|
+
def scope = context.scope
|
|
41
35
|
|
|
42
36
|
end # Method
|
|
43
37
|
end # Subject
|
data/lib/mutant/subject.rb
CHANGED
|
@@ -37,23 +37,17 @@ module Mutant
|
|
|
37
37
|
# Source path
|
|
38
38
|
#
|
|
39
39
|
# @return [Pathname]
|
|
40
|
-
def source_path
|
|
41
|
-
context.source_path
|
|
42
|
-
end
|
|
40
|
+
def source_path = context.source_path
|
|
43
41
|
|
|
44
42
|
# Prepare subject for insertion of mutation
|
|
45
43
|
#
|
|
46
44
|
# @return [self]
|
|
47
|
-
def prepare
|
|
48
|
-
self
|
|
49
|
-
end
|
|
45
|
+
def prepare = self
|
|
50
46
|
|
|
51
47
|
# Perform post insert cleanup
|
|
52
48
|
#
|
|
53
49
|
# @return [self]
|
|
54
|
-
def post_insert
|
|
55
|
-
self
|
|
56
|
-
end
|
|
50
|
+
def post_insert = self
|
|
57
51
|
|
|
58
52
|
# Source line range
|
|
59
53
|
#
|
|
@@ -67,24 +61,18 @@ module Mutant
|
|
|
67
61
|
# First source line
|
|
68
62
|
#
|
|
69
63
|
# @return [Integer]
|
|
70
|
-
def source_line
|
|
71
|
-
source_lines.begin
|
|
72
|
-
end
|
|
64
|
+
def source_line = source_lines.begin
|
|
73
65
|
|
|
74
66
|
# Identification string
|
|
75
67
|
#
|
|
76
68
|
# @return [String]
|
|
77
|
-
def identification
|
|
78
|
-
"#{expression.syntax}:#{source_path}:#{source_line}"
|
|
79
|
-
end
|
|
69
|
+
def identification = "#{expression.syntax}:#{source_path}:#{source_line}"
|
|
80
70
|
memoize :identification
|
|
81
71
|
|
|
82
72
|
# Source representation of AST
|
|
83
73
|
#
|
|
84
74
|
# @return [String]
|
|
85
|
-
def source
|
|
86
|
-
Unparser.unparse(wrap_node(node))
|
|
87
|
-
end
|
|
75
|
+
def source = Unparser.unparse(wrap_node(node))
|
|
88
76
|
memoize :source
|
|
89
77
|
|
|
90
78
|
# Match expression
|
data/lib/mutant/timer.rb
CHANGED
|
@@ -48,16 +48,12 @@ module Mutant
|
|
|
48
48
|
# Capture a deadline status
|
|
49
49
|
#
|
|
50
50
|
# @return [Status]
|
|
51
|
-
def status
|
|
52
|
-
Status.new(time_left:)
|
|
53
|
-
end
|
|
51
|
+
def status = Status.new(time_left:)
|
|
54
52
|
|
|
55
53
|
# Probe the time left
|
|
56
54
|
#
|
|
57
55
|
# @return [Float, nil]
|
|
58
|
-
def time_left
|
|
59
|
-
allowed_time - (timer.now - @start_at)
|
|
60
|
-
end
|
|
56
|
+
def time_left = allowed_time - (timer.now - @start_at)
|
|
61
57
|
|
|
62
58
|
# Deadline that never expires
|
|
63
59
|
class None < self
|