mutant 0.8.3 → 0.8.4
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 +8 -0
- data/Gemfile +1 -4
- data/Gemfile.shared +3 -0
- data/Rakefile +0 -2
- data/config/flay.yml +1 -1
- data/config/rubocop.yml +8 -0
- data/lib/mutant.rb +2 -0
- data/lib/mutant/ast/meta/restarg.rb +15 -0
- data/lib/mutant/ast/meta/symbol.rb +15 -0
- data/lib/mutant/cli.rb +11 -11
- data/lib/mutant/config.rb +1 -1
- data/lib/mutant/env.rb +1 -1
- data/lib/mutant/matcher/config.rb +2 -2
- data/lib/mutant/mutator/node/block.rb +16 -0
- data/lib/mutant/mutator/node/define.rb +14 -0
- data/lib/mutant/mutator/node/send.rb +12 -1
- data/lib/mutant/mutator/node/send/binary.rb +25 -1
- data/lib/mutant/parallel.rb +2 -2
- data/lib/mutant/result.rb +1 -1
- data/lib/mutant/runner/sink.rb +2 -2
- data/lib/mutant/version.rb +1 -1
- data/meta/begin.rb +0 -2
- data/meta/block.rb +15 -0
- data/meta/def.rb +25 -0
- data/meta/or_asgn.rb +9 -0
- data/meta/send.rb +41 -1
- data/mutant-rspec.gemspec +0 -2
- data/mutant.gemspec +5 -6
- data/spec/spec_helper.rb +1 -1
- data/spec/support/corpus.rb +1 -0
- data/spec/support/shared_context.rb +5 -5
- data/spec/unit/mutant/cli_spec.rb +6 -6
- data/spec/unit/mutant/env/boostrap_spec.rb +3 -3
- data/spec/unit/mutant/env_spec.rb +1 -1
- data/spec/unit/mutant/matcher/compiler_spec.rb +1 -1
- data/spec/unit/mutant/parallel/master_spec.rb +2 -2
- data/spec/unit/mutant/reporter/cli/printer/config_spec.rb +1 -1
- data/spec/unit/mutant/reporter/cli/printer/env_progress_spec.rb +3 -3
- data/spec/unit/mutant/reporter/cli/printer/env_result_spec.rb +1 -1
- data/spec/unit/mutant/reporter/cli/printer/mutation_progress_result_spec.rb +2 -2
- data/spec/unit/mutant/reporter/cli/printer/mutation_result_spec.rb +3 -3
- data/spec/unit/mutant/reporter/cli/printer/status_progressive_spec.rb +5 -5
- data/spec/unit/mutant/reporter/cli/printer/status_spec.rb +5 -5
- data/spec/unit/mutant/reporter/cli/printer/subject_progress_spec.rb +2 -2
- data/spec/unit/mutant/reporter/cli/printer/subject_result_spec.rb +2 -2
- data/spec/unit/mutant/reporter/cli_spec.rb +6 -4
- data/spec/unit/mutant/result_spec.rb +23 -0
- data/spec/unit/mutant/runner/sink/mutation_spec.rb +8 -8
- data/spec/unit/mutant/selector/expression_spec.rb +1 -1
- data/test_app/Gemfile.rspec3.2 +1 -0
- data/test_app/Gemfile.rspec3.3 +1 -0
- data/test_app/spec/unit/test_app/literal_spec.rb +0 -2
- metadata +27 -18
- data/Guardfile +0 -16
- data/test_app/Gemfile.rspec3.0 +0 -6
- data/test_app/Gemfile.rspec3.1 +0 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a7008d6d94f2de1e1c8d276c943491b0fb6cfdc1
|
4
|
+
data.tar.gz: 70b30707970890aa21961febe6a7657aa1889522
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b9fe654b8233c2666adadd104d7b6cfe4a5409b81913d9d446364424920a659becb763659c24e308915263a1a6a52e20ea8d7895ca27effb057ea169b1d51f79
|
7
|
+
data.tar.gz: 5ea82f2c27289e2f307a5809f6c21a8d95315191069f240488419d6c5a65d360bc64ccf8a5d8f8b1f7eca4f23d283107c3a37768472d6a3970d52a9c2e114571
|
data/Changelog.md
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
# v0.8.4 2015-09-10
|
2
|
+
|
3
|
+
* Add mutation from `a != b` to `!a.eql?(b)` and `!a.equal?(b)` #417
|
4
|
+
* Add mutation `A.const_get(:B)` -> `A::B` #426
|
5
|
+
* Add mutation `def foo(*args); end` into `def foo(*args); args = []; end` #423
|
6
|
+
* Add mutation from `foo.baz { bar }` to `foo.bar` #416
|
7
|
+
* Update anima dependency to 0.3.0
|
8
|
+
|
1
9
|
# v0.8.3 2015-09-01
|
2
10
|
|
3
11
|
* Remove invalid mutation `super(...)` to `super`
|
data/Gemfile
CHANGED
@@ -1,8 +1,5 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
1
|
source 'https://rubygems.org'
|
4
2
|
|
5
3
|
gemspec name: 'mutant'
|
6
4
|
|
7
|
-
|
8
|
-
gem 'devtools', git: 'https://github.com/rom-rb/devtools.git'
|
5
|
+
eval_gemfile File.expand_path('../Gemfile.shared', __FILE__)
|
data/Gemfile.shared
ADDED
data/Rakefile
CHANGED
data/config/flay.yml
CHANGED
data/config/rubocop.yml
CHANGED
@@ -132,3 +132,11 @@ SpaceAroundOperators:
|
|
132
132
|
# We use parallel assignments with great success
|
133
133
|
ParallelAssignment:
|
134
134
|
Enabled: false
|
135
|
+
|
136
|
+
# Allow additional specs
|
137
|
+
ExtraSpacing:
|
138
|
+
Enabled: false
|
139
|
+
|
140
|
+
# Buggy
|
141
|
+
FormatParameterMismatch:
|
142
|
+
Enabled: false
|
data/lib/mutant.rb
CHANGED
@@ -49,8 +49,10 @@ require 'mutant/ast/named_children'
|
|
49
49
|
require 'mutant/ast/node_predicates'
|
50
50
|
require 'mutant/ast/meta'
|
51
51
|
require 'mutant/ast/meta/send'
|
52
|
+
require 'mutant/ast/meta/symbol'
|
52
53
|
require 'mutant/ast/meta/optarg'
|
53
54
|
require 'mutant/ast/meta/resbody'
|
55
|
+
require 'mutant/ast/meta/restarg'
|
54
56
|
require 'mutant/actor'
|
55
57
|
require 'mutant/actor/receiver'
|
56
58
|
require 'mutant/actor/sender'
|
data/lib/mutant/cli.rb
CHANGED
@@ -98,7 +98,7 @@ module Mutant
|
|
98
98
|
def add_environment_options(opts)
|
99
99
|
opts.separator('Environment:')
|
100
100
|
opts.on('--zombie', 'Run mutant zombified') do
|
101
|
-
|
101
|
+
with(zombie: true)
|
102
102
|
end
|
103
103
|
opts.on('-I', '--include DIRECTORY', 'Add DIRECTORY to $LOAD_PATH') do |directory|
|
104
104
|
add(:includes, directory)
|
@@ -107,7 +107,7 @@ module Mutant
|
|
107
107
|
add(:requires, name)
|
108
108
|
end
|
109
109
|
opts.on('-j', '--jobs NUMBER', 'Number of kill jobs. Defaults to number of processors.') do |number|
|
110
|
-
|
110
|
+
with(jobs: Integer(number))
|
111
111
|
end
|
112
112
|
end
|
113
113
|
|
@@ -119,7 +119,7 @@ module Mutant
|
|
119
119
|
#
|
120
120
|
# @api private
|
121
121
|
def setup_integration(name)
|
122
|
-
|
122
|
+
with(integration: Integration.setup(name))
|
123
123
|
rescue LoadError
|
124
124
|
raise Error, "Could not load integration #{name.inspect} (you may want to try installing the gem mutant-#{name})"
|
125
125
|
end
|
@@ -139,7 +139,7 @@ module Mutant
|
|
139
139
|
'--expected-coverage COVERAGE',
|
140
140
|
'Fail unless COVERAGE is not reached exactly, parsed via Rational()'
|
141
141
|
) do |coverage|
|
142
|
-
|
142
|
+
with(expected_coverage: Rational(coverage))
|
143
143
|
end
|
144
144
|
opts.on('--use INTEGRATION', 'Use INTEGRATION to kill mutations', &method(:setup_integration))
|
145
145
|
end
|
@@ -169,14 +169,14 @@ module Mutant
|
|
169
169
|
# @api private
|
170
170
|
def add_debug_options(opts)
|
171
171
|
opts.on('--fail-fast', 'Fail fast') do
|
172
|
-
|
172
|
+
with(fail_fast: true)
|
173
173
|
end
|
174
174
|
opts.on('--version', 'Print mutants version') do
|
175
175
|
puts("mutant-#{VERSION}")
|
176
176
|
Kernel.exit(EXIT_SUCCESS)
|
177
177
|
end
|
178
178
|
opts.on('-d', '--debug', 'Enable debugging output') do
|
179
|
-
|
179
|
+
with(debug: true)
|
180
180
|
end
|
181
181
|
opts.on_tail('-h', '--help', 'Show this message') do
|
182
182
|
puts(opts.to_s)
|
@@ -184,15 +184,15 @@ module Mutant
|
|
184
184
|
end
|
185
185
|
end
|
186
186
|
|
187
|
-
#
|
187
|
+
# With configuration
|
188
188
|
#
|
189
189
|
# @param [Hash<Symbol, Object>] attributes
|
190
190
|
#
|
191
191
|
# @return [undefined]
|
192
192
|
#
|
193
193
|
# @api private
|
194
|
-
def
|
195
|
-
@config = @config.
|
194
|
+
def with(attributes)
|
195
|
+
@config = @config.with(attributes)
|
196
196
|
end
|
197
197
|
|
198
198
|
# Add configuration
|
@@ -207,7 +207,7 @@ module Mutant
|
|
207
207
|
#
|
208
208
|
# @api private
|
209
209
|
def add(attribute, value)
|
210
|
-
|
210
|
+
with(attribute => config.public_send(attribute) + [value])
|
211
211
|
end
|
212
212
|
|
213
213
|
# Add matcher configuration
|
@@ -222,7 +222,7 @@ module Mutant
|
|
222
222
|
#
|
223
223
|
# @api private
|
224
224
|
def add_matcher(attribute, value)
|
225
|
-
|
225
|
+
with(matcher: config.matcher.add(attribute, value))
|
226
226
|
end
|
227
227
|
|
228
228
|
end # CLI
|
data/lib/mutant/config.rb
CHANGED
@@ -4,7 +4,7 @@ module Mutant
|
|
4
4
|
# Does not reference any "external" volatile state. The configuration applied
|
5
5
|
# to current environment is being represented by the Mutant::Env object.
|
6
6
|
class Config
|
7
|
-
include Adamantium::Flat, Anima
|
7
|
+
include Adamantium::Flat, Anima.new(
|
8
8
|
:debug,
|
9
9
|
:integration,
|
10
10
|
:matcher,
|
data/lib/mutant/env.rb
CHANGED
@@ -2,7 +2,7 @@ module Mutant
|
|
2
2
|
class Matcher
|
3
3
|
# Subject matcher configuration
|
4
4
|
class Config
|
5
|
-
include Adamantium, Anima
|
5
|
+
include Adamantium, Anima.new(
|
6
6
|
:match_expressions,
|
7
7
|
:ignore_expressions,
|
8
8
|
:subject_filters
|
@@ -41,7 +41,7 @@ module Mutant
|
|
41
41
|
#
|
42
42
|
# @api private
|
43
43
|
def add(attribute, value)
|
44
|
-
|
44
|
+
with(attribute => public_send(attribute) + [value])
|
45
45
|
end
|
46
46
|
|
47
47
|
private
|
@@ -36,6 +36,22 @@ module Mutant
|
|
36
36
|
return unless body
|
37
37
|
emit(body)
|
38
38
|
emit_body_mutations
|
39
|
+
|
40
|
+
mutate_body_receiver
|
41
|
+
end
|
42
|
+
|
43
|
+
# Mutate method send in body scope of `send`
|
44
|
+
#
|
45
|
+
# @return [undefined]
|
46
|
+
#
|
47
|
+
# @api private
|
48
|
+
def mutate_body_receiver
|
49
|
+
return unless n_send?(body)
|
50
|
+
|
51
|
+
body_meta = AST::Meta::Send.new(body)
|
52
|
+
send_meta = AST::Meta::Send.new(send)
|
53
|
+
|
54
|
+
emit(s(:send, send_meta.receiver, body_meta.selector, *body_meta.arguments))
|
39
55
|
end
|
40
56
|
|
41
57
|
end # Block
|
@@ -14,6 +14,7 @@ module Mutant
|
|
14
14
|
def dispatch
|
15
15
|
emit_arguments_mutations
|
16
16
|
emit_optarg_body_assignments
|
17
|
+
emit_restarg_body_mutation
|
17
18
|
emit_body(N_RAISE)
|
18
19
|
emit_body(nil)
|
19
20
|
emit_body_mutations if body
|
@@ -32,6 +33,19 @@ module Mutant
|
|
32
33
|
end
|
33
34
|
end
|
34
35
|
|
36
|
+
# Emit mutation with arg splat as empty array signment in method
|
37
|
+
#
|
38
|
+
# @return [undefined]
|
39
|
+
#
|
40
|
+
# @api private
|
41
|
+
def emit_restarg_body_mutation
|
42
|
+
arguments.children.each do |argument|
|
43
|
+
next unless n_restarg?(argument) && argument.children.one?
|
44
|
+
|
45
|
+
emit_body_prepend(s(:lvasgn, AST::Meta::Restarg.new(argument).name, s(:array)))
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
35
49
|
# Emit valid body ASTs depending on instance body
|
36
50
|
#
|
37
51
|
# @param node [Parser::AST::Node]
|
@@ -90,11 +90,23 @@ module Mutant
|
|
90
90
|
def normal_dispatch
|
91
91
|
emit_naked_receiver
|
92
92
|
emit_selector_replacement
|
93
|
+
emit_const_get_mutation
|
93
94
|
emit_argument_propagation
|
94
95
|
mutate_receiver
|
95
96
|
mutate_arguments
|
96
97
|
end
|
97
98
|
|
99
|
+
# Emit mutation from `const_get` to const literal
|
100
|
+
#
|
101
|
+
# @return [undefined]
|
102
|
+
#
|
103
|
+
# @api private
|
104
|
+
def emit_const_get_mutation
|
105
|
+
return unless selector.equal?(:const_get) && n_sym?(arguments.first)
|
106
|
+
|
107
|
+
emit(s(:const, receiver, AST::Meta::Symbol.new(arguments.first).name))
|
108
|
+
end
|
109
|
+
|
98
110
|
# Emit selector replacement
|
99
111
|
#
|
100
112
|
# @return [undefined]
|
@@ -158,7 +170,6 @@ module Mutant
|
|
158
170
|
emit_receiver(nil) if n_self?(receiver) && !(
|
159
171
|
KEYWORDS.include?(selector) ||
|
160
172
|
METHOD_OPERATORS.include?(selector) ||
|
161
|
-
OP_ASSIGN.include?(parent_type) ||
|
162
173
|
meta.attribute_assignment?
|
163
174
|
)
|
164
175
|
end
|
@@ -19,8 +19,32 @@ module Mutant
|
|
19
19
|
emit(left)
|
20
20
|
emit_left_mutations
|
21
21
|
emit_selector_replacement
|
22
|
-
emit(right)
|
22
|
+
emit(right)
|
23
23
|
emit_right_mutations
|
24
|
+
emit_not_equality_mutations
|
25
|
+
end
|
26
|
+
|
27
|
+
# Emit mutations for `!=`
|
28
|
+
#
|
29
|
+
# @return [undefined]
|
30
|
+
#
|
31
|
+
# @api private
|
32
|
+
def emit_not_equality_mutations
|
33
|
+
return unless operator.equal?(:'!=')
|
34
|
+
|
35
|
+
emit_not_equality_mutation(:eql?)
|
36
|
+
emit_not_equality_mutation(:equal?)
|
37
|
+
end
|
38
|
+
|
39
|
+
# Emit negated method sends with specified operator
|
40
|
+
#
|
41
|
+
# @param new_operator [Symbol] selector to be negated
|
42
|
+
#
|
43
|
+
# @return [undefined]
|
44
|
+
#
|
45
|
+
# @api private
|
46
|
+
def emit_not_equality_mutation(new_operator)
|
47
|
+
emit(n_not(s(:send, left, new_operator, right)))
|
24
48
|
end
|
25
49
|
|
26
50
|
end # Binary
|
data/lib/mutant/parallel.rb
CHANGED
@@ -75,12 +75,12 @@ module Mutant
|
|
75
75
|
|
76
76
|
# Parallel run configuration
|
77
77
|
class Config
|
78
|
-
include
|
78
|
+
include Adamantium::Flat, Anima.new(:env, :processor, :source, :sink, :jobs)
|
79
79
|
end # Config
|
80
80
|
|
81
81
|
# Parallel execution status
|
82
82
|
class Status
|
83
|
-
include Adamantium::Flat, Anima
|
83
|
+
include Adamantium::Flat, Anima.new(:payload, :done, :active_jobs)
|
84
84
|
end
|
85
85
|
|
86
86
|
end # Parallel
|
data/lib/mutant/result.rb
CHANGED
data/lib/mutant/runner/sink.rb
CHANGED
@@ -78,8 +78,8 @@ module Mutant
|
|
78
78
|
|
79
79
|
original = @subject_results[mutation.subject]
|
80
80
|
|
81
|
-
@subject_results[mutation.subject] = original.
|
82
|
-
mutation_results: (original.mutation_results
|
81
|
+
@subject_results[mutation.subject] = original.with(
|
82
|
+
mutation_results: (original.mutation_results + [mutation_result]),
|
83
83
|
tests: mutation_result.test_result.tests
|
84
84
|
)
|
85
85
|
|
data/lib/mutant/version.rb
CHANGED
data/meta/begin.rb
CHANGED
data/meta/block.rb
CHANGED
@@ -69,3 +69,18 @@ Mutant::Meta::Example.add do
|
|
69
69
|
mutation 'foo { |(_a)| }'
|
70
70
|
mutation 'foo'
|
71
71
|
end
|
72
|
+
|
73
|
+
Mutant::Meta::Example.add do
|
74
|
+
source 'self.foo { bar(nil) }'
|
75
|
+
|
76
|
+
singleton_mutations
|
77
|
+
mutation 'self.foo'
|
78
|
+
mutation 'foo { bar(nil) }'
|
79
|
+
mutation 'self.foo { bar }'
|
80
|
+
mutation 'self.foo { nil }'
|
81
|
+
mutation 'self.foo {}'
|
82
|
+
mutation 'self.foo { self }'
|
83
|
+
mutation 'self.foo { raise }'
|
84
|
+
mutation 'bar(nil)'
|
85
|
+
mutation 'self.bar(nil)'
|
86
|
+
end
|
data/meta/def.rb
CHANGED
@@ -5,6 +5,31 @@ Mutant::Meta::Example.add do
|
|
5
5
|
mutation 'remove_method :foo'
|
6
6
|
end
|
7
7
|
|
8
|
+
Mutant::Meta::Example.add do
|
9
|
+
source 'def foo(a, *b); nil; end'
|
10
|
+
|
11
|
+
mutation 'def foo(_a, *b); nil; end'
|
12
|
+
mutation 'def foo; nil; end'
|
13
|
+
mutation 'def foo(a, *b); end'
|
14
|
+
mutation 'def foo(a, *b); raise; end'
|
15
|
+
mutation 'def foo(a); nil; end'
|
16
|
+
mutation 'def foo(*b); nil; end'
|
17
|
+
mutation 'def foo(a, *b); b = []; nil; end'
|
18
|
+
mutation 'remove_method :foo'
|
19
|
+
end
|
20
|
+
|
21
|
+
Mutant::Meta::Example.add do
|
22
|
+
source 'def foo(a, *); nil; end'
|
23
|
+
|
24
|
+
mutation 'def foo(_a, *); nil; end'
|
25
|
+
mutation 'def foo; nil; end'
|
26
|
+
mutation 'def foo(a, *); end'
|
27
|
+
mutation 'def foo(a, *); raise; end'
|
28
|
+
mutation 'def foo(a); nil; end'
|
29
|
+
mutation 'def foo(*); nil; end'
|
30
|
+
mutation 'remove_method :foo'
|
31
|
+
end
|
32
|
+
|
8
33
|
Mutant::Meta::Example.add do
|
9
34
|
source 'def foo; foo; rescue; end'
|
10
35
|
|