mutant 0.10.35 → 0.11.3
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/LICENSE +2 -2
- data/lib/mutant/bootstrap.rb +4 -0
- data/lib/mutant/cli/command/environment.rb +8 -0
- data/lib/mutant/config.rb +50 -18
- data/lib/mutant/expression/descendants.rb +19 -0
- data/lib/mutant/matcher/chain.rb +1 -1
- data/lib/mutant/matcher/descendants.rb +26 -0
- data/lib/mutant/matcher/method.rb +11 -1
- data/lib/mutant/matcher/methods.rb +30 -9
- data/lib/mutant/version.rb +1 -1
- data/lib/mutant/world.rb +14 -0
- data/lib/mutant.rb +47 -36
- metadata +23 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4fd616c16c6eb981572f300d63760de29c418e0c8c72b29b0462565aeec59271
|
4
|
+
data.tar.gz: cff1c3128b75347267692919f598642dc6906faff02253b8bb5cf0a738b7488e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0a1fe601d15da1235e4384c15346f3080021b8f08dfdd2313f60882f722d45bc824d8099fd13cebe77ea97edd06ecba0bbd2ff64ede9b7f5765e2115652f4202
|
7
|
+
data.tar.gz: b61a27b8b5119e489908bb43aa4aec0a348e552b443fa3b937ed20718f436e77740b0b891fc731fd1126eb5170525ffa7388d4ab555f9a7ef7e33812141b4ec7
|
data/LICENSE
CHANGED
@@ -5,8 +5,8 @@ END-USER LICENSE AGREEMENT
|
|
5
5
|
IMPORTANT: THIS SOFTWARE END-USER LICENSE AGREEMENT ("EULA") IS A LEGAL
|
6
6
|
AGREEMENT (“Agreement”) BETWEEN YOU (THE CUSTOMER, EITHER AS AN INDIVIDUAL OR,
|
7
7
|
IF PURCHASED OR OTHERWISE ACQUIRED BY OR FOR AN ENTITY, AS AN ENTITY) AND
|
8
|
-
|
9
|
-
PROCESS AND USING
|
8
|
+
SCHIRP DSO LTD. READ IT CAREFULLY BEFORE COMPLETING THE INSTALLATION
|
9
|
+
PROCESS AND USING MUTANT AND RELATED SOFTWARE COMPONENTS (“SOFTWARE”).
|
10
10
|
|
11
11
|
IT PROVIDES A LICENSE TO USE THE SOFTWARE AND CONTAINS WARRANTY INFORMATION
|
12
12
|
AND LIABILITY DISCLAIMERS. BY INSTALLING AND USING THE SOFTWARE, YOU ARE
|
data/lib/mutant/bootstrap.rb
CHANGED
@@ -71,6 +71,10 @@ module Mutant
|
|
71
71
|
|
72
72
|
hooks.run(:env_infection_pre, env)
|
73
73
|
|
74
|
+
config.environment_variables.each do |key, value|
|
75
|
+
world.environment_variables[key] = value
|
76
|
+
end
|
77
|
+
|
74
78
|
config.includes.each(&world.load_path.public_method(:<<))
|
75
79
|
config.requires.each(&world.kernel.public_method(:require))
|
76
80
|
|
@@ -62,6 +62,7 @@ module Mutant
|
|
62
62
|
set(matcher: @config.matcher.add(attribute, value))
|
63
63
|
end
|
64
64
|
|
65
|
+
# rubocop:disable Metrics/MethodLength
|
65
66
|
def add_environment_options(parser)
|
66
67
|
parser.separator('Environment:')
|
67
68
|
parser.on('--zombie', 'Run mutant zombified') do
|
@@ -73,7 +74,14 @@ module Mutant
|
|
73
74
|
parser.on('-r', '--require NAME', 'Require file with NAME') do |name|
|
74
75
|
add(:requires, name)
|
75
76
|
end
|
77
|
+
parser.on('--env KEY=VALUE', 'Set environment variable') do |value|
|
78
|
+
match = ENV_VARIABLE_KEY_VALUE_REGEXP.match(value) || fail("Invalid env variable: #{value.inspect}")
|
79
|
+
set(
|
80
|
+
environment_variables: @config.environment_variables.merge(match[:key] => match[:value])
|
81
|
+
)
|
82
|
+
end
|
76
83
|
end
|
84
|
+
# rubocop:enable Metrics/MethodLength
|
77
85
|
|
78
86
|
def add_integration_options(parser)
|
79
87
|
parser.separator('Integration:')
|
data/lib/mutant/config.rb
CHANGED
@@ -5,9 +5,12 @@ module Mutant
|
|
5
5
|
#
|
6
6
|
# Does not reference any "external" volatile state. The configuration applied
|
7
7
|
# to current environment is being represented by the Mutant::Env object.
|
8
|
+
#
|
9
|
+
# rubocop:disable Metrics/ClassLength
|
8
10
|
class Config
|
9
11
|
include Adamantium, Anima.new(
|
10
12
|
:coverage_criteria,
|
13
|
+
:environment_variables,
|
11
14
|
:expression_parser,
|
12
15
|
:fail_fast,
|
13
16
|
:hooks,
|
@@ -48,16 +51,17 @@ module Mutant
|
|
48
51
|
# rubocop:disable Metrics/MethodLength
|
49
52
|
def merge(other)
|
50
53
|
other.with(
|
51
|
-
coverage_criteria:
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
54
|
+
coverage_criteria: coverage_criteria.merge(other.coverage_criteria),
|
55
|
+
environment_variables: environment_variables.merge(other.environment_variables),
|
56
|
+
fail_fast: fail_fast || other.fail_fast,
|
57
|
+
hooks: hooks + other.hooks,
|
58
|
+
includes: includes + other.includes,
|
59
|
+
integration: other.integration || integration,
|
60
|
+
jobs: other.jobs || jobs,
|
61
|
+
matcher: matcher.merge(other.matcher),
|
62
|
+
mutation_timeout: other.mutation_timeout || mutation_timeout,
|
63
|
+
requires: requires + other.requires,
|
64
|
+
zombie: zombie || other.zombie
|
61
65
|
)
|
62
66
|
end
|
63
67
|
# rubocop:enable Metrics/AbcSize
|
@@ -117,6 +121,24 @@ module Mutant
|
|
117
121
|
)
|
118
122
|
)
|
119
123
|
|
124
|
+
# Parse a hash of environment variables
|
125
|
+
#
|
126
|
+
# @param [Hash<Object,Object>]
|
127
|
+
#
|
128
|
+
# @return [Either<String,Hash<String,String>]
|
129
|
+
#
|
130
|
+
def self.parse_environment_variables(hash)
|
131
|
+
invalid = hash.keys.reject { |key| key.instance_of?(String) }
|
132
|
+
return Either::Left.new("Non string keys: #{invalid}") if invalid.any?
|
133
|
+
|
134
|
+
invalid = hash.keys.grep_v(ENV_VARIABLE_KEY_REGEXP)
|
135
|
+
return Either::Left.new("Invalid keys: #{invalid}") if invalid.any?
|
136
|
+
|
137
|
+
invalid = hash.values.reject { |value| value.instance_of?(String) }
|
138
|
+
return Either::Left.new("Non string values: #{invalid}") if invalid.any?
|
139
|
+
|
140
|
+
Either::Right.new(hash)
|
141
|
+
end
|
120
142
|
TRANSFORM = Transform::Sequence.new(
|
121
143
|
[
|
122
144
|
Transform::Exception.new(SystemCallError, :read.to_proc),
|
@@ -124,14 +146,23 @@ module Mutant
|
|
124
146
|
Transform::Hash.new(
|
125
147
|
optional: [
|
126
148
|
Transform::Hash::Key.new('coverage_criteria', ->(value) { CoverageCriteria::TRANSFORM.call(value) }),
|
127
|
-
Transform::Hash::Key.new(
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
149
|
+
Transform::Hash::Key.new(
|
150
|
+
'environment_variables',
|
151
|
+
Transform::Sequence.new(
|
152
|
+
[
|
153
|
+
Transform::Primitive.new(Hash),
|
154
|
+
Transform::Block.capture(:environment_variables, &method(:parse_environment_variables))
|
155
|
+
]
|
156
|
+
)
|
157
|
+
),
|
158
|
+
Transform::Hash::Key.new('fail_fast', Transform::BOOLEAN),
|
159
|
+
Transform::Hash::Key.new('hooks', PATHNAME_ARRAY),
|
160
|
+
Transform::Hash::Key.new('includes', Transform::STRING_ARRAY),
|
161
|
+
Transform::Hash::Key.new('integration', Transform::STRING),
|
162
|
+
Transform::Hash::Key.new('jobs', Transform::INTEGER),
|
163
|
+
Transform::Hash::Key.new('matcher', Matcher::Config::LOADER),
|
164
|
+
Transform::Hash::Key.new('mutation_timeout', Transform::FLOAT),
|
165
|
+
Transform::Hash::Key.new('requires', Transform::STRING_ARRAY)
|
135
166
|
],
|
136
167
|
required: []
|
137
168
|
),
|
@@ -141,4 +172,5 @@ module Mutant
|
|
141
172
|
|
142
173
|
private_constant(:TRANSFORM)
|
143
174
|
end # Config
|
175
|
+
# rubocop:enable Metrics/ClassLength
|
144
176
|
end # Mutant
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Mutant
|
4
|
+
class Expression
|
5
|
+
class Descendants < self
|
6
|
+
include Anima.new(:const_name)
|
7
|
+
|
8
|
+
REGEXP = /\Adescendants:(?<const_name>.+)\z/.freeze
|
9
|
+
|
10
|
+
def syntax
|
11
|
+
"descendants:#{const_name}"
|
12
|
+
end
|
13
|
+
|
14
|
+
def matcher
|
15
|
+
Matcher::Descendants.new(const_name: const_name)
|
16
|
+
end
|
17
|
+
end # Descendants
|
18
|
+
end # Expression
|
19
|
+
end # Mutant
|
data/lib/mutant/matcher/chain.rb
CHANGED
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Mutant
|
4
|
+
class Matcher
|
5
|
+
# Matcher for all descendants by constant name
|
6
|
+
class Descendants < self
|
7
|
+
include Anima.new(:const_name)
|
8
|
+
|
9
|
+
def call(env)
|
10
|
+
const = env.world.try_const_get(const_name) or return EMPTY_ARRAY
|
11
|
+
|
12
|
+
Chain.new(
|
13
|
+
matched_scopes(env, const).map { |scope| Scope.new(scope.raw) }
|
14
|
+
).call(env)
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def matched_scopes(env, const)
|
20
|
+
env.matchable_scopes.select do |scope|
|
21
|
+
scope.raw.equal?(const) || const > scope.raw
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end # Descendant
|
25
|
+
end # Matcher
|
26
|
+
end # Mutant
|
@@ -82,7 +82,17 @@ module Mutant
|
|
82
82
|
end
|
83
83
|
|
84
84
|
def source_location
|
85
|
-
|
85
|
+
signature = sorbet_signature
|
86
|
+
|
87
|
+
if signature
|
88
|
+
signature.method.source_location
|
89
|
+
else
|
90
|
+
target_method.source_location
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def sorbet_signature
|
95
|
+
T::Private::Methods.signature_for_method(target_method)
|
86
96
|
end
|
87
97
|
|
88
98
|
def subject
|
@@ -21,7 +21,7 @@ module Mutant
|
|
21
21
|
# @return [Enumerable<Subject>]
|
22
22
|
def call(env)
|
23
23
|
Chain.new(
|
24
|
-
methods.map { |method| matcher.new(scope, method) }
|
24
|
+
methods(env).map { |method| matcher.new(scope, method) }
|
25
25
|
).call(env)
|
26
26
|
end
|
27
27
|
|
@@ -31,17 +31,16 @@ module Mutant
|
|
31
31
|
self.class::MATCHER
|
32
32
|
end
|
33
33
|
|
34
|
-
def methods
|
34
|
+
def methods(env)
|
35
35
|
candidate_names.each_with_object([]) do |name, methods|
|
36
|
-
method = access(name)
|
37
|
-
methods << method if method
|
36
|
+
method = access(env, name)
|
37
|
+
methods << method if method&.owner.equal?(candidate_scope)
|
38
38
|
end
|
39
39
|
end
|
40
|
-
memoize :methods
|
41
40
|
|
42
41
|
def candidate_names
|
43
42
|
CANDIDATE_NAMES
|
44
|
-
.map
|
43
|
+
.map { |name| candidate_scope.public_send(name, false) }
|
45
44
|
.reduce(:+)
|
46
45
|
.sort
|
47
46
|
end
|
@@ -55,7 +54,7 @@ module Mutant
|
|
55
54
|
|
56
55
|
private
|
57
56
|
|
58
|
-
def access(method_name)
|
57
|
+
def access(_env, method_name)
|
59
58
|
scope.method(method_name)
|
60
59
|
end
|
61
60
|
|
@@ -71,7 +70,7 @@ module Mutant
|
|
71
70
|
|
72
71
|
private
|
73
72
|
|
74
|
-
def access(method_name)
|
73
|
+
def access(_env, method_name)
|
75
74
|
scope.method(method_name)
|
76
75
|
end
|
77
76
|
|
@@ -84,11 +83,33 @@ module Mutant
|
|
84
83
|
class Instance < self
|
85
84
|
MATCHER = Matcher::Method::Instance
|
86
85
|
|
86
|
+
MESSAGE = <<~'MESSAGE'
|
87
|
+
Caught an exception while accessing a method with
|
88
|
+
#instance_method that is part of #{public,privat,protected}_instance_methods.
|
89
|
+
|
90
|
+
This is a bug in your ruby implementation its stdlib, libaries our your code.
|
91
|
+
|
92
|
+
Mutant will ignore this method:
|
93
|
+
|
94
|
+
Object: %<scope>s
|
95
|
+
Method: %<method_name>s
|
96
|
+
Exception: %<exception>s
|
97
|
+
|
98
|
+
See: https://github.com/mbj/mutant/issues/1273
|
99
|
+
MESSAGE
|
100
|
+
|
87
101
|
private
|
88
102
|
|
89
|
-
|
103
|
+
# rubocop:disable Lint/RescueException
|
104
|
+
def access(env, method_name)
|
90
105
|
scope.instance_method(method_name)
|
106
|
+
rescue Exception => exception
|
107
|
+
env.warn(
|
108
|
+
MESSAGE % { scope: scope, method_name: method_name, exception: exception }
|
109
|
+
)
|
110
|
+
nil
|
91
111
|
end
|
112
|
+
# rubocop:enable Lint/RescueException
|
92
113
|
|
93
114
|
def candidate_scope
|
94
115
|
scope
|
data/lib/mutant/version.rb
CHANGED
data/lib/mutant/world.rb
CHANGED
@@ -5,6 +5,7 @@ module Mutant
|
|
5
5
|
class World
|
6
6
|
include Adamantium, Anima.new(
|
7
7
|
:condition_variable,
|
8
|
+
:environment_variables,
|
8
9
|
:gem,
|
9
10
|
:gem_method,
|
10
11
|
:io,
|
@@ -49,6 +50,19 @@ module Mutant
|
|
49
50
|
end
|
50
51
|
end
|
51
52
|
|
53
|
+
# Try const get
|
54
|
+
#
|
55
|
+
# @param [String]
|
56
|
+
#
|
57
|
+
# @return [Class|Module|nil]
|
58
|
+
#
|
59
|
+
# rubocop:disable Lint/SuppressedException
|
60
|
+
def try_const_get(name)
|
61
|
+
kernel.const_get(name)
|
62
|
+
rescue NameError
|
63
|
+
end
|
64
|
+
# rubocop:enable Lint/SuppressedException
|
65
|
+
|
52
66
|
# Deadline
|
53
67
|
#
|
54
68
|
# @param [Float, nil] allowed_time
|
data/lib/mutant.rb
CHANGED
@@ -14,6 +14,7 @@ require 'pathname'
|
|
14
14
|
require 'regexp_parser'
|
15
15
|
require 'set'
|
16
16
|
require 'singleton'
|
17
|
+
require 'sorbet-runtime'
|
17
18
|
require 'stringio'
|
18
19
|
require 'unparser'
|
19
20
|
require 'yaml'
|
@@ -37,6 +38,11 @@ module Mutant
|
|
37
38
|
EMPTY_ARRAY = [].freeze
|
38
39
|
EMPTY_HASH = {}.freeze
|
39
40
|
SCOPE_OPERATOR = '::'
|
41
|
+
|
42
|
+
env_key = /[a-zA-Z_\d]+/
|
43
|
+
|
44
|
+
ENV_VARIABLE_KEY_VALUE_REGEXP = /\A(?<key>#{env_key}+)=(?<value>.*)\z/.freeze
|
45
|
+
ENV_VARIABLE_KEY_REGEXP = /\A#{env_key}\z/.freeze
|
40
46
|
end # Mutant
|
41
47
|
|
42
48
|
require 'mutant/procto'
|
@@ -163,23 +169,25 @@ require 'mutant/subject/method/instance'
|
|
163
169
|
require 'mutant/subject/method/singleton'
|
164
170
|
require 'mutant/subject/method/metaclass'
|
165
171
|
require 'mutant/matcher'
|
166
|
-
require 'mutant/matcher/config'
|
167
172
|
require 'mutant/matcher/chain'
|
173
|
+
require 'mutant/matcher/config'
|
174
|
+
require 'mutant/matcher/descendants'
|
175
|
+
require 'mutant/matcher/filter'
|
168
176
|
require 'mutant/matcher/method'
|
169
|
-
require 'mutant/matcher/method/singleton'
|
170
|
-
require 'mutant/matcher/method/metaclass'
|
171
177
|
require 'mutant/matcher/method/instance'
|
178
|
+
require 'mutant/matcher/method/metaclass'
|
179
|
+
require 'mutant/matcher/method/singleton'
|
172
180
|
require 'mutant/matcher/methods'
|
173
181
|
require 'mutant/matcher/namespace'
|
174
|
-
require 'mutant/matcher/scope'
|
175
|
-
require 'mutant/matcher/filter'
|
176
182
|
require 'mutant/matcher/null'
|
183
|
+
require 'mutant/matcher/scope'
|
177
184
|
require 'mutant/matcher/static'
|
178
185
|
require 'mutant/expression'
|
179
|
-
require 'mutant/expression/
|
186
|
+
require 'mutant/expression/descendants'
|
180
187
|
require 'mutant/expression/method'
|
181
188
|
require 'mutant/expression/methods'
|
182
189
|
require 'mutant/expression/namespace'
|
190
|
+
require 'mutant/expression/parser'
|
183
191
|
require 'mutant/test'
|
184
192
|
require 'mutant/timer'
|
185
193
|
require 'mutant/integration'
|
@@ -233,46 +241,49 @@ require 'mutant/license/subscription/commercial'
|
|
233
241
|
|
234
242
|
module Mutant
|
235
243
|
WORLD = World.new(
|
236
|
-
condition_variable:
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
244
|
+
condition_variable: ConditionVariable,
|
245
|
+
environment_variables: ENV,
|
246
|
+
gem: Gem,
|
247
|
+
gem_method: method(:gem),
|
248
|
+
io: IO,
|
249
|
+
json: JSON,
|
250
|
+
kernel: Kernel,
|
251
|
+
load_path: $LOAD_PATH,
|
252
|
+
marshal: Marshal,
|
253
|
+
mutex: Mutex,
|
254
|
+
object_space: ObjectSpace,
|
255
|
+
open3: Open3,
|
256
|
+
pathname: Pathname,
|
257
|
+
process: Process,
|
258
|
+
stderr: $stderr,
|
259
|
+
stdout: $stdout,
|
260
|
+
thread: Thread,
|
261
|
+
timer: Timer.new(Process)
|
253
262
|
)
|
254
263
|
|
255
264
|
# Reopen class to initialize constant to avoid dep circle
|
256
265
|
class Config
|
257
266
|
DEFAULT = new(
|
258
|
-
coverage_criteria:
|
259
|
-
expression_parser:
|
267
|
+
coverage_criteria: Config::CoverageCriteria::EMPTY,
|
268
|
+
expression_parser: Expression::Parser.new([
|
269
|
+
Expression::Descendants,
|
260
270
|
Expression::Method,
|
261
271
|
Expression::Methods,
|
262
272
|
Expression::Namespace::Exact,
|
263
273
|
Expression::Namespace::Recursive
|
264
274
|
]),
|
265
|
-
fail_fast:
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
275
|
+
fail_fast: false,
|
276
|
+
environment_variables: EMPTY_HASH,
|
277
|
+
hooks: EMPTY_ARRAY,
|
278
|
+
includes: EMPTY_ARRAY,
|
279
|
+
integration: nil,
|
280
|
+
isolation: Mutant::Isolation::Fork.new(WORLD),
|
281
|
+
jobs: nil,
|
282
|
+
matcher: Matcher::Config::DEFAULT,
|
283
|
+
mutation_timeout: nil,
|
284
|
+
reporter: Reporter::CLI.build(WORLD.stdout),
|
285
|
+
requires: EMPTY_ARRAY,
|
286
|
+
zombie: false
|
276
287
|
)
|
277
288
|
end # Config
|
278
289
|
|
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.
|
4
|
+
version: 0.11.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Markus Schirp
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-02-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: diff-lcs
|
@@ -30,14 +30,14 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 3.
|
33
|
+
version: 3.1.0
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: 3.
|
40
|
+
version: 3.1.0
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: regexp_parser
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -58,20 +58,34 @@ dependencies:
|
|
58
58
|
- - ">="
|
59
59
|
- !ruby/object:Gem::Version
|
60
60
|
version: 2.0.3
|
61
|
+
- !ruby/object:Gem::Dependency
|
62
|
+
name: sorbet-runtime
|
63
|
+
requirement: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - "~>"
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: 0.5.0
|
68
|
+
type: :runtime
|
69
|
+
prerelease: false
|
70
|
+
version_requirements: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - "~>"
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: 0.5.0
|
61
75
|
- !ruby/object:Gem::Dependency
|
62
76
|
name: unparser
|
63
77
|
requirement: !ruby/object:Gem::Requirement
|
64
78
|
requirements:
|
65
79
|
- - "~>"
|
66
80
|
- !ruby/object:Gem::Version
|
67
|
-
version: 0.6.
|
81
|
+
version: 0.6.4
|
68
82
|
type: :runtime
|
69
83
|
prerelease: false
|
70
84
|
version_requirements: !ruby/object:Gem::Requirement
|
71
85
|
requirements:
|
72
86
|
- - "~>"
|
73
87
|
- !ruby/object:Gem::Version
|
74
|
-
version: 0.6.
|
88
|
+
version: 0.6.4
|
75
89
|
- !ruby/object:Gem::Dependency
|
76
90
|
name: parallel
|
77
91
|
requirement: !ruby/object:Gem::Requirement
|
@@ -193,6 +207,7 @@ files:
|
|
193
207
|
- lib/mutant/context.rb
|
194
208
|
- lib/mutant/env.rb
|
195
209
|
- lib/mutant/expression.rb
|
210
|
+
- lib/mutant/expression/descendants.rb
|
196
211
|
- lib/mutant/expression/method.rb
|
197
212
|
- lib/mutant/expression/methods.rb
|
198
213
|
- lib/mutant/expression/namespace.rb
|
@@ -212,6 +227,7 @@ files:
|
|
212
227
|
- lib/mutant/matcher.rb
|
213
228
|
- lib/mutant/matcher/chain.rb
|
214
229
|
- lib/mutant/matcher/config.rb
|
230
|
+
- lib/mutant/matcher/descendants.rb
|
215
231
|
- lib/mutant/matcher/filter.rb
|
216
232
|
- lib/mutant/matcher/method.rb
|
217
233
|
- lib/mutant/matcher/method/instance.rb
|
@@ -368,7 +384,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
368
384
|
- !ruby/object:Gem::Version
|
369
385
|
version: '0'
|
370
386
|
requirements: []
|
371
|
-
rubygems_version: 3.
|
387
|
+
rubygems_version: 3.3.3
|
372
388
|
signing_key:
|
373
389
|
specification_version: 4
|
374
390
|
summary: ''
|