mutant 0.7.8 → 0.7.9
Sign up to get free protection for your applications and to get access to all the features.
- 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