mutant 0.2.20 → 0.3.0.beta2
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 +7 -0
- data/.travis.yml +10 -11
- data/Changelog.md +93 -38
- data/Gemfile +3 -1
- data/Gemfile.devtools +16 -20
- data/Guardfile +1 -1
- data/README.md +36 -16
- data/Rakefile +21 -2
- data/TODO +11 -7
- data/bin/mutant +4 -0
- data/bin/zombie +4 -0
- data/config/devtools.yml +2 -0
- data/config/flay.yml +2 -2
- data/config/flog.yml +1 -1
- data/config/{site.reek → reek.yml} +94 -70
- data/lib/mutant/cli/classifier/method.rb +100 -0
- data/lib/mutant/cli/classifier/namespace.rb +47 -0
- data/lib/mutant/cli/classifier/scope.rb +35 -0
- data/lib/mutant/cli/classifier.rb +141 -0
- data/lib/mutant/cli.rb +115 -162
- data/lib/mutant/color.rb +2 -2
- data/lib/mutant/config.rb +27 -0
- data/lib/mutant/constants.rb +32 -17
- data/lib/mutant/context/scope.rb +33 -51
- data/lib/mutant/context.rb +8 -19
- data/lib/mutant/differ.rb +5 -5
- data/lib/mutant/helper.rb +2 -17
- data/lib/mutant/killer/forked.rb +44 -0
- data/lib/mutant/killer/forking.rb +3 -57
- data/lib/mutant/killer/rspec.rb +16 -20
- data/lib/mutant/killer/static.rb +6 -7
- data/lib/mutant/killer.rb +48 -74
- data/lib/mutant/loader.rb +6 -6
- data/lib/mutant/matcher/chain.rb +4 -25
- data/lib/mutant/matcher/method/instance.rb +14 -24
- data/lib/mutant/matcher/method/singleton.rb +35 -46
- data/lib/mutant/matcher/method.rb +95 -83
- data/lib/mutant/matcher/{scope_methods.rb → methods.rb} +53 -76
- data/lib/mutant/matcher/namespace.rb +71 -0
- data/lib/mutant/matcher/scope.rb +34 -0
- data/lib/mutant/matcher.rb +24 -34
- data/lib/mutant/mutation/evil.rb +35 -0
- data/lib/mutant/mutation/filter/code.rb +7 -28
- data/lib/mutant/mutation/filter/regexp.rb +6 -18
- data/lib/mutant/mutation/filter/whitelist.rb +5 -4
- data/lib/mutant/mutation/filter.rb +10 -9
- data/lib/mutant/mutation/neutral.rb +35 -0
- data/lib/mutant/mutation.rb +21 -61
- data/lib/mutant/mutator/node/argument.rb +88 -0
- data/lib/mutant/mutator/node/arguments.rb +52 -0
- data/lib/mutant/mutator/node/assignment.rb +34 -38
- data/lib/mutant/mutator/node/begin.rb +33 -0
- data/lib/mutant/mutator/node/block.rb +14 -14
- data/lib/mutant/mutator/node/case.rb +59 -0
- data/lib/mutant/mutator/node/define.rb +26 -22
- data/lib/mutant/mutator/node/if.rb +31 -71
- data/lib/mutant/mutator/node/literal/array.rb +25 -9
- data/lib/mutant/mutator/node/literal/boolean.rb +13 -30
- data/lib/mutant/mutator/node/literal/dynamic.rb +6 -5
- data/lib/mutant/mutator/node/literal/fixnum.rb +18 -7
- data/lib/mutant/mutator/node/literal/float.rb +15 -8
- data/lib/mutant/mutator/node/literal/hash.rb +33 -52
- data/lib/mutant/mutator/node/literal/nil.rb +8 -7
- data/lib/mutant/mutator/node/literal/range.rb +25 -50
- data/lib/mutant/mutator/node/literal/regex.rb +15 -23
- data/lib/mutant/mutator/node/literal/string.rb +7 -6
- data/lib/mutant/mutator/node/literal/symbol.rb +7 -6
- data/lib/mutant/mutator/node/literal.rb +4 -46
- data/lib/mutant/mutator/node/mlhs.rb +27 -0
- data/lib/mutant/mutator/node/noop.rb +18 -43
- data/lib/mutant/mutator/node/return.rb +8 -8
- data/lib/mutant/mutator/node/send/binary.rb +31 -0
- data/lib/mutant/mutator/node/send.rb +106 -72
- data/lib/mutant/mutator/node/super.rb +15 -20
- data/lib/mutant/mutator/node/when.rb +32 -7
- data/lib/mutant/mutator/node/while.rb +9 -7
- data/lib/mutant/mutator/node.rb +116 -66
- data/lib/mutant/mutator/registry.rb +14 -11
- data/lib/mutant/mutator/util/array.rb +9 -9
- data/lib/mutant/mutator/util/symbol.rb +6 -20
- data/lib/mutant/mutator/util.rb +6 -3
- data/lib/mutant/mutator.rb +12 -28
- data/lib/mutant/node_helpers.rb +28 -0
- data/lib/mutant/random.rb +3 -2
- data/lib/mutant/reporter/cli/printer/config.rb +174 -0
- data/lib/mutant/reporter/cli/printer/killer.rb +42 -0
- data/lib/mutant/reporter/cli/printer/mutation.rb +55 -0
- data/lib/mutant/reporter/cli/printer/subject.rb +147 -0
- data/lib/mutant/reporter/cli/printer.rb +165 -0
- data/lib/mutant/reporter/cli.rb +9 -277
- data/lib/mutant/reporter/null.rb +6 -30
- data/lib/mutant/reporter.rb +6 -73
- data/lib/mutant/runner/config.rb +82 -0
- data/lib/mutant/runner/mutation.rb +58 -0
- data/lib/mutant/runner/subject.rb +81 -0
- data/lib/mutant/runner.rb +42 -92
- data/lib/mutant/singleton_methods.rb +2 -2
- data/lib/mutant/strategy/method_expansion.rb +51 -0
- data/lib/mutant/strategy/rspec/dm2/lookup/method.rb +142 -0
- data/lib/mutant/strategy/rspec/dm2/lookup.rb +61 -0
- data/lib/mutant/strategy/rspec/dm2.rb +22 -0
- data/lib/mutant/strategy/rspec.rb +20 -22
- data/lib/mutant/strategy/static.rb +18 -0
- data/lib/mutant/strategy.rb +15 -50
- data/lib/mutant/subject/method.rb +100 -0
- data/lib/mutant/subject.rb +18 -49
- data/lib/mutant/support/method_object.rb +4 -2
- data/lib/mutant.rb +40 -35
- data/mutant.gemspec +9 -8
- data/spec/integration/mutant/rspec_killer_spec.rb +3 -3
- data/spec/integration/mutant/test_mutator_handles_types_spec.rb +9 -0
- data/spec/integration/mutant/zombie_spec.rb +1 -1
- data/spec/shared/method_matcher_behavior.rb +35 -0
- data/spec/shared/mutator_behavior.rb +63 -32
- data/spec/spec_helper.rb +13 -3
- data/spec/support/ice_nine_config.rb +8 -0
- data/spec/support/rspec.rb +1 -1
- data/spec/support/zombie.rb +1 -1
- data/spec/unit/mutant/cli/class_methods/new_spec.rb +42 -28
- data/spec/unit/mutant/cli/class_methods/run_spec.rb +15 -13
- data/spec/unit/mutant/cli/classifier/class_methods/build_spec.rb +44 -0
- data/spec/unit/mutant/context/scope/root_spec.rb +4 -4
- data/spec/unit/mutant/killer/rspec/class_methods/new_spec.rb +6 -5
- data/spec/unit/mutant/killer/success_predicate_spec.rb +28 -0
- data/spec/unit/mutant/loader/eval/class_methods/run_spec.rb +1 -1
- data/spec/unit/mutant/matcher/chain/each_spec.rb +1 -1
- data/spec/unit/mutant/matcher/chain/matchers_spec.rb +1 -1
- data/spec/unit/mutant/matcher/method/instance/each_spec.rb +112 -0
- data/spec/unit/mutant/matcher/method/singleton/each_spec.rb +93 -0
- data/spec/unit/mutant/matcher/methods/instance/each_spec.rb +59 -0
- data/spec/unit/mutant/matcher/methods/singleton/each_spec.rb +53 -0
- data/spec/unit/mutant/matcher/namespace/each_spec.rb +37 -0
- data/spec/unit/mutant/mutator/node/begin/mutation_spec.rb +33 -0
- data/spec/unit/mutant/mutator/node/block/mutation_spec.rb +42 -14
- data/spec/unit/mutant/mutator/node/case/mutation_spec.rb +319 -0
- data/spec/unit/mutant/mutator/node/define/mutation_spec.rb +31 -27
- data/spec/unit/mutant/mutator/node/if/mutation_spec.rb +75 -0
- data/spec/unit/mutant/mutator/node/literal/fixnum_spec.rb +1 -1
- data/spec/unit/mutant/mutator/node/literal/hash_spec.rb +2 -2
- data/spec/unit/mutant/mutator/node/literal/nil_spec.rb +1 -3
- data/spec/unit/mutant/mutator/node/literal/regex_spec.rb +1 -9
- data/spec/unit/mutant/mutator/node/return/mutation_spec.rb +6 -2
- data/spec/unit/mutant/mutator/node/send/mutation_spec.rb +111 -108
- data/spec/unit/mutant/mutator/node/super/mutation_spec.rb +0 -33
- data/spec/unit/mutant/mutator/node/while/mutation_spec.rb +2 -2
- data/spec/unit/mutant/runner/config/subjects_spec.rb +38 -0
- data/spec/unit/mutant/runner/config/success_predicate_spec.rb +53 -0
- data/spec/unit/mutant/runner/failed_predicte_spec.rb +33 -0
- data/spec/unit/mutant/runner/mutation/killer_spec.rb +39 -0
- data/spec/unit/mutant/runner/subject/success_predicate_spec.rb +49 -0
- data/spec/unit/mutant/strategy/method_expansion/class_methods/run_spec.rb +49 -0
- data/spec/unit/mutant/strategy/rspec/dm2/lookup/method/instance/spec_files_spec.rb +52 -0
- data/spec/unit/mutant/strategy/rspec/dm2/lookup/method/singleton/spec_files_spec.rb +42 -0
- data/spec/unit/mutant/subject/context_spec.rb +6 -3
- data/spec/unit/mutant/subject/each_spec.rb +11 -8
- data/spec/unit/mutant/subject/node_spec.rb +6 -2
- data/test_app/spec/shared/method_filter_parse_behavior.rb +0 -2
- data/test_app/spec/shared/method_match_behavior.rb +1 -1
- data/test_app/spec/spec_helper.rb +4 -2
- metadata +101 -109
- data/config/roodi.yml +0 -26
- data/lib/mutant/matcher/method/classifier.rb +0 -141
- data/lib/mutant/matcher/object_space.rb +0 -114
- data/lib/mutant/mutator/node/actual_arguments.rb +0 -25
- data/lib/mutant/mutator/node/default_arguments.rb +0 -25
- data/lib/mutant/mutator/node/formal_arguments_19/default_mutations.rb +0 -33
- data/lib/mutant/mutator/node/formal_arguments_19/pattern_argument_expansion.rb +0 -35
- data/lib/mutant/mutator/node/formal_arguments_19/require_defaults.rb +0 -37
- data/lib/mutant/mutator/node/formal_arguments_19.rb +0 -41
- data/lib/mutant/mutator/node/iter_19.rb +0 -27
- data/lib/mutant/mutator/node/literal/empty_array.rb +0 -26
- data/lib/mutant/mutator/node/pattern_arguments.rb +0 -41
- data/lib/mutant/mutator/node/pattern_variable.rb +0 -23
- data/lib/mutant/mutator/node/receiver_case.rb +0 -122
- data/lib/mutant/mutator/node/send/binary_operator_method.rb +0 -61
- data/lib/mutant/mutator/node/send/with_arguments.rb +0 -81
- data/lib/mutant/reporter/stats.rb +0 -120
- data/lib/mutant/strategy/rspec/example_lookup.rb +0 -163
- data/spec/integration/mutant/method_matching_spec.rb +0 -269
- data/spec/shared/method_match_behavior.rb +0 -39
- data/spec/unit/mutant/killer/fail_ques_spec.rb +0 -39
- data/spec/unit/mutant/matcher/class_methods/from_string_spec.rb +0 -49
- data/spec/unit/mutant/matcher/class_methods/parse_spec.rb +0 -12
- data/spec/unit/mutant/matcher/method/class_methods/parse_spec.rb +0 -21
- data/spec/unit/mutant/matcher/method/classifier/class_methods/run_spec.rb +0 -52
- data/spec/unit/mutant/matcher/object_space/class_methods/parse_spec.rb +0 -24
- data/spec/unit/mutant/matcher/object_space/each_spec.rb +0 -31
- data/spec/unit/mutant/mutator/node/if_statement/mutation_spec.rb +0 -60
- data/spec/unit/mutant/mutator/node/receiver_case/mutation_spec.rb +0 -27
- data/spec/unit/mutant/strategy/rspec/example_lookup/spec_file_spec.rb +0 -236
- data/spec/unit/mutant/subject/class_methods/new_spec.rb +0 -13
- data/tasks/metrics/ci.rake +0 -7
- data/tasks/metrics/flay.rake +0 -41
- data/tasks/metrics/flog.rake +0 -43
- data/tasks/metrics/heckle.rake +0 -216
- data/tasks/metrics/metric_fu.rake +0 -31
- data/tasks/metrics/reek.rake +0 -15
- data/tasks/metrics/roodi.rake +0 -15
- data/tasks/metrics/yardstick.rake +0 -23
- data/tasks/spec.rake +0 -45
- data/tasks/yard.rake +0 -9
|
@@ -4,7 +4,11 @@ module Mutant
|
|
|
4
4
|
|
|
5
5
|
# Mutator for super with parantheses
|
|
6
6
|
class Super < self
|
|
7
|
-
|
|
7
|
+
|
|
8
|
+
handle(:super)
|
|
9
|
+
|
|
10
|
+
Z_SUPER = NodeHelpers.s(:zsuper)
|
|
11
|
+
EMPTY_SUPER = NodeHelpers.s(:super)
|
|
8
12
|
|
|
9
13
|
private
|
|
10
14
|
|
|
@@ -15,24 +19,15 @@ module Mutant
|
|
|
15
19
|
# @api private
|
|
16
20
|
#
|
|
17
21
|
def dispatch
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
+
emit(Z_SUPER)
|
|
23
|
+
emit(EMPTY_SUPER)
|
|
24
|
+
children.each_index do |index|
|
|
25
|
+
mutate_child(index)
|
|
26
|
+
delete_child(index)
|
|
27
|
+
end
|
|
22
28
|
end
|
|
23
29
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
# @api private
|
|
29
|
-
#
|
|
30
|
-
def emit_without_block
|
|
31
|
-
dup = dup_node
|
|
32
|
-
dup.block = nil
|
|
33
|
-
emit(dup)
|
|
34
|
-
end
|
|
35
|
-
end
|
|
36
|
-
end
|
|
37
|
-
end
|
|
38
|
-
end
|
|
30
|
+
end # Super
|
|
31
|
+
end # Node
|
|
32
|
+
end # Mutator
|
|
33
|
+
end # Mutant
|
|
@@ -2,10 +2,10 @@ module Mutant
|
|
|
2
2
|
class Mutator
|
|
3
3
|
class Node
|
|
4
4
|
|
|
5
|
-
# Mutator for
|
|
5
|
+
# Mutator for when nodes
|
|
6
6
|
class When < self
|
|
7
7
|
|
|
8
|
-
handle(
|
|
8
|
+
handle(:when)
|
|
9
9
|
|
|
10
10
|
private
|
|
11
11
|
|
|
@@ -16,10 +16,35 @@ module Mutant
|
|
|
16
16
|
# @api private
|
|
17
17
|
#
|
|
18
18
|
def dispatch
|
|
19
|
-
|
|
19
|
+
mutate_body
|
|
20
|
+
mutate_conditions
|
|
20
21
|
end
|
|
21
22
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
23
|
+
# Emit condition mutations
|
|
24
|
+
#
|
|
25
|
+
# @return [undefined]
|
|
26
|
+
#
|
|
27
|
+
# @api private
|
|
28
|
+
#
|
|
29
|
+
def mutate_conditions
|
|
30
|
+
conditions = children.length - 1
|
|
31
|
+
children[0..-2].each_index do |index|
|
|
32
|
+
delete_child(index) if conditions > 1
|
|
33
|
+
mutate_child(index)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Emit body mutations
|
|
38
|
+
#
|
|
39
|
+
# @return [undefined]
|
|
40
|
+
#
|
|
41
|
+
# @api private
|
|
42
|
+
#
|
|
43
|
+
def mutate_body
|
|
44
|
+
mutate_child(children.length-1)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
end # When
|
|
48
|
+
end # Node
|
|
49
|
+
end # Mutator
|
|
50
|
+
end # Mutant
|
|
@@ -5,7 +5,9 @@ module Mutant
|
|
|
5
5
|
# Mutator for while expressions
|
|
6
6
|
class While < self
|
|
7
7
|
|
|
8
|
-
handle(
|
|
8
|
+
handle(:while)
|
|
9
|
+
|
|
10
|
+
children :condition, :body
|
|
9
11
|
|
|
10
12
|
private
|
|
11
13
|
|
|
@@ -16,11 +18,11 @@ module Mutant
|
|
|
16
18
|
# @api private
|
|
17
19
|
#
|
|
18
20
|
def dispatch
|
|
19
|
-
|
|
20
|
-
|
|
21
|
+
emit_condition_mutations
|
|
22
|
+
emit_body_mutations
|
|
21
23
|
end
|
|
22
24
|
|
|
23
|
-
end
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
end
|
|
25
|
+
end # While
|
|
26
|
+
end # Node
|
|
27
|
+
end # Mutator
|
|
28
|
+
end # Mutant
|
data/lib/mutant/mutator/node.rb
CHANGED
|
@@ -3,25 +3,82 @@ module Mutant
|
|
|
3
3
|
class Mutator
|
|
4
4
|
# Abstract base class for node mutators
|
|
5
5
|
class Node < self
|
|
6
|
-
include AbstractType
|
|
6
|
+
include AbstractType, NodeHelpers, Unparser::Constants
|
|
7
7
|
|
|
8
8
|
# Return identity of node
|
|
9
9
|
#
|
|
10
|
-
# @param [
|
|
10
|
+
# @param [Parser::AST::Node] node
|
|
11
11
|
#
|
|
12
12
|
# @return [String]
|
|
13
13
|
#
|
|
14
14
|
# @api private
|
|
15
15
|
#
|
|
16
16
|
def self.identity(node)
|
|
17
|
-
|
|
17
|
+
Unparser.unparse(node)
|
|
18
18
|
end
|
|
19
19
|
|
|
20
|
+
# Define named child
|
|
21
|
+
#
|
|
22
|
+
# @param [Symbol] name
|
|
23
|
+
# @param [Fixnum] index
|
|
24
|
+
#
|
|
25
|
+
# @return [undefined]
|
|
26
|
+
#
|
|
27
|
+
# @api private
|
|
28
|
+
#
|
|
29
|
+
def self.define_named_child(name, index)
|
|
30
|
+
define_method("#{name}") do
|
|
31
|
+
children.at(index)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
define_method("emit_#{name}_mutations") do
|
|
35
|
+
mutate_child(index)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
define_method("emit_#{name}") do |node|
|
|
39
|
+
emit_child_update(index, node)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
private_class_method :define_named_child
|
|
43
|
+
|
|
44
|
+
# Define remaining children
|
|
45
|
+
#
|
|
46
|
+
# @param [Array<Symbol>] names
|
|
47
|
+
#
|
|
48
|
+
# @return [undefined]
|
|
49
|
+
#
|
|
50
|
+
# @api private
|
|
51
|
+
#
|
|
52
|
+
def self.define_remaining_children(names)
|
|
53
|
+
define_method(:remaining_children_with_index) do
|
|
54
|
+
children.each_with_index.drop(names.length)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
define_method(:remaining_children) do
|
|
58
|
+
children.drop(names.length)
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
private_class_method :define_remaining_children
|
|
62
|
+
|
|
63
|
+
# Create name helpers
|
|
64
|
+
#
|
|
65
|
+
# @return [undefined]
|
|
66
|
+
#
|
|
67
|
+
# @api private
|
|
68
|
+
#
|
|
69
|
+
def self.children(*names)
|
|
70
|
+
names.each_with_index do |name, index|
|
|
71
|
+
define_named_child(name, index)
|
|
72
|
+
end
|
|
73
|
+
define_remaining_children(names)
|
|
74
|
+
end
|
|
75
|
+
private_class_method :children
|
|
76
|
+
|
|
20
77
|
private
|
|
21
78
|
|
|
22
79
|
# Return mutated node
|
|
23
80
|
#
|
|
24
|
-
# @return [
|
|
81
|
+
# @return [Parser::AST::Node]
|
|
25
82
|
#
|
|
26
83
|
# @api private
|
|
27
84
|
#
|
|
@@ -29,85 +86,89 @@ module Mutant
|
|
|
29
86
|
|
|
30
87
|
# Return duplicated node
|
|
31
88
|
#
|
|
32
|
-
# @return [
|
|
89
|
+
# @return [Parser::AST::Node]
|
|
33
90
|
#
|
|
34
91
|
# @api private
|
|
35
92
|
#
|
|
36
93
|
alias_method :dup_node, :dup_input
|
|
37
94
|
|
|
38
|
-
# Emit
|
|
95
|
+
# Emit children mutations
|
|
39
96
|
#
|
|
40
|
-
# @
|
|
41
|
-
#
|
|
42
|
-
# @return [Rubinius::AST::Node]
|
|
97
|
+
# @return [undefined]
|
|
43
98
|
#
|
|
44
99
|
# @api private
|
|
45
100
|
#
|
|
46
|
-
def
|
|
47
|
-
|
|
101
|
+
def emit_children_mutations
|
|
102
|
+
Mutator::Util::Array.each(children) do |children|
|
|
103
|
+
emit_self(*children)
|
|
104
|
+
end
|
|
48
105
|
end
|
|
49
106
|
|
|
50
|
-
#
|
|
107
|
+
# Return children
|
|
51
108
|
#
|
|
52
|
-
# @return [
|
|
109
|
+
# @return [Array<Parser::AST::Node>]
|
|
53
110
|
#
|
|
54
111
|
# @api private
|
|
55
112
|
#
|
|
56
|
-
def
|
|
57
|
-
|
|
113
|
+
def children
|
|
114
|
+
node.children
|
|
58
115
|
end
|
|
59
116
|
|
|
60
|
-
#
|
|
117
|
+
# Dispatch on child index
|
|
61
118
|
#
|
|
62
|
-
# @
|
|
119
|
+
# @param [Fixnum] index
|
|
120
|
+
#
|
|
121
|
+
# @return [undefined]
|
|
63
122
|
#
|
|
64
123
|
# @api private
|
|
65
124
|
#
|
|
66
|
-
def
|
|
67
|
-
|
|
125
|
+
def mutate_child(index, mutator = Mutator)
|
|
126
|
+
children = node.children
|
|
127
|
+
child = children[index]
|
|
128
|
+
mutator.each(child) do |mutation|
|
|
129
|
+
emit_child_update(index, mutation)
|
|
130
|
+
end
|
|
68
131
|
end
|
|
69
132
|
|
|
70
|
-
#
|
|
133
|
+
# Emit delete child mutation
|
|
71
134
|
#
|
|
72
|
-
# @param [
|
|
135
|
+
# @param [Fixnum] index
|
|
73
136
|
#
|
|
74
|
-
# @return [
|
|
137
|
+
# @return [undefined]
|
|
75
138
|
#
|
|
76
139
|
# @api private
|
|
77
140
|
#
|
|
78
|
-
def
|
|
79
|
-
|
|
141
|
+
def delete_child(index)
|
|
142
|
+
dup_children = children.dup
|
|
143
|
+
dup_children.delete_at(index)
|
|
144
|
+
emit_self(*dup_children)
|
|
80
145
|
end
|
|
81
146
|
|
|
82
|
-
# Emit
|
|
147
|
+
# Emit updated child
|
|
148
|
+
#
|
|
149
|
+
# @param [Fixnum] index
|
|
150
|
+
# @param [Object] update
|
|
83
151
|
#
|
|
84
152
|
# @return [undefined]
|
|
85
153
|
#
|
|
86
154
|
# @api private
|
|
87
155
|
#
|
|
88
|
-
def
|
|
89
|
-
|
|
156
|
+
def emit_child_update(index, update)
|
|
157
|
+
new_children = children.dup
|
|
158
|
+
new_children[index]=update
|
|
159
|
+
emit_self(*new_children)
|
|
90
160
|
end
|
|
91
161
|
|
|
92
|
-
# Emit
|
|
162
|
+
# Emit a new AST node with same class as wrapped node
|
|
93
163
|
#
|
|
94
|
-
# @param [
|
|
164
|
+
# @param [Array<Parser::AST::Node>] children
|
|
95
165
|
#
|
|
96
166
|
# @return [undefined]
|
|
97
167
|
#
|
|
98
168
|
# @api private
|
|
99
169
|
#
|
|
100
|
-
def
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
mutator.each(value) do |mutation|
|
|
104
|
-
dup = dup_node
|
|
105
|
-
dup.public_send(:"#{name}=", mutation)
|
|
106
|
-
if block_given?
|
|
107
|
-
dup = yield(dup)
|
|
108
|
-
end
|
|
109
|
-
emit(dup)
|
|
110
|
-
end
|
|
170
|
+
def emit_self(*children)
|
|
171
|
+
emit(new_self(*children))
|
|
111
172
|
end
|
|
112
173
|
|
|
113
174
|
# Emit a new AST node with NilLiteral class
|
|
@@ -117,44 +178,33 @@ module Mutant
|
|
|
117
178
|
# @api private
|
|
118
179
|
#
|
|
119
180
|
def emit_nil
|
|
120
|
-
emit(
|
|
181
|
+
emit(N_NIL)
|
|
121
182
|
end
|
|
122
183
|
|
|
123
|
-
# Return new
|
|
184
|
+
# Return new self typed child
|
|
124
185
|
#
|
|
125
|
-
# @
|
|
126
|
-
# @param [Symbol] name
|
|
127
|
-
# @param [Object] arguments
|
|
128
|
-
#
|
|
129
|
-
# @return [Rubinius::AST::SendWithArguments]
|
|
186
|
+
# @return [Parser::AST::Node]
|
|
130
187
|
#
|
|
131
188
|
# @api private
|
|
132
189
|
#
|
|
133
|
-
def
|
|
134
|
-
|
|
190
|
+
def new_self(*children)
|
|
191
|
+
Parser::AST::Node.new(node.type, children)
|
|
135
192
|
end
|
|
136
193
|
|
|
137
|
-
#
|
|
194
|
+
# Emit values
|
|
138
195
|
#
|
|
139
|
-
# @param [
|
|
140
|
-
# @param [Symbol] name
|
|
196
|
+
# @param [Array<Object>] values
|
|
141
197
|
#
|
|
142
|
-
# @return [
|
|
198
|
+
# @return [undefined]
|
|
143
199
|
#
|
|
144
200
|
# @api private
|
|
145
201
|
#
|
|
146
|
-
def
|
|
147
|
-
|
|
202
|
+
def emit_values(values)
|
|
203
|
+
values.each do |value|
|
|
204
|
+
emit_self(value)
|
|
205
|
+
end
|
|
148
206
|
end
|
|
149
207
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
#
|
|
154
|
-
# @api private
|
|
155
|
-
#
|
|
156
|
-
alias_method :dup_node, :dup_input
|
|
157
|
-
|
|
158
|
-
end
|
|
159
|
-
end
|
|
160
|
-
end
|
|
208
|
+
end # Node
|
|
209
|
+
end # Mutator
|
|
210
|
+
end # Mutant
|
|
@@ -15,21 +15,22 @@ module Mutant
|
|
|
15
15
|
|
|
16
16
|
# Register mutator class for AST node class
|
|
17
17
|
#
|
|
18
|
-
# @param [
|
|
18
|
+
# @param [Symbol] type
|
|
19
19
|
# @param [Class] mutator_class
|
|
20
20
|
#
|
|
21
21
|
# @api private
|
|
22
22
|
#
|
|
23
23
|
# @return [self]
|
|
24
24
|
#
|
|
25
|
-
def self.register(
|
|
26
|
-
registry
|
|
25
|
+
def self.register(type, mutator_class)
|
|
26
|
+
raise "duplicate type registration: #{type}" if registry.key?(type)
|
|
27
|
+
registry[type]=mutator_class
|
|
27
28
|
self
|
|
28
29
|
end
|
|
29
30
|
|
|
30
|
-
# Lookup mutator class for
|
|
31
|
+
# Lookup mutator class for node
|
|
31
32
|
#
|
|
32
|
-
# @param [
|
|
33
|
+
# @param [Parser::AST::Node] node
|
|
33
34
|
#
|
|
34
35
|
# @return [Class]
|
|
35
36
|
#
|
|
@@ -38,11 +39,13 @@ module Mutant
|
|
|
38
39
|
#
|
|
39
40
|
# @api private
|
|
40
41
|
#
|
|
41
|
-
def self.lookup(
|
|
42
|
-
|
|
43
|
-
|
|
42
|
+
def self.lookup(node)
|
|
43
|
+
type = node.type
|
|
44
|
+
registry.fetch(type) do
|
|
45
|
+
raise ArgumentError,"No mutator to handle: #{type.inspect}"
|
|
44
46
|
end
|
|
45
47
|
end
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
end
|
|
48
|
+
|
|
49
|
+
end # Registry
|
|
50
|
+
end # Mutator
|
|
51
|
+
end # Mutant
|
|
@@ -26,7 +26,7 @@ module Mutant
|
|
|
26
26
|
end
|
|
27
27
|
end
|
|
28
28
|
|
|
29
|
-
end
|
|
29
|
+
end # Presence
|
|
30
30
|
|
|
31
31
|
# Array element mutator
|
|
32
32
|
class Element < Util
|
|
@@ -34,27 +34,27 @@ module Mutant
|
|
|
34
34
|
private
|
|
35
35
|
|
|
36
36
|
# Emit mutations
|
|
37
|
-
#
|
|
37
|
+
#
|
|
38
38
|
# @return [undefined]
|
|
39
39
|
#
|
|
40
40
|
# @api private
|
|
41
41
|
#
|
|
42
42
|
def dispatch
|
|
43
43
|
input.each_with_index do |element, index|
|
|
44
|
-
dup = dup_input
|
|
45
44
|
Mutator.each(element).each do |mutation|
|
|
45
|
+
dup = dup_input
|
|
46
46
|
dup[index]=mutation
|
|
47
47
|
emit(dup)
|
|
48
48
|
end
|
|
49
49
|
end
|
|
50
50
|
end
|
|
51
51
|
|
|
52
|
-
end
|
|
52
|
+
end # Element
|
|
53
53
|
|
|
54
54
|
private
|
|
55
55
|
|
|
56
56
|
# Emit mutations
|
|
57
|
-
#
|
|
57
|
+
#
|
|
58
58
|
# @return [undefined]
|
|
59
59
|
#
|
|
60
60
|
# @api private
|
|
@@ -65,7 +65,7 @@ module Mutant
|
|
|
65
65
|
emit([])
|
|
66
66
|
end
|
|
67
67
|
|
|
68
|
-
end
|
|
69
|
-
end
|
|
70
|
-
end
|
|
71
|
-
end
|
|
68
|
+
end # Array
|
|
69
|
+
end # Node
|
|
70
|
+
end # Mutant
|
|
71
|
+
end # Mutator
|
|
@@ -2,7 +2,7 @@ module Mutant
|
|
|
2
2
|
class Mutator
|
|
3
3
|
class Util
|
|
4
4
|
|
|
5
|
-
#
|
|
5
|
+
# Utility symbol mutator
|
|
6
6
|
class Symbol < self
|
|
7
7
|
|
|
8
8
|
handle(::Symbol)
|
|
@@ -16,24 +16,10 @@ module Mutant
|
|
|
16
16
|
# @api private
|
|
17
17
|
#
|
|
18
18
|
def dispatch
|
|
19
|
-
emit_new { :"s#{Random.hex_string}" }
|
|
19
|
+
emit_new { :"s#{Random.hex_string}" }
|
|
20
20
|
end
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
#
|
|
27
|
-
# @return [false]
|
|
28
|
-
# otherwise
|
|
29
|
-
#
|
|
30
|
-
# @api private
|
|
31
|
-
#
|
|
32
|
-
def ignore?
|
|
33
|
-
input.to_s[0] == '_'
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
end
|
|
37
|
-
end
|
|
38
|
-
end
|
|
39
|
-
end
|
|
22
|
+
end # Symbol
|
|
23
|
+
end # Util
|
|
24
|
+
end # Mutator
|
|
25
|
+
end # Mutant
|
data/lib/mutant/mutator/util.rb
CHANGED
|
@@ -23,6 +23,8 @@ module Mutant
|
|
|
23
23
|
self
|
|
24
24
|
end
|
|
25
25
|
|
|
26
|
+
private
|
|
27
|
+
|
|
26
28
|
# Test if mutation is new
|
|
27
29
|
#
|
|
28
30
|
# @param [Object] generated
|
|
@@ -38,6 +40,7 @@ module Mutant
|
|
|
38
40
|
def new?(generated)
|
|
39
41
|
input != generated
|
|
40
42
|
end
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
end
|
|
43
|
+
|
|
44
|
+
end # Util
|
|
45
|
+
end # Mutator
|
|
46
|
+
end # Mutant
|
data/lib/mutant/mutator.rb
CHANGED
|
@@ -5,30 +5,30 @@ module Mutant
|
|
|
5
5
|
|
|
6
6
|
# Run mutator on input
|
|
7
7
|
#
|
|
8
|
-
# @param [
|
|
8
|
+
# @param [Parser::AST::Node] node
|
|
9
9
|
# @param [#call] block
|
|
10
10
|
#
|
|
11
11
|
# @return [self]
|
|
12
12
|
#
|
|
13
13
|
# @api private
|
|
14
14
|
#
|
|
15
|
-
def self.each(
|
|
16
|
-
return to_enum(__method__,
|
|
17
|
-
Registry.lookup(
|
|
15
|
+
def self.each(node, &block)
|
|
16
|
+
return to_enum(__method__, node) unless block_given?
|
|
17
|
+
Registry.lookup(node).new(node, block)
|
|
18
18
|
|
|
19
19
|
self
|
|
20
20
|
end
|
|
21
21
|
|
|
22
22
|
# Register node class handler
|
|
23
23
|
#
|
|
24
|
-
# @param [Class:Rubinius::AST::Node] node_class
|
|
25
|
-
#
|
|
26
24
|
# @return [undefined]
|
|
27
25
|
#
|
|
28
26
|
# @api private
|
|
29
27
|
#
|
|
30
|
-
def self.handle(
|
|
31
|
-
|
|
28
|
+
def self.handle(*types)
|
|
29
|
+
types.each do |type|
|
|
30
|
+
Registry.register(type, self)
|
|
31
|
+
end
|
|
32
32
|
end
|
|
33
33
|
private_class_method :handle
|
|
34
34
|
|
|
@@ -97,22 +97,6 @@ module Mutant
|
|
|
97
97
|
@seen << self.class.identity(object)
|
|
98
98
|
end
|
|
99
99
|
|
|
100
|
-
# Test if generated mutation is allowed
|
|
101
|
-
#
|
|
102
|
-
# @param [Object] object
|
|
103
|
-
#
|
|
104
|
-
# @return [true]
|
|
105
|
-
# if mutation is allowed
|
|
106
|
-
#
|
|
107
|
-
# @return [false]
|
|
108
|
-
# otherwise
|
|
109
|
-
#
|
|
110
|
-
# @api private
|
|
111
|
-
#
|
|
112
|
-
def allow?(object)
|
|
113
|
-
true
|
|
114
|
-
end
|
|
115
|
-
|
|
116
100
|
# Dispatch node generations
|
|
117
101
|
#
|
|
118
102
|
# @return [undefined]
|
|
@@ -130,7 +114,7 @@ module Mutant
|
|
|
130
114
|
# @api private
|
|
131
115
|
#
|
|
132
116
|
def emit(object)
|
|
133
|
-
return unless new?(object)
|
|
117
|
+
return unless new?(object)
|
|
134
118
|
|
|
135
119
|
guard(object)
|
|
136
120
|
|
|
@@ -171,7 +155,7 @@ module Mutant
|
|
|
171
155
|
|
|
172
156
|
# Call block with node
|
|
173
157
|
#
|
|
174
|
-
# @param [
|
|
158
|
+
# @param [Parser::AST::Node] node
|
|
175
159
|
#
|
|
176
160
|
# @return [self]
|
|
177
161
|
#
|
|
@@ -202,5 +186,5 @@ module Mutant
|
|
|
202
186
|
Helper.deep_clone(input)
|
|
203
187
|
end
|
|
204
188
|
|
|
205
|
-
end
|
|
206
|
-
end
|
|
189
|
+
end # Mutator
|
|
190
|
+
end # Mutant
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
module Mutant
|
|
2
|
+
# Mixin for node helpers
|
|
3
|
+
module NodeHelpers
|
|
4
|
+
|
|
5
|
+
# Build node
|
|
6
|
+
#
|
|
7
|
+
# @param [Symbol] type
|
|
8
|
+
#
|
|
9
|
+
# @return [Parser::AST::Node]
|
|
10
|
+
#
|
|
11
|
+
# @api private
|
|
12
|
+
#
|
|
13
|
+
def s(type, *children)
|
|
14
|
+
Parser::AST::Node.new(type, children)
|
|
15
|
+
end
|
|
16
|
+
module_function :s
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
NAN = s(:send, s(:float, 0.0), :/, s(:args, s(:float, 0.0)))
|
|
20
|
+
NEGATIVE_INFINITY = s(:send, s(:float, -1.0), :/, s(:args, s(:float, 0.0)))
|
|
21
|
+
INFINITY = s(:send, s(:float, 1.0), :/, s(:args, s(:float, 0.0)))
|
|
22
|
+
NEW_OBJECT = s(:send, s(:const, s(:cbase), :Object), :new)
|
|
23
|
+
|
|
24
|
+
N_NIL = s(:nil)
|
|
25
|
+
N_EMPTY = s(:empty)
|
|
26
|
+
|
|
27
|
+
end # NodeHelpers
|
|
28
|
+
end # Mutant
|
data/lib/mutant/random.rb
CHANGED