mutant 0.10.4 → 0.10.9
Sign up to get free protection for your applications and to get access to all the features.
- 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 +80 -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/commercial.rb +2 -3
- data/lib/mutant/license/subscription/opensource.rb +0 -1
- 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 +91 -30
- data/lib/mutant/runner/sink.rb +12 -5
- 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 +12 -13
- 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
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e2d4849ffe2057370e38c3718afe4cbbfcbfaf76b058c4c5364ff2a7475a3122
|
4
|
+
data.tar.gz: 6e9abc09f95b929c6ee5b1f09745aa7ce01cc66ab70aaa3e044f2da5b897ce25
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '050159a447e4f328e9283cea9785dc08bd51d6132995ff9ecda4cdfbda08f665f8294607f5eeaf390e9b3a069ae69dab675fc2767b1300973ec9bfa2b918b70a'
|
7
|
+
data.tar.gz: 582384118f7e8df7091280f6bc78e6d6f95f612f28a0892637d1e1a845c93754df29f5e463e8a1a69ca5f85ed95e666f82ab4ac957bf3a896d3f34fb26a5693b
|
data/bin/mutant
CHANGED
@@ -10,7 +10,6 @@ require 'mutant'
|
|
10
10
|
|
11
11
|
command = Mutant::CLI.parse(
|
12
12
|
arguments: ARGV,
|
13
|
-
config: Mutant::Config::DEFAULT,
|
14
13
|
world: Mutant::WORLD
|
15
14
|
)
|
16
15
|
|
@@ -40,7 +39,6 @@ status =
|
|
40
39
|
|
41
40
|
Zombie::Mutant::CLI.parse(
|
42
41
|
arguments: ARGV,
|
43
|
-
config: Zombie::Mutant::Config::DEFAULT,
|
44
42
|
world: Zombie::Mutant::WORLD
|
45
43
|
).call
|
46
44
|
else
|
data/lib/mutant.rb
CHANGED
@@ -163,6 +163,7 @@ require 'mutant/integration/null'
|
|
163
163
|
require 'mutant/selector'
|
164
164
|
require 'mutant/selector/expression'
|
165
165
|
require 'mutant/selector/null'
|
166
|
+
require 'mutant/world'
|
166
167
|
require 'mutant/config'
|
167
168
|
require 'mutant/cli'
|
168
169
|
require 'mutant/cli/command'
|
@@ -178,16 +179,14 @@ require 'mutant/reporter/sequence'
|
|
178
179
|
require 'mutant/reporter/cli'
|
179
180
|
require 'mutant/reporter/cli/printer'
|
180
181
|
require 'mutant/reporter/cli/printer/config'
|
182
|
+
require 'mutant/reporter/cli/printer/coverage_result'
|
181
183
|
require 'mutant/reporter/cli/printer/env'
|
182
184
|
require 'mutant/reporter/cli/printer/env_progress'
|
183
185
|
require 'mutant/reporter/cli/printer/env_result'
|
184
186
|
require 'mutant/reporter/cli/printer/isolation_result'
|
185
|
-
require 'mutant/reporter/cli/printer/mutation_progress_result'
|
186
187
|
require 'mutant/reporter/cli/printer/mutation_result'
|
187
188
|
require 'mutant/reporter/cli/printer/status_progressive'
|
188
|
-
require 'mutant/reporter/cli/printer/subject_progress'
|
189
189
|
require 'mutant/reporter/cli/printer/subject_result'
|
190
|
-
require 'mutant/reporter/cli/printer/test_result'
|
191
190
|
require 'mutant/reporter/cli/format'
|
192
191
|
require 'mutant/repository'
|
193
192
|
require 'mutant/repository/diff'
|
@@ -218,12 +217,14 @@ module Mutant
|
|
218
217
|
stderr: $stderr,
|
219
218
|
stdout: $stdout,
|
220
219
|
thread: Thread,
|
220
|
+
timer: Timer.new(Process),
|
221
221
|
warnings: Warnings.new(Warning)
|
222
222
|
)
|
223
223
|
|
224
224
|
# Reopen class to initialize constant to avoid dep circle
|
225
225
|
class Config
|
226
226
|
DEFAULT = new(
|
227
|
+
coverage_criteria: Config::CoverageCriteria::DEFAULT,
|
227
228
|
expression_parser: Expression::Parser.new([
|
228
229
|
Expression::Method,
|
229
230
|
Expression::Methods,
|
@@ -232,10 +233,11 @@ module Mutant
|
|
232
233
|
]),
|
233
234
|
fail_fast: false,
|
234
235
|
includes: EMPTY_ARRAY,
|
235
|
-
integration:
|
236
|
+
integration: nil,
|
236
237
|
isolation: Mutant::Isolation::Fork.new(WORLD),
|
237
|
-
jobs:
|
238
|
+
jobs: nil,
|
238
239
|
matcher: Matcher::Config::DEFAULT,
|
240
|
+
mutation_timeout: nil,
|
239
241
|
reporter: Reporter::CLI.build(WORLD.stdout),
|
240
242
|
requires: EMPTY_ARRAY,
|
241
243
|
zombie: false
|
data/lib/mutant/cli/command.rb
CHANGED
@@ -4,7 +4,7 @@ module Mutant
|
|
4
4
|
module CLI
|
5
5
|
# rubocop:disable Metrics/ClassLength
|
6
6
|
class Command
|
7
|
-
include AbstractType, Anima.new(:world, :
|
7
|
+
include AbstractType, Anima.new(:world, :main, :parent, :arguments)
|
8
8
|
|
9
9
|
include Equalizer.new(:parent, :arguments)
|
10
10
|
|
@@ -105,7 +105,7 @@ module Mutant
|
|
105
105
|
def parse
|
106
106
|
Either
|
107
107
|
.wrap_error(OptionParser::InvalidOption) { parser.order(arguments) }
|
108
|
-
.lmap
|
108
|
+
.lmap(&method(:with_help))
|
109
109
|
.bind(&method(:parse_remaining))
|
110
110
|
end
|
111
111
|
|
@@ -159,9 +159,7 @@ module Mutant
|
|
159
159
|
command_name, *arguments = arguments
|
160
160
|
|
161
161
|
if command_name.nil?
|
162
|
-
Either::Left.new(
|
163
|
-
"Missing required subcommand!\n\n#{parser}"
|
164
|
-
)
|
162
|
+
Either::Left.new(with_help('Missing required subcommand!'))
|
165
163
|
else
|
166
164
|
find_command(command_name).bind do |command|
|
167
165
|
command.parse(**to_h, parent: self, arguments: arguments)
|
@@ -187,9 +185,13 @@ module Mutant
|
|
187
185
|
if subcommand
|
188
186
|
Either::Right.new(subcommand)
|
189
187
|
else
|
190
|
-
Either::Left.new("
|
188
|
+
Either::Left.new(with_help("Cannot find subcommand #{name.inspect}"))
|
191
189
|
end
|
192
190
|
end
|
191
|
+
|
192
|
+
def with_help(message)
|
193
|
+
"#{full_name}: #{message}\n\n#{parser}"
|
194
|
+
end
|
193
195
|
end # Command
|
194
196
|
# rubocop:enable Metrics/ClassLength
|
195
197
|
end # CLI
|
@@ -28,20 +28,30 @@ module Mutant
|
|
28
28
|
#
|
29
29
|
# @return [Bool]
|
30
30
|
def zombie?
|
31
|
-
config.zombie
|
31
|
+
@config.zombie
|
32
32
|
end
|
33
33
|
|
34
34
|
private
|
35
35
|
|
36
|
+
def initialize(attributes)
|
37
|
+
super(attributes)
|
38
|
+
@config = Config.env
|
39
|
+
end
|
40
|
+
|
36
41
|
def execute
|
37
42
|
soft_fail(License.apply(world))
|
38
|
-
.bind { Config.load_config_file(world
|
39
|
-
.
|
43
|
+
.bind { Config.load_config_file(world) }
|
44
|
+
.fmap(&method(:expand))
|
45
|
+
.bind { Bootstrap.apply(world, @config) }
|
40
46
|
.bind(&Runner.public_method(:apply))
|
41
47
|
.from_right { |error| world.stderr.puts(error); return false }
|
42
48
|
.success?
|
43
49
|
end
|
44
50
|
|
51
|
+
def expand(file_config)
|
52
|
+
@config = @config.merge(file_config)
|
53
|
+
end
|
54
|
+
|
45
55
|
def soft_fail(result)
|
46
56
|
result.either(
|
47
57
|
lambda do |message|
|
@@ -60,7 +70,7 @@ module Mutant
|
|
60
70
|
end
|
61
71
|
|
62
72
|
def parse_remaining_arguments(arguments)
|
63
|
-
traverse(config.expression_parser.public_method(:apply), arguments)
|
73
|
+
traverse(@config.expression_parser.public_method(:apply), arguments)
|
64
74
|
.fmap do |match_expressions|
|
65
75
|
matcher(match_expressions: match_expressions)
|
66
76
|
self
|
@@ -78,19 +88,19 @@ module Mutant
|
|
78
88
|
end
|
79
89
|
|
80
90
|
def set(**attributes)
|
81
|
-
@config = config.with(attributes)
|
91
|
+
@config = @config.with(attributes)
|
82
92
|
end
|
83
93
|
|
84
94
|
def matcher(**attributes)
|
85
|
-
set(matcher: config.matcher.with(attributes))
|
95
|
+
set(matcher: @config.matcher.with(attributes))
|
86
96
|
end
|
87
97
|
|
88
98
|
def add(attribute, value)
|
89
|
-
set(attribute => config.public_send(attribute) + [value])
|
99
|
+
set(attribute => @config.public_send(attribute) + [value])
|
90
100
|
end
|
91
101
|
|
92
102
|
def add_matcher(attribute, value)
|
93
|
-
set(matcher: config.matcher.add(attribute, value))
|
103
|
+
set(matcher: @config.matcher.add(attribute, value))
|
94
104
|
end
|
95
105
|
|
96
106
|
def add_environment_options(parser)
|
@@ -119,10 +129,10 @@ module Mutant
|
|
119
129
|
parser.separator('Matcher:')
|
120
130
|
|
121
131
|
parser.on('--ignore-subject EXPRESSION', 'Ignore subjects that match EXPRESSION as prefix') do |pattern|
|
122
|
-
add_matcher(:ignore_expressions, config.expression_parser.apply(pattern).from_right)
|
132
|
+
add_matcher(:ignore_expressions, @config.expression_parser.apply(pattern).from_right)
|
123
133
|
end
|
124
134
|
parser.on('--start-subject EXPRESSION', 'Start mutation testing at a specific subject') do |pattern|
|
125
|
-
add_matcher(:start_expressions, config.expression_parser.apply(pattern).from_right)
|
135
|
+
add_matcher(:start_expressions, @config.expression_parser.apply(pattern).from_right)
|
126
136
|
end
|
127
137
|
parser.on('--since REVISION', 'Only select subjects touched since REVISION') do |revision|
|
128
138
|
add_matcher(
|
@@ -143,6 +153,9 @@ module Mutant
|
|
143
153
|
parser.on('-j', '--jobs NUMBER', 'Number of kill jobs. Defaults to number of processors.') do |number|
|
144
154
|
set(jobs: Integer(number))
|
145
155
|
end
|
156
|
+
parser.on('-t', '--mutation-timeout NUMBER', 'Per mutation analysis timeout') do |number|
|
157
|
+
set(mutation_timeout: Float(number))
|
158
|
+
end
|
146
159
|
end
|
147
160
|
end # Run
|
148
161
|
# rubocop:enable Metrics/ClassLength
|
data/lib/mutant/config.rb
CHANGED
@@ -1,61 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
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
|
-
:warnings
|
24
|
-
)
|
25
|
-
|
26
|
-
INSPECT = '#<Mutant::World>'
|
27
|
-
|
28
|
-
private_constant(*constants(false))
|
29
|
-
|
30
|
-
# Object inspection
|
31
|
-
#
|
32
|
-
# @return [String]
|
33
|
-
def inspect
|
34
|
-
INSPECT
|
35
|
-
end
|
36
|
-
|
37
|
-
# Capture stdout of a command
|
38
|
-
#
|
39
|
-
# @param [Array<String>] command
|
40
|
-
#
|
41
|
-
# @return [Either<String,String>]
|
42
|
-
def capture_stdout(command)
|
43
|
-
stdout, status = open3.capture2(*command, binmode: true)
|
44
|
-
|
45
|
-
if status.success?
|
46
|
-
Either::Right.new(stdout)
|
47
|
-
else
|
48
|
-
Either::Left.new("Command #{command} failed!")
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end # World
|
52
|
-
|
53
4
|
# Standalone configuration of a mutant execution.
|
54
5
|
#
|
55
6
|
# Does not reference any "external" volatile state. The configuration applied
|
56
7
|
# to current environment is being represented by the Mutant::Env object.
|
57
8
|
class Config
|
58
9
|
include Adamantium::Flat, Anima.new(
|
10
|
+
:coverage_criteria,
|
59
11
|
:expression_parser,
|
60
12
|
:fail_fast,
|
61
13
|
:includes,
|
@@ -63,6 +15,7 @@ module Mutant
|
|
63
15
|
:isolation,
|
64
16
|
:jobs,
|
65
17
|
:matcher,
|
18
|
+
:mutation_timeout,
|
66
19
|
:reporter,
|
67
20
|
:requires,
|
68
21
|
:zombie
|
@@ -72,30 +25,6 @@ module Mutant
|
|
72
25
|
define_method(:"#{name}?") { public_send(name) }
|
73
26
|
end
|
74
27
|
|
75
|
-
boolean = Transform::Boolean.new
|
76
|
-
integer = Transform::Primitive.new(Integer)
|
77
|
-
string = Transform::Primitive.new(String)
|
78
|
-
|
79
|
-
string_array = Transform::Array.new(string)
|
80
|
-
|
81
|
-
TRANSFORM = Transform::Sequence.new(
|
82
|
-
[
|
83
|
-
Transform::Exception.new(SystemCallError, :read.to_proc),
|
84
|
-
Transform::Exception.new(YAML::SyntaxError, YAML.method(:safe_load)),
|
85
|
-
Transform::Hash.new(
|
86
|
-
optional: [
|
87
|
-
Transform::Hash::Key.new('fail_fast', boolean),
|
88
|
-
Transform::Hash::Key.new('includes', string_array),
|
89
|
-
Transform::Hash::Key.new('integration', string),
|
90
|
-
Transform::Hash::Key.new('jobs', integer),
|
91
|
-
Transform::Hash::Key.new('requires', string_array)
|
92
|
-
],
|
93
|
-
required: []
|
94
|
-
),
|
95
|
-
Transform::Hash::Symbolize.new
|
96
|
-
]
|
97
|
-
)
|
98
|
-
|
99
28
|
MORE_THAN_ONE_CONFIG_FILE = <<~'MESSAGE'
|
100
29
|
Found more than one candidate for use as implicit config file: %s
|
101
30
|
MESSAGE
|
@@ -108,17 +37,62 @@ module Mutant
|
|
108
37
|
|
109
38
|
private_constant(*constants(false))
|
110
39
|
|
40
|
+
class CoverageCriteria
|
41
|
+
include Anima.new(:process_abort, :test_result, :timeout)
|
42
|
+
|
43
|
+
DEFAULT = new(
|
44
|
+
process_abort: false,
|
45
|
+
test_result: true,
|
46
|
+
timeout: false
|
47
|
+
)
|
48
|
+
|
49
|
+
TRANSFORM =
|
50
|
+
Transform::Sequence.new(
|
51
|
+
[
|
52
|
+
Transform::Hash.new(
|
53
|
+
optional: [
|
54
|
+
Transform::Hash::Key.new('process_abort', Transform::BOOLEAN),
|
55
|
+
Transform::Hash::Key.new('test_result', Transform::BOOLEAN),
|
56
|
+
Transform::Hash::Key.new('timeout', Transform::BOOLEAN)
|
57
|
+
],
|
58
|
+
required: []
|
59
|
+
),
|
60
|
+
Transform::Hash::Symbolize.new,
|
61
|
+
->(value) { Either::Right.new(DEFAULT.with(**value)) }
|
62
|
+
]
|
63
|
+
)
|
64
|
+
end # CoverageCriteria
|
65
|
+
|
66
|
+
# Merge with other config
|
67
|
+
#
|
68
|
+
# @param [Config] other
|
69
|
+
#
|
70
|
+
# @return [Config]
|
71
|
+
def merge(other)
|
72
|
+
other.with(
|
73
|
+
fail_fast: fail_fast || other.fail_fast,
|
74
|
+
includes: other.includes + includes,
|
75
|
+
jobs: other.jobs || jobs,
|
76
|
+
integration: other.integration || integration,
|
77
|
+
mutation_timeout: other.mutation_timeout || mutation_timeout,
|
78
|
+
matcher: matcher.merge(other.matcher),
|
79
|
+
requires: other.requires + requires,
|
80
|
+
zombie: zombie || other.zombie
|
81
|
+
)
|
82
|
+
end
|
83
|
+
|
111
84
|
# Load config file
|
112
85
|
#
|
113
86
|
# @param [World] world
|
114
87
|
# @param [Config] config
|
115
88
|
#
|
116
89
|
# @return [Either<String,Config>]
|
117
|
-
def self.load_config_file(world
|
118
|
-
|
90
|
+
def self.load_config_file(world)
|
91
|
+
config = DEFAULT
|
92
|
+
files = CANDIDATES.map(&world.pathname.public_method(:new)).select(&:readable?)
|
119
93
|
|
120
94
|
if files.one?
|
121
|
-
load_contents(files.first).fmap(&config.
|
95
|
+
load_contents(files.first).fmap(&config.public_method(:with))
|
122
96
|
elsif files.empty?
|
123
97
|
Either::Right.new(config)
|
124
98
|
else
|
@@ -129,9 +103,38 @@ module Mutant
|
|
129
103
|
def self.load_contents(path)
|
130
104
|
Transform::Named
|
131
105
|
.new(path.to_s, TRANSFORM)
|
132
|
-
.
|
106
|
+
.call(path)
|
133
107
|
.lmap(&:compact_message)
|
134
108
|
end
|
135
109
|
private_class_method :load_contents
|
110
|
+
|
111
|
+
# The configuration from the environment
|
112
|
+
#
|
113
|
+
# @return [Config]
|
114
|
+
def self.env
|
115
|
+
DEFAULT.with(jobs: Etc.nprocessors)
|
116
|
+
end
|
117
|
+
|
118
|
+
TRANSFORM = Transform::Sequence.new(
|
119
|
+
[
|
120
|
+
Transform::Exception.new(SystemCallError, :read.to_proc),
|
121
|
+
Transform::Exception.new(YAML::SyntaxError, YAML.method(:safe_load)),
|
122
|
+
Transform::Hash.new(
|
123
|
+
optional: [
|
124
|
+
Transform::Hash::Key.new('coverage_criteria', CoverageCriteria::TRANSFORM),
|
125
|
+
Transform::Hash::Key.new('fail_fast', Transform::BOOLEAN),
|
126
|
+
Transform::Hash::Key.new('includes', Transform::STRING_ARRAY),
|
127
|
+
Transform::Hash::Key.new('integration', Transform::STRING),
|
128
|
+
Transform::Hash::Key.new('jobs', Transform::INTEGER),
|
129
|
+
Transform::Hash::Key.new('mutation_timeout', Transform::FLOAT),
|
130
|
+
Transform::Hash::Key.new('requires', Transform::STRING_ARRAY)
|
131
|
+
],
|
132
|
+
required: []
|
133
|
+
),
|
134
|
+
Transform::Hash::Symbolize.new
|
135
|
+
]
|
136
|
+
)
|
137
|
+
|
138
|
+
private_constant(:TRANSFORM)
|
136
139
|
end # Config
|
137
140
|
end # Mutant
|
data/lib/mutant/env.rb
CHANGED
@@ -24,10 +24,15 @@ module Mutant
|
|
24
24
|
# @param [Config] config
|
25
25
|
#
|
26
26
|
# @return [Env]
|
27
|
+
#
|
28
|
+
# rubocop:disable Metrics/MethodLength
|
27
29
|
def self.empty(world, config)
|
28
30
|
new(
|
29
31
|
config: config,
|
30
|
-
integration: Integration::Null.new(
|
32
|
+
integration: Integration::Null.new(
|
33
|
+
expression_parser: config.expression_parser,
|
34
|
+
timer: world.timer
|
35
|
+
),
|
31
36
|
matchable_scopes: EMPTY_ARRAY,
|
32
37
|
mutations: EMPTY_ARRAY,
|
33
38
|
parser: Parser.new,
|
@@ -36,6 +41,7 @@ module Mutant
|
|
36
41
|
world: world
|
37
42
|
)
|
38
43
|
end
|
44
|
+
# rubocop:enable Metrics/MethodLength
|
39
45
|
|
40
46
|
# Kill mutation
|
41
47
|
#
|
@@ -43,14 +49,14 @@ module Mutant
|
|
43
49
|
#
|
44
50
|
# @return [Result::Mutation]
|
45
51
|
def kill(mutation)
|
46
|
-
start =
|
52
|
+
start = timer.now
|
47
53
|
|
48
54
|
tests = selections.fetch(mutation.subject)
|
49
55
|
|
50
56
|
Result::Mutation.new(
|
51
57
|
isolation_result: run_mutation_tests(mutation, tests),
|
52
58
|
mutation: mutation,
|
53
|
-
runtime:
|
59
|
+
runtime: timer.now - start
|
54
60
|
)
|
55
61
|
end
|
56
62
|
|
@@ -127,7 +133,7 @@ module Mutant
|
|
127
133
|
private
|
128
134
|
|
129
135
|
def run_mutation_tests(mutation, tests)
|
130
|
-
config.isolation.call do
|
136
|
+
config.isolation.call(config.mutation_timeout) do
|
131
137
|
result = mutation.insert(world.kernel)
|
132
138
|
|
133
139
|
if result.equal?(Loader::Result::VoidValue.instance)
|
@@ -138,5 +144,9 @@ module Mutant
|
|
138
144
|
end
|
139
145
|
end
|
140
146
|
|
147
|
+
def timer
|
148
|
+
world.timer
|
149
|
+
end
|
150
|
+
|
141
151
|
end # Env
|
142
152
|
end # Mutant
|