mutant 0.10.0 → 0.10.7
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/bin/mutant +0 -2
- data/lib/mutant.rb +7 -5
- data/lib/mutant/cli/command.rb +8 -6
- data/lib/mutant/cli/command/run.rb +23 -10
- data/lib/mutant/config.rb +78 -77
- data/lib/mutant/env.rb +14 -4
- data/lib/mutant/integration.rb +7 -10
- data/lib/mutant/integration/null.rb +0 -1
- data/lib/mutant/isolation.rb +11 -48
- data/lib/mutant/isolation/fork.rb +107 -40
- data/lib/mutant/isolation/none.rb +18 -5
- data/lib/mutant/license/subscription.rb +1 -1
- data/lib/mutant/license/subscription/commercial.rb +2 -3
- data/lib/mutant/license/subscription/opensource.rb +2 -2
- data/lib/mutant/matcher/config.rb +13 -0
- data/lib/mutant/matcher/method/instance.rb +0 -2
- data/lib/mutant/mutator/node/send.rb +1 -1
- data/lib/mutant/parallel.rb +0 -1
- data/lib/mutant/parallel/worker.rb +0 -2
- data/lib/mutant/reporter/cli.rb +0 -2
- data/lib/mutant/reporter/cli/printer/config.rb +9 -5
- data/lib/mutant/reporter/cli/printer/coverage_result.rb +19 -0
- data/lib/mutant/reporter/cli/printer/env_progress.rb +2 -0
- data/lib/mutant/reporter/cli/printer/isolation_result.rb +19 -35
- data/lib/mutant/reporter/cli/printer/mutation_result.rb +4 -9
- data/lib/mutant/reporter/cli/printer/subject_result.rb +2 -2
- data/lib/mutant/result.rb +81 -30
- data/lib/mutant/runner/sink.rb +12 -5
- data/lib/mutant/selector/expression.rb +3 -1
- data/lib/mutant/test.rb +1 -1
- data/lib/mutant/timer.rb +60 -11
- data/lib/mutant/transform.rb +25 -21
- data/lib/mutant/version.rb +1 -1
- data/lib/mutant/warnings.rb +0 -1
- data/lib/mutant/world.rb +67 -0
- metadata +13 -15
- data/lib/mutant/minitest/coverage.rb +0 -53
- data/lib/mutant/reporter/cli/printer/mutation_progress_result.rb +0 -28
- data/lib/mutant/reporter/cli/printer/subject_progress.rb +0 -58
- data/lib/mutant/reporter/cli/printer/test_result.rb +0 -32
data/lib/mutant/runner/sink.rb
CHANGED
@@ -10,7 +10,7 @@ module Mutant
|
|
10
10
|
# @return [undefined]
|
11
11
|
def initialize(*)
|
12
12
|
super
|
13
|
-
@start =
|
13
|
+
@start = env.world.timer.now
|
14
14
|
@subject_results = {}
|
15
15
|
end
|
16
16
|
|
@@ -20,7 +20,7 @@ module Mutant
|
|
20
20
|
def status
|
21
21
|
Result::Env.new(
|
22
22
|
env: env,
|
23
|
-
runtime:
|
23
|
+
runtime: env.world.timer.now - @start,
|
24
24
|
subject_results: @subject_results.values
|
25
25
|
)
|
26
26
|
end
|
@@ -42,7 +42,7 @@ module Mutant
|
|
42
42
|
|
43
43
|
@subject_results[subject] = Result::Subject.new(
|
44
44
|
subject: subject,
|
45
|
-
|
45
|
+
coverage_results: previous_coverage_results(subject).dup << coverage_result(mutation_result),
|
46
46
|
tests: env.selections.fetch(subject)
|
47
47
|
)
|
48
48
|
|
@@ -51,9 +51,16 @@ module Mutant
|
|
51
51
|
|
52
52
|
private
|
53
53
|
|
54
|
-
def
|
54
|
+
def coverage_result(mutation_result)
|
55
|
+
Result::Coverage.new(
|
56
|
+
mutation_result: mutation_result,
|
57
|
+
criteria_result: mutation_result.criteria_result(env.config.coverage_criteria)
|
58
|
+
)
|
59
|
+
end
|
60
|
+
|
61
|
+
def previous_coverage_results(subject)
|
55
62
|
subject_result = @subject_results.fetch(subject) { return EMPTY_ARRAY }
|
56
|
-
subject_result.
|
63
|
+
subject_result.coverage_results
|
57
64
|
end
|
58
65
|
|
59
66
|
end # Sink
|
@@ -14,7 +14,9 @@ module Mutant
|
|
14
14
|
def call(subject)
|
15
15
|
subject.match_expressions.each do |match_expression|
|
16
16
|
subject_tests = integration.all_tests.select do |test|
|
17
|
-
|
17
|
+
test.expressions.any? do |test_expression|
|
18
|
+
match_expression.prefix?(test_expression)
|
19
|
+
end
|
18
20
|
end
|
19
21
|
return subject_tests if subject_tests.any?
|
20
22
|
end
|
data/lib/mutant/test.rb
CHANGED
data/lib/mutant/timer.rb
CHANGED
@@ -1,21 +1,70 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Mutant
|
4
|
-
|
5
|
-
|
6
|
-
#
|
7
|
-
# @return [Float]
|
8
|
-
def self.elapsed
|
9
|
-
start = now
|
10
|
-
yield
|
11
|
-
now - start
|
12
|
-
end
|
4
|
+
class Timer
|
5
|
+
include Concord.new(:process)
|
13
6
|
|
14
7
|
# The now monotonic time
|
15
8
|
#
|
16
9
|
# @return [Float]
|
17
|
-
def
|
18
|
-
|
10
|
+
def now
|
11
|
+
process.clock_gettime(Process::CLOCK_MONOTONIC)
|
19
12
|
end
|
13
|
+
|
14
|
+
class Deadline
|
15
|
+
include Anima.new(:timer, :allowed_time)
|
16
|
+
|
17
|
+
def initialize(**arguments)
|
18
|
+
super(**arguments)
|
19
|
+
@start_at = timer.now
|
20
|
+
end
|
21
|
+
|
22
|
+
# Test if deadline is expired
|
23
|
+
#
|
24
|
+
# @return [Boolean]
|
25
|
+
def expired?
|
26
|
+
time_left <= 0
|
27
|
+
end
|
28
|
+
|
29
|
+
# Deadline status snapshot
|
30
|
+
class Status
|
31
|
+
include Concord::Public.new(:time_left)
|
32
|
+
|
33
|
+
# Test if deadline is not yet expired
|
34
|
+
def ok?
|
35
|
+
time_left.nil? || time_left.positive?
|
36
|
+
end
|
37
|
+
end # Status
|
38
|
+
|
39
|
+
# Capture a deadline status
|
40
|
+
#
|
41
|
+
# @return [Status]
|
42
|
+
def status
|
43
|
+
Status.new(time_left)
|
44
|
+
end
|
45
|
+
|
46
|
+
# Probe the time left
|
47
|
+
#
|
48
|
+
# @return [Float, nil]
|
49
|
+
def time_left
|
50
|
+
allowed_time - (timer.now - @start_at)
|
51
|
+
end
|
52
|
+
|
53
|
+
# Deadline that never expires
|
54
|
+
class None < self
|
55
|
+
include Concord.new
|
56
|
+
|
57
|
+
STATUS = Status.new(nil)
|
58
|
+
|
59
|
+
# The time left
|
60
|
+
#
|
61
|
+
# @return [Float, nil]
|
62
|
+
def time_left; end
|
63
|
+
|
64
|
+
def expired?
|
65
|
+
false
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end # Deadline
|
20
69
|
end # Timer
|
21
70
|
end # Mutant
|
data/lib/mutant/transform.rb
CHANGED
@@ -16,7 +16,7 @@ module Mutant
|
|
16
16
|
# @param [Object] input
|
17
17
|
#
|
18
18
|
# @return [Either<Error, Object>]
|
19
|
-
abstract_method :
|
19
|
+
abstract_method :call
|
20
20
|
|
21
21
|
# Deep error data structure
|
22
22
|
class Error
|
@@ -61,8 +61,8 @@ module Mutant
|
|
61
61
|
# Apply transformation to input
|
62
62
|
#
|
63
63
|
# @return [Either<Error, Object>]
|
64
|
-
def
|
65
|
-
transformer.
|
64
|
+
def call(input)
|
65
|
+
transformer.call(input).lmap(&method(:wrap_error))
|
66
66
|
end
|
67
67
|
|
68
68
|
# Named slug
|
@@ -126,8 +126,8 @@ module Mutant
|
|
126
126
|
# @param [Object] input
|
127
127
|
#
|
128
128
|
# @return [Either<Error, Object>]
|
129
|
-
def
|
130
|
-
transform.
|
129
|
+
def call(input)
|
130
|
+
transform.call(input).lmap(&method(:wrap_error))
|
131
131
|
end
|
132
132
|
|
133
133
|
# Rendering slug
|
@@ -152,7 +152,7 @@ module Mutant
|
|
152
152
|
# @param [Object] input
|
153
153
|
#
|
154
154
|
# @return [Either<Error, Object>]
|
155
|
-
def
|
155
|
+
def call(input)
|
156
156
|
if input.instance_of?(primitive)
|
157
157
|
success(input)
|
158
158
|
else
|
@@ -187,7 +187,7 @@ module Mutant
|
|
187
187
|
# @param [Object] input
|
188
188
|
#
|
189
189
|
# @return [Either<Error, Object>]
|
190
|
-
def
|
190
|
+
def call(input)
|
191
191
|
if input.equal?(true) || input.equal?(false)
|
192
192
|
success(input)
|
193
193
|
else
|
@@ -215,9 +215,9 @@ module Mutant
|
|
215
215
|
# @param [Object] input
|
216
216
|
#
|
217
217
|
# @return [Either<Error, Array<Object>>]
|
218
|
-
def
|
218
|
+
def call(input)
|
219
219
|
PRIMITIVE
|
220
|
-
.
|
220
|
+
.call(input)
|
221
221
|
.lmap(&method(:lift_error))
|
222
222
|
.bind(&method(:run))
|
223
223
|
end
|
@@ -229,7 +229,7 @@ module Mutant
|
|
229
229
|
output = []
|
230
230
|
|
231
231
|
input.each_with_index do |value, index|
|
232
|
-
output << transform.
|
232
|
+
output << transform.call(value).lmap do |error|
|
233
233
|
return failure(
|
234
234
|
error(
|
235
235
|
cause: Index.wrap(error, index),
|
@@ -261,7 +261,7 @@ module Mutant
|
|
261
261
|
# @param [Hash{String => Object}]
|
262
262
|
#
|
263
263
|
# @return [Hash{Symbol => Object}]
|
264
|
-
def
|
264
|
+
def call(input)
|
265
265
|
success(input.transform_keys(&:to_sym))
|
266
266
|
end
|
267
267
|
end # Symbolize
|
@@ -283,8 +283,8 @@ module Mutant
|
|
283
283
|
# @param [Object]
|
284
284
|
#
|
285
285
|
# @return [Either<Error, Object>]
|
286
|
-
def
|
287
|
-
transform.
|
286
|
+
def call(input)
|
287
|
+
transform.call(input).lmap do |error|
|
288
288
|
error(cause: error, input: input)
|
289
289
|
end
|
290
290
|
end
|
@@ -295,9 +295,9 @@ module Mutant
|
|
295
295
|
# @param [Object] input
|
296
296
|
#
|
297
297
|
# @return [Either<Error, Object>]
|
298
|
-
def
|
298
|
+
def call(input)
|
299
299
|
PRIMITIVE
|
300
|
-
.
|
300
|
+
.call(input)
|
301
301
|
.lmap(&method(:lift_error))
|
302
302
|
.bind(&method(:reject_keys))
|
303
303
|
.bind(&method(:transform))
|
@@ -322,8 +322,6 @@ module Mutant
|
|
322
322
|
)
|
323
323
|
end
|
324
324
|
|
325
|
-
# ignore :reek:NestedIterators
|
326
|
-
#
|
327
325
|
# rubocop:disable Metrics/MethodLength
|
328
326
|
def transform_keys(keys, input)
|
329
327
|
success(
|
@@ -342,7 +340,7 @@ module Mutant
|
|
342
340
|
# rubocop:enable Metrics/MethodLength
|
343
341
|
|
344
342
|
def coerce_key(key, input)
|
345
|
-
key.
|
343
|
+
key.call(input.fetch(key.value)).lmap do |error|
|
346
344
|
error(input: input, cause: error)
|
347
345
|
end
|
348
346
|
end
|
@@ -388,11 +386,11 @@ module Mutant
|
|
388
386
|
# ignore :reek:NestedIterators
|
389
387
|
#
|
390
388
|
# @return [Either<Error, Object>]
|
391
|
-
def
|
389
|
+
def call(input)
|
392
390
|
current = input
|
393
391
|
|
394
392
|
steps.each_with_index do |step, index|
|
395
|
-
current = step.
|
393
|
+
current = step.call(current).from_right do |error|
|
396
394
|
return failure(error(cause: Index.wrap(error, index), input: input))
|
397
395
|
end
|
398
396
|
end
|
@@ -410,11 +408,17 @@ module Mutant
|
|
410
408
|
# @param [Object]
|
411
409
|
#
|
412
410
|
# @return [Either<Error, Object>]
|
413
|
-
def
|
411
|
+
def call(input)
|
414
412
|
Either
|
415
413
|
.wrap_error(error_class) { block.call(input) }
|
416
414
|
.lmap { |exception| error(input: input, message: exception.to_s) }
|
417
415
|
end
|
418
416
|
end # Exception
|
417
|
+
|
418
|
+
BOOLEAN = Transform::Boolean.new
|
419
|
+
FLOAT = Transform::Primitive.new(Float)
|
420
|
+
INTEGER = Transform::Primitive.new(Integer)
|
421
|
+
STRING = Transform::Primitive.new(String)
|
422
|
+
STRING_ARRAY = Transform::Array.new(STRING)
|
419
423
|
end # Transform
|
420
424
|
end # Mutant
|
data/lib/mutant/version.rb
CHANGED
data/lib/mutant/warnings.rb
CHANGED
@@ -55,7 +55,6 @@ module Mutant
|
|
55
55
|
# For that reason we do have to use the original method capture to dispatch
|
56
56
|
# in disabled state.
|
57
57
|
#
|
58
|
-
# ignore :reek:RepeatedConditional
|
59
58
|
class Warnings
|
60
59
|
# Error raised when warning capture is used recursively
|
61
60
|
class RecursiveUseError < RuntimeError; end
|
data/lib/mutant/world.rb
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Mutant
|
4
|
+
# The outer world IO objects mutant does interact with
|
5
|
+
class World
|
6
|
+
include Adamantium::Flat, Anima.new(
|
7
|
+
:condition_variable,
|
8
|
+
:gem,
|
9
|
+
:gem_method,
|
10
|
+
:io,
|
11
|
+
:json,
|
12
|
+
:kernel,
|
13
|
+
:load_path,
|
14
|
+
:marshal,
|
15
|
+
:mutex,
|
16
|
+
:object_space,
|
17
|
+
:open3,
|
18
|
+
:pathname,
|
19
|
+
:process,
|
20
|
+
:stderr,
|
21
|
+
:stdout,
|
22
|
+
:thread,
|
23
|
+
:timer,
|
24
|
+
:warnings
|
25
|
+
)
|
26
|
+
|
27
|
+
INSPECT = '#<Mutant::World>'
|
28
|
+
|
29
|
+
private_constant(*constants(false))
|
30
|
+
|
31
|
+
# Object inspection
|
32
|
+
#
|
33
|
+
# @return [String]
|
34
|
+
def inspect
|
35
|
+
INSPECT
|
36
|
+
end
|
37
|
+
|
38
|
+
# Capture stdout of a command
|
39
|
+
#
|
40
|
+
# @param [Array<String>] command
|
41
|
+
#
|
42
|
+
# @return [Either<String,String>]
|
43
|
+
def capture_stdout(command)
|
44
|
+
stdout, status = open3.capture2(*command, binmode: true)
|
45
|
+
|
46
|
+
if status.success?
|
47
|
+
Either::Right.new(stdout)
|
48
|
+
else
|
49
|
+
Either::Left.new("Command #{command} failed!")
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
# Deadline
|
54
|
+
#
|
55
|
+
# @param [Float, nil] allowed_time
|
56
|
+
def deadline(allowed_time)
|
57
|
+
if allowed_time
|
58
|
+
Timer::Deadline.new(
|
59
|
+
allowed_time: allowed_time,
|
60
|
+
timer: timer
|
61
|
+
)
|
62
|
+
else
|
63
|
+
Timer::Deadline::None.new
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end # World
|
67
|
+
end # Mutant
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mutant
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.10.
|
4
|
+
version: 0.10.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Markus Schirp
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-11-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: abstract_type
|
@@ -184,14 +184,14 @@ dependencies:
|
|
184
184
|
requirements:
|
185
185
|
- - "~>"
|
186
186
|
- !ruby/object:Gem::Version
|
187
|
-
version: 0.5.
|
187
|
+
version: 0.5.4
|
188
188
|
type: :runtime
|
189
189
|
prerelease: false
|
190
190
|
version_requirements: !ruby/object:Gem::Requirement
|
191
191
|
requirements:
|
192
192
|
- - "~>"
|
193
193
|
- !ruby/object:Gem::Version
|
194
|
-
version: 0.5.
|
194
|
+
version: 0.5.4
|
195
195
|
- !ruby/object:Gem::Dependency
|
196
196
|
name: variable
|
197
197
|
requirement: !ruby/object:Gem::Requirement
|
@@ -226,28 +226,28 @@ dependencies:
|
|
226
226
|
requirements:
|
227
227
|
- - "~>"
|
228
228
|
- !ruby/object:Gem::Version
|
229
|
-
version: '3.
|
229
|
+
version: '3.10'
|
230
230
|
type: :development
|
231
231
|
prerelease: false
|
232
232
|
version_requirements: !ruby/object:Gem::Requirement
|
233
233
|
requirements:
|
234
234
|
- - "~>"
|
235
235
|
- !ruby/object:Gem::Version
|
236
|
-
version: '3.
|
236
|
+
version: '3.10'
|
237
237
|
- !ruby/object:Gem::Dependency
|
238
238
|
name: rspec-core
|
239
239
|
requirement: !ruby/object:Gem::Requirement
|
240
240
|
requirements:
|
241
241
|
- - "~>"
|
242
242
|
- !ruby/object:Gem::Version
|
243
|
-
version: '3.
|
243
|
+
version: '3.10'
|
244
244
|
type: :development
|
245
245
|
prerelease: false
|
246
246
|
version_requirements: !ruby/object:Gem::Requirement
|
247
247
|
requirements:
|
248
248
|
- - "~>"
|
249
249
|
- !ruby/object:Gem::Version
|
250
|
-
version: '3.
|
250
|
+
version: '3.10'
|
251
251
|
- !ruby/object:Gem::Dependency
|
252
252
|
name: rspec-its
|
253
253
|
requirement: !ruby/object:Gem::Requirement
|
@@ -268,14 +268,14 @@ dependencies:
|
|
268
268
|
requirements:
|
269
269
|
- - "~>"
|
270
270
|
- !ruby/object:Gem::Version
|
271
|
-
version: '1.
|
271
|
+
version: '1.2'
|
272
272
|
type: :development
|
273
273
|
prerelease: false
|
274
274
|
version_requirements: !ruby/object:Gem::Requirement
|
275
275
|
requirements:
|
276
276
|
- - "~>"
|
277
277
|
- !ruby/object:Gem::Version
|
278
|
-
version: '1.
|
278
|
+
version: '1.2'
|
279
279
|
description: Mutation Testing for Ruby.
|
280
280
|
email:
|
281
281
|
- mbj@schirp-dso.com
|
@@ -342,7 +342,6 @@ files:
|
|
342
342
|
- lib/mutant/meta/example.rb
|
343
343
|
- lib/mutant/meta/example/dsl.rb
|
344
344
|
- lib/mutant/meta/example/verification.rb
|
345
|
-
- lib/mutant/minitest/coverage.rb
|
346
345
|
- lib/mutant/mutation.rb
|
347
346
|
- lib/mutant/mutator.rb
|
348
347
|
- lib/mutant/mutator/node.rb
|
@@ -417,16 +416,14 @@ files:
|
|
417
416
|
- lib/mutant/reporter/cli/format.rb
|
418
417
|
- lib/mutant/reporter/cli/printer.rb
|
419
418
|
- lib/mutant/reporter/cli/printer/config.rb
|
419
|
+
- lib/mutant/reporter/cli/printer/coverage_result.rb
|
420
420
|
- lib/mutant/reporter/cli/printer/env.rb
|
421
421
|
- lib/mutant/reporter/cli/printer/env_progress.rb
|
422
422
|
- lib/mutant/reporter/cli/printer/env_result.rb
|
423
423
|
- lib/mutant/reporter/cli/printer/isolation_result.rb
|
424
|
-
- lib/mutant/reporter/cli/printer/mutation_progress_result.rb
|
425
424
|
- lib/mutant/reporter/cli/printer/mutation_result.rb
|
426
425
|
- lib/mutant/reporter/cli/printer/status_progressive.rb
|
427
|
-
- lib/mutant/reporter/cli/printer/subject_progress.rb
|
428
426
|
- lib/mutant/reporter/cli/printer/subject_result.rb
|
429
|
-
- lib/mutant/reporter/cli/printer/test_result.rb
|
430
427
|
- lib/mutant/reporter/null.rb
|
431
428
|
- lib/mutant/reporter/sequence.rb
|
432
429
|
- lib/mutant/repository.rb
|
@@ -451,6 +448,7 @@ files:
|
|
451
448
|
- lib/mutant/util.rb
|
452
449
|
- lib/mutant/version.rb
|
453
450
|
- lib/mutant/warnings.rb
|
451
|
+
- lib/mutant/world.rb
|
454
452
|
- lib/mutant/zombifier.rb
|
455
453
|
homepage: https://github.com/mbj/mutant
|
456
454
|
licenses:
|
@@ -471,7 +469,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
471
469
|
- !ruby/object:Gem::Version
|
472
470
|
version: '0'
|
473
471
|
requirements: []
|
474
|
-
rubygems_version: 3.
|
472
|
+
rubygems_version: 3.1.4
|
475
473
|
signing_key:
|
476
474
|
specification_version: 4
|
477
475
|
summary: ''
|