mutant 0.5.22 → 0.5.23
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 +3 -0
- data/Changelog.md +4 -0
- data/README.md +1 -13
- data/config/flay.yml +1 -1
- data/lib/mutant.rb +1 -0
- data/lib/mutant/expression/method.rb +1 -1
- data/lib/mutant/isolation.rb +3 -43
- data/lib/mutant/matcher/chain.rb +1 -1
- data/lib/mutant/matcher/method/instance.rb +3 -3
- data/lib/mutant/matcher/method/singleton.rb +3 -3
- data/lib/mutant/matcher/methods.rb +1 -1
- data/lib/mutant/mutator/node/block.rb +1 -1
- data/lib/mutant/mutator/node/conditional_loop.rb +1 -1
- data/lib/mutant/mutator/node/define.rb +1 -1
- data/lib/mutant/mutator/node/literal/float.rb +4 -6
- data/lib/mutant/mutator/node/literal/range.rb +3 -3
- data/lib/mutant/mutator/node/when.rb +1 -1
- data/lib/mutant/mutator/util.rb +1 -1
- data/lib/mutant/node_helpers.rb +9 -14
- data/lib/mutant/reporter/cli/registry.rb +1 -1
- data/lib/mutant/reporter/cli/report/config.rb +1 -1
- data/lib/mutant/runner/config.rb +1 -1
- data/lib/mutant/version.rb +1 -1
- data/mutant.gemspec +1 -1
- data/spec/unit/mutant/isolation_spec.rb +5 -50
- metadata +15 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 19cc50cff5125bbeef98eb0511a7c02c7154b4d5
|
4
|
+
data.tar.gz: 153344653cd236a26f822ea809333a881b66491b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1b3b1a8e57fcfc7c5423e16b1c7a375ef26494e1d6df55c12e458efcf7cc4f26be1681c379b7ce110d91f3c7179f43f294d099b1ce41203a162043ce893ba505
|
7
|
+
data.tar.gz: 43b9c7b3c628cf529316433463083163ec8ae83911575df994cdc71d604b34a6e05872be557cef18150c78c20015973bd5db37fd81ec170b377f02b220264bc0
|
data/.travis.yml
CHANGED
data/Changelog.md
CHANGED
data/README.md
CHANGED
@@ -6,7 +6,6 @@ mutant
|
|
6
6
|
[](https://codeclimate.com/github/mbj/mutant)
|
7
7
|
[](http://inch-ci.org/github/mbj/mutant)
|
8
8
|
[](https://rubygems.org/gems/mutant)
|
9
|
-
[](https://gittip.com/mbj)
|
10
9
|
|
11
10
|
Mutant is a mutation testing tool for ruby.
|
12
11
|
|
@@ -41,7 +40,7 @@ Blog-Posts
|
|
41
40
|
Integrations
|
42
41
|
------------
|
43
42
|
|
44
|
-
|
43
|
+
rspec2 and rspec-3 are supported currently. Minitest support is still *planned*.
|
45
44
|
|
46
45
|
Projects using Mutant
|
47
46
|
---------------------
|
@@ -147,17 +146,6 @@ current prefix level, these example groups *must* kill the mutation.
|
|
147
146
|
This test selection strategy is compatible with the old `--rspec-dm2` and `--rspec-unit` strategy.
|
148
147
|
The old flags were removed. It allows to define very fine grained specs, or coarse grained - as you like.
|
149
148
|
|
150
|
-
Donations
|
151
|
-
---------
|
152
|
-
|
153
|
-
I ([mbj](https://github.com/mbj)) build this and adjacent tools in my free time.
|
154
|
-
LOTS of unaccounted time and fun already went into this project.
|
155
|
-
|
156
|
-
You might consider to donate if you like this tool.
|
157
|
-
|
158
|
-
* [](https://gittip.com/mbj)
|
159
|
-
* [](http://flattr.com/thing/1823010/mbjmutant-on-GitHub)
|
160
|
-
|
161
149
|
Support
|
162
150
|
-------
|
163
151
|
|
data/config/flay.yml
CHANGED
data/lib/mutant.rb
CHANGED
@@ -24,7 +24,7 @@ module Mutant
|
|
24
24
|
def matcher(cache)
|
25
25
|
methods_matcher = MATCHERS.fetch(scope_symbol).new(cache, scope)
|
26
26
|
method = methods_matcher.methods.detect do |meth|
|
27
|
-
meth.name
|
27
|
+
meth.name.equal?(method_name)
|
28
28
|
end or raise NameError, "Cannot find method #{identifier}"
|
29
29
|
methods_matcher.matcher.build(cache, scope, method)
|
30
30
|
end
|
data/lib/mutant/isolation.rb
CHANGED
@@ -16,50 +16,10 @@ module Mutant
|
|
16
16
|
# @api private
|
17
17
|
#
|
18
18
|
def self.call(&block)
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
if pid.nil?
|
24
|
-
begin
|
25
|
-
reader.close
|
26
|
-
writer.write(Marshal.dump(block.call))
|
27
|
-
Kernel.exit!(0)
|
28
|
-
ensure
|
29
|
-
Kernel.exit!(1)
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
writer.close
|
34
|
-
|
35
|
-
read_result(reader, pid)
|
36
|
-
end
|
37
|
-
|
38
|
-
# Read result from child process
|
39
|
-
#
|
40
|
-
# @param [IO] reader
|
41
|
-
# @param [Fixnum] pid
|
42
|
-
#
|
43
|
-
# @return [Object]
|
44
|
-
#
|
45
|
-
# @raise [Error]
|
46
|
-
#
|
47
|
-
def self.read_result(reader, pid)
|
48
|
-
begin
|
49
|
-
data = Marshal.load(reader.read)
|
50
|
-
rescue ArgumentError, TypeError
|
51
|
-
raise Error, 'Childprocess wrote un-unmarshallable data'
|
52
|
-
end
|
53
|
-
|
54
|
-
status = Process.waitpid2(pid).last
|
55
|
-
|
56
|
-
unless status.exitstatus.zero?
|
57
|
-
raise Error, "Childprocess exited with nonzero exit status: #{status.exitstatus}"
|
58
|
-
end
|
59
|
-
|
60
|
-
data
|
19
|
+
Parallel.map([block], in_processes: 1) do |block|
|
20
|
+
block.call
|
21
|
+
end.first
|
61
22
|
end
|
62
|
-
private_class_method :read_result
|
63
23
|
|
64
24
|
end # Isolator
|
65
25
|
end # Mutant
|
data/lib/mutant/matcher/chain.rb
CHANGED
@@ -49,9 +49,9 @@ module Mutant
|
|
49
49
|
def match?(node)
|
50
50
|
location = node.location || return
|
51
51
|
expression = location.expression || return
|
52
|
-
expression.line
|
53
|
-
node.type
|
54
|
-
node.children[NAME_INDEX]
|
52
|
+
expression.line.equal?(source_line) &&
|
53
|
+
node.type.equal?(:def) &&
|
54
|
+
node.children[NAME_INDEX].equal?(method_name)
|
55
55
|
end
|
56
56
|
|
57
57
|
# Matcher for memoized instance methods
|
@@ -45,7 +45,7 @@ module Mutant
|
|
45
45
|
def line?(node)
|
46
46
|
expression = node.location.expression
|
47
47
|
return false unless expression
|
48
|
-
expression.line
|
48
|
+
expression.line.equal?(source_line)
|
49
49
|
end
|
50
50
|
|
51
51
|
# Test for name match
|
@@ -57,7 +57,7 @@ module Mutant
|
|
57
57
|
# @api private
|
58
58
|
#
|
59
59
|
def name?(node)
|
60
|
-
node.children[NAME_INDEX]
|
60
|
+
node.children[NAME_INDEX].equal?(method_name)
|
61
61
|
end
|
62
62
|
|
63
63
|
# Test for receiver match
|
@@ -95,7 +95,7 @@ module Mutant
|
|
95
95
|
#
|
96
96
|
def receiver_name?(node)
|
97
97
|
name = node.children[CONST_NAME_INDEX]
|
98
|
-
name.to_s
|
98
|
+
name.to_s.eql?(context.unqualified_name)
|
99
99
|
end
|
100
100
|
|
101
101
|
end # Singleton
|
@@ -43,7 +43,7 @@ module Mutant
|
|
43
43
|
def methods
|
44
44
|
candidate_names.each_with_object([]) do |name, methods|
|
45
45
|
method = access(name)
|
46
|
-
methods << method if method.owner
|
46
|
+
methods << method if method.owner.equal?(candidate_scope)
|
47
47
|
end
|
48
48
|
end
|
49
49
|
memoize :methods
|
@@ -22,9 +22,9 @@ module Mutant
|
|
22
22
|
end
|
23
23
|
|
24
24
|
SPECIAL = [
|
25
|
-
|
26
|
-
|
27
|
-
|
25
|
+
N_NAN,
|
26
|
+
N_NEGATIVE_INFINITY,
|
27
|
+
N_INFINITY
|
28
28
|
].freeze
|
29
29
|
|
30
30
|
# Emit special cases
|
@@ -34,9 +34,7 @@ module Mutant
|
|
34
34
|
# @api private
|
35
35
|
#
|
36
36
|
def emit_special_cases
|
37
|
-
SPECIAL.each
|
38
|
-
emit(value)
|
39
|
-
end
|
37
|
+
SPECIAL.each(&method(:emit))
|
40
38
|
end
|
41
39
|
|
42
40
|
# Return values to test against
|
@@ -48,7 +48,7 @@ module Mutant
|
|
48
48
|
#
|
49
49
|
def emit_upper_bound_mutations
|
50
50
|
emit__end_mutations
|
51
|
-
emit_type(
|
51
|
+
emit_type(N_NAN, _end)
|
52
52
|
end
|
53
53
|
|
54
54
|
# Emit start mutations
|
@@ -59,8 +59,8 @@ module Mutant
|
|
59
59
|
#
|
60
60
|
def emit_lower_bound_mutations
|
61
61
|
emit_start_mutations
|
62
|
-
emit_type(start,
|
63
|
-
emit_type(start,
|
62
|
+
emit_type(start, N_INFINITY)
|
63
|
+
emit_type(start, N_NAN)
|
64
64
|
end
|
65
65
|
|
66
66
|
end # Range
|
data/lib/mutant/mutator/util.rb
CHANGED
data/lib/mutant/node_helpers.rb
CHANGED
@@ -15,20 +15,15 @@ module Mutant
|
|
15
15
|
end
|
16
16
|
module_function :s
|
17
17
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
N_TRUE = s(:true)
|
28
|
-
N_FALSE = s(:false)
|
29
|
-
N_NIL = s(:nil)
|
30
|
-
N_EMPTY = s(:empty)
|
31
|
-
N_SELF = s(:self)
|
18
|
+
N_NAN = s(:send, s(:float, 0.0), :/, s(:float, 0.0))
|
19
|
+
N_INFINITY = s(:send, s(:float, 1.0), :/, s(:float, 0.0))
|
20
|
+
N_NEGATIVE_INFINITY = s(:send, s(:float, -1.0), :/, s(:float, 0.0))
|
21
|
+
N_RAISE = s(:send, nil, :raise)
|
22
|
+
N_TRUE = s(:true)
|
23
|
+
N_FALSE = s(:false)
|
24
|
+
N_NIL = s(:nil)
|
25
|
+
N_EMPTY = s(:empty)
|
26
|
+
N_SELF = s(:self)
|
32
27
|
|
33
28
|
# Build a negated boolean node
|
34
29
|
#
|
@@ -60,7 +60,7 @@ module Mutant
|
|
60
60
|
def generic_stats
|
61
61
|
subjects.each_with_object(Hash.new(0)) do |runner, stats|
|
62
62
|
Walker.run(runner.subject.node) do |node|
|
63
|
-
if Mutator::Registry.lookup(node)
|
63
|
+
if Mutator::Registry.lookup(node).equal?(Mutator::Node::Generic)
|
64
64
|
stats[node.type] += 1
|
65
65
|
end
|
66
66
|
end
|
data/lib/mutant/runner/config.rb
CHANGED
@@ -48,7 +48,7 @@ module Mutant
|
|
48
48
|
# @api private
|
49
49
|
#
|
50
50
|
def success?
|
51
|
-
coverage.round(COVERAGE_PRECISION)
|
51
|
+
coverage.round(COVERAGE_PRECISION).eql?(config.expected_coverage.round(COVERAGE_PRECISION))
|
52
52
|
end
|
53
53
|
memoize :success?
|
54
54
|
|
data/lib/mutant/version.rb
CHANGED
data/mutant.gemspec
CHANGED
@@ -37,7 +37,7 @@ Gem::Specification.new do |gem|
|
|
37
37
|
gem.add_runtime_dependency('inflecto', '~> 0.0.2')
|
38
38
|
gem.add_runtime_dependency('anima', '~> 0.2.0')
|
39
39
|
gem.add_runtime_dependency('concord', '~> 0.1.5')
|
40
|
+
gem.add_runtime_dependency('parallel', '~> 1.0.0')
|
40
41
|
|
41
42
|
gem.add_development_dependency('bundler', '~> 1.3', '>= 1.3.5')
|
42
|
-
gem.add_development_dependency('parallel', '~> 1.0.0')
|
43
43
|
end
|
@@ -1,61 +1,16 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Mutant::Isolation do
|
4
|
-
describe '.
|
4
|
+
describe '.run' do
|
5
5
|
let(:object) { described_class }
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
skip 'Series of events is indeterministic cross ruby implementations. Skipping this test under non 2.1.2'
|
10
|
-
end
|
7
|
+
it 'isolates global effects from process' do
|
8
|
+
expect { object.call { ::Foo = 1 } }.not_to change { defined?(Foo) }.from(nil)
|
11
9
|
end
|
12
10
|
|
13
|
-
|
14
|
-
|
15
|
-
subject { object.call(&block) }
|
16
|
-
|
17
|
-
def redirect_stderr
|
18
|
-
$stderr = File.open('/dev/null')
|
19
|
-
end
|
20
|
-
|
21
|
-
unless ENV['COVERAGE']
|
22
|
-
context 'when block returns mashallable data, and process exists zero' do
|
23
|
-
let(:block) do
|
24
|
-
lambda do
|
25
|
-
:data_from_child_process
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
it { should eql(:data_from_child_process) }
|
30
|
-
end
|
11
|
+
it 'return block value' do
|
12
|
+
expect(object.call { :foo }).to be(:foo)
|
31
13
|
end
|
32
14
|
|
33
|
-
context 'when block does return marshallable data' do
|
34
|
-
let(:block) do
|
35
|
-
lambda do
|
36
|
-
redirect_stderr
|
37
|
-
$stderr # not mashallable, nothing written to pipe and raises exception in child
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
it 'raises an exception' do
|
42
|
-
expect { subject }.to raise_error(described_class::Error, 'Childprocess wrote un-unmarshallable data')
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
context 'when block causes the child to exit nonzero' do
|
47
|
-
let(:block) do
|
48
|
-
lambda do
|
49
|
-
method = Kernel.method(:exit!)
|
50
|
-
Kernel.define_singleton_method(:exit!) do |_status|
|
51
|
-
method.call(1)
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
it 'raises an exception' do
|
57
|
-
expect { subject }.to raise_error(described_class::Error, 'Childprocess exited with nonzero exit status: 1')
|
58
|
-
end
|
59
|
-
end
|
60
15
|
end
|
61
16
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mutant
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
4
|
+
version: 0.5.23
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Markus Schirp
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-06-
|
11
|
+
date: 2014-06-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: parser
|
@@ -207,39 +207,39 @@ dependencies:
|
|
207
207
|
- !ruby/object:Gem::Version
|
208
208
|
version: 0.1.5
|
209
209
|
- !ruby/object:Gem::Dependency
|
210
|
-
name:
|
210
|
+
name: parallel
|
211
211
|
requirement: !ruby/object:Gem::Requirement
|
212
212
|
requirements:
|
213
213
|
- - "~>"
|
214
214
|
- !ruby/object:Gem::Version
|
215
|
-
version:
|
216
|
-
|
217
|
-
- !ruby/object:Gem::Version
|
218
|
-
version: 1.3.5
|
219
|
-
type: :development
|
215
|
+
version: 1.0.0
|
216
|
+
type: :runtime
|
220
217
|
prerelease: false
|
221
218
|
version_requirements: !ruby/object:Gem::Requirement
|
222
219
|
requirements:
|
223
220
|
- - "~>"
|
224
221
|
- !ruby/object:Gem::Version
|
225
|
-
version:
|
226
|
-
- - ">="
|
227
|
-
- !ruby/object:Gem::Version
|
228
|
-
version: 1.3.5
|
222
|
+
version: 1.0.0
|
229
223
|
- !ruby/object:Gem::Dependency
|
230
|
-
name:
|
224
|
+
name: bundler
|
231
225
|
requirement: !ruby/object:Gem::Requirement
|
232
226
|
requirements:
|
233
227
|
- - "~>"
|
234
228
|
- !ruby/object:Gem::Version
|
235
|
-
version: 1.
|
229
|
+
version: '1.3'
|
230
|
+
- - ">="
|
231
|
+
- !ruby/object:Gem::Version
|
232
|
+
version: 1.3.5
|
236
233
|
type: :development
|
237
234
|
prerelease: false
|
238
235
|
version_requirements: !ruby/object:Gem::Requirement
|
239
236
|
requirements:
|
240
237
|
- - "~>"
|
241
238
|
- !ruby/object:Gem::Version
|
242
|
-
version: 1.
|
239
|
+
version: '1.3'
|
240
|
+
- - ">="
|
241
|
+
- !ruby/object:Gem::Version
|
242
|
+
version: 1.3.5
|
243
243
|
description: Mutation testing for ruby
|
244
244
|
email:
|
245
245
|
- mbj@schirp-dso.com
|
@@ -577,4 +577,3 @@ test_files:
|
|
577
577
|
- spec/unit/mutant/warning_expectation.rb
|
578
578
|
- spec/unit/mutant/warning_filter_spec.rb
|
579
579
|
- spec/unit/mutant_spec.rb
|
580
|
-
has_rdoc:
|