mutant 0.8.0 → 0.8.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
data/lib/mutant/ast/sexp.rb
CHANGED
@@ -12,7 +12,6 @@ module Mutant
|
|
12
12
|
# @return [Parser::AST::Node]
|
13
13
|
#
|
14
14
|
# @api private
|
15
|
-
#
|
16
15
|
def s(type, *children)
|
17
16
|
Parser::AST::Node.new(type, children)
|
18
17
|
end
|
@@ -24,7 +23,6 @@ module Mutant
|
|
24
23
|
# @return [Parser::AST::Node]
|
25
24
|
#
|
26
25
|
# @api private
|
27
|
-
#
|
28
26
|
def n_not(node)
|
29
27
|
s(:send, node, :!)
|
30
28
|
end
|
data/lib/mutant/cache.rb
CHANGED
@@ -8,19 +8,17 @@ module Mutant
|
|
8
8
|
# @return [undefined]
|
9
9
|
#
|
10
10
|
# @api private
|
11
|
-
#
|
12
11
|
def initialize
|
13
12
|
@cache = {}
|
14
13
|
end
|
15
14
|
|
16
|
-
#
|
15
|
+
# Root node parsed from file
|
17
16
|
#
|
18
17
|
# @param [#to_s] path
|
19
18
|
#
|
20
19
|
# @return [AST::Node]
|
21
20
|
#
|
22
21
|
# @api private
|
23
|
-
#
|
24
22
|
def parse(path)
|
25
23
|
@cache.fetch(path) do
|
26
24
|
@cache[path] = Parser::CurrentRuby.parse(File.read(path))
|
data/lib/mutant/cli.rb
CHANGED
@@ -18,7 +18,6 @@ module Mutant
|
|
18
18
|
# the exit status
|
19
19
|
#
|
20
20
|
# @api private
|
21
|
-
#
|
22
21
|
def self.run(arguments)
|
23
22
|
Runner.call(Env::Bootstrap.call(call(arguments))).success? ? EXIT_SUCCESS : EXIT_FAILURE
|
24
23
|
rescue Error => exception
|
@@ -33,19 +32,17 @@ module Mutant
|
|
33
32
|
# @return [undefined]
|
34
33
|
#
|
35
34
|
# @api private
|
36
|
-
#
|
37
35
|
def initialize(arguments)
|
38
36
|
@config = Config::DEFAULT
|
39
37
|
|
40
38
|
parse(arguments)
|
41
39
|
end
|
42
40
|
|
43
|
-
#
|
41
|
+
# Config parsed from CLI
|
44
42
|
#
|
45
43
|
# @return [Config]
|
46
44
|
#
|
47
45
|
# @api private
|
48
|
-
#
|
49
46
|
attr_reader :config
|
50
47
|
|
51
48
|
private
|
@@ -61,7 +58,6 @@ module Mutant
|
|
61
58
|
# @return [undefined]
|
62
59
|
#
|
63
60
|
# @api private
|
64
|
-
#
|
65
61
|
def parse(arguments)
|
66
62
|
opts = OptionParser.new do |builder|
|
67
63
|
builder.banner = 'usage: mutant [options] MATCH_EXPRESSION ...'
|
@@ -82,12 +78,11 @@ module Mutant
|
|
82
78
|
# @return [undefined]
|
83
79
|
#
|
84
80
|
# @api private
|
85
|
-
#
|
86
81
|
def parse_match_expressions(expressions)
|
87
82
|
fail Error, 'No expressions given' if expressions.empty?
|
88
83
|
|
89
|
-
expressions.
|
90
|
-
add_matcher(:match_expressions, expression)
|
84
|
+
expressions.each do |expression|
|
85
|
+
add_matcher(:match_expressions, config.expression_parser.(expression))
|
91
86
|
end
|
92
87
|
end
|
93
88
|
|
@@ -97,10 +92,9 @@ module Mutant
|
|
97
92
|
#
|
98
93
|
# @return [undefined]
|
99
94
|
#
|
100
|
-
# @api private
|
101
|
-
#
|
102
95
|
# rubocop:disable MethodLength
|
103
96
|
#
|
97
|
+
# @api private
|
104
98
|
def add_environment_options(opts)
|
105
99
|
opts.separator('Environment:')
|
106
100
|
opts.on('--zombie', 'Run mutant zombified') do
|
@@ -124,7 +118,6 @@ module Mutant
|
|
124
118
|
# @return [undefined]
|
125
119
|
#
|
126
120
|
# @api private
|
127
|
-
#
|
128
121
|
def setup_integration(name)
|
129
122
|
update(integration: Integration.setup(name))
|
130
123
|
rescue LoadError
|
@@ -138,7 +131,6 @@ module Mutant
|
|
138
131
|
# @return [undefined]
|
139
132
|
#
|
140
133
|
# @api private
|
141
|
-
#
|
142
134
|
def add_mutation_options(opts)
|
143
135
|
opts.separator(nil)
|
144
136
|
opts.separator('Options:')
|
@@ -159,10 +151,12 @@ module Mutant
|
|
159
151
|
# @return [undefined]
|
160
152
|
#
|
161
153
|
# @api private
|
162
|
-
#
|
163
154
|
def add_filter_options(opts)
|
164
|
-
opts.on('--ignore-subject
|
165
|
-
add_matcher(:
|
155
|
+
opts.on('--ignore-subject EXPRESSION', 'Ignore subjects that match EXPRESSION as prefix') do |pattern|
|
156
|
+
add_matcher(:ignore_expressions, config.expression_parser.(pattern))
|
157
|
+
end
|
158
|
+
opts.on('--since REVISION', 'Only select subjects touched since REVISION') do |revision|
|
159
|
+
add_matcher(:subject_filters, Repository::SubjectFilter.new(Repository::Diff.from_head(revision)))
|
166
160
|
end
|
167
161
|
end
|
168
162
|
|
@@ -173,7 +167,6 @@ module Mutant
|
|
173
167
|
# @return [undefined]
|
174
168
|
#
|
175
169
|
# @api private
|
176
|
-
#
|
177
170
|
def add_debug_options(opts)
|
178
171
|
opts.on('--fail-fast', 'Fail fast') do
|
179
172
|
update(fail_fast: true)
|
@@ -198,7 +191,6 @@ module Mutant
|
|
198
191
|
# @return [undefined]
|
199
192
|
#
|
200
193
|
# @api private
|
201
|
-
#
|
202
194
|
def update(attributes)
|
203
195
|
@config = @config.update(attributes)
|
204
196
|
end
|
@@ -214,7 +206,6 @@ module Mutant
|
|
214
206
|
# @return [undefined]
|
215
207
|
#
|
216
208
|
# @api private
|
217
|
-
#
|
218
209
|
def add(attribute, value)
|
219
210
|
update(attribute => config.public_send(attribute).dup << value)
|
220
211
|
end
|
@@ -230,7 +221,6 @@ module Mutant
|
|
230
221
|
# @return [undefined]
|
231
222
|
#
|
232
223
|
# @api private
|
233
|
-
#
|
234
224
|
def add_matcher(attribute, value)
|
235
225
|
update(matcher: config.matcher.add(attribute, value))
|
236
226
|
end
|
data/lib/mutant/color.rb
CHANGED
@@ -10,7 +10,6 @@ module Mutant
|
|
10
10
|
# @return [String]
|
11
11
|
#
|
12
12
|
# @api private
|
13
|
-
#
|
14
13
|
def format(text)
|
15
14
|
"\e[#{@code}m#{text}\e[0m"
|
16
15
|
end
|
@@ -25,7 +24,6 @@ module Mutant
|
|
25
24
|
# the argument string
|
26
25
|
#
|
27
26
|
# @api private
|
28
|
-
#
|
29
27
|
def format(text)
|
30
28
|
text
|
31
29
|
end
|
@@ -37,7 +35,6 @@ module Mutant
|
|
37
35
|
# @return [undefined]
|
38
36
|
#
|
39
37
|
# @api private
|
40
|
-
#
|
41
38
|
def initialize
|
42
39
|
end
|
43
40
|
|
data/lib/mutant/config.rb
CHANGED
@@ -1,5 +1,8 @@
|
|
1
1
|
module Mutant
|
2
|
-
#
|
2
|
+
# Standalone configuration of a mutant execution.
|
3
|
+
#
|
4
|
+
# Does not reference any "external" volatile state. The configuration applied
|
5
|
+
# to current environment is being represented by the Mutant::Env object.
|
3
6
|
class Config
|
4
7
|
include Adamantium::Flat, Anima::Update, Anima.new(
|
5
8
|
:debug,
|
@@ -12,7 +15,8 @@ module Mutant
|
|
12
15
|
:fail_fast,
|
13
16
|
:jobs,
|
14
17
|
:zombie,
|
15
|
-
:expected_coverage
|
18
|
+
:expected_coverage,
|
19
|
+
:expression_parser
|
16
20
|
)
|
17
21
|
|
18
22
|
%i[fail_fast zombie debug].each do |name|
|
data/lib/mutant/context.rb
CHANGED
@@ -3,22 +3,20 @@ module Mutant
|
|
3
3
|
class Context
|
4
4
|
include Adamantium::Flat, AbstractType, Concord::Public.new(:source_path)
|
5
5
|
|
6
|
-
#
|
6
|
+
# Root ast node
|
7
7
|
#
|
8
8
|
# @param [Parser::AST::Node] node
|
9
9
|
#
|
10
10
|
# @return [Parser::AST::Node]
|
11
11
|
#
|
12
12
|
# @api private
|
13
|
-
#
|
14
13
|
abstract_method :root
|
15
14
|
|
16
|
-
#
|
15
|
+
# Identification string
|
17
16
|
#
|
18
17
|
# @return [String]
|
19
18
|
#
|
20
19
|
# @api private
|
21
|
-
#
|
22
20
|
abstract_method :identification
|
23
21
|
|
24
22
|
end # Context
|
data/lib/mutant/context/scope.rb
CHANGED
@@ -7,24 +7,22 @@ module Mutant
|
|
7
7
|
|
8
8
|
NAMESPACE_DELIMITER = '::'.freeze
|
9
9
|
|
10
|
-
# Return
|
10
|
+
# Return root node for mutation
|
11
11
|
#
|
12
12
|
# @return [Parser::AST::Node]
|
13
13
|
#
|
14
14
|
# @api private
|
15
|
-
#
|
16
15
|
def root(node)
|
17
16
|
nesting.reverse.reduce(node) do |current, scope|
|
18
17
|
self.class.wrap(scope, current)
|
19
18
|
end
|
20
19
|
end
|
21
20
|
|
22
|
-
#
|
21
|
+
# Identification string
|
23
22
|
#
|
24
23
|
# @return [String]
|
25
24
|
#
|
26
25
|
# @api private
|
27
|
-
#
|
28
26
|
def identification
|
29
27
|
scope.name
|
30
28
|
end
|
@@ -41,7 +39,6 @@ module Mutant
|
|
41
39
|
# if scope is of kind module
|
42
40
|
#
|
43
41
|
# @api private
|
44
|
-
#
|
45
42
|
def self.wrap(scope, node)
|
46
43
|
name = s(:const, nil, scope.name.split(NAMESPACE_DELIMITER).last.to_sym)
|
47
44
|
case scope
|
@@ -54,12 +51,11 @@ module Mutant
|
|
54
51
|
end
|
55
52
|
end
|
56
53
|
|
57
|
-
#
|
54
|
+
# Nesting of scope
|
58
55
|
#
|
59
56
|
# @return [Enumerable<Class,Module>]
|
60
57
|
#
|
61
58
|
# @api private
|
62
|
-
#
|
63
59
|
def nesting
|
64
60
|
const = ::Object
|
65
61
|
name_nesting.each_with_object([]) do |name, nesting|
|
@@ -69,45 +65,43 @@ module Mutant
|
|
69
65
|
end
|
70
66
|
memoize :nesting
|
71
67
|
|
72
|
-
#
|
68
|
+
# Unqualified name of scope
|
73
69
|
#
|
74
70
|
# @return [String]
|
75
71
|
#
|
76
72
|
# @api private
|
77
|
-
#
|
78
73
|
def unqualified_name
|
79
74
|
name_nesting.last
|
80
75
|
end
|
81
76
|
|
82
|
-
#
|
77
|
+
# Match expressions for scope
|
83
78
|
#
|
84
79
|
# @return [Enumerable<Expression>]
|
85
80
|
#
|
86
81
|
# @api private
|
87
|
-
#
|
88
82
|
def match_expressions
|
89
83
|
name_nesting.each_index.reverse_each.map do |index|
|
90
|
-
Expression.
|
84
|
+
Expression::Namespace::Recursive.new(
|
85
|
+
scope_name: name_nesting.take(index.succ).join(NAMESPACE_DELIMITER)
|
86
|
+
)
|
91
87
|
end
|
92
88
|
end
|
93
89
|
memoize :match_expressions
|
94
90
|
|
95
|
-
#
|
91
|
+
# Scope wrapped by context
|
96
92
|
#
|
97
93
|
# @return [::Module|::Class]
|
98
94
|
#
|
99
95
|
# @api private
|
100
|
-
#
|
101
96
|
attr_reader :scope
|
102
97
|
|
103
98
|
private
|
104
99
|
|
105
|
-
#
|
100
|
+
# Nesting of names in scope
|
106
101
|
#
|
107
102
|
# @return [Array<String>]
|
108
103
|
#
|
109
104
|
# @api private
|
110
|
-
#
|
111
105
|
def name_nesting
|
112
106
|
scope.name.split(NAMESPACE_DELIMITER)
|
113
107
|
end
|
data/lib/mutant/delegator.rb
CHANGED
@@ -11,7 +11,6 @@ module Mutant
|
|
11
11
|
# @return [undefined]
|
12
12
|
#
|
13
13
|
# @api private
|
14
|
-
#
|
15
14
|
def delegate(*names)
|
16
15
|
names.each(&method(:define_delegator))
|
17
16
|
end
|
@@ -23,7 +22,6 @@ module Mutant
|
|
23
22
|
# @return [undefined]
|
24
23
|
#
|
25
24
|
# @api private
|
26
|
-
#
|
27
25
|
def define_delegator(name)
|
28
26
|
fail "method #{name} already defined" if instance_methods.include?(name)
|
29
27
|
define_method(name) do
|
@@ -41,7 +39,6 @@ module Mutant
|
|
41
39
|
# @return [undefined]
|
42
40
|
#
|
43
41
|
# @api private
|
44
|
-
#
|
45
42
|
def self.included(host)
|
46
43
|
super
|
47
44
|
|
data/lib/mutant/diff.rb
CHANGED
@@ -7,7 +7,7 @@ module Mutant
|
|
7
7
|
DELETION = '-'.freeze
|
8
8
|
NEWLINE = "\n".freeze
|
9
9
|
|
10
|
-
#
|
10
|
+
# Unified source diff between old and new
|
11
11
|
#
|
12
12
|
# @return [String]
|
13
13
|
# if there is exactly one diff
|
@@ -16,7 +16,6 @@ module Mutant
|
|
16
16
|
# otherwise
|
17
17
|
#
|
18
18
|
# @api private
|
19
|
-
#
|
20
19
|
def diff
|
21
20
|
return if diffs.empty?
|
22
21
|
|
@@ -26,7 +25,7 @@ module Mutant
|
|
26
25
|
end
|
27
26
|
memoize :diff
|
28
27
|
|
29
|
-
#
|
28
|
+
# Colorized unified source diff between old and new
|
30
29
|
#
|
31
30
|
# @return [String]
|
32
31
|
# if there is a diff
|
@@ -35,14 +34,13 @@ module Mutant
|
|
35
34
|
# otherwise
|
36
35
|
#
|
37
36
|
# @api private
|
38
|
-
#
|
39
37
|
def colorized_diff
|
40
38
|
return unless diff
|
41
39
|
diff.lines.map(&self.class.method(:colorize_line)).join
|
42
40
|
end
|
43
41
|
memoize :colorized_diff
|
44
42
|
|
45
|
-
#
|
43
|
+
# Build new object from source strings
|
46
44
|
#
|
47
45
|
# @param [String] old
|
48
46
|
# @param [String] new
|
@@ -50,7 +48,6 @@ module Mutant
|
|
50
48
|
# @return [Diff]
|
51
49
|
#
|
52
50
|
# @api private
|
53
|
-
#
|
54
51
|
def self.build(old, new)
|
55
52
|
new(lines(old), lines(new))
|
56
53
|
end
|
@@ -62,7 +59,6 @@ module Mutant
|
|
62
59
|
# @return [Array<String>]
|
63
60
|
#
|
64
61
|
# @api private
|
65
|
-
#
|
66
62
|
def self.lines(source)
|
67
63
|
source.lines.map(&:chomp)
|
68
64
|
end
|
@@ -70,34 +66,31 @@ module Mutant
|
|
70
66
|
|
71
67
|
private
|
72
68
|
|
73
|
-
#
|
69
|
+
# Diffs between old and new
|
74
70
|
#
|
75
71
|
# @return [Array<Array>]
|
76
72
|
#
|
77
73
|
# @api private
|
78
|
-
#
|
79
74
|
def diffs
|
80
75
|
::Diff::LCS.diff(old, new)
|
81
76
|
end
|
82
77
|
|
83
|
-
#
|
78
|
+
# Raw diff-lcs hunks
|
84
79
|
#
|
85
80
|
# @return [Array<Diff::LCS::Hunk>]
|
86
81
|
#
|
87
82
|
# @api private
|
88
|
-
#
|
89
83
|
def hunks
|
90
84
|
diffs.map do |diff|
|
91
85
|
::Diff::LCS::Hunk.new(old, new, diff, max_length, 0)
|
92
86
|
end
|
93
87
|
end
|
94
88
|
|
95
|
-
#
|
89
|
+
# Minimized hunks
|
96
90
|
#
|
97
91
|
# @return [Array<Diff::LCS::Hunk>]
|
98
92
|
#
|
99
93
|
# @api private
|
100
|
-
#
|
101
94
|
def minimized_hunks
|
102
95
|
head, *tail = hunks
|
103
96
|
|
@@ -111,24 +104,22 @@ module Mutant
|
|
111
104
|
end
|
112
105
|
end
|
113
106
|
|
114
|
-
#
|
107
|
+
# Max length of source line in new and old
|
115
108
|
#
|
116
109
|
# @return [Fixnum]
|
117
110
|
#
|
118
111
|
# @api private
|
119
|
-
#
|
120
112
|
def max_length
|
121
113
|
[old, new].map(&:length).max
|
122
114
|
end
|
123
115
|
|
124
|
-
#
|
116
|
+
# Colorized a unified diff line
|
125
117
|
#
|
126
118
|
# @param [String] line
|
127
119
|
#
|
128
120
|
# @return [String]
|
129
121
|
#
|
130
122
|
# @api private
|
131
|
-
#
|
132
123
|
def self.colorize_line(line)
|
133
124
|
case line[0]
|
134
125
|
when ADDITION
|