mutant 0.11.7 → 0.11.10
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/lib/mutant/ast/meta/optarg.rb +1 -1
- data/lib/mutant/ast/regexp/transformer/direct.rb +3 -11
- data/lib/mutant/matcher/method/metaclass.rb +1 -1
- data/lib/mutant/matcher/method.rb +2 -1
- data/lib/mutant/matcher/methods.rb +2 -2
- data/lib/mutant/matcher.rb +1 -1
- data/lib/mutant/mutator/node/argument.rb +1 -1
- data/lib/mutant/mutator/node/arguments.rb +8 -0
- data/lib/mutant/mutator/node/block.rb +3 -1
- data/lib/mutant/mutator/node/dynamic_literal.rb +1 -1
- data/lib/mutant/mutator/node/procarg_zero.rb +1 -5
- data/lib/mutant/mutator/node/regexp/named_group.rb +5 -5
- data/lib/mutant/parallel/driver.rb +18 -2
- data/lib/mutant/parser.rb +19 -1
- data/lib/mutant/runner.rb +4 -0
- data/lib/mutant/subject/config.rb +25 -0
- data/lib/mutant/subject.rb +5 -1
- data/lib/mutant/version.rb +1 -1
- data/lib/mutant.rb +1 -0
- metadata +10 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 163279d053e71f375fc6854b89e1ca0730d7de6a1cf883772097a635067fdc92
|
4
|
+
data.tar.gz: c943e8ad5544a90d967ac9c580557a1e41997de4a2363cffe829710f0a71c8ae
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1a130b60a8e53fb84d6b95897bc2749007df58d114b8201ac409eb40f203ee9f90804df51f49083c345784d420335eaeaa884299e0c1d37634be6d72875b5580
|
7
|
+
data.tar.gz: 18845045b045a1692c5574c092f7035560cab6267a8bd2a904266a69919630df59a47e0cc0d6edfc32717c834824b1b8d698da979aa7480359d363c1df9f1c1f
|
@@ -36,7 +36,6 @@ module Mutant
|
|
36
36
|
class ASTToExpression < Transformer::ASTToExpression
|
37
37
|
include LookupTable
|
38
38
|
|
39
|
-
# rubocop:disable Metrics/BlockLength
|
40
39
|
properties = ::Regexp::Syntax
|
41
40
|
.version_class("ruby/#{RUBY_VERSION}")
|
42
41
|
.features.fetch(:property)
|
@@ -44,14 +43,8 @@ module Mutant
|
|
44
43
|
property_specifier = "\\p{#{property}}"
|
45
44
|
non_property_specifier = "\\P{#{property}}"
|
46
45
|
|
47
|
-
|
48
|
-
|
49
|
-
non_property_regex = /#{non_property_specifier}/
|
50
|
-
# This is probably a regexp_parser bug, ignoring registration of that property
|
51
|
-
# See: https://github.com/ammar/regexp_parser/issues/84
|
52
|
-
rescue RegexpError
|
53
|
-
next
|
54
|
-
end
|
46
|
+
property_regex = /#{property_specifier}/
|
47
|
+
non_property_regex = /#{non_property_specifier}/
|
55
48
|
|
56
49
|
[
|
57
50
|
[
|
@@ -73,8 +66,7 @@ module Mutant
|
|
73
66
|
::Regexp::Parser.parse(non_property_regex).expressions.first.class
|
74
67
|
]
|
75
68
|
]
|
76
|
-
|
77
|
-
# rubocop:enable Metrics/BlockLength
|
69
|
+
end
|
78
70
|
|
79
71
|
# rubocop:disable Layout/LineLength
|
80
72
|
TABLE = Table.create(
|
@@ -99,6 +99,7 @@ module Mutant
|
|
99
99
|
node = matched_node_path.last || return
|
100
100
|
|
101
101
|
self.class::SUBJECT_CLASS.new(
|
102
|
+
config: Subject::Config.parse(ast.comment_associations.fetch(node, [])),
|
102
103
|
context: context,
|
103
104
|
node: node,
|
104
105
|
visibility: visibility
|
@@ -106,7 +107,7 @@ module Mutant
|
|
106
107
|
end
|
107
108
|
|
108
109
|
def matched_node_path
|
109
|
-
AST.find_last_path(ast, &method(:match?))
|
110
|
+
AST.find_last_path(ast.node, &method(:match?))
|
110
111
|
end
|
111
112
|
memoize :matched_node_path
|
112
113
|
|
@@ -85,9 +85,9 @@ module Mutant
|
|
85
85
|
|
86
86
|
MESSAGE = <<~'MESSAGE'
|
87
87
|
Caught an exception while accessing a method with
|
88
|
-
#instance_method that is part of #{public,
|
88
|
+
#instance_method that is part of #{public,private,protected}_instance_methods.
|
89
89
|
|
90
|
-
This is a bug in your ruby implementation its stdlib,
|
90
|
+
This is a bug in your ruby implementation, its stdlib, your dependencies, or your code.
|
91
91
|
|
92
92
|
Mutant will ignore this method:
|
93
93
|
|
data/lib/mutant/matcher.rb
CHANGED
@@ -26,7 +26,7 @@ module Mutant
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def self.allowed_subject?(config, subject)
|
29
|
-
select_subject?(config, subject) && !ignore_subject?(config, subject)
|
29
|
+
select_subject?(config, subject) && !ignore_subject?(config, subject) && !subject.inline_disabled?
|
30
30
|
end
|
31
31
|
private_class_method :allowed_subject?
|
32
32
|
|
@@ -16,6 +16,7 @@ module Mutant
|
|
16
16
|
emit_argument_presence
|
17
17
|
emit_argument_mutations
|
18
18
|
emit_mlhs_expansion
|
19
|
+
emit_procarg0_removal
|
19
20
|
end
|
20
21
|
|
21
22
|
def emit_argument_presence
|
@@ -75,6 +76,13 @@ module Mutant
|
|
75
76
|
end
|
76
77
|
end
|
77
78
|
|
79
|
+
def emit_procarg0_removal
|
80
|
+
return unless children.one? && n_procarg0?((procarg0 = Mutant::Util.one(children)))
|
81
|
+
|
82
|
+
arguments = procarg0.children
|
83
|
+
emit_type(*arguments) if arguments.count > 1
|
84
|
+
end
|
85
|
+
|
78
86
|
end # Arguments
|
79
87
|
end # Node
|
80
88
|
end # Mutator
|
@@ -7,14 +7,10 @@ module Mutant
|
|
7
7
|
|
8
8
|
handle :procarg0
|
9
9
|
|
10
|
-
children :argument
|
11
|
-
|
12
10
|
private
|
13
11
|
|
14
12
|
def dispatch
|
15
|
-
|
16
|
-
|
17
|
-
emit_type(s(:arg, :"_#{name}")) unless name.to_s.start_with?('_')
|
13
|
+
children.each_index(&method(:mutate_child))
|
18
14
|
end
|
19
15
|
end # ProcargZero
|
20
16
|
end # Node
|
@@ -8,25 +8,25 @@ module Mutant
|
|
8
8
|
class NamedGroup < Node
|
9
9
|
handle(:regexp_named_group)
|
10
10
|
|
11
|
-
children :name
|
11
|
+
children :name
|
12
12
|
|
13
13
|
private
|
14
14
|
|
15
15
|
def dispatch
|
16
|
-
return
|
16
|
+
return if remaining_children.empty?
|
17
17
|
|
18
|
-
|
18
|
+
remaining_children_indices.each(&method(:mutate_child))
|
19
19
|
|
20
20
|
# Allows unused captures to be kept and named if they are explicitly prefixed with an
|
21
21
|
# underscore, like we allow with unused local variables.
|
22
22
|
return if name_underscored?
|
23
23
|
|
24
|
-
emit(s(:regexp_passive_group,
|
24
|
+
emit(s(:regexp_passive_group, *remaining_children))
|
25
25
|
emit_name_underscore_mutation
|
26
26
|
end
|
27
27
|
|
28
28
|
def emit_name_underscore_mutation
|
29
|
-
emit_type("_#{name}",
|
29
|
+
emit_type("_#{name}", *remaining_children)
|
30
30
|
end
|
31
31
|
|
32
32
|
def name_underscored?
|
@@ -4,7 +4,7 @@ module Mutant
|
|
4
4
|
module Parallel
|
5
5
|
# Driver for parallelized execution
|
6
6
|
class Driver
|
7
|
-
include
|
7
|
+
include Anima.new(
|
8
8
|
:threads,
|
9
9
|
:var_active_jobs,
|
10
10
|
:var_final,
|
@@ -16,6 +16,11 @@ module Mutant
|
|
16
16
|
|
17
17
|
private(*anima.attribute_names)
|
18
18
|
|
19
|
+
def initialize(**attributes)
|
20
|
+
@alive = true
|
21
|
+
super
|
22
|
+
end
|
23
|
+
|
19
24
|
# Wait for computation to finish, with timeout
|
20
25
|
#
|
21
26
|
# @param [Float] timeout
|
@@ -23,11 +28,22 @@ module Mutant
|
|
23
28
|
# @return [Variable::Result<Sink#status>]
|
24
29
|
# current status
|
25
30
|
def wait_timeout(timeout)
|
26
|
-
var_final.take_timeout(timeout)
|
31
|
+
var_final.take_timeout(timeout) if @alive
|
27
32
|
|
28
33
|
finalize(status)
|
29
34
|
end
|
30
35
|
|
36
|
+
# Stop parallel computation
|
37
|
+
#
|
38
|
+
# This will cause all work to be immediately stopped.
|
39
|
+
#
|
40
|
+
# @return [self]
|
41
|
+
def stop
|
42
|
+
@alive = false
|
43
|
+
threads.each(&:kill)
|
44
|
+
self
|
45
|
+
end
|
46
|
+
|
31
47
|
private
|
32
48
|
|
33
49
|
def finalize(status)
|
data/lib/mutant/parser.rb
CHANGED
@@ -5,6 +5,13 @@ module Mutant
|
|
5
5
|
class Parser
|
6
6
|
include Adamantium, Equalizer.new
|
7
7
|
|
8
|
+
class AST
|
9
|
+
include Anima.new(
|
10
|
+
:node,
|
11
|
+
:comment_associations
|
12
|
+
)
|
13
|
+
end
|
14
|
+
|
8
15
|
# Initialize object
|
9
16
|
#
|
10
17
|
# @return [undefined]
|
@@ -18,7 +25,18 @@ module Mutant
|
|
18
25
|
#
|
19
26
|
# @return [AST::Node]
|
20
27
|
def call(path)
|
21
|
-
@cache[path] ||=
|
28
|
+
@cache[path] ||= parse(path.read)
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def parse(source)
|
34
|
+
node, comments = Unparser.parse_with_comments(source)
|
35
|
+
|
36
|
+
AST.new(
|
37
|
+
node: node,
|
38
|
+
comment_associations: ::Parser::Source::Comment.associate_by_identity(node, comments)
|
39
|
+
)
|
22
40
|
end
|
23
41
|
|
24
42
|
end # Parser
|
data/lib/mutant/runner.rb
CHANGED
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Mutant
|
4
|
+
class Subject
|
5
|
+
class Config
|
6
|
+
include Adamantium, Anima.new(:inline_disable)
|
7
|
+
|
8
|
+
DEFAULT = new(inline_disable: false)
|
9
|
+
|
10
|
+
DISABLE_REGEXP = /(\s|^)mutant:disable(?:\s|$)/.freeze
|
11
|
+
SYNTAX_REGEXP = /\A(?:#|=begin\n)/.freeze
|
12
|
+
|
13
|
+
def self.parse(comments)
|
14
|
+
new(
|
15
|
+
inline_disable: comments.any? { |comment| DISABLE_REGEXP.match?(comment_body(comment)) }
|
16
|
+
)
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.comment_body(comment)
|
20
|
+
comment.text.sub(SYNTAX_REGEXP, '')
|
21
|
+
end
|
22
|
+
private_class_method :comment_body
|
23
|
+
end # Config
|
24
|
+
end # Subject
|
25
|
+
end # Mutant
|
data/lib/mutant/subject.rb
CHANGED
@@ -4,7 +4,7 @@ module Mutant
|
|
4
4
|
# Subject of a mutation
|
5
5
|
class Subject
|
6
6
|
include AbstractType, Adamantium, Enumerable
|
7
|
-
include Anima.new(:context, :node)
|
7
|
+
include Anima.new(:config, :context, :node)
|
8
8
|
|
9
9
|
# Mutations for this subject
|
10
10
|
#
|
@@ -19,6 +19,10 @@ module Mutant
|
|
19
19
|
end
|
20
20
|
memoize :mutations
|
21
21
|
|
22
|
+
def inline_disabled?
|
23
|
+
config.inline_disable
|
24
|
+
end
|
25
|
+
|
22
26
|
# Source path
|
23
27
|
#
|
24
28
|
# @return [Pathname]
|
data/lib/mutant/version.rb
CHANGED
data/lib/mutant.rb
CHANGED
@@ -164,6 +164,7 @@ require 'mutant/loader'
|
|
164
164
|
require 'mutant/context'
|
165
165
|
require 'mutant/scope'
|
166
166
|
require 'mutant/subject'
|
167
|
+
require 'mutant/subject/config'
|
167
168
|
require 'mutant/subject/method'
|
168
169
|
require 'mutant/subject/method/instance'
|
169
170
|
require 'mutant/subject/method/singleton'
|
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.11.
|
4
|
+
version: 0.11.10
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Markus Schirp
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-05-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: diff-lcs
|
@@ -45,6 +45,9 @@ dependencies:
|
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
47
|
version: '2.3'
|
48
|
+
- - ">="
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
version: 2.3.1
|
48
51
|
type: :runtime
|
49
52
|
prerelease: false
|
50
53
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -52,6 +55,9 @@ dependencies:
|
|
52
55
|
- - "~>"
|
53
56
|
- !ruby/object:Gem::Version
|
54
57
|
version: '2.3'
|
58
|
+
- - ">="
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: 2.3.1
|
55
61
|
- !ruby/object:Gem::Dependency
|
56
62
|
name: sorbet-runtime
|
57
63
|
requirement: !ruby/object:Gem::Requirement
|
@@ -347,6 +353,7 @@ files:
|
|
347
353
|
- lib/mutant/selector/expression.rb
|
348
354
|
- lib/mutant/selector/null.rb
|
349
355
|
- lib/mutant/subject.rb
|
356
|
+
- lib/mutant/subject/config.rb
|
350
357
|
- lib/mutant/subject/method.rb
|
351
358
|
- lib/mutant/subject/method/instance.rb
|
352
359
|
- lib/mutant/subject/method/metaclass.rb
|
@@ -379,7 +386,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
379
386
|
- !ruby/object:Gem::Version
|
380
387
|
version: '0'
|
381
388
|
requirements: []
|
382
|
-
rubygems_version: 3.
|
389
|
+
rubygems_version: 3.1.6
|
383
390
|
signing_key:
|
384
391
|
specification_version: 4
|
385
392
|
summary: ''
|