mutant 0.7.8 → 0.7.9
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/.travis.yml +1 -1
- data/Changelog.md +5 -0
- data/README.md +11 -29
- data/config/flay.yml +1 -1
- data/config/reek.yml +1 -0
- data/lib/mutant.rb +3 -3
- data/lib/mutant/cli.rb +12 -9
- data/lib/mutant/integration.rb +13 -0
- data/lib/mutant/meta/example.rb +2 -2
- data/lib/mutant/reporter/cli.rb +3 -2
- data/lib/mutant/reporter/cli/printer.rb +2 -2
- data/lib/mutant/reporter/cli/tput.rb +29 -11
- data/lib/mutant/result.rb +0 -2
- data/lib/mutant/version.rb +1 -1
- data/meta/and.rb +0 -2
- data/meta/and_asgn.rb +0 -2
- data/meta/array.rb +0 -2
- data/meta/begin.rb +0 -2
- data/meta/block.rb +0 -2
- data/meta/block_pass.rb +0 -2
- data/meta/blockarg.rb +0 -2
- data/meta/boolean.rb +0 -2
- data/meta/break.rb +0 -2
- data/meta/case.rb +0 -2
- data/meta/casgn.rb +0 -2
- data/meta/cbase.rb +0 -2
- data/meta/const.rb +0 -2
- data/meta/cvar.rb +0 -2
- data/meta/cvasgn.rb +0 -2
- data/meta/def.rb +0 -2
- data/meta/defined.rb +0 -2
- data/meta/dstr.rb +0 -2
- data/meta/dsym.rb +0 -2
- data/meta/ensure.rb +0 -2
- data/meta/false.rb +0 -2
- data/meta/float.rb +0 -2
- data/meta/gvar.rb +0 -2
- data/meta/gvasgn.rb +0 -2
- data/meta/hash.rb +0 -2
- data/meta/if.rb +0 -2
- data/meta/int.rb +0 -2
- data/meta/ivasgn.rb +0 -2
- data/meta/kwbegin.rb +0 -2
- data/meta/lvar.rb +0 -2
- data/meta/lvasgn.rb +0 -2
- data/meta/masgn.rb +0 -2
- data/meta/match_current_line.rb +0 -2
- data/meta/next.rb +0 -2
- data/meta/nil.rb +0 -2
- data/meta/nthref.rb +0 -2
- data/meta/op_assgn.rb +0 -2
- data/meta/or.rb +0 -2
- data/meta/or_asgn.rb +0 -2
- data/meta/range.rb +0 -2
- data/meta/redo.rb +0 -2
- data/meta/regex.rb +0 -2
- data/meta/rescue.rb +0 -2
- data/meta/restarg.rb +0 -2
- data/meta/return.rb +0 -2
- data/meta/self.rb +0 -2
- data/meta/send.rb +0 -2
- data/meta/str.rb +0 -2
- data/meta/super.rb +0 -2
- data/meta/symbol.rb +0 -2
- data/meta/true.rb +0 -2
- data/meta/until.rb +0 -2
- data/meta/while.rb +0 -2
- data/meta/yield.rb +0 -2
- data/mutant-rspec.gemspec +1 -1
- data/mutant.gemspec +3 -3
- data/spec/integration/mutant/rspec_spec.rb +3 -39
- data/spec/shared/framework_integration_behavior.rb +35 -0
- data/spec/unit/mutant/cli_spec.rb +34 -1
- data/spec/unit/mutant/env_spec.rb +0 -1
- data/spec/unit/mutant/integration/rspec_spec.rb +193 -0
- data/spec/unit/mutant/loader/eval_spec.rb +1 -1
- data/spec/unit/mutant/matcher/methods/instance_spec.rb +22 -21
- data/spec/unit/mutant/matcher/methods/singleton_spec.rb +21 -19
- data/spec/unit/mutant/parallel/worker_spec.rb +0 -2
- data/spec/unit/mutant/reporter/cli/tput_spec.rb +48 -0
- data/spec/unit/mutant/reporter/cli_spec.rb +29 -9
- data/test_app/Gemfile.rspec3.0 +1 -0
- data/test_app/Gemfile.rspec3.1 +1 -0
- data/test_app/Gemfile.rspec3.2 +1 -0
- data/test_app/lib/test_app.rb +1 -1
- data/test_app/lib/test_app/literal.rb +0 -2
- data/test_app/spec/spec_helper.rb +0 -2
- data/test_app/spec/unit/test_app/literal_spec.rb +22 -0
- metadata +15 -5
- data/test_app/spec/unit/test_app/literal/command_spec.rb +0 -11
- data/test_app/spec/unit/test_app/literal/string_spec.rb +0 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a01c96b2fcfbb344d37ed40dc9773c36d0433bfc
|
4
|
+
data.tar.gz: f4ef32cec5591667c75a1e1e31200d51529a7b50
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6aa3c28aeffad6471ced7ab755d34cab8b0c6d986c4d6739245b9706e3608fd18fbfed75287f94ac5d337e5078f4e711e94aee748ff9508b439689ad24417a2b
|
7
|
+
data.tar.gz: 36c0f9f971e94f602299f785a7d28a1f56b7e566a6ec3717f46905c7f7e306b574d028a7cd10e32f35b6455b742c0f5538b327fa4360e91c392a8dd76f6cc732
|
data/.travis.yml
CHANGED
data/Changelog.md
CHANGED
data/README.md
CHANGED
@@ -45,26 +45,6 @@ Blog-Posts
|
|
45
45
|
* http://www.sitepoint.com/mutation-testing-mutant/
|
46
46
|
* http://solnic.eu/2013/01/23/mutation-testing-with-mutant.html
|
47
47
|
|
48
|
-
Projects using Mutant
|
49
|
-
---------------------
|
50
|
-
|
51
|
-
The following projects adopted mutant, and aim for 100% mutation coverage:
|
52
|
-
|
53
|
-
* [axiom](https://github.com/dkubb/axiom)
|
54
|
-
* [axiom-types](https://github.com/dkubb/axiom-types)
|
55
|
-
* [rom-mapper](https://github.com/rom-rb/rom-mapper)
|
56
|
-
* [rom-session](https://github.com/rom-rb/rom-session)
|
57
|
-
* [event_bus](https://github.com/kevinrutherford/event_bus)
|
58
|
-
* [virtus](https://github.com/solnic/virtus)
|
59
|
-
* [quacky](https://github.com/benmoss/quacky)
|
60
|
-
* [substation](https://github.com/snusnu/substation)
|
61
|
-
* [large_binomials](https://github.com/filipvanlaenen/large_binomials)
|
62
|
-
* [promise.rb](https://github.com/lgierth/promise.rb)
|
63
|
-
* [full_name](https://github.com/AGILiDEE/full_name)
|
64
|
-
* various small/minor stuff under https://github.com/mbj
|
65
|
-
|
66
|
-
Feel free to ping me to add your project to the list!
|
67
|
-
|
68
48
|
Installation
|
69
49
|
------------
|
70
50
|
|
@@ -87,10 +67,8 @@ The Crash / Stuck Problem (MRI)
|
|
87
67
|
-------------------------------
|
88
68
|
|
89
69
|
Mutations generated by mutant can cause MRI to enter VM states its not prepared for.
|
90
|
-
All MRI versions
|
91
|
-
and OS scheduling behavior.
|
92
|
-
|
93
|
-
It seems that https://github.com/ruby/ruby/commit/8fe95fea9d238a6deb70c8953ceb3a28a67f4636 fixes the problem (unlreleased). So in doubht you have currently to run muant against latest head / trunk.
|
70
|
+
All MRI versions > 1.9 and < 2.2.1 are affected by this depending on your compiler flags,
|
71
|
+
compiler version, and OS scheduling behavior.
|
94
72
|
|
95
73
|
This can have the following unintended effects:
|
96
74
|
|
@@ -107,8 +85,11 @@ This can have the following unintended effects:
|
|
107
85
|
|
108
86
|
References:
|
109
87
|
|
110
|
-
*
|
111
|
-
*
|
88
|
+
* [MRI fix](https://github.com/ruby/ruby/commit/8fe95fea9d238a6deb70c8953ceb3a28a67f4636)
|
89
|
+
* [MRI backport to 2.2.1](https://github.com/ruby/ruby/commit/8fe95fea9d238a6deb70c8953ceb3a28a67f4636)
|
90
|
+
* [Mutant issue](https://github.com/mbj/mutant/issues/265)
|
91
|
+
* [Upstream bug redmine](https://bugs.ruby-lang.org/issues/10460)
|
92
|
+
* [Upstream bug github](https://github.com/ruby/ruby/pull/822)
|
112
93
|
|
113
94
|
Examples
|
114
95
|
--------
|
@@ -152,7 +133,7 @@ Assuming you are using rspec, you can mutation test Rails models by adding the f
|
|
152
133
|
group :test do
|
153
134
|
gem 'mutant'
|
154
135
|
gem 'mutant-rspec'
|
155
|
-
end
|
136
|
+
end
|
156
137
|
```
|
157
138
|
|
158
139
|
Next, run bundle and comment out ```require 'rspec/autorun'``` from your spec_helper.rb file. Having done so you should be able to use commands like the following:
|
@@ -171,8 +152,9 @@ Your options:
|
|
171
152
|
* [GitHub Issues](https://github.com/mbj/mutant/issues)
|
172
153
|
* Ping me on [twitter](https://twitter.com/_m_b_j_)
|
173
154
|
|
174
|
-
There is also the [#mutant] channel on freenode.
|
175
|
-
join it often. Please prefer to use GitHub issues with
|
155
|
+
There is also the [#mutant](http://irclog.whitequark.org/mutant) channel on freenode.
|
156
|
+
As my OSS time budged is very limited I cannot join it often. Please prefer to use GitHub issues with
|
157
|
+
a 'Question: ' prefix in title.
|
176
158
|
|
177
159
|
Credits
|
178
160
|
-------
|
data/config/flay.yml
CHANGED
data/config/reek.yml
CHANGED
@@ -132,4 +132,5 @@ UtilityFunction:
|
|
132
132
|
- Mutant::Meta::Example::Verification#format_mutation
|
133
133
|
- Mutant::Reporter::CLI::Format::Progressive#new_buffer
|
134
134
|
- Mutant::Reporter::CLI::Printer::StatusProgressive#object # False positive calls super
|
135
|
+
- Mutant::Integration::Rspec#parse_expression # intentional, private
|
135
136
|
max_helper_calls: 0
|
data/lib/mutant.rb
CHANGED
@@ -7,9 +7,9 @@ require 'diff/lcs'
|
|
7
7
|
require 'diff/lcs/hunk'
|
8
8
|
require 'equalizer'
|
9
9
|
require 'ice_nine'
|
10
|
-
require 'ice_nine'
|
11
10
|
require 'morpher'
|
12
11
|
require 'open3'
|
12
|
+
require 'optparse'
|
13
13
|
require 'parallel'
|
14
14
|
require 'parser'
|
15
15
|
require 'parser/current'
|
@@ -178,7 +178,6 @@ require 'mutant/mutator/node/splat'
|
|
178
178
|
require 'mutant/mutator/node/resbody'
|
179
179
|
require 'mutant/mutator/node/rescue'
|
180
180
|
require 'mutant/mutator/node/match_current_line'
|
181
|
-
require 'mutant/config'
|
182
181
|
require 'mutant/loader'
|
183
182
|
require 'mutant/context'
|
184
183
|
require 'mutant/context/scope'
|
@@ -206,6 +205,7 @@ require 'mutant/test'
|
|
206
205
|
require 'mutant/integration'
|
207
206
|
require 'mutant/selector'
|
208
207
|
require 'mutant/selector/expression'
|
208
|
+
require 'mutant/config'
|
209
209
|
require 'mutant/cli'
|
210
210
|
require 'mutant/color'
|
211
211
|
require 'mutant/diff'
|
@@ -225,7 +225,7 @@ require 'mutant/zombifier/file'
|
|
225
225
|
module Mutant
|
226
226
|
# Reopen class to initialize constant to avoid dep circle
|
227
227
|
class Config
|
228
|
-
CI_DEFAULT_PROCESSOR_COUNT =
|
228
|
+
CI_DEFAULT_PROCESSOR_COUNT = 4
|
229
229
|
|
230
230
|
DEFAULT = new(
|
231
231
|
debug: false,
|
data/lib/mutant/cli.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'optparse'
|
2
|
-
|
3
1
|
module Mutant
|
4
2
|
|
5
3
|
# Commandline parser
|
@@ -68,13 +66,13 @@ module Mutant
|
|
68
66
|
opts = OptionParser.new do |builder|
|
69
67
|
builder.banner = 'usage: mutant [options] MATCH_EXPRESSION ...'
|
70
68
|
%w[add_environment_options add_mutation_options add_filter_options add_debug_options].each do |name|
|
71
|
-
|
69
|
+
__send__(name, builder)
|
72
70
|
end
|
73
71
|
end
|
74
72
|
|
75
73
|
parse_match_expressions(opts.parse!(arguments))
|
76
74
|
rescue OptionParser::ParseError => error
|
77
|
-
raise(Error, error
|
75
|
+
raise(Error, error)
|
78
76
|
end
|
79
77
|
|
80
78
|
# Parse matchers
|
@@ -128,8 +126,7 @@ module Mutant
|
|
128
126
|
# @api private
|
129
127
|
#
|
130
128
|
def setup_integration(name)
|
131
|
-
|
132
|
-
update(integration: Integration.lookup(name))
|
129
|
+
update(integration: Integration.setup(name))
|
133
130
|
rescue LoadError
|
134
131
|
raise Error, "Could not load integration #{name.inspect} (you may want to try installing the gem mutant-#{name})"
|
135
132
|
end
|
@@ -143,10 +140,16 @@ module Mutant
|
|
143
140
|
# @api private
|
144
141
|
#
|
145
142
|
def add_mutation_options(opts)
|
146
|
-
opts.separator(
|
143
|
+
opts.separator(nil)
|
147
144
|
opts.separator('Options:')
|
148
145
|
|
149
|
-
opts.on(
|
146
|
+
opts.on(
|
147
|
+
'--expected-coverage COVERAGE',
|
148
|
+
'Fail unless COVERAGE is not reached exactly, parsed via Rational()'
|
149
|
+
) do |coverage|
|
150
|
+
update(expected_coverage: Rational(coverage))
|
151
|
+
end
|
152
|
+
opts.on('--score COVERAGE', 'Fail unless COVERAGE is not reached exactly [deprecated]') do |coverage|
|
150
153
|
update(expected_coverage: Rational(coverage, 100))
|
151
154
|
end
|
152
155
|
opts.on('--use STRATEGY', 'Use STRATEGY for killing mutations', &method(:setup_integration))
|
@@ -182,7 +185,7 @@ module Mutant
|
|
182
185
|
update(fail_fast: true)
|
183
186
|
end
|
184
187
|
opts.on('--version', 'Print mutants version') do
|
185
|
-
puts("mutant-#{
|
188
|
+
puts("mutant-#{VERSION}")
|
186
189
|
Kernel.exit(EXIT_SUCCESS)
|
187
190
|
end
|
188
191
|
opts.on('-d', '--debug', 'Enable debugging output') do
|
data/lib/mutant/integration.rb
CHANGED
@@ -6,6 +6,19 @@ module Mutant
|
|
6
6
|
|
7
7
|
REGISTRY = {}
|
8
8
|
|
9
|
+
# Setup integration
|
10
|
+
#
|
11
|
+
# @param [String] name
|
12
|
+
#
|
13
|
+
# @return [Integration]
|
14
|
+
#
|
15
|
+
# @api private
|
16
|
+
#
|
17
|
+
def self.setup(name)
|
18
|
+
require "mutant/integration/#{name}"
|
19
|
+
lookup(name)
|
20
|
+
end
|
21
|
+
|
9
22
|
# Lookup integration for name
|
10
23
|
#
|
11
24
|
# @param [String] name
|
data/lib/mutant/meta/example.rb
CHANGED
data/lib/mutant/reporter/cli.rb
CHANGED
@@ -13,9 +13,10 @@ module Mutant
|
|
13
13
|
# @api private
|
14
14
|
#
|
15
15
|
def self.build(output)
|
16
|
+
tput = Tput.detect
|
16
17
|
tty = output.respond_to?(:tty?) && output.tty?
|
17
|
-
format = if !Mutant.ci? && tty &&
|
18
|
-
Format::Framed.new(tty: tty, tput:
|
18
|
+
format = if !Mutant.ci? && tty && tput
|
19
|
+
Format::Framed.new(tty: tty, tput: tput)
|
19
20
|
else
|
20
21
|
Format::Progressive.new(tty: tty)
|
21
22
|
end
|
@@ -176,7 +176,7 @@ module Mutant
|
|
176
176
|
# @api private
|
177
177
|
#
|
178
178
|
def active_subject_results
|
179
|
-
active_mutation_jobs = active_jobs.select { |job| job.payload.kind_of?(
|
179
|
+
active_mutation_jobs = active_jobs.select { |job| job.payload.kind_of?(Mutation) }
|
180
180
|
active_subjects = active_mutation_jobs.map(&:payload).flat_map(&:subject).to_set
|
181
181
|
|
182
182
|
payload.subject_results.select do |subject_result|
|
@@ -258,7 +258,7 @@ module Mutant
|
|
258
258
|
# @api private
|
259
259
|
#
|
260
260
|
def coverage_percent
|
261
|
-
|
261
|
+
coverage * 100
|
262
262
|
end
|
263
263
|
|
264
264
|
# Return overhead percent
|
@@ -3,23 +3,41 @@ module Mutant
|
|
3
3
|
class CLI
|
4
4
|
# Interface to the optionally present tput binary
|
5
5
|
class Tput
|
6
|
-
include Adamantium, Concord::Public.new(:
|
6
|
+
include Adamantium, Concord::Public.new(:prepare, :restore)
|
7
7
|
|
8
8
|
private_class_method :new
|
9
9
|
|
10
|
-
|
10
|
+
# Return detected tput support
|
11
|
+
#
|
12
|
+
# @return [Tput]
|
13
|
+
# if tput support is present
|
14
|
+
#
|
15
|
+
# @return [nil]
|
16
|
+
# otherwise
|
17
|
+
def self.detect
|
18
|
+
reset = capture('tput reset')
|
19
|
+
save = capture('tput sc') if reset
|
20
|
+
restore = capture('tput rc') if save
|
21
|
+
clean = capture('tput ed') || capture('tput cd') if restore
|
22
|
+
new(reset + save, restore + clean) if clean
|
23
|
+
end
|
24
|
+
|
25
|
+
# Capture output
|
26
|
+
#
|
27
|
+
# @param [String] command
|
28
|
+
# command to run
|
29
|
+
#
|
30
|
+
# @return [String]
|
31
|
+
# stdout of command on success
|
32
|
+
#
|
33
|
+
# @return [nil]
|
34
|
+
# otherwise
|
35
|
+
#
|
36
|
+
def self.capture(command)
|
11
37
|
stdout, _stderr, exitstatus = Open3.capture3(command)
|
12
38
|
stdout if exitstatus.success?
|
13
39
|
end
|
14
|
-
|
15
|
-
reset = capture.('tput reset')
|
16
|
-
save = capture.('tput sc') if reset
|
17
|
-
restore = capture.('tput rc') if save
|
18
|
-
clean = capture.('tput ed') if restore
|
19
|
-
|
20
|
-
UNAVAILABLE = new(false, nil, nil)
|
21
|
-
|
22
|
-
INSTANCE = clean ? new(true, reset + save, restore + clean) : UNAVAILABLE
|
40
|
+
private_class_method :capture
|
23
41
|
|
24
42
|
end # TPUT
|
25
43
|
end # CLI
|
data/lib/mutant/result.rb
CHANGED
data/lib/mutant/version.rb
CHANGED
data/meta/and.rb
CHANGED
data/meta/and_asgn.rb
CHANGED
data/meta/array.rb
CHANGED
data/meta/begin.rb
CHANGED
data/meta/block.rb
CHANGED
data/meta/block_pass.rb
CHANGED
data/meta/blockarg.rb
CHANGED
data/meta/boolean.rb
CHANGED
data/meta/break.rb
CHANGED
data/meta/case.rb
CHANGED
data/meta/casgn.rb
CHANGED
data/meta/cbase.rb
CHANGED
data/meta/const.rb
CHANGED