mutant 0.8.0 → 0.8.1
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/Changelog.md +7 -0
- data/config/flay.yml +1 -1
- data/config/reek.yml +1 -0
- data/lib/mutant.rb +10 -3
- data/lib/mutant/actor.rb +2 -5
- data/lib/mutant/actor/env.rb +1 -3
- data/lib/mutant/actor/mailbox.rb +2 -4
- data/lib/mutant/actor/receiver.rb +0 -2
- data/lib/mutant/actor/sender.rb +0 -1
- data/lib/mutant/ast.rb +22 -28
- data/lib/mutant/ast/meta.rb +8 -88
- data/lib/mutant/ast/named_children.rb +1 -8
- data/lib/mutant/ast/sexp.rb +0 -2
- data/lib/mutant/cache.rb +1 -3
- data/lib/mutant/cli.rb +9 -19
- data/lib/mutant/color.rb +0 -3
- data/lib/mutant/config.rb +6 -2
- data/lib/mutant/context.rb +2 -4
- data/lib/mutant/context/scope.rb +10 -16
- data/lib/mutant/delegator.rb +0 -3
- data/lib/mutant/diff.rb +8 -17
- data/lib/mutant/env.rb +3 -5
- data/lib/mutant/env/bootstrap.rb +32 -39
- data/lib/mutant/expression.rb +14 -132
- data/lib/mutant/expression/method.rb +25 -42
- data/lib/mutant/expression/methods.rb +17 -29
- data/lib/mutant/expression/namespace.rb +33 -28
- data/lib/mutant/expression/parser.rb +71 -0
- data/lib/mutant/integration.rb +17 -16
- data/lib/mutant/isolation.rb +14 -14
- data/lib/mutant/loader.rb +2 -4
- data/lib/mutant/matcher.rb +1 -11
- data/lib/mutant/matcher/chain.rb +0 -1
- data/lib/mutant/matcher/compiler.rb +19 -52
- data/lib/mutant/matcher/config.rb +65 -5
- data/lib/mutant/matcher/filter.rb +11 -1
- data/lib/mutant/matcher/method.rb +11 -21
- data/lib/mutant/matcher/method/instance.rb +2 -16
- data/lib/mutant/matcher/method/singleton.rb +3 -20
- data/lib/mutant/matcher/methods.rb +11 -21
- data/lib/mutant/matcher/namespace.rb +0 -4
- data/lib/mutant/matcher/null.rb +0 -1
- data/lib/mutant/matcher/scope.rb +0 -12
- data/lib/mutant/meta.rb +0 -1
- data/lib/mutant/meta/example.rb +12 -26
- data/lib/mutant/meta/example/dsl.rb +1 -8
- data/lib/mutant/mutation.rb +6 -14
- data/lib/mutant/mutator.rb +2 -14
- data/lib/mutant/mutator/node.rb +6 -33
- data/lib/mutant/mutator/node/and_asgn.rb +0 -1
- data/lib/mutant/mutator/node/argument.rb +0 -5
- data/lib/mutant/mutator/node/arguments.rb +1 -7
- data/lib/mutant/mutator/node/begin.rb +0 -2
- data/lib/mutant/mutator/node/binary.rb +0 -3
- data/lib/mutant/mutator/node/block.rb +0 -2
- data/lib/mutant/mutator/node/break.rb +0 -1
- data/lib/mutant/mutator/node/case.rb +0 -3
- data/lib/mutant/mutator/node/conditional_loop.rb +0 -1
- data/lib/mutant/mutator/node/const.rb +0 -1
- data/lib/mutant/mutator/node/define.rb +0 -1
- data/lib/mutant/mutator/node/defined.rb +0 -1
- data/lib/mutant/mutator/node/dstr.rb +0 -1
- data/lib/mutant/mutator/node/dsym.rb +0 -1
- data/lib/mutant/mutator/node/generic.rb +0 -1
- data/lib/mutant/mutator/node/if.rb +0 -4
- data/lib/mutant/mutator/node/kwbegin.rb +0 -1
- data/lib/mutant/mutator/node/literal/array.rb +0 -2
- data/lib/mutant/mutator/node/literal/boolean.rb +0 -1
- data/lib/mutant/mutator/node/literal/fixnum.rb +2 -5
- data/lib/mutant/mutator/node/literal/float.rb +1 -4
- data/lib/mutant/mutator/node/literal/hash.rb +0 -3
- data/lib/mutant/mutator/node/literal/nil.rb +0 -1
- data/lib/mutant/mutator/node/literal/range.rb +1 -5
- data/lib/mutant/mutator/node/literal/regex.rb +1 -3
- data/lib/mutant/mutator/node/literal/string.rb +0 -1
- data/lib/mutant/mutator/node/literal/symbol.rb +0 -1
- data/lib/mutant/mutator/node/masgn.rb +0 -1
- data/lib/mutant/mutator/node/match_current_line.rb +0 -1
- data/lib/mutant/mutator/node/mlhs.rb +0 -1
- data/lib/mutant/mutator/node/named_value/access.rb +0 -1
- data/lib/mutant/mutator/node/named_value/constant_assignment.rb +0 -2
- data/lib/mutant/mutator/node/named_value/variable_assignment.rb +0 -2
- data/lib/mutant/mutator/node/next.rb +0 -1
- data/lib/mutant/mutator/node/noop.rb +0 -1
- data/lib/mutant/mutator/node/nthref.rb +0 -1
- data/lib/mutant/mutator/node/op_asgn.rb +0 -1
- data/lib/mutant/mutator/node/or_asgn.rb +1 -2
- data/lib/mutant/mutator/node/resbody.rb +0 -2
- data/lib/mutant/mutator/node/rescue.rb +1 -6
- data/lib/mutant/mutator/node/return.rb +0 -1
- data/lib/mutant/mutator/node/send.rb +16 -17
- data/lib/mutant/mutator/node/send/attribute_assignment.rb +0 -3
- data/lib/mutant/mutator/node/send/binary.rb +0 -1
- data/lib/mutant/mutator/node/send/index.rb +0 -3
- data/lib/mutant/mutator/node/splat.rb +0 -1
- data/lib/mutant/mutator/node/super.rb +0 -1
- data/lib/mutant/mutator/node/when.rb +2 -7
- data/lib/mutant/mutator/node/yield.rb +0 -1
- data/lib/mutant/mutator/node/zsuper.rb +0 -1
- data/lib/mutant/mutator/registry.rb +1 -4
- data/lib/mutant/mutator/util.rb +0 -2
- data/lib/mutant/mutator/util/array.rb +0 -3
- data/lib/mutant/mutator/util/symbol.rb +0 -1
- data/lib/mutant/parallel.rb +3 -9
- data/lib/mutant/parallel/master.rb +7 -17
- data/lib/mutant/parallel/source.rb +2 -7
- data/lib/mutant/parallel/worker.rb +1 -5
- data/lib/mutant/reporter.rb +0 -4
- data/lib/mutant/reporter/cli.rb +1 -8
- data/lib/mutant/reporter/cli/format.rb +7 -18
- data/lib/mutant/reporter/cli/printer.rb +2 -12
- data/lib/mutant/reporter/cli/printer/config.rb +1 -4
- data/lib/mutant/reporter/cli/printer/env_progress.rb +3 -7
- data/lib/mutant/reporter/cli/printer/env_result.rb +0 -1
- data/lib/mutant/reporter/cli/printer/mutation_progress_result.rb +0 -2
- data/lib/mutant/reporter/cli/printer/mutation_result.rb +3 -11
- data/lib/mutant/reporter/cli/printer/status.rb +1 -4
- data/lib/mutant/reporter/cli/printer/status_progressive.rb +1 -3
- data/lib/mutant/reporter/cli/printer/subject_progress.rb +0 -5
- data/lib/mutant/reporter/cli/printer/subject_result.rb +0 -1
- data/lib/mutant/reporter/cli/printer/test_result.rb +0 -1
- data/lib/mutant/reporter/cli/tput.rb +4 -1
- data/lib/mutant/reporter/trace.rb +2 -4
- data/lib/mutant/repository.rb +88 -0
- data/lib/mutant/require_highjack.rb +0 -1
- data/lib/mutant/result.rb +25 -48
- data/lib/mutant/runner.rb +7 -16
- data/lib/mutant/runner/sink.rb +3 -11
- data/lib/mutant/selector.rb +1 -2
- data/lib/mutant/selector/expression.rb +1 -2
- data/lib/mutant/subject.rb +10 -21
- data/lib/mutant/subject/method.rb +11 -12
- data/lib/mutant/subject/method/instance.rb +1 -5
- data/lib/mutant/subject/method/singleton.rb +1 -3
- data/lib/mutant/test.rb +1 -2
- data/lib/mutant/version.rb +2 -2
- data/lib/mutant/warning_filter.rb +2 -7
- data/lib/mutant/zombifier.rb +6 -10
- data/meta/send.rb +8 -0
- data/spec/spec_helper.rb +5 -1
- data/spec/support/corpus.rb +5 -9
- data/spec/support/rb_bug.rb +0 -1
- data/spec/support/rspec.rb +0 -1
- data/spec/support/ruby_vm.rb +0 -2
- data/spec/unit/mutant/ast/meta/send_spec.rb +42 -0
- data/spec/unit/mutant/ast/named_children_spec.rb +51 -0
- data/spec/unit/mutant/ast/sexp_spec.rb +36 -0
- data/spec/unit/mutant/ast_spec.rb +8 -0
- data/spec/unit/mutant/cli_spec.rb +34 -19
- data/spec/unit/mutant/context/scope_spec.rb +11 -0
- data/spec/unit/mutant/env/boostrap_spec.rb +5 -2
- data/spec/unit/mutant/env_spec.rb +14 -15
- data/spec/unit/mutant/expression/method_spec.rb +10 -14
- data/spec/unit/mutant/expression/methods_spec.rb +24 -11
- data/spec/unit/mutant/expression/namespace/flat_spec.rb +5 -6
- data/spec/unit/mutant/expression/namespace/recursive_spec.rb +16 -10
- data/spec/unit/mutant/expression/parser_spec.rb +67 -0
- data/spec/unit/mutant/expression_spec.rb +24 -57
- data/spec/unit/mutant/integration/rspec_spec.rb +7 -7
- data/spec/unit/mutant/integration_spec.rb +2 -2
- data/spec/unit/mutant/isolation_spec.rb +31 -29
- data/spec/unit/mutant/matcher/compiler/subject_prefix_spec.rb +2 -2
- data/spec/unit/mutant/matcher/compiler_spec.rb +27 -58
- data/spec/unit/mutant/matcher/config_spec.rb +45 -0
- data/spec/unit/mutant/matcher/filter_spec.rb +12 -5
- data/spec/unit/mutant/matcher/method/instance_spec.rb +0 -1
- data/spec/unit/mutant/matcher/method/singleton_spec.rb +0 -1
- data/spec/unit/mutant/matcher/namespace_spec.rb +4 -4
- data/spec/unit/mutant/parallel/worker_spec.rb +1 -1
- data/spec/unit/mutant/reporter/cli/printer/config_spec.rb +4 -4
- data/spec/unit/mutant/reporter/cli/printer/env_progress_spec.rb +7 -7
- data/spec/unit/mutant/reporter/cli/printer/env_result_spec.rb +2 -2
- data/spec/unit/mutant/reporter/cli/printer/status_progressive_spec.rb +2 -2
- data/spec/unit/mutant/reporter/cli/printer/status_spec.rb +12 -12
- data/spec/unit/mutant/reporter/cli/printer/subject_progress_spec.rb +1 -1
- data/spec/unit/mutant/reporter/cli_spec.rb +9 -10
- data/spec/unit/mutant/repository/diff_spec.rb +80 -0
- data/spec/unit/mutant/repository/subject_filter_spec.rb +28 -0
- data/spec/unit/mutant/result/env_spec.rb +1 -1
- data/spec/unit/mutant/runner_spec.rb +0 -1
- data/spec/unit/mutant/selector/expression_spec.rb +14 -14
- data/spec/unit/mutant/subject/method/instance_spec.rb +2 -2
- data/spec/unit/mutant/subject/method/singleton_spec.rb +2 -2
- data/spec/unit/mutant/subject_spec.rb +5 -2
- metadata +20 -3
- data/spec/support/mutation_verifier.rb +0 -96
@@ -13,7 +13,6 @@ module Mutant
|
|
13
13
|
# otherwise
|
14
14
|
#
|
15
15
|
# @api private
|
16
|
-
#
|
17
16
|
def each(&block)
|
18
17
|
return to_enum unless block_given?
|
19
18
|
|
@@ -22,22 +21,22 @@ module Mutant
|
|
22
21
|
self
|
23
22
|
end
|
24
23
|
|
25
|
-
|
24
|
+
private
|
25
|
+
|
26
|
+
# method matcher class
|
26
27
|
#
|
27
28
|
# @return [Class:Matcher::Method]
|
28
29
|
#
|
29
30
|
# @api private
|
30
|
-
#
|
31
31
|
def matcher
|
32
32
|
self.class::MATCHER
|
33
33
|
end
|
34
34
|
|
35
|
-
#
|
35
|
+
# Available methods scope
|
36
36
|
#
|
37
37
|
# @return [Enumerable<Method, UnboundMethod>]
|
38
38
|
#
|
39
39
|
# @api private
|
40
|
-
#
|
41
40
|
def methods
|
42
41
|
candidate_names.each_with_object([]) do |name, methods|
|
43
42
|
method = access(name)
|
@@ -46,14 +45,11 @@ module Mutant
|
|
46
45
|
end
|
47
46
|
memoize :methods
|
48
47
|
|
49
|
-
|
50
|
-
|
51
|
-
# Return subjects
|
48
|
+
# Subjects detected on scope
|
52
49
|
#
|
53
50
|
# @return [Array<Subject>]
|
54
51
|
#
|
55
52
|
# @api private
|
56
|
-
#
|
57
53
|
def subjects
|
58
54
|
methods.map do |method|
|
59
55
|
matcher.build(env, scope, method)
|
@@ -61,12 +57,11 @@ module Mutant
|
|
61
57
|
end
|
62
58
|
memoize :subjects
|
63
59
|
|
64
|
-
#
|
60
|
+
# Candidate method names on target scope
|
65
61
|
#
|
66
62
|
# @return [Enumerable<Symbol>]
|
67
63
|
#
|
68
64
|
# @api private
|
69
|
-
#
|
70
65
|
def candidate_names
|
71
66
|
(
|
72
67
|
candidate_scope.public_instance_methods(false) +
|
@@ -75,12 +70,11 @@ module Mutant
|
|
75
70
|
).sort
|
76
71
|
end
|
77
72
|
|
78
|
-
#
|
73
|
+
# Candidate scope
|
79
74
|
#
|
80
75
|
# @return [Class, Module]
|
81
76
|
#
|
82
77
|
# @api private
|
83
|
-
#
|
84
78
|
abstract_method :candidate_scope
|
85
79
|
|
86
80
|
# Matcher for singleton methods
|
@@ -89,24 +83,22 @@ module Mutant
|
|
89
83
|
|
90
84
|
private
|
91
85
|
|
92
|
-
#
|
86
|
+
# Method object on scope
|
93
87
|
#
|
94
88
|
# @param [Symbol] method_name
|
95
89
|
#
|
96
90
|
# @return [Method]
|
97
91
|
#
|
98
92
|
# @api private
|
99
|
-
#
|
100
93
|
def access(method_name)
|
101
94
|
scope.method(method_name)
|
102
95
|
end
|
103
96
|
|
104
|
-
#
|
97
|
+
# Candidate scope
|
105
98
|
#
|
106
99
|
# @return [Class]
|
107
100
|
#
|
108
101
|
# @api private
|
109
|
-
#
|
110
102
|
def candidate_scope
|
111
103
|
scope.singleton_class
|
112
104
|
end
|
@@ -120,24 +112,22 @@ module Mutant
|
|
120
112
|
|
121
113
|
private
|
122
114
|
|
123
|
-
#
|
115
|
+
# Method object on scope
|
124
116
|
#
|
125
117
|
# @param [Symbol] method_name
|
126
118
|
#
|
127
119
|
# @return [UnboundMethod]
|
128
120
|
#
|
129
121
|
# @api private
|
130
|
-
#
|
131
122
|
def access(method_name)
|
132
123
|
scope.instance_method(method_name)
|
133
124
|
end
|
134
125
|
|
135
|
-
#
|
126
|
+
# Candidate scope
|
136
127
|
#
|
137
128
|
# @return [Class, Module]
|
138
129
|
#
|
139
130
|
# @api private
|
140
|
-
#
|
141
131
|
def candidate_scope
|
142
132
|
scope
|
143
133
|
end
|
@@ -2,8 +2,6 @@ module Mutant
|
|
2
2
|
class Matcher
|
3
3
|
|
4
4
|
# Matcher for specific namespace
|
5
|
-
#
|
6
|
-
# rubocop:disable LineLength
|
7
5
|
class Namespace < self
|
8
6
|
include Concord::Public.new(:env, :expression)
|
9
7
|
|
@@ -16,7 +14,6 @@ module Mutant
|
|
16
14
|
# otherwise
|
17
15
|
#
|
18
16
|
# @api private
|
19
|
-
#
|
20
17
|
def each(&block)
|
21
18
|
return to_enum unless block_given?
|
22
19
|
|
@@ -36,7 +33,6 @@ module Mutant
|
|
36
33
|
# @return [Boolean]
|
37
34
|
#
|
38
35
|
# @api private
|
39
|
-
#
|
40
36
|
def match?(scope)
|
41
37
|
expression.prefix?(scope.expression)
|
42
38
|
end
|
data/lib/mutant/matcher/null.rb
CHANGED
data/lib/mutant/matcher/scope.rb
CHANGED
@@ -9,17 +9,6 @@ module Mutant
|
|
9
9
|
Matcher::Methods::Instance
|
10
10
|
].freeze
|
11
11
|
|
12
|
-
# Return identification
|
13
|
-
#
|
14
|
-
# @return [String]
|
15
|
-
#
|
16
|
-
# @api private
|
17
|
-
#
|
18
|
-
def identification
|
19
|
-
scope.name
|
20
|
-
end
|
21
|
-
memoize :identification
|
22
|
-
|
23
12
|
# Enumerate subjects
|
24
13
|
#
|
25
14
|
# @return [self]
|
@@ -29,7 +18,6 @@ module Mutant
|
|
29
18
|
# otherwise
|
30
19
|
#
|
31
20
|
# @api private
|
32
|
-
#
|
33
21
|
def each(&block)
|
34
22
|
return to_enum unless block_given?
|
35
23
|
|
data/lib/mutant/meta.rb
CHANGED
data/lib/mutant/meta/example.rb
CHANGED
@@ -3,33 +3,30 @@ module Mutant
|
|
3
3
|
class Example
|
4
4
|
include Adamantium, Concord::Public.new(:file, :node, :mutations)
|
5
5
|
|
6
|
-
#
|
6
|
+
# Verification instance for example
|
7
7
|
#
|
8
8
|
# @return [Verification]
|
9
9
|
#
|
10
10
|
# @api private
|
11
|
-
#
|
12
11
|
def verification
|
13
12
|
Verification.new(self, generated)
|
14
13
|
end
|
15
14
|
|
16
|
-
#
|
15
|
+
# Normalized source
|
17
16
|
#
|
18
17
|
# @return [String]
|
19
18
|
#
|
20
19
|
# @api private
|
21
|
-
#
|
22
20
|
def source
|
23
21
|
Unparser.unparse(node)
|
24
22
|
end
|
25
23
|
memoize :source
|
26
24
|
|
27
|
-
#
|
25
|
+
# Generated mutations on example source
|
28
26
|
#
|
29
27
|
# @return [Enumerable<Mutant::Mutation>]
|
30
28
|
#
|
31
29
|
# @api private
|
32
|
-
#
|
33
30
|
def generated
|
34
31
|
Mutator.each(node).map do |node|
|
35
32
|
Mutation::Evil.new(self, node)
|
@@ -46,17 +43,15 @@ module Mutant
|
|
46
43
|
# @return [Boolean]
|
47
44
|
#
|
48
45
|
# @api private
|
49
|
-
#
|
50
46
|
def success?
|
51
47
|
unparser.success? && missing.empty? && unexpected.empty? && no_diffs.empty?
|
52
48
|
end
|
53
49
|
|
54
|
-
#
|
50
|
+
# Error report
|
55
51
|
#
|
56
52
|
# @return [String]
|
57
53
|
#
|
58
54
|
# @api private
|
59
|
-
#
|
60
55
|
def error_report
|
61
56
|
unless unparser.success?
|
62
57
|
return unparser.report
|
@@ -66,34 +61,31 @@ module Mutant
|
|
66
61
|
|
67
62
|
private
|
68
63
|
|
69
|
-
#
|
64
|
+
# Unexpected mutations
|
70
65
|
#
|
71
66
|
# @return [Array<Parser::AST::Node>]
|
72
67
|
#
|
73
68
|
# @api private
|
74
|
-
#
|
75
69
|
def unexpected
|
76
70
|
mutations.map(&:node) - example.mutations
|
77
71
|
end
|
78
72
|
memoize :unexpected
|
79
73
|
|
80
|
-
#
|
74
|
+
# Mutations with no diff to original
|
81
75
|
#
|
82
76
|
# @return [Enumerable<Mutation>]
|
83
77
|
#
|
84
78
|
# @api private
|
85
|
-
#
|
86
79
|
def no_diffs
|
87
80
|
mutations.select { |mutation| mutation.source.eql?(example.source) }
|
88
81
|
end
|
89
82
|
memoize :no_diffs
|
90
83
|
|
91
|
-
#
|
84
|
+
# Mutation report
|
92
85
|
#
|
93
86
|
# @return [String]
|
94
87
|
#
|
95
88
|
# @api private
|
96
|
-
#
|
97
89
|
def mutation_report
|
98
90
|
original_node = example.node
|
99
91
|
[
|
@@ -107,12 +99,11 @@ module Mutant
|
|
107
99
|
].join("\n======\n")
|
108
100
|
end
|
109
101
|
|
110
|
-
#
|
102
|
+
# Missing mutation report
|
111
103
|
#
|
112
104
|
# @return [Array, nil]
|
113
105
|
#
|
114
106
|
# @api private
|
115
|
-
#
|
116
107
|
def missing_report
|
117
108
|
[
|
118
109
|
'Missing mutations:',
|
@@ -120,12 +111,11 @@ module Mutant
|
|
120
111
|
] if missing.any?
|
121
112
|
end
|
122
113
|
|
123
|
-
#
|
114
|
+
# No diff mutation report
|
124
115
|
#
|
125
116
|
# @return [Array, nil]
|
126
117
|
#
|
127
118
|
# @api private
|
128
|
-
#
|
129
119
|
def no_diff_report
|
130
120
|
[
|
131
121
|
'No source diffs to original:',
|
@@ -135,12 +125,11 @@ module Mutant
|
|
135
125
|
] if no_diffs.any?
|
136
126
|
end
|
137
127
|
|
138
|
-
#
|
128
|
+
# Unexpected mutation report
|
139
129
|
#
|
140
130
|
# @return [Array, nil]
|
141
131
|
#
|
142
132
|
# @api private
|
143
|
-
#
|
144
133
|
def unexpected_report
|
145
134
|
[
|
146
135
|
'Unexpected mutations:',
|
@@ -153,7 +142,6 @@ module Mutant
|
|
153
142
|
# @return [String]
|
154
143
|
#
|
155
144
|
# @api private
|
156
|
-
#
|
157
145
|
def format_mutation(node)
|
158
146
|
[
|
159
147
|
node.inspect,
|
@@ -161,23 +149,21 @@ module Mutant
|
|
161
149
|
].join("\n")
|
162
150
|
end
|
163
151
|
|
164
|
-
#
|
152
|
+
# Missing mutations
|
165
153
|
#
|
166
154
|
# @return [Array<Parser::AST::Node>]
|
167
155
|
#
|
168
156
|
# @api private
|
169
|
-
#
|
170
157
|
def missing
|
171
158
|
example.mutations - mutations.map(&:node)
|
172
159
|
end
|
173
160
|
memoize :missing
|
174
161
|
|
175
|
-
#
|
162
|
+
# Unparser verifier
|
176
163
|
#
|
177
164
|
# @return [Unparser::CLI::Source]
|
178
165
|
#
|
179
166
|
# @api private
|
180
|
-
#
|
181
167
|
def unparser
|
182
168
|
Unparser::CLI::Source::Node.new(Unparser::Preprocessor.run(example.node))
|
183
169
|
end
|
@@ -11,7 +11,6 @@ module Mutant
|
|
11
11
|
# @return [Example]
|
12
12
|
#
|
13
13
|
# @api private
|
14
|
-
#
|
15
14
|
def self.run(file, block)
|
16
15
|
instance = new(file)
|
17
16
|
instance.instance_eval(&block)
|
@@ -23,14 +22,13 @@ module Mutant
|
|
23
22
|
# @return [undefined]
|
24
23
|
#
|
25
24
|
# @api private
|
26
|
-
#
|
27
25
|
def initialize(file)
|
28
26
|
@file = file
|
29
27
|
@source = nil
|
30
28
|
@expected = []
|
31
29
|
end
|
32
30
|
|
33
|
-
#
|
31
|
+
# Example captured by DSL
|
34
32
|
#
|
35
33
|
# @return [Example]
|
36
34
|
#
|
@@ -38,7 +36,6 @@ module Mutant
|
|
38
36
|
# in case example cannot be build
|
39
37
|
#
|
40
38
|
# @api private
|
41
|
-
#
|
42
39
|
def example
|
43
40
|
fail 'source not defined' unless @source
|
44
41
|
Example.new(@file, @source, @expected)
|
@@ -53,7 +50,6 @@ module Mutant
|
|
53
50
|
# @return [self]
|
54
51
|
#
|
55
52
|
# @api private
|
56
|
-
#
|
57
53
|
def source(input)
|
58
54
|
fail 'source already defined' if @source
|
59
55
|
@source = node(input)
|
@@ -68,7 +64,6 @@ module Mutant
|
|
68
64
|
# @return [self]
|
69
65
|
#
|
70
66
|
# @api private
|
71
|
-
#
|
72
67
|
def mutation(input)
|
73
68
|
node = node(input)
|
74
69
|
if @expected.include?(node)
|
@@ -84,7 +79,6 @@ module Mutant
|
|
84
79
|
# @return [undefined]
|
85
80
|
#
|
86
81
|
# @api private
|
87
|
-
#
|
88
82
|
def singleton_mutations
|
89
83
|
mutation('nil')
|
90
84
|
mutation('self')
|
@@ -100,7 +94,6 @@ module Mutant
|
|
100
94
|
# in case input cannot be coerced
|
101
95
|
#
|
102
96
|
# @api private
|
103
|
-
#
|
104
97
|
def node(input)
|
105
98
|
case input
|
106
99
|
when String
|
data/lib/mutant/mutation.rb
CHANGED
@@ -7,45 +7,41 @@ module Mutant
|
|
7
7
|
CODE_DELIMITER = "\0".freeze
|
8
8
|
CODE_RANGE = (0..4).freeze
|
9
9
|
|
10
|
-
#
|
10
|
+
# Identification string
|
11
11
|
#
|
12
12
|
# @return [String]
|
13
13
|
#
|
14
14
|
# @api private
|
15
|
-
#
|
16
15
|
def identification
|
17
16
|
"#{self.class::SYMBOL}:#{subject.identification}:#{code}"
|
18
17
|
end
|
19
18
|
memoize :identification
|
20
19
|
|
21
|
-
#
|
20
|
+
# Mutation code
|
22
21
|
#
|
23
22
|
# @return [String]
|
24
23
|
#
|
25
24
|
# @api private
|
26
|
-
#
|
27
25
|
def code
|
28
26
|
sha1[CODE_RANGE]
|
29
27
|
end
|
30
28
|
memoize :code
|
31
29
|
|
32
|
-
#
|
30
|
+
# Normalized mutation source
|
33
31
|
#
|
34
32
|
# @return [String]
|
35
33
|
#
|
36
34
|
# @api private
|
37
|
-
#
|
38
35
|
def source
|
39
36
|
Unparser.unparse(node)
|
40
37
|
end
|
41
38
|
memoize :source
|
42
39
|
|
43
|
-
#
|
40
|
+
# Normalized original source
|
44
41
|
#
|
45
42
|
# @return [String]
|
46
43
|
#
|
47
44
|
# @api private
|
48
|
-
#
|
49
45
|
def original_source
|
50
46
|
subject.source
|
51
47
|
end
|
@@ -57,7 +53,6 @@ module Mutant
|
|
57
53
|
# @return [Boolean]
|
58
54
|
#
|
59
55
|
# @api private
|
60
|
-
#
|
61
56
|
def self.success?(test_result)
|
62
57
|
self::TEST_PASS_SUCCESS.equal?(test_result.passed)
|
63
58
|
end
|
@@ -71,7 +66,6 @@ module Mutant
|
|
71
66
|
# @return [self]
|
72
67
|
#
|
73
68
|
# @api private
|
74
|
-
#
|
75
69
|
def insert
|
76
70
|
subject.public?
|
77
71
|
subject.prepare
|
@@ -81,23 +75,21 @@ module Mutant
|
|
81
75
|
|
82
76
|
private
|
83
77
|
|
84
|
-
#
|
78
|
+
# SHA1 sum of source and subject identification
|
85
79
|
#
|
86
80
|
# @return [String]
|
87
81
|
#
|
88
82
|
# @api private
|
89
|
-
#
|
90
83
|
def sha1
|
91
84
|
Digest::SHA1.hexdigest(subject.identification + CODE_DELIMITER + source)
|
92
85
|
end
|
93
86
|
memoize :sha1
|
94
87
|
|
95
|
-
#
|
88
|
+
# Mutated root node
|
96
89
|
#
|
97
90
|
# @return [Parser::AST::Node]
|
98
91
|
#
|
99
92
|
# @api private
|
100
|
-
#
|
101
93
|
def root
|
102
94
|
subject.context.root(node)
|
103
95
|
end
|