mutant 0.10.29 → 0.10.30
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 +1 -1
- data/lib/mutant.rb +2 -0
- data/lib/mutant/bootstrap.rb +13 -5
- data/lib/mutant/config.rb +17 -5
- data/lib/mutant/env.rb +4 -0
- data/lib/mutant/expression.rb +1 -1
- data/lib/mutant/hooks.rb +77 -0
- data/lib/mutant/matcher/config.rb +1 -1
- data/lib/mutant/matcher/methods.rb +1 -1
- data/lib/mutant/parallel/worker.rb +3 -0
- data/lib/mutant/pipe.rb +12 -0
- data/lib/mutant/repository/diff.rb +1 -1
- data/lib/mutant/transform.rb +1 -1
- data/lib/mutant/version.rb +1 -1
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 92495691b68b4f556972ce8ec9bc8db2a30acb78980f509b27f2d12d4883b1f6
|
4
|
+
data.tar.gz: b7e46f8a0e0544243aab53a9f873bc602ec52e83caa9de3e851e4415b8f15899
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e7e49890adfcebdb4158d0e3d4afdc45589c49f1f66a4ecd700a7003dc3bf73acb967d6a51c1ea3c014edc1367ee1f5c79c4ebce8f5ca8c9dfac7f721649ad26
|
7
|
+
data.tar.gz: 644ec9e3cb8a5d768b52d709aaf86222fdf588822d139f008aaed3aadd2a9606b0524760e4cbec230d3ba17012374006febd1cbad1eab9839e4166560e3add51
|
data/bin/mutant
CHANGED
data/lib/mutant.rb
CHANGED
@@ -186,6 +186,7 @@ require 'mutant/selector'
|
|
186
186
|
require 'mutant/selector/expression'
|
187
187
|
require 'mutant/selector/null'
|
188
188
|
require 'mutant/world'
|
189
|
+
require 'mutant/hooks'
|
189
190
|
require 'mutant/config'
|
190
191
|
require 'mutant/config/coverage_criteria'
|
191
192
|
require 'mutant/cli'
|
@@ -257,6 +258,7 @@ module Mutant
|
|
257
258
|
Expression::Namespace::Recursive
|
258
259
|
]),
|
259
260
|
fail_fast: false,
|
261
|
+
hooks: EMPTY_ARRAY,
|
260
262
|
includes: EMPTY_ARRAY,
|
261
263
|
integration: nil,
|
262
264
|
isolation: Mutant::Isolation::Fork.new(WORLD),
|
data/lib/mutant/bootstrap.rb
CHANGED
@@ -31,8 +31,7 @@ module Mutant
|
|
31
31
|
#
|
32
32
|
# rubocop:disable Metrics/MethodLength
|
33
33
|
def self.call(world, config)
|
34
|
-
env = Env
|
35
|
-
.empty(world, config)
|
34
|
+
env = load_hooks(Env.empty(world, config))
|
36
35
|
.tap(&method(:infect))
|
37
36
|
.with(matchable_scopes: matchable_scopes(world, config))
|
38
37
|
|
@@ -49,6 +48,11 @@ module Mutant
|
|
49
48
|
end
|
50
49
|
# rubocop:enable Metrics/MethodLength
|
51
50
|
|
51
|
+
def self.load_hooks(env)
|
52
|
+
env.with(hooks: Hooks.load_config(env.config))
|
53
|
+
end
|
54
|
+
private_class_method :load_hooks
|
55
|
+
|
52
56
|
def self.start_subject(env, subjects)
|
53
57
|
start_expressions = env.config.matcher.start_expressions
|
54
58
|
|
@@ -63,10 +67,14 @@ module Mutant
|
|
63
67
|
private_class_method :start_subject
|
64
68
|
|
65
69
|
def self.infect(env)
|
66
|
-
config, world = env.config, env.world
|
70
|
+
config, hooks, world = env.config, env.hooks, env.world
|
71
|
+
|
72
|
+
hooks.run(:env_infection_pre, env)
|
73
|
+
|
74
|
+
config.includes.each(&world.load_path.public_method(:<<))
|
75
|
+
config.requires.each(&world.kernel.public_method(:require))
|
67
76
|
|
68
|
-
|
69
|
-
config.requires.each(&world.kernel.method(:require))
|
77
|
+
hooks.run(:env_infection_post, env)
|
70
78
|
end
|
71
79
|
private_class_method :infect
|
72
80
|
|
data/lib/mutant/config.rb
CHANGED
@@ -10,6 +10,7 @@ module Mutant
|
|
10
10
|
:coverage_criteria,
|
11
11
|
:expression_parser,
|
12
12
|
:fail_fast,
|
13
|
+
:hooks,
|
13
14
|
:includes,
|
14
15
|
:integration,
|
15
16
|
:isolation,
|
@@ -49,11 +50,12 @@ module Mutant
|
|
49
50
|
other.with(
|
50
51
|
coverage_criteria: coverage_criteria.merge(other.coverage_criteria),
|
51
52
|
fail_fast: fail_fast || other.fail_fast,
|
53
|
+
hooks: hooks + other.hooks,
|
52
54
|
includes: includes + other.includes,
|
53
|
-
jobs: other.jobs || jobs,
|
54
55
|
integration: other.integration || integration,
|
55
|
-
|
56
|
+
jobs: other.jobs || jobs,
|
56
57
|
matcher: matcher.merge(other.matcher),
|
58
|
+
mutation_timeout: other.mutation_timeout || mutation_timeout,
|
57
59
|
requires: requires + other.requires,
|
58
60
|
zombie: zombie || other.zombie
|
59
61
|
)
|
@@ -106,20 +108,30 @@ module Mutant
|
|
106
108
|
DEFAULT.with(jobs: Etc.nprocessors)
|
107
109
|
end
|
108
110
|
|
111
|
+
PATHNAME_ARRAY = Transform::Array.new(
|
112
|
+
Transform::Sequence.new(
|
113
|
+
[
|
114
|
+
Transform::STRING,
|
115
|
+
Transform::Exception.new(ArgumentError, Pathname.public_method(:new))
|
116
|
+
]
|
117
|
+
)
|
118
|
+
)
|
119
|
+
|
109
120
|
TRANSFORM = Transform::Sequence.new(
|
110
121
|
[
|
111
122
|
Transform::Exception.new(SystemCallError, :read.to_proc),
|
112
|
-
Transform::Exception.new(YAML::SyntaxError, YAML.
|
123
|
+
Transform::Exception.new(YAML::SyntaxError, YAML.public_method(:safe_load)),
|
113
124
|
Transform::Hash.new(
|
114
125
|
optional: [
|
115
126
|
Transform::Hash::Key.new('coverage_criteria', ->(value) { CoverageCriteria::TRANSFORM.call(value) }),
|
116
127
|
Transform::Hash::Key.new('fail_fast', Transform::BOOLEAN),
|
128
|
+
Transform::Hash::Key.new('hooks', PATHNAME_ARRAY),
|
117
129
|
Transform::Hash::Key.new('includes', Transform::STRING_ARRAY),
|
118
130
|
Transform::Hash::Key.new('integration', Transform::STRING),
|
119
131
|
Transform::Hash::Key.new('jobs', Transform::INTEGER),
|
132
|
+
Transform::Hash::Key.new('matcher', Matcher::Config::LOADER),
|
120
133
|
Transform::Hash::Key.new('mutation_timeout', Transform::FLOAT),
|
121
|
-
Transform::Hash::Key.new('requires', Transform::STRING_ARRAY)
|
122
|
-
Transform::Hash::Key.new('matcher', Matcher::Config::LOADER)
|
134
|
+
Transform::Hash::Key.new('requires', Transform::STRING_ARRAY)
|
123
135
|
],
|
124
136
|
required: []
|
125
137
|
),
|
data/lib/mutant/env.rb
CHANGED
@@ -5,6 +5,7 @@ module Mutant
|
|
5
5
|
class Env
|
6
6
|
include Adamantium, Anima.new(
|
7
7
|
:config,
|
8
|
+
:hooks,
|
8
9
|
:integration,
|
9
10
|
:matchable_scopes,
|
10
11
|
:mutations,
|
@@ -29,6 +30,7 @@ module Mutant
|
|
29
30
|
def self.empty(world, config)
|
30
31
|
new(
|
31
32
|
config: config,
|
33
|
+
hooks: Hooks.empty,
|
32
34
|
integration: Integration::Null.new(
|
33
35
|
expression_parser: config.expression_parser,
|
34
36
|
world: world
|
@@ -136,7 +138,9 @@ module Mutant
|
|
136
138
|
|
137
139
|
def run_mutation_tests(mutation, tests)
|
138
140
|
config.isolation.call(config.mutation_timeout) do
|
141
|
+
hooks.run(:mutation_insert_pre, mutation)
|
139
142
|
result = mutation.insert(world.kernel)
|
143
|
+
hooks.run(:mutation_insert_post, mutation)
|
140
144
|
|
141
145
|
if result.equal?(Loader::Result::VoidValue.instance)
|
142
146
|
Result::Test::VoidValue.instance
|
data/lib/mutant/expression.rb
CHANGED
data/lib/mutant/hooks.rb
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Mutant
|
4
|
+
class Hooks
|
5
|
+
include Adamantium, Concord::Public.new(:map)
|
6
|
+
|
7
|
+
DEFAULTS = %i[
|
8
|
+
env_infection_pre
|
9
|
+
env_infection_post
|
10
|
+
mutation_insert_post
|
11
|
+
mutation_insert_pre
|
12
|
+
].product([EMPTY_ARRAY]).to_h.transform_values(&:freeze).freeze
|
13
|
+
|
14
|
+
MESSAGE = 'Unknown hook %s'
|
15
|
+
|
16
|
+
private_constant(*constants(false))
|
17
|
+
|
18
|
+
class UnknownHook < RuntimeError; end
|
19
|
+
|
20
|
+
def self.assert_name(name)
|
21
|
+
fail UnknownHook, MESSAGE % name.inspect unless DEFAULTS.key?(name)
|
22
|
+
self
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.empty
|
26
|
+
new(DEFAULTS)
|
27
|
+
end
|
28
|
+
|
29
|
+
def merge(other)
|
30
|
+
self.class.new(
|
31
|
+
other.map.merge(map) { |_key, new, old| (old + new).freeze }.freeze
|
32
|
+
)
|
33
|
+
end
|
34
|
+
|
35
|
+
def run(name, payload)
|
36
|
+
Hooks.assert_name(name)
|
37
|
+
|
38
|
+
map.fetch(name).each { |block| block.call(payload) }
|
39
|
+
|
40
|
+
self
|
41
|
+
end
|
42
|
+
|
43
|
+
class Builder
|
44
|
+
def initialize
|
45
|
+
@map = DEFAULTS.transform_values(&:dup)
|
46
|
+
end
|
47
|
+
|
48
|
+
def register(name, &block)
|
49
|
+
Hooks.assert_name(name)
|
50
|
+
|
51
|
+
@map.fetch(name) << block
|
52
|
+
|
53
|
+
self
|
54
|
+
end
|
55
|
+
|
56
|
+
def to_hooks
|
57
|
+
Hooks.new(@map.transform_values(&:freeze).freeze)
|
58
|
+
end
|
59
|
+
end # Builder
|
60
|
+
|
61
|
+
# rubocop:disable Security/Eval
|
62
|
+
def self.load_pathname(pathname)
|
63
|
+
hooks = Builder.new
|
64
|
+
|
65
|
+
binding.eval(pathname.read, pathname.to_s)
|
66
|
+
|
67
|
+
hooks.to_hooks
|
68
|
+
end
|
69
|
+
# rubocop:enable Security/Eval
|
70
|
+
|
71
|
+
def self.load_config(config)
|
72
|
+
config.hooks.reduce(empty) do |current, path|
|
73
|
+
current.merge(load_pathname(path))
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end # Hooks
|
77
|
+
end # Mutant
|
@@ -25,7 +25,7 @@ module Mutant
|
|
25
25
|
|
26
26
|
private_constant(*constants(false))
|
27
27
|
|
28
|
-
DEFAULT = new(
|
28
|
+
DEFAULT = new(anima.attribute_names.map { |name| [name, []] }.to_h)
|
29
29
|
|
30
30
|
expression = Transform::Block.capture(:expression) do |input|
|
31
31
|
Mutant::Config::DEFAULT.expression_parser.call(input)
|
data/lib/mutant/pipe.rb
CHANGED
@@ -35,6 +35,18 @@ module Mutant
|
|
35
35
|
reader
|
36
36
|
end
|
37
37
|
|
38
|
+
# Set binmode (again)
|
39
|
+
#
|
40
|
+
# Ruby has a bug where the binmode setting may be lost duringa fork.
|
41
|
+
# This API allows to set the binmode again.
|
42
|
+
#
|
43
|
+
# @return [self]
|
44
|
+
def reset_binmode
|
45
|
+
reader.binmode
|
46
|
+
writer.binmode
|
47
|
+
self
|
48
|
+
end
|
49
|
+
|
38
50
|
class Connection
|
39
51
|
include Anima.new(:marshal, :reader, :writer)
|
40
52
|
|
data/lib/mutant/transform.rb
CHANGED
data/lib/mutant/version.rb
CHANGED
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.30
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Markus Schirp
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-04-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: diff-lcs
|
@@ -195,6 +195,7 @@ files:
|
|
195
195
|
- lib/mutant/expression/methods.rb
|
196
196
|
- lib/mutant/expression/namespace.rb
|
197
197
|
- lib/mutant/expression/parser.rb
|
198
|
+
- lib/mutant/hooks.rb
|
198
199
|
- lib/mutant/integration.rb
|
199
200
|
- lib/mutant/integration/null.rb
|
200
201
|
- lib/mutant/isolation.rb
|
@@ -363,7 +364,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
363
364
|
- !ruby/object:Gem::Version
|
364
365
|
version: '0'
|
365
366
|
requirements: []
|
366
|
-
rubygems_version: 3.
|
367
|
+
rubygems_version: 3.0.3
|
367
368
|
signing_key:
|
368
369
|
specification_version: 4
|
369
370
|
summary: ''
|