mutant 0.11.11 → 0.11.14
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/mutant/ast/find_metaclass_containing.rb +6 -6
- data/lib/mutant/ast/meta/const.rb +1 -1
- data/lib/mutant/ast/meta/optarg.rb +1 -1
- data/lib/mutant/ast/meta/resbody.rb +1 -1
- data/lib/mutant/ast/meta/send.rb +1 -1
- data/lib/mutant/ast/meta/symbol.rb +1 -1
- data/lib/mutant/ast/meta.rb +1 -1
- data/lib/mutant/ast/named_children.rb +1 -1
- data/lib/mutant/ast/node_predicates.rb +1 -1
- data/lib/mutant/ast/nodes.rb +1 -1
- data/lib/mutant/ast/pattern/lexer.rb +1 -1
- data/lib/mutant/ast/pattern/parser.rb +1 -1
- data/lib/mutant/ast/pattern/source.rb +1 -1
- data/lib/mutant/ast/pattern/token.rb +1 -1
- data/lib/mutant/ast/pattern.rb +1 -1
- data/lib/mutant/ast/regexp/transformer/direct.rb +1 -1
- data/lib/mutant/ast/regexp/transformer/named_group.rb +1 -1
- data/lib/mutant/ast/regexp/transformer/options_group.rb +1 -1
- data/lib/mutant/ast/regexp/transformer/quantifier.rb +1 -1
- data/lib/mutant/ast/regexp/transformer/recursive.rb +1 -1
- data/lib/mutant/ast/regexp/transformer/root.rb +1 -1
- data/lib/mutant/ast/regexp/transformer/text.rb +1 -1
- data/lib/mutant/ast/regexp/transformer.rb +1 -1
- data/lib/mutant/ast/regexp.rb +1 -1
- data/lib/mutant/ast/sexp.rb +1 -1
- data/lib/mutant/ast/structure.rb +8 -3
- data/lib/mutant/ast/types.rb +1 -1
- data/lib/mutant/ast.rb +31 -29
- data/lib/mutant/bootstrap.rb +8 -7
- data/lib/mutant/cli/command/environment.rb +5 -3
- data/lib/mutant/cli/command/util.rb +17 -2
- data/lib/mutant/config.rb +76 -40
- data/lib/mutant/env.rb +1 -1
- data/lib/mutant/license/subscription/opensource.rb +13 -3
- data/lib/mutant/matcher/method/instance.rb +3 -2
- data/lib/mutant/matcher/method/metaclass.rb +4 -3
- data/lib/mutant/matcher/method/singleton.rb +3 -2
- data/lib/mutant/matcher/method.rb +36 -20
- data/lib/mutant/meta/example.rb +4 -1
- data/lib/mutant/mutation/config.rb +36 -0
- data/lib/mutant/mutator/node/arguments.rb +1 -1
- data/lib/mutant/mutator/node/begin.rb +2 -1
- data/lib/mutant/mutator/node/block.rb +5 -3
- data/lib/mutant/mutator/node/define.rb +5 -2
- data/lib/mutant/mutator/node/kwargs.rb +2 -2
- data/lib/mutant/mutator/node/literal/regex.rb +1 -1
- data/lib/mutant/mutator/node/literal/symbol.rb +2 -2
- data/lib/mutant/mutator/node/named_value/constant_assignment.rb +1 -1
- data/lib/mutant/mutator/node/named_value/variable_assignment.rb +2 -2
- data/lib/mutant/mutator/node/resbody.rb +0 -10
- data/lib/mutant/mutator/node.rb +47 -1
- data/lib/mutant/mutator/util/array.rb +0 -17
- data/lib/mutant/mutator.rb +2 -26
- data/lib/mutant/parser.rb +0 -7
- data/lib/mutant/reporter/cli/printer/config.rb +1 -1
- data/lib/mutant/subject/config.rb +5 -4
- data/lib/mutant/subject.rb +4 -1
- data/lib/mutant/transform.rb +14 -0
- data/lib/mutant/version.rb +1 -1
- data/lib/mutant.rb +2 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 58b6affbd17beee4a525b5efa35e83b18d3d65316ec5abd2b773c4722377e79b
|
4
|
+
data.tar.gz: 10b60ffd99ea8b477537bed09af2c122ffc14152a69c9a020ed09cca73dfa2d8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 39bd2f27290e3e3ba1ec6be8ae515759db5970fe121e9732797819bcb243c1038b0582c49e52fe7c6ab99d9332dfce4eb4fcf62b75558bd79954929bb432a8fd
|
7
|
+
data.tar.gz: da7555f1f168b6359163aeb3cd58dd69b5cb553da005830169cabdc9de949317f7ddae0790e6e84cc7990dfcd3d7c0c2c9b85f05c0b7b8de18bf96079d2c58e7
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Mutant
|
4
|
-
|
4
|
+
class AST
|
5
5
|
# Given an AST, finds the sclass that directly(-ish) contains the provided
|
6
6
|
# node.
|
7
7
|
# This won't match arbitrarily complex structures - it only searches the
|
@@ -10,7 +10,7 @@ module Mutant
|
|
10
10
|
# Descending into 'begin' nodes is supported because these are generated for
|
11
11
|
# the one-line syntax class << self; def foo; end
|
12
12
|
class FindMetaclassContaining
|
13
|
-
include NodePredicates, Concord.new(:
|
13
|
+
include NodePredicates, Concord.new(:ast, :target), Procto
|
14
14
|
|
15
15
|
SCLASS_BODY_INDEX = 1
|
16
16
|
|
@@ -22,11 +22,11 @@ module Mutant
|
|
22
22
|
#
|
23
23
|
# @api private
|
24
24
|
def call
|
25
|
-
|
26
|
-
|
25
|
+
Structure.for(ast.node.type).each_node(ast.node) do |current|
|
26
|
+
return current if n_sclass?(current) && metaclass_of?(current)
|
27
|
+
end
|
27
28
|
|
28
|
-
|
29
|
-
end.last
|
29
|
+
nil
|
30
30
|
end
|
31
31
|
|
32
32
|
private
|
data/lib/mutant/ast/meta/send.rb
CHANGED
data/lib/mutant/ast/meta.rb
CHANGED
data/lib/mutant/ast/nodes.rb
CHANGED
data/lib/mutant/ast/pattern.rb
CHANGED
data/lib/mutant/ast/regexp.rb
CHANGED
data/lib/mutant/ast/sexp.rb
CHANGED
data/lib/mutant/ast/structure.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Mutant
|
4
|
-
|
4
|
+
class AST
|
5
5
|
# AST Structure metadata
|
6
6
|
# rubocop:disable Metrics/ModuleLength
|
7
7
|
module Structure
|
@@ -26,7 +26,7 @@ module Mutant
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def value(node)
|
29
|
-
node.children.
|
29
|
+
node.children.at(index)
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
@@ -246,7 +246,7 @@ module Mutant
|
|
246
246
|
type: :class,
|
247
247
|
fixed: Node.fixed(
|
248
248
|
[
|
249
|
-
[Node::Fixed::
|
249
|
+
[Node::Fixed::Attribute, :name],
|
250
250
|
[Node::Fixed::Descendant, :superclass],
|
251
251
|
[Node::Fixed::Descendant, :body]
|
252
252
|
]
|
@@ -386,6 +386,11 @@ module Mutant
|
|
386
386
|
fixed: Node.fixed([[Node::Fixed::Attribute, :value]]),
|
387
387
|
variable: nil
|
388
388
|
),
|
389
|
+
Node.new(
|
390
|
+
type: :forwarded_args,
|
391
|
+
fixed: EMPTY_ARRAY,
|
392
|
+
variable: nil
|
393
|
+
),
|
389
394
|
Node.new(
|
390
395
|
type: :for,
|
391
396
|
fixed: Node.fixed(
|
data/lib/mutant/ast/types.rb
CHANGED
data/lib/mutant/ast.rb
CHANGED
@@ -1,41 +1,43 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Mutant
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
4
|
+
class AST
|
5
|
+
include Adamantium, Anima.new(
|
6
|
+
:node,
|
7
|
+
:comment_associations
|
8
|
+
)
|
9
|
+
|
10
|
+
class View
|
11
|
+
include Adamantium, Anima.new(:node, :path)
|
12
|
+
end
|
13
|
+
|
14
|
+
def on_line(line)
|
15
|
+
line_map.fetch(line, EMPTY_HASH).map do |node, path|
|
16
|
+
View.new(node: node, path: path)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def line_map
|
23
|
+
line_map = {}
|
24
|
+
|
25
|
+
walk_path(node) do |node, path|
|
26
|
+
expression = node.location.expression || next
|
27
|
+
(line_map[expression.line] ||= []) << [node, path]
|
26
28
|
end
|
27
|
-
|
29
|
+
|
30
|
+
line_map
|
28
31
|
end
|
32
|
+
memoize :line_map
|
29
33
|
|
30
|
-
def
|
31
|
-
block.call(node, stack)
|
34
|
+
def walk_path(node, stack = [node.type], &block)
|
35
|
+
block.call(node, stack.dup)
|
32
36
|
node.children.grep(::Parser::AST::Node) do |child|
|
33
|
-
stack.push(child)
|
34
|
-
|
37
|
+
stack.push(child.type)
|
38
|
+
walk_path(child, stack, &block)
|
35
39
|
stack.pop
|
36
40
|
end
|
37
41
|
end
|
38
|
-
private_class_method :walk
|
39
|
-
|
40
42
|
end # AST
|
41
43
|
end # Mutant
|
data/lib/mutant/bootstrap.rb
CHANGED
@@ -24,16 +24,15 @@ module Mutant
|
|
24
24
|
|
25
25
|
# Run Bootstrap
|
26
26
|
#
|
27
|
-
# @param [
|
28
|
-
# @param [Config] config
|
27
|
+
# @param [Env] env
|
29
28
|
#
|
30
29
|
# @return [Either<String, Env>]
|
31
30
|
#
|
32
31
|
# rubocop:disable Metrics/MethodLength
|
33
|
-
def self.call(
|
34
|
-
env = load_hooks(
|
32
|
+
def self.call(env)
|
33
|
+
env = load_hooks(env)
|
35
34
|
.tap(&method(:infect))
|
36
|
-
.with(matchable_scopes: matchable_scopes(
|
35
|
+
.with(matchable_scopes: matchable_scopes(env))
|
37
36
|
|
38
37
|
subjects = start_subject(env, Matcher.from_config(env.config.matcher).call(env))
|
39
38
|
|
@@ -82,8 +81,10 @@ module Mutant
|
|
82
81
|
end
|
83
82
|
private_class_method :infect
|
84
83
|
|
85
|
-
def self.matchable_scopes(
|
86
|
-
|
84
|
+
def self.matchable_scopes(env)
|
85
|
+
config = env.config
|
86
|
+
|
87
|
+
scopes = env.world.object_space.each_object(Module).each_with_object([]) do |scope, aggregate|
|
87
88
|
expression = expression(config.reporter, config.expression_parser, scope) || next
|
88
89
|
aggregate << Scope.new(scope, expression)
|
89
90
|
end
|
@@ -23,9 +23,11 @@ module Mutant
|
|
23
23
|
end
|
24
24
|
|
25
25
|
def bootstrap
|
26
|
-
|
26
|
+
env = Env.empty(world, @config)
|
27
|
+
|
28
|
+
Config.load_config_file(env)
|
27
29
|
.fmap(&method(:expand))
|
28
|
-
.bind { Bootstrap.call(
|
30
|
+
.bind { Bootstrap.call(env.with(config: @config)) }
|
29
31
|
end
|
30
32
|
|
31
33
|
def expand(file_config)
|
@@ -121,7 +123,7 @@ module Mutant
|
|
121
123
|
set(jobs: Integer(number))
|
122
124
|
end
|
123
125
|
parser.on('-t', '--mutation-timeout NUMBER', 'Per mutation analysis timeout') do |number|
|
124
|
-
set(
|
126
|
+
set(mutation: @config.mutation.with(timeout: Float(number)))
|
125
127
|
end
|
126
128
|
end
|
127
129
|
end # Run
|
@@ -14,6 +14,12 @@ module Mutant
|
|
14
14
|
OPTIONS = %i[add_target_options].freeze
|
15
15
|
|
16
16
|
def action
|
17
|
+
@ignore_patterns.map! do |syntax|
|
18
|
+
AST::Pattern.parse(syntax).from_right do |message|
|
19
|
+
return Either::Left.new(message)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
17
23
|
@targets.each(&method(:print_mutations))
|
18
24
|
Either::Right.new(nil)
|
19
25
|
end
|
@@ -50,18 +56,27 @@ module Mutant
|
|
50
56
|
def initialize(_arguments)
|
51
57
|
super
|
52
58
|
|
53
|
-
@targets
|
59
|
+
@targets = []
|
60
|
+
@ignore_patterns = []
|
54
61
|
end
|
55
62
|
|
56
63
|
def add_target_options(parser)
|
57
64
|
parser.on('-e', '--evaluate SOURCE') do |source|
|
58
65
|
@targets << Target::Source.new(source)
|
59
66
|
end
|
67
|
+
|
68
|
+
parser.on('-i', '--ignore-pattern AST_PATTERN') do |pattern|
|
69
|
+
@ignore_patterns << pattern
|
70
|
+
end
|
60
71
|
end
|
61
72
|
|
62
73
|
def print_mutations(target)
|
63
74
|
world.stdout.puts(target.identification)
|
64
|
-
|
75
|
+
|
76
|
+
Mutator::Node.mutate(
|
77
|
+
config: Mutant::Mutation::Config::DEFAULT.with(ignore_patterns: @ignore_patterns),
|
78
|
+
node: target.node
|
79
|
+
).each do |mutation|
|
65
80
|
Reporter::CLI::Printer::Mutation.call(
|
66
81
|
world.stdout,
|
67
82
|
Mutant::Mutation::Evil.new(target, mutation)
|