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
data/lib/mutant/matcher.rb
CHANGED
|
@@ -1,57 +1,47 @@
|
|
|
1
1
|
module Mutant
|
|
2
|
-
# Abstract matcher to find
|
|
2
|
+
# Abstract matcher to find subjects to mutate
|
|
3
3
|
class Matcher
|
|
4
4
|
include Adamantium::Flat, Enumerable, AbstractType
|
|
5
5
|
extend DescendantsTracker
|
|
6
6
|
|
|
7
7
|
# Enumerate subjects
|
|
8
8
|
#
|
|
9
|
-
# @
|
|
10
|
-
#
|
|
11
|
-
# @return [undefined]
|
|
9
|
+
# @param [Object] input
|
|
12
10
|
#
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
# Return identification
|
|
11
|
+
# @return [self]
|
|
12
|
+
# if block given
|
|
16
13
|
#
|
|
17
|
-
# @return [
|
|
14
|
+
# @return [Enumerator<Subject>]
|
|
18
15
|
#
|
|
19
16
|
# @api private
|
|
20
17
|
#
|
|
21
|
-
|
|
18
|
+
def self.each(input, &block)
|
|
19
|
+
return to_enum(__method__, input) unless block_given?
|
|
22
20
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
#
|
|
21
|
+
new(input).each(&block)
|
|
22
|
+
|
|
23
|
+
self
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Enumerate subjects
|
|
29
27
|
#
|
|
30
28
|
# @api private
|
|
31
29
|
#
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
# Return match from string
|
|
30
|
+
# @return [self]
|
|
31
|
+
# if block given
|
|
37
32
|
#
|
|
38
|
-
# @
|
|
33
|
+
# @return [Enumerabe<Subject>]
|
|
34
|
+
# otherwise
|
|
39
35
|
#
|
|
40
|
-
|
|
41
|
-
|
|
36
|
+
abstract_method :each
|
|
37
|
+
|
|
38
|
+
# Return identification
|
|
42
39
|
#
|
|
43
|
-
# @return [
|
|
44
|
-
# returns nil otherwise
|
|
40
|
+
# @return [String
|
|
45
41
|
#
|
|
46
42
|
# @api private
|
|
47
43
|
#
|
|
48
|
-
|
|
49
|
-
descendants.each do |descendant|
|
|
50
|
-
matcher = descendant.parse(input)
|
|
51
|
-
return matcher if matcher
|
|
52
|
-
end
|
|
44
|
+
abstract_method :identification
|
|
53
45
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
end
|
|
57
|
-
end
|
|
46
|
+
end # Matcher
|
|
47
|
+
end # Mutant
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
module Mutant
|
|
2
|
+
class Mutation
|
|
3
|
+
# Evul mutation
|
|
4
|
+
class Evil < self
|
|
5
|
+
|
|
6
|
+
# Return identification
|
|
7
|
+
#
|
|
8
|
+
# @return [String]
|
|
9
|
+
#
|
|
10
|
+
# @api private
|
|
11
|
+
#
|
|
12
|
+
def identification
|
|
13
|
+
"evil:#{super}"
|
|
14
|
+
end
|
|
15
|
+
memoize :identification
|
|
16
|
+
|
|
17
|
+
# Test if killer is successful
|
|
18
|
+
#
|
|
19
|
+
# @param [Killer] killer
|
|
20
|
+
#
|
|
21
|
+
# @return [true]
|
|
22
|
+
# if killer killed mutation
|
|
23
|
+
#
|
|
24
|
+
# @return [false]
|
|
25
|
+
# otherwise
|
|
26
|
+
#
|
|
27
|
+
# @api private
|
|
28
|
+
#
|
|
29
|
+
def success?(killer)
|
|
30
|
+
killer.killed?
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
end # Evil
|
|
34
|
+
end # Mutation
|
|
35
|
+
end # Mutant
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
module Mutant
|
|
2
2
|
class Mutation
|
|
3
|
-
class Filter
|
|
3
|
+
class Filter
|
|
4
4
|
# Mutation filter that filters on mutation codes
|
|
5
5
|
class Code < self
|
|
6
|
-
include
|
|
6
|
+
include Concord::Public.new(:code)
|
|
7
7
|
|
|
8
8
|
# Test for match
|
|
9
9
|
#
|
|
@@ -36,33 +36,12 @@ module Mutant
|
|
|
36
36
|
# @api private
|
|
37
37
|
#
|
|
38
38
|
def self.handle(notation)
|
|
39
|
-
match = PATTERN.match(notation)
|
|
39
|
+
match = PATTERN.match(notation)
|
|
40
40
|
return unless match
|
|
41
41
|
new(match[1])
|
|
42
42
|
end
|
|
43
43
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
# @api private
|
|
49
|
-
#
|
|
50
|
-
attr_reader :code
|
|
51
|
-
|
|
52
|
-
private
|
|
53
|
-
|
|
54
|
-
# Initialize code filter
|
|
55
|
-
#
|
|
56
|
-
# @param [String] code
|
|
57
|
-
#
|
|
58
|
-
# @return [undefined]
|
|
59
|
-
#
|
|
60
|
-
# @api private
|
|
61
|
-
#
|
|
62
|
-
def initialize(code)
|
|
63
|
-
@code = code
|
|
64
|
-
end
|
|
65
|
-
end
|
|
66
|
-
end
|
|
67
|
-
end
|
|
68
|
-
end
|
|
44
|
+
end # Code
|
|
45
|
+
end # Filter
|
|
46
|
+
end # Mutation
|
|
47
|
+
end # Mutant
|
|
@@ -3,6 +3,7 @@ module Mutant
|
|
|
3
3
|
class Filter
|
|
4
4
|
# Mutaiton filter filtering in regexp match on mutation identification
|
|
5
5
|
class Regexp < self
|
|
6
|
+
include Concord::Public.new(:regexp)
|
|
6
7
|
|
|
7
8
|
# Test for match
|
|
8
9
|
#
|
|
@@ -17,23 +18,10 @@ module Mutant
|
|
|
17
18
|
# @api private
|
|
18
19
|
#
|
|
19
20
|
def match?(mutation)
|
|
20
|
-
|
|
21
|
+
!!(regexp =~ mutation.identification)
|
|
21
22
|
end
|
|
22
23
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
# @param [Regexp] regexp
|
|
28
|
-
#
|
|
29
|
-
# @return [undefined]
|
|
30
|
-
#
|
|
31
|
-
# @api private
|
|
32
|
-
#
|
|
33
|
-
def initialize(regexp)
|
|
34
|
-
@regexp = regexp
|
|
35
|
-
end
|
|
36
|
-
end
|
|
37
|
-
end
|
|
38
|
-
end
|
|
39
|
-
end
|
|
24
|
+
end # Regexp
|
|
25
|
+
end # Filter
|
|
26
|
+
end # Mutation
|
|
27
|
+
end # Mutant
|
|
@@ -32,7 +32,7 @@ module Mutant
|
|
|
32
32
|
# @api private
|
|
33
33
|
#
|
|
34
34
|
def self.build(notation)
|
|
35
|
-
descendants.each do |descendant|
|
|
35
|
+
descendants.each do |descendant|
|
|
36
36
|
filter = descendant.handle(notation)
|
|
37
37
|
return filter if filter
|
|
38
38
|
end
|
|
@@ -42,34 +42,35 @@ module Mutant
|
|
|
42
42
|
|
|
43
43
|
# Return filter for handle
|
|
44
44
|
#
|
|
45
|
-
# @param [String]
|
|
45
|
+
# @param [String] _notation
|
|
46
46
|
#
|
|
47
47
|
# @return [nil]
|
|
48
48
|
# returns nil
|
|
49
49
|
#
|
|
50
50
|
# @api private
|
|
51
51
|
#
|
|
52
|
-
def self.handle(
|
|
52
|
+
def self.handle(_notation)
|
|
53
53
|
nil
|
|
54
54
|
end
|
|
55
55
|
|
|
56
56
|
# Mutation filter matching all mutations
|
|
57
|
-
Mutant.
|
|
57
|
+
Mutant.singleton_subclass_instance('ALL', self) do
|
|
58
58
|
|
|
59
59
|
# Test for match
|
|
60
60
|
#
|
|
61
|
-
# @pram [Mutation]
|
|
61
|
+
# @pram [Mutation] _mutation
|
|
62
62
|
#
|
|
63
63
|
# @return [true]
|
|
64
64
|
# returns true
|
|
65
65
|
#
|
|
66
66
|
# @api private
|
|
67
67
|
#
|
|
68
|
-
def match?(
|
|
68
|
+
def match?(_mutation)
|
|
69
69
|
true
|
|
70
70
|
end
|
|
71
71
|
|
|
72
72
|
end
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
end
|
|
73
|
+
|
|
74
|
+
end # Filter
|
|
75
|
+
end # Mutation
|
|
76
|
+
end # Mutant
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
module Mutant
|
|
2
|
+
class Mutation
|
|
3
|
+
# Neutral mutation
|
|
4
|
+
class Neutral < self
|
|
5
|
+
|
|
6
|
+
# Return identification
|
|
7
|
+
#
|
|
8
|
+
# @return [String]
|
|
9
|
+
#
|
|
10
|
+
# @api private
|
|
11
|
+
#
|
|
12
|
+
def identification
|
|
13
|
+
"noop:#{super}"
|
|
14
|
+
end
|
|
15
|
+
memoize :identification
|
|
16
|
+
|
|
17
|
+
# Test if killer is successful
|
|
18
|
+
#
|
|
19
|
+
# @param [Killer] killer
|
|
20
|
+
#
|
|
21
|
+
# @return [true]
|
|
22
|
+
# if killer did NOT killed mutation
|
|
23
|
+
#
|
|
24
|
+
# @return [false]
|
|
25
|
+
# otherwise
|
|
26
|
+
#
|
|
27
|
+
# @api private
|
|
28
|
+
#
|
|
29
|
+
def success?(killer)
|
|
30
|
+
!killer.killed?
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
end # Neutral
|
|
34
|
+
end # Mutation
|
|
35
|
+
end # Mutant
|
data/lib/mutant/mutation.rb
CHANGED
|
@@ -1,42 +1,43 @@
|
|
|
1
1
|
module Mutant
|
|
2
2
|
# Represent a mutated node with its subject
|
|
3
3
|
class Mutation
|
|
4
|
-
include Adamantium::Flat,
|
|
4
|
+
include AbstractType, Adamantium::Flat, Concord::Public.new(:subject, :node)
|
|
5
5
|
|
|
6
|
-
# Return
|
|
6
|
+
# Return mutated root node
|
|
7
7
|
#
|
|
8
|
-
# @return [
|
|
8
|
+
# @return [Parser::AST::Node]
|
|
9
9
|
#
|
|
10
10
|
# @api private
|
|
11
11
|
#
|
|
12
|
-
|
|
12
|
+
def root
|
|
13
|
+
subject.root(node)
|
|
14
|
+
end
|
|
15
|
+
memoize :root
|
|
13
16
|
|
|
14
|
-
#
|
|
17
|
+
# Test if killer is successful
|
|
15
18
|
#
|
|
16
|
-
# @
|
|
19
|
+
# @param [Killer] killer
|
|
17
20
|
#
|
|
18
|
-
# @
|
|
21
|
+
# @return [true]
|
|
22
|
+
# if killer is successful
|
|
19
23
|
#
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
# Return mutated root node
|
|
23
|
-
#
|
|
24
|
-
# @return [Rubinius::AST::Node]
|
|
24
|
+
# @return [false]
|
|
25
|
+
# otherwise
|
|
25
26
|
#
|
|
26
27
|
# @api private
|
|
27
28
|
#
|
|
28
|
-
|
|
29
|
-
subject.root(node)
|
|
30
|
-
end
|
|
31
|
-
memoize :root
|
|
29
|
+
abstract_method :success?
|
|
32
30
|
|
|
33
31
|
# Insert mutated node
|
|
34
32
|
#
|
|
33
|
+
# FIXME: Cache subject visibility in a better way! Ideally dont mutate it.
|
|
34
|
+
#
|
|
35
35
|
# @return [self]
|
|
36
36
|
#
|
|
37
37
|
# @api private
|
|
38
38
|
#
|
|
39
39
|
def insert
|
|
40
|
+
subject.public?
|
|
40
41
|
Loader::Eval.run(root, subject)
|
|
41
42
|
self
|
|
42
43
|
end
|
|
@@ -70,7 +71,7 @@ module Mutant
|
|
|
70
71
|
# @api private
|
|
71
72
|
#
|
|
72
73
|
def sha1
|
|
73
|
-
Digest::SHA1.hexdigest(subject.identification + source)
|
|
74
|
+
Digest::SHA1.hexdigest(subject.identification + 0.chr + source)
|
|
74
75
|
end
|
|
75
76
|
memoize :sha1
|
|
76
77
|
|
|
@@ -81,7 +82,7 @@ module Mutant
|
|
|
81
82
|
# @api private
|
|
82
83
|
#
|
|
83
84
|
def source
|
|
84
|
-
|
|
85
|
+
Unparser.unparse(node)
|
|
85
86
|
end
|
|
86
87
|
memoize :source
|
|
87
88
|
|
|
@@ -95,46 +96,5 @@ module Mutant
|
|
|
95
96
|
subject.source
|
|
96
97
|
end
|
|
97
98
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
# Initialize mutation object
|
|
101
|
-
#
|
|
102
|
-
# @param [Subject] subject
|
|
103
|
-
# @param [Rubinius::Node::AST] node
|
|
104
|
-
#
|
|
105
|
-
# @return [undefined]
|
|
106
|
-
#
|
|
107
|
-
# @api private
|
|
108
|
-
#
|
|
109
|
-
def initialize(subject, node)
|
|
110
|
-
@subject, @node = subject, node
|
|
111
|
-
end
|
|
112
|
-
|
|
113
|
-
# Noop mutation
|
|
114
|
-
class Noop < self
|
|
115
|
-
|
|
116
|
-
# Initialize object
|
|
117
|
-
#
|
|
118
|
-
# @param [Subject] subject
|
|
119
|
-
#
|
|
120
|
-
# @return [undefined]
|
|
121
|
-
#
|
|
122
|
-
# @api private
|
|
123
|
-
#
|
|
124
|
-
def initialize(subject)
|
|
125
|
-
super(subject, subject.node)
|
|
126
|
-
end
|
|
127
|
-
|
|
128
|
-
# Return identification
|
|
129
|
-
#
|
|
130
|
-
# @return [String]
|
|
131
|
-
#
|
|
132
|
-
# @api private
|
|
133
|
-
#
|
|
134
|
-
def identification
|
|
135
|
-
"noop:#{super}"
|
|
136
|
-
end
|
|
137
|
-
memoize :identification
|
|
138
|
-
end
|
|
139
|
-
end
|
|
140
|
-
end
|
|
99
|
+
end # Mutation
|
|
100
|
+
end # Mutant
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
module Mutant
|
|
2
|
+
class Mutator
|
|
3
|
+
class Node
|
|
4
|
+
|
|
5
|
+
# Mutator for required arguments
|
|
6
|
+
class Argument < self
|
|
7
|
+
handle(:arg)
|
|
8
|
+
|
|
9
|
+
UNDERSCORE = '_'.freeze
|
|
10
|
+
|
|
11
|
+
children :name
|
|
12
|
+
|
|
13
|
+
private
|
|
14
|
+
|
|
15
|
+
# Perform dispatch
|
|
16
|
+
#
|
|
17
|
+
# @return [undefined]
|
|
18
|
+
#
|
|
19
|
+
# @api private
|
|
20
|
+
#
|
|
21
|
+
def dispatch
|
|
22
|
+
return if skip?
|
|
23
|
+
emit_name_mutation
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Emit name mutations
|
|
27
|
+
#
|
|
28
|
+
# @return [undefined]
|
|
29
|
+
#
|
|
30
|
+
# @api private
|
|
31
|
+
#
|
|
32
|
+
def emit_name_mutation
|
|
33
|
+
Mutator::Util::Symbol.each(name) do |name|
|
|
34
|
+
emit_name(name)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Test if argument mutation is skipped
|
|
39
|
+
#
|
|
40
|
+
# @return [true]
|
|
41
|
+
# if argument should not get mutated
|
|
42
|
+
#
|
|
43
|
+
# @return [false]
|
|
44
|
+
# otherwise
|
|
45
|
+
#
|
|
46
|
+
# @api private
|
|
47
|
+
#
|
|
48
|
+
def skip?
|
|
49
|
+
name.to_s.start_with?(UNDERSCORE)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# Mutator for optional arguments
|
|
53
|
+
class Optional < self
|
|
54
|
+
|
|
55
|
+
handle(:optarg)
|
|
56
|
+
|
|
57
|
+
children :name, :default
|
|
58
|
+
|
|
59
|
+
private
|
|
60
|
+
|
|
61
|
+
# Perform dispatch
|
|
62
|
+
#
|
|
63
|
+
# @return [undefined]
|
|
64
|
+
#
|
|
65
|
+
# @api private
|
|
66
|
+
#
|
|
67
|
+
def dispatch
|
|
68
|
+
emit_name_mutation
|
|
69
|
+
emit_required_mutation
|
|
70
|
+
emit_default_mutations
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# Emit required mutation
|
|
74
|
+
#
|
|
75
|
+
# @return [undefined]
|
|
76
|
+
#
|
|
77
|
+
# @api private
|
|
78
|
+
#
|
|
79
|
+
def emit_required_mutation
|
|
80
|
+
emit(s(:arg, name))
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
end # Optional
|
|
84
|
+
|
|
85
|
+
end # Argument
|
|
86
|
+
end # Node
|
|
87
|
+
end # Mutator
|
|
88
|
+
end # Mutant
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
module Mutant
|
|
2
|
+
class Mutator
|
|
3
|
+
class Node
|
|
4
|
+
# Mutator for arguments node
|
|
5
|
+
class Arguments < self
|
|
6
|
+
|
|
7
|
+
handle(:args)
|
|
8
|
+
|
|
9
|
+
private
|
|
10
|
+
|
|
11
|
+
# Perform dispatch
|
|
12
|
+
#
|
|
13
|
+
# @return [undefined]
|
|
14
|
+
#
|
|
15
|
+
# @api private
|
|
16
|
+
#
|
|
17
|
+
def dispatch
|
|
18
|
+
emit_children_mutations
|
|
19
|
+
emit_mlhs_expansion
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Emit mlhs expansions
|
|
23
|
+
#
|
|
24
|
+
# @return [undefined]
|
|
25
|
+
#
|
|
26
|
+
# @api private
|
|
27
|
+
#
|
|
28
|
+
def emit_mlhs_expansion
|
|
29
|
+
mlhs_childs_with_index.each do |child, index|
|
|
30
|
+
dup_children = children.dup
|
|
31
|
+
dup_children.delete_at(index)
|
|
32
|
+
dup_children.insert(index, *child.children)
|
|
33
|
+
emit_self(*dup_children)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Return mlhs childs
|
|
38
|
+
#
|
|
39
|
+
# @return [Enumerable<Parser::AST::Node, Fixnum>]
|
|
40
|
+
#
|
|
41
|
+
# @api private
|
|
42
|
+
#
|
|
43
|
+
def mlhs_childs_with_index
|
|
44
|
+
children.each_with_index.select do |child, index|
|
|
45
|
+
child.type == :mlhs
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
end # Arguments
|
|
50
|
+
end # Node
|
|
51
|
+
end # Mutator
|
|
52
|
+
end # Mutant
|
|
@@ -1,55 +1,51 @@
|
|
|
1
1
|
module Mutant
|
|
2
2
|
class Mutator
|
|
3
3
|
class Node
|
|
4
|
-
|
|
5
|
-
# Abstract base class for assignment mutators
|
|
4
|
+
# Mutator base class for assignments
|
|
6
5
|
class Assignment < self
|
|
7
6
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
# Abstract base class for variable assignments
|
|
7
|
+
# Mutator for variable assignment
|
|
11
8
|
class Variable < self
|
|
12
9
|
|
|
13
|
-
|
|
10
|
+
children :name, :value
|
|
11
|
+
|
|
12
|
+
MAP = IceNine.deep_freeze(
|
|
13
|
+
:gvasgn => '$',
|
|
14
|
+
:cvasgn => '@@',
|
|
15
|
+
:ivasgn => '@',
|
|
16
|
+
:lvasgn => ''
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
handle *MAP.keys
|
|
20
|
+
|
|
21
|
+
private
|
|
22
|
+
|
|
23
|
+
# Perform dispatch
|
|
14
24
|
#
|
|
15
25
|
# @return [undefined]
|
|
16
26
|
#
|
|
17
27
|
# @api private
|
|
18
28
|
#
|
|
19
29
|
def dispatch
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
mutation
|
|
23
|
-
end
|
|
24
|
-
emit_attribute_mutations(:value)
|
|
30
|
+
mutate_name
|
|
31
|
+
emit_value_mutations
|
|
25
32
|
end
|
|
26
33
|
|
|
27
|
-
#
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
# Mutator for class variable assignments
|
|
40
|
-
class Class < self
|
|
41
|
-
PREFIX = '@@'.freeze
|
|
42
|
-
handle(Rubinius::AST::ClassVariableAssignment)
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
# Mutator for global variable assignments
|
|
46
|
-
class Global < self
|
|
47
|
-
PREFIX = '$'.freeze
|
|
48
|
-
handle(Rubinius::AST::GlobalVariableAssignment)
|
|
34
|
+
# Emit name mutations
|
|
35
|
+
#
|
|
36
|
+
# @return [undefined]
|
|
37
|
+
#
|
|
38
|
+
# @api private
|
|
39
|
+
#
|
|
40
|
+
def mutate_name
|
|
41
|
+
prefix = MAP.fetch(node.type)
|
|
42
|
+
Mutator::Util::Symbol.each(name) do |name|
|
|
43
|
+
emit_name("#{prefix}#{name}")
|
|
44
|
+
end
|
|
49
45
|
end
|
|
50
46
|
|
|
51
|
-
end
|
|
52
|
-
end
|
|
53
|
-
end
|
|
54
|
-
end
|
|
55
|
-
end
|
|
47
|
+
end # Variable
|
|
48
|
+
end # Assignment
|
|
49
|
+
end # Node
|
|
50
|
+
end # Mutator
|
|
51
|
+
end # Mutant
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
module Mutant
|
|
2
|
+
class Mutator
|
|
3
|
+
class Node
|
|
4
|
+
|
|
5
|
+
# Mutator for begin nodes
|
|
6
|
+
class Begin < self
|
|
7
|
+
|
|
8
|
+
handle(:begin)
|
|
9
|
+
|
|
10
|
+
private
|
|
11
|
+
|
|
12
|
+
# Emit mutants
|
|
13
|
+
#
|
|
14
|
+
# @return [undefined]
|
|
15
|
+
#
|
|
16
|
+
# @api private
|
|
17
|
+
#
|
|
18
|
+
def dispatch
|
|
19
|
+
Util::Array.each(children) do |children|
|
|
20
|
+
if children.length > 1
|
|
21
|
+
emit_self(*children)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
children.each do |child|
|
|
25
|
+
emit(child)
|
|
26
|
+
end
|
|
27
|
+
emit(nil)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
end # Block
|
|
31
|
+
end # Node
|
|
32
|
+
end # Mutator
|
|
33
|
+
end # Mutant
|