mutant 0.8.12 → 0.8.13
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/.gitignore +0 -1
- data/.rubocop.yml +3 -3
- data/Changelog.md +6 -0
- data/Gemfile.lock +167 -0
- data/README.md +5 -3
- data/bin/mutant +1 -1
- data/circle.yml +1 -4
- data/config/flay.yml +1 -1
- data/config/rubocop.yml +3 -0
- data/lib/mutant/ast/regexp.rb +1 -4
- data/lib/mutant/ast/regexp/transformer/direct.rb +1 -0
- data/lib/mutant/ast/types.rb +1 -0
- data/lib/mutant/cli.rb +0 -2
- data/lib/mutant/color.rb +1 -2
- data/lib/mutant/mutator/node/define.rb +0 -14
- data/lib/mutant/mutator/node/literal/nil.rb +1 -2
- data/lib/mutant/mutator/node/send.rb +2 -0
- data/lib/mutant/version.rb +1 -1
- data/meta/case.rb +1 -0
- data/meta/def.rb +0 -12
- data/meta/kwarg.rb +0 -1
- data/meta/kwoptarg.rb +0 -1
- data/meta/rescue.rb +0 -2
- data/meta/restarg.rb +0 -1
- data/meta/send.rb +26 -1
- data/mutant-rspec.gemspec +1 -1
- data/mutant.gemspec +2 -1
- data/spec/integration/mutant/rspec_spec.rb +1 -1
- data/spec/integrations.yml +13 -58
- data/spec/support/corpus.rb +14 -6
- data/spec/support/xspec.rb +3 -3
- data/spec/unit/mutant/ast/regexp/parse_spec.rb +0 -2
- data/spec/unit/mutant/ast/regexp_spec.rb +5 -0
- data/spec/unit/mutant/cli_spec.rb +0 -8
- data/spec/unit/mutant/env/bootstrap_spec.rb +2 -4
- data/spec/unit/mutant/matcher/methods/instance_spec.rb +5 -10
- data/spec/unit/mutant/matcher/methods/singleton_spec.rb +5 -10
- data/spec/unit/mutant/repository/diff_spec.rb +1 -0
- data/spec/unit/mutant/subject/method/instance_spec.rb +2 -9
- data/test_app/Gemfile.rspec3.6 +7 -0
- metadata +7 -5
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 948b6088b39701179c5fdb357512b08412e3b15d
|
|
4
|
+
data.tar.gz: 02ade22a8daf9d491c5aa31ef070dd9192a88837
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c211d0c7ddc497e4d034112f9561ea3372e65cadae39fd1409bcb5cece2d49793cbd45d01b586a2b05bb23606a77ac64734ef2231e1af4d4b085c938a59421a6
|
|
7
|
+
data.tar.gz: 263d9080112bd79a374befc071f798f59b35d4e7c320b84a283819b35bf0d27c07009e3e2029b54a2567ca23b252664a8a9979596d537892d95135eb6614cd1d
|
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
data/Changelog.md
CHANGED
data/Gemfile.lock
ADDED
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
PATH
|
|
2
|
+
remote: .
|
|
3
|
+
specs:
|
|
4
|
+
mutant (0.8.12)
|
|
5
|
+
abstract_type (~> 0.0.7)
|
|
6
|
+
adamantium (~> 0.2.0)
|
|
7
|
+
anima (~> 0.3.0)
|
|
8
|
+
ast (~> 2.2)
|
|
9
|
+
concord (~> 0.1.5)
|
|
10
|
+
diff-lcs (~> 1.2)
|
|
11
|
+
equalizer (~> 0.0.9)
|
|
12
|
+
ice_nine (~> 0.11.1)
|
|
13
|
+
memoizable (~> 0.4.2)
|
|
14
|
+
morpher (~> 0.2.6)
|
|
15
|
+
parallel (~> 1.3)
|
|
16
|
+
parser (~> 2.3.1, >= 2.3.1.4)
|
|
17
|
+
procto (~> 0.0.2)
|
|
18
|
+
regexp_parser (~> 0.4.1)
|
|
19
|
+
unparser (~> 0.2.5)
|
|
20
|
+
mutant-rspec (0.8.12)
|
|
21
|
+
mutant (~> 0.8.12)
|
|
22
|
+
rspec-core (>= 3.4.0, < 3.7.0)
|
|
23
|
+
|
|
24
|
+
GEM
|
|
25
|
+
remote: https://rubygems.org/
|
|
26
|
+
specs:
|
|
27
|
+
abstract_type (0.0.7)
|
|
28
|
+
adamantium (0.2.0)
|
|
29
|
+
ice_nine (~> 0.11.0)
|
|
30
|
+
memoizable (~> 0.4.0)
|
|
31
|
+
anima (0.3.0)
|
|
32
|
+
abstract_type (~> 0.0.7)
|
|
33
|
+
adamantium (~> 0.2)
|
|
34
|
+
equalizer (~> 0.0.11)
|
|
35
|
+
ast (2.3.0)
|
|
36
|
+
axiom-types (0.1.1)
|
|
37
|
+
descendants_tracker (~> 0.0.4)
|
|
38
|
+
ice_nine (~> 0.11.0)
|
|
39
|
+
thread_safe (~> 0.3, >= 0.3.1)
|
|
40
|
+
codeclimate-engine-rb (0.4.0)
|
|
41
|
+
virtus (~> 1.0)
|
|
42
|
+
coercible (1.0.0)
|
|
43
|
+
descendants_tracker (~> 0.0.1)
|
|
44
|
+
concord (0.1.5)
|
|
45
|
+
adamantium (~> 0.2.0)
|
|
46
|
+
equalizer (~> 0.0.9)
|
|
47
|
+
descendants_tracker (0.0.4)
|
|
48
|
+
thread_safe (~> 0.3, >= 0.3.1)
|
|
49
|
+
devtools (0.1.15)
|
|
50
|
+
adamantium (~> 0.2.0)
|
|
51
|
+
anima (~> 0.3.0)
|
|
52
|
+
concord (~> 0.1.5)
|
|
53
|
+
flay (~> 2.8.1)
|
|
54
|
+
flog (~> 4.4.0)
|
|
55
|
+
mutant (~> 0.8.11)
|
|
56
|
+
mutant-rspec (~> 0.8.11)
|
|
57
|
+
procto (~> 0.0.3)
|
|
58
|
+
rake (~> 11.3.0)
|
|
59
|
+
reek (~> 4.5.0)
|
|
60
|
+
rspec (~> 3.5.0)
|
|
61
|
+
rspec-core (~> 3.5.4)
|
|
62
|
+
rspec-its (~> 1.2.0)
|
|
63
|
+
rubocop (~> 0.46.0)
|
|
64
|
+
simplecov (~> 0.12.0)
|
|
65
|
+
yard (~> 0.9.1)
|
|
66
|
+
yardstick (~> 0.9.9)
|
|
67
|
+
diff-lcs (1.2.5)
|
|
68
|
+
docile (1.1.5)
|
|
69
|
+
equalizer (0.0.11)
|
|
70
|
+
erubis (2.7.0)
|
|
71
|
+
ffi (1.9.14)
|
|
72
|
+
flay (2.8.1)
|
|
73
|
+
erubis (~> 2.7.0)
|
|
74
|
+
path_expander (~> 1.0)
|
|
75
|
+
ruby_parser (~> 3.0)
|
|
76
|
+
sexp_processor (~> 4.0)
|
|
77
|
+
flog (4.4.0)
|
|
78
|
+
path_expander (~> 1.0)
|
|
79
|
+
ruby_parser (~> 3.1, > 3.1.0)
|
|
80
|
+
sexp_processor (~> 4.4)
|
|
81
|
+
ice_nine (0.11.2)
|
|
82
|
+
json (2.0.2)
|
|
83
|
+
memoizable (0.4.2)
|
|
84
|
+
thread_safe (~> 0.3, >= 0.3.1)
|
|
85
|
+
morpher (0.2.6)
|
|
86
|
+
abstract_type (~> 0.0.7)
|
|
87
|
+
adamantium (~> 0.2.0)
|
|
88
|
+
anima (~> 0.3.0)
|
|
89
|
+
ast (~> 2.2)
|
|
90
|
+
concord (~> 0.1.5)
|
|
91
|
+
equalizer (~> 0.0.9)
|
|
92
|
+
ice_nine (~> 0.11.0)
|
|
93
|
+
procto (~> 0.0.2)
|
|
94
|
+
parallel (1.10.0)
|
|
95
|
+
parser (2.3.3.1)
|
|
96
|
+
ast (~> 2.2)
|
|
97
|
+
path_expander (1.0.1)
|
|
98
|
+
powerpack (0.1.1)
|
|
99
|
+
procto (0.0.3)
|
|
100
|
+
rainbow (2.1.0)
|
|
101
|
+
rake (11.3.0)
|
|
102
|
+
reek (4.5.2)
|
|
103
|
+
codeclimate-engine-rb (~> 0.4.0)
|
|
104
|
+
parser (~> 2.3.1, >= 2.3.1.2)
|
|
105
|
+
rainbow (~> 2.0)
|
|
106
|
+
regexp_parser (0.4.1)
|
|
107
|
+
rspec (3.5.0)
|
|
108
|
+
rspec-core (~> 3.5.0)
|
|
109
|
+
rspec-expectations (~> 3.5.0)
|
|
110
|
+
rspec-mocks (~> 3.5.0)
|
|
111
|
+
rspec-core (3.5.4)
|
|
112
|
+
rspec-support (~> 3.5.0)
|
|
113
|
+
rspec-expectations (3.5.0)
|
|
114
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
115
|
+
rspec-support (~> 3.5.0)
|
|
116
|
+
rspec-its (1.2.0)
|
|
117
|
+
rspec-core (>= 3.0.0)
|
|
118
|
+
rspec-expectations (>= 3.0.0)
|
|
119
|
+
rspec-mocks (3.5.0)
|
|
120
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
121
|
+
rspec-support (~> 3.5.0)
|
|
122
|
+
rspec-support (3.5.0)
|
|
123
|
+
rubocop (0.46.0)
|
|
124
|
+
parser (>= 2.3.1.1, < 3.0)
|
|
125
|
+
powerpack (~> 0.1)
|
|
126
|
+
rainbow (>= 1.99.1, < 3.0)
|
|
127
|
+
ruby-progressbar (~> 1.7)
|
|
128
|
+
unicode-display_width (~> 1.0, >= 1.0.1)
|
|
129
|
+
ruby-progressbar (1.8.1)
|
|
130
|
+
ruby_parser (3.8.3)
|
|
131
|
+
sexp_processor (~> 4.1)
|
|
132
|
+
sexp_processor (4.7.0)
|
|
133
|
+
simplecov (0.12.0)
|
|
134
|
+
docile (~> 1.1.0)
|
|
135
|
+
json (>= 1.8, < 3)
|
|
136
|
+
simplecov-html (~> 0.10.0)
|
|
137
|
+
simplecov-html (0.10.0)
|
|
138
|
+
thread_safe (0.3.5)
|
|
139
|
+
unicode-display_width (1.1.1)
|
|
140
|
+
unparser (0.2.5)
|
|
141
|
+
abstract_type (~> 0.0.7)
|
|
142
|
+
adamantium (~> 0.2.0)
|
|
143
|
+
concord (~> 0.1.5)
|
|
144
|
+
diff-lcs (~> 1.2.5)
|
|
145
|
+
equalizer (~> 0.0.9)
|
|
146
|
+
parser (~> 2.3.0)
|
|
147
|
+
procto (~> 0.0.2)
|
|
148
|
+
virtus (1.0.5)
|
|
149
|
+
axiom-types (~> 0.1)
|
|
150
|
+
coercible (~> 1.0)
|
|
151
|
+
descendants_tracker (~> 0.0, >= 0.0.3)
|
|
152
|
+
equalizer (~> 0.0, >= 0.0.9)
|
|
153
|
+
yard (0.9.5)
|
|
154
|
+
yardstick (0.9.9)
|
|
155
|
+
yard (~> 0.8, >= 0.8.7.2)
|
|
156
|
+
|
|
157
|
+
PLATFORMS
|
|
158
|
+
ruby
|
|
159
|
+
|
|
160
|
+
DEPENDENCIES
|
|
161
|
+
bundler (~> 1.10)
|
|
162
|
+
devtools (~> 0.1.12)
|
|
163
|
+
ffi (~> 1.9.6)
|
|
164
|
+
mutant!
|
|
165
|
+
|
|
166
|
+
BUNDLED WITH
|
|
167
|
+
1.13.6
|
data/README.md
CHANGED
|
@@ -2,9 +2,9 @@ mutant
|
|
|
2
2
|
======
|
|
3
3
|
|
|
4
4
|
[](https://circleci.com/gh/mbj/mutant/tree/master)
|
|
5
|
-
[](https://gemnasium.com/mbj/mutant)
|
|
6
|
+
[](https://codeclimate.com/github/mbj/mutant)
|
|
7
|
+
[](http://inch-ci.org/github/mbj/mutant)
|
|
8
8
|
[](https://rubygems.org/gems/mutant)
|
|
9
9
|
[](https://flattr.com/thing/1823010/mbjmutant-on-GitHub)
|
|
10
10
|
[](https://mutation-testing.slack.com/messages/mutant)
|
|
@@ -341,6 +341,7 @@ Blog posts
|
|
|
341
341
|
Sorted by recency:
|
|
342
342
|
|
|
343
343
|
* [A deep dive into mutation testing and how the Mutant gem works][troessner]
|
|
344
|
+
* [Keep calm and kill mutants (December, 2015)][itransition]
|
|
344
345
|
* [How to write better code using mutation testing (November 2015)][blockscore]
|
|
345
346
|
* [How good are your Ruby tests? Testing your tests with mutant (June 2015)][arkency1]
|
|
346
347
|
* [Mutation testing and continuous integration (May 2015)][arkency2]
|
|
@@ -349,6 +350,7 @@ Sorted by recency:
|
|
|
349
350
|
* [Mutation testing with mutant (January 2013)][solnic]
|
|
350
351
|
|
|
351
352
|
[troessner]: https://troessner.svbtle.com/kill-all-the-mutants-a-deep-dive-into-mutation-testing-and-how-the-mutant-gem-works
|
|
353
|
+
[itransition]: https://github.com/maksar/mentat
|
|
352
354
|
[blockscore]: https://blog.blockscore.com/how-to-write-better-code-using-mutation-testing/
|
|
353
355
|
[sitepoint]: http://www.sitepoint.com/mutation-testing-mutant/
|
|
354
356
|
[arkency1]: http://blog.arkency.com/2015/06/how-good-are-your-ruby-tests-testing-your-tests-with-mutant/
|
data/bin/mutant
CHANGED
data/circle.yml
CHANGED
data/config/flay.yml
CHANGED
data/config/rubocop.yml
CHANGED
data/lib/mutant/ast/regexp.rb
CHANGED
|
@@ -12,10 +12,7 @@ module Mutant
|
|
|
12
12
|
#
|
|
13
13
|
# @return [Regexp::Expression]
|
|
14
14
|
def self.parse(regexp)
|
|
15
|
-
::Regexp::Parser.parse(
|
|
16
|
-
regexp,
|
|
17
|
-
"ruby/#{RUBY_VERSION.split('.').first(2).join('.')}"
|
|
18
|
-
)
|
|
15
|
+
::Regexp::Parser.parse(regexp)
|
|
19
16
|
end
|
|
20
17
|
|
|
21
18
|
# Check if expression is supported by mapper
|
|
@@ -50,6 +50,7 @@ module Mutant
|
|
|
50
50
|
[:regexp_set_open_escape, [:escape, :set_open, '\['], ::Regexp::Expression::EscapeSequence::Literal],
|
|
51
51
|
[:regexp_set_close_escape, [:escape, :set_close, '\]'], ::Regexp::Expression::EscapeSequence::Literal],
|
|
52
52
|
[:regexp_eol_escape, [:escape, :eol, '\$'], ::Regexp::Expression::EscapeSequence::Literal],
|
|
53
|
+
[:regexp_bol_escape, [:escape, :bol, '\^'], ::Regexp::Expression::EscapeSequence::Literal],
|
|
53
54
|
[:regexp_bell_escape, [:escape, :bell, '\a'], ::Regexp::Expression::EscapeSequence::Literal],
|
|
54
55
|
[:regexp_escape_escape, [:escape, :escape, '\e'], ::Regexp::Expression::EscapeSequence::AsciiEscape],
|
|
55
56
|
[:regexp_form_feed_escape, [:escape, :form_feed, '\f'], ::Regexp::Expression::EscapeSequence::FormFeed],
|
data/lib/mutant/ast/types.rb
CHANGED
data/lib/mutant/cli.rb
CHANGED
|
@@ -64,8 +64,6 @@ module Mutant
|
|
|
64
64
|
#
|
|
65
65
|
# @return [undefined]
|
|
66
66
|
def parse_match_expressions(expressions)
|
|
67
|
-
fail Error, 'No expressions given' if expressions.empty?
|
|
68
|
-
|
|
69
67
|
expressions.each do |expression|
|
|
70
68
|
add_matcher(:match_expressions, config.expression_parser.(expression))
|
|
71
69
|
end
|
data/lib/mutant/color.rb
CHANGED
|
@@ -60,20 +60,6 @@ module Mutant
|
|
|
60
60
|
|
|
61
61
|
children :name, :arguments, :body
|
|
62
62
|
|
|
63
|
-
# Emit mutations
|
|
64
|
-
#
|
|
65
|
-
# @return [undefined]
|
|
66
|
-
def dispatch
|
|
67
|
-
super()
|
|
68
|
-
emit_remove_method
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
# Remove an instance method
|
|
72
|
-
#
|
|
73
|
-
# @return [undefined]
|
|
74
|
-
def emit_remove_method
|
|
75
|
-
emit(s(:send, nil, :remove_method, s(:sym, name)))
|
|
76
|
-
end
|
|
77
63
|
end # Instance
|
|
78
64
|
|
|
79
65
|
# Mutator for singleton method defines
|
data/lib/mutant/version.rb
CHANGED
data/meta/case.rb
CHANGED
data/meta/def.rb
CHANGED
|
@@ -2,7 +2,6 @@ Mutant::Meta::Example.add :def do
|
|
|
2
2
|
source 'def foo; end'
|
|
3
3
|
|
|
4
4
|
mutation 'def foo; raise; end'
|
|
5
|
-
mutation 'remove_method :foo'
|
|
6
5
|
end
|
|
7
6
|
|
|
8
7
|
Mutant::Meta::Example.add :def do
|
|
@@ -15,7 +14,6 @@ Mutant::Meta::Example.add :def do
|
|
|
15
14
|
mutation 'def foo(a); nil; end'
|
|
16
15
|
mutation 'def foo(*b); nil; end'
|
|
17
16
|
mutation 'def foo(a, *b); b = []; nil; end'
|
|
18
|
-
mutation 'remove_method :foo'
|
|
19
17
|
end
|
|
20
18
|
|
|
21
19
|
Mutant::Meta::Example.add :def do
|
|
@@ -27,7 +25,6 @@ Mutant::Meta::Example.add :def do
|
|
|
27
25
|
mutation 'def foo(a, *); raise; end'
|
|
28
26
|
mutation 'def foo(a); nil; end'
|
|
29
27
|
mutation 'def foo(*); nil; end'
|
|
30
|
-
mutation 'remove_method :foo'
|
|
31
28
|
end
|
|
32
29
|
|
|
33
30
|
Mutant::Meta::Example.add :def do
|
|
@@ -37,7 +34,6 @@ Mutant::Meta::Example.add :def do
|
|
|
37
34
|
mutation 'def foo; nil; rescue; end'
|
|
38
35
|
mutation 'def foo; self; rescue; end'
|
|
39
36
|
mutation 'def foo; end'
|
|
40
|
-
mutation 'remove_method :foo'
|
|
41
37
|
|
|
42
38
|
# Promote rescue resbody bodies
|
|
43
39
|
mutation 'def foo; foo; end'
|
|
@@ -69,7 +65,6 @@ Mutant::Meta::Example.add :def do
|
|
|
69
65
|
# Failing body
|
|
70
66
|
mutation 'def a; raise; end'
|
|
71
67
|
|
|
72
|
-
mutation 'remove_method :a'
|
|
73
68
|
end
|
|
74
69
|
|
|
75
70
|
Mutant::Meta::Example.add :def do
|
|
@@ -90,7 +85,6 @@ Mutant::Meta::Example.add :def do
|
|
|
90
85
|
|
|
91
86
|
mutation 'def foo; raise; end'
|
|
92
87
|
|
|
93
|
-
mutation 'remove_method :foo'
|
|
94
88
|
end
|
|
95
89
|
|
|
96
90
|
Mutant::Meta::Example.add :def do
|
|
@@ -110,7 +104,6 @@ Mutant::Meta::Example.add :def do
|
|
|
110
104
|
# Mutation of body
|
|
111
105
|
mutation 'def foo(a, b); raise; end'
|
|
112
106
|
|
|
113
|
-
mutation 'remove_method :foo'
|
|
114
107
|
end
|
|
115
108
|
|
|
116
109
|
Mutant::Meta::Example.add :def do
|
|
@@ -127,7 +120,6 @@ Mutant::Meta::Example.add :def do
|
|
|
127
120
|
mutation 'def foo(b = nil); true; end'
|
|
128
121
|
mutation 'def foo(a, _b = nil); true; end'
|
|
129
122
|
mutation 'def foo(a, b); true; end'
|
|
130
|
-
mutation 'remove_method :foo'
|
|
131
123
|
end
|
|
132
124
|
|
|
133
125
|
Mutant::Meta::Example.add :def do
|
|
@@ -135,7 +127,6 @@ Mutant::Meta::Example.add :def do
|
|
|
135
127
|
|
|
136
128
|
mutation 'def foo(_unused); raise; end'
|
|
137
129
|
mutation 'def foo; end'
|
|
138
|
-
mutation 'remove_method :foo'
|
|
139
130
|
end
|
|
140
131
|
|
|
141
132
|
Mutant::Meta::Example.add :def do
|
|
@@ -146,7 +137,6 @@ Mutant::Meta::Example.add :def do
|
|
|
146
137
|
mutation 'def foo(_unused = true); raise; end'
|
|
147
138
|
mutation 'def foo(_unused); end'
|
|
148
139
|
mutation 'def foo; end'
|
|
149
|
-
mutation 'remove_method :foo'
|
|
150
140
|
end
|
|
151
141
|
|
|
152
142
|
Mutant::Meta::Example.add :def do
|
|
@@ -168,7 +158,6 @@ Mutant::Meta::Example.add :def do
|
|
|
168
158
|
mutation 'def foo(a = 0, b = 0); a = 0; end'
|
|
169
159
|
mutation 'def foo(a = 0, b = 0); b = 0; end'
|
|
170
160
|
mutation 'def foo(a = 0, b = 0); raise; end'
|
|
171
|
-
mutation 'remove_method :foo'
|
|
172
161
|
end
|
|
173
162
|
|
|
174
163
|
Mutant::Meta::Example.add :def do
|
|
@@ -181,7 +170,6 @@ Mutant::Meta::Example.add :def do
|
|
|
181
170
|
mutation 'def foo(_a = true); end'
|
|
182
171
|
mutation 'def foo(a = true); raise; end'
|
|
183
172
|
mutation 'def foo(a = true); a = true; end'
|
|
184
|
-
mutation 'remove_method :foo'
|
|
185
173
|
end
|
|
186
174
|
|
|
187
175
|
Mutant::Meta::Example.add :def do
|
data/meta/kwarg.rb
CHANGED
data/meta/kwoptarg.rb
CHANGED
data/meta/rescue.rb
CHANGED
data/meta/restarg.rb
CHANGED
data/meta/send.rb
CHANGED
|
@@ -625,7 +625,7 @@ Mutant::Meta::Example.add :send do
|
|
|
625
625
|
mutation 'self[*bar]'
|
|
626
626
|
end
|
|
627
627
|
|
|
628
|
-
(Mutant::AST::Types::BINARY_METHOD_OPERATORS - %i[<= >= < > == != eql?]).each do |operator|
|
|
628
|
+
(Mutant::AST::Types::BINARY_METHOD_OPERATORS - %i[=~ <= >= < > == != eql?]).each do |operator|
|
|
629
629
|
Mutant::Meta::Example.add :send do
|
|
630
630
|
source "true #{operator} false"
|
|
631
631
|
|
|
@@ -746,3 +746,28 @@ Mutant::Meta::Example.add :send do
|
|
|
746
746
|
mutation 'Proc.new { raise }'
|
|
747
747
|
mutation 'lambda { }'
|
|
748
748
|
end
|
|
749
|
+
|
|
750
|
+
Mutant::Meta::Example.add :send do
|
|
751
|
+
source 'a =~ //'
|
|
752
|
+
|
|
753
|
+
singleton_mutations
|
|
754
|
+
mutation 'a'
|
|
755
|
+
mutation 'nil =~ //'
|
|
756
|
+
mutation 'self =~ //'
|
|
757
|
+
mutation '//'
|
|
758
|
+
mutation 'a =~ /nomatch\A/'
|
|
759
|
+
mutation 'a.match?(//)'
|
|
760
|
+
end
|
|
761
|
+
|
|
762
|
+
Mutant::Meta::Example.add :send do
|
|
763
|
+
source '//.match(a)'
|
|
764
|
+
|
|
765
|
+
singleton_mutations
|
|
766
|
+
mutation 'a'
|
|
767
|
+
mutation '//.match'
|
|
768
|
+
mutation '//.match(nil)'
|
|
769
|
+
mutation '//.match(self)'
|
|
770
|
+
mutation '//.match?(a)'
|
|
771
|
+
mutation '//'
|
|
772
|
+
mutation '/nomatch\A/.match(a)'
|
|
773
|
+
end
|
data/mutant-rspec.gemspec
CHANGED
|
@@ -16,7 +16,7 @@ Gem::Specification.new do |gem|
|
|
|
16
16
|
gem.extra_rdoc_files = %w[LICENSE]
|
|
17
17
|
|
|
18
18
|
gem.add_runtime_dependency('mutant', "~> #{gem.version}")
|
|
19
|
-
gem.add_runtime_dependency('rspec-core', '>= 3.4.0', '< 3.
|
|
19
|
+
gem.add_runtime_dependency('rspec-core', '>= 3.4.0', '< 3.7.0')
|
|
20
20
|
|
|
21
21
|
gem.add_development_dependency('bundler', '~> 1.3', '>= 1.3.5')
|
|
22
22
|
end
|
data/mutant.gemspec
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
require File.expand_path('../lib/mutant/version', __FILE__)
|
|
2
2
|
|
|
3
|
+
# rubocop:disable Metrics/BlockLength
|
|
3
4
|
Gem::Specification.new do |gem|
|
|
4
5
|
gem.name = 'mutant'
|
|
5
6
|
gem.version = Mutant::VERSION.dup
|
|
@@ -35,7 +36,7 @@ Gem::Specification.new do |gem|
|
|
|
35
36
|
gem.add_runtime_dependency('equalizer', '~> 0.0.9')
|
|
36
37
|
gem.add_runtime_dependency('anima', '~> 0.3.0')
|
|
37
38
|
gem.add_runtime_dependency('concord', '~> 0.1.5')
|
|
38
|
-
gem.add_runtime_dependency('regexp_parser', '~> 0.
|
|
39
|
+
gem.add_runtime_dependency('regexp_parser', '~> 0.4.1')
|
|
39
40
|
|
|
40
41
|
gem.add_development_dependency('devtools', '~> 0.1.12')
|
|
41
42
|
gem.add_development_dependency('bundler', '~> 1.10')
|
|
@@ -2,7 +2,7 @@ RSpec.describe 'rspec integration', mutant: false do
|
|
|
2
2
|
|
|
3
3
|
let(:base_cmd) { 'bundle exec mutant -I lib --require test_app --use rspec' }
|
|
4
4
|
|
|
5
|
-
%w[3.4 3.5].each do |version|
|
|
5
|
+
%w[3.4 3.5 3.6].each do |version|
|
|
6
6
|
context "RSpec #{version}" do
|
|
7
7
|
let(:gemfile) { "Gemfile.rspec#{version}" }
|
|
8
8
|
|
data/spec/integrations.yml
CHANGED
|
@@ -2,87 +2,42 @@
|
|
|
2
2
|
- name: rubyspec
|
|
3
3
|
namespace: Rubyspec
|
|
4
4
|
repo_uri: 'https://github.com/ruby/rubyspec.git'
|
|
5
|
+
repo_ref: 'origin/master'
|
|
6
|
+
ruby_glob_pattern: '**/*_spec.rb'
|
|
5
7
|
mutation_coverage: false
|
|
6
8
|
mutation_generation: true
|
|
7
9
|
expected_errors:
|
|
8
10
|
"#<Parser::SyntaxError: invalid multibyte escape: /\xAA/>":
|
|
9
11
|
- language/regexp/escapes_spec.rb
|
|
10
|
-
"#<Parser::SyntaxError: literal contains escape sequences incompatible with UTF-8>":
|
|
11
|
-
- core/array/fixtures/encoded_strings.rb
|
|
12
|
-
- core/array/pack/shared/string.rb
|
|
13
|
-
- core/array/pack/shared/unicode.rb
|
|
14
|
-
- core/encoding/converter/convert_spec.rb
|
|
15
|
-
- core/encoding/converter/last_error_spec.rb
|
|
16
|
-
- core/encoding/converter/primitive_convert_spec.rb
|
|
17
|
-
- core/encoding/converter/primitive_errinfo_spec.rb
|
|
18
|
-
- core/encoding/converter/putback_spec.rb
|
|
19
|
-
- core/encoding/fixtures/classes.rb
|
|
20
|
-
- core/encoding/invalid_byte_sequence_error/error_bytes_spec.rb
|
|
21
|
-
- core/encoding/invalid_byte_sequence_error/incomplete_input_spec.rb
|
|
22
|
-
- core/encoding/invalid_byte_sequence_error/readagain_bytes_spec.rb
|
|
23
|
-
- core/encoding/replicate_spec.rb
|
|
24
|
-
- core/io/gets_spec.rb
|
|
25
|
-
- core/io/read_spec.rb
|
|
26
|
-
- core/io/shared/gets_ascii.rb
|
|
27
|
-
- core/io/write_spec.rb
|
|
28
|
-
- core/random/bytes_spec.rb
|
|
29
|
-
- core/regexp/match_spec.rb
|
|
30
|
-
- core/regexp/shared/new_ascii.rb
|
|
31
|
-
- core/string/byteslice_spec.rb
|
|
32
|
-
- core/string/codepoints_spec.rb
|
|
33
|
-
- core/string/comparison_spec.rb
|
|
34
|
-
- core/string/count_spec.rb
|
|
35
|
-
- core/string/delete_spec.rb
|
|
36
|
-
- core/string/element_set_spec.rb
|
|
37
|
-
- core/string/encode_spec.rb
|
|
38
|
-
- core/string/encoding_spec.rb
|
|
39
|
-
- core/string/fixtures/iso-8859-9-encoding.rb
|
|
40
|
-
- core/string/getbyte_spec.rb
|
|
41
|
-
- core/string/gsub_spec.rb
|
|
42
|
-
- core/string/new_spec.rb
|
|
43
|
-
- core/string/scrub_spec.rb
|
|
44
|
-
- core/string/shared/chars.rb
|
|
45
|
-
- core/string/shared/codepoints.rb
|
|
46
|
-
- core/string/shared/each_codepoint_without_block.rb
|
|
47
|
-
- core/string/shared/encode.rb
|
|
48
|
-
- core/string/shared/eql.rb
|
|
49
|
-
- core/string/shared/succ.rb
|
|
50
|
-
- core/string/slice_spec.rb
|
|
51
|
-
- core/string/squeeze_spec.rb
|
|
52
|
-
- core/string/unicode_normalize_spec.rb
|
|
53
|
-
- core/string/valid_encoding_spec.rb
|
|
54
|
-
- core/symbol/casecmp_spec.rb
|
|
55
|
-
- core/time/_dump_spec.rb
|
|
56
|
-
- core/time/_load_spec.rb
|
|
57
|
-
- language/regexp/encoding_spec.rb
|
|
58
|
-
- language/string_spec.rb
|
|
59
|
-
- library/openssl/shared/constants.rb
|
|
60
|
-
- library/socket/basicsocket/recv_spec.rb
|
|
61
|
-
- library/socket/socket/gethostbyname_spec.rb
|
|
62
|
-
- library/stringscanner/getch_spec.rb
|
|
63
|
-
- library/stringscanner/shared/get_byte.rb
|
|
64
|
-
- library/zlib/inflate/set_dictionary_spec.rb
|
|
65
|
-
- optional/capi/encoding_spec.rb
|
|
66
|
-
- optional/capi/string_spec.rb
|
|
67
12
|
'#<RegexpError: invalid multibyte escape: /\xAA/>':
|
|
68
13
|
- language/regexp/escapes_spec.rb
|
|
69
14
|
"#<Regexp::Scanner::PrematureEndError: Premature end of pattern at #{str}>":
|
|
70
15
|
- language/regexp/interpolation_spec.rb
|
|
16
|
+
'#<Regexp::Scanner::PrematureEndError: Premature end of pattern at \xA>':
|
|
17
|
+
- language/regexp/escapes_spec.rb
|
|
71
18
|
- name: regexp_parser
|
|
72
19
|
namespace: Regexp
|
|
73
20
|
repo_uri: 'https://github.com/ammar/regexp_parser.git'
|
|
21
|
+
repo_ref: 'v0.4.1'
|
|
22
|
+
ruby_glob_pattern: '**/*.rb'
|
|
74
23
|
mutation_coverage: false
|
|
75
24
|
mutation_generation: true
|
|
76
|
-
expected_errors:
|
|
25
|
+
expected_errors:
|
|
26
|
+
"Regexp::Syntax::Ruby::V233 does not implement: [escape:codepoint]":
|
|
27
|
+
- regexp_parser/test/parser/test_escapes.rb
|
|
77
28
|
- name: auom
|
|
78
29
|
namespace: AUOM
|
|
79
30
|
repo_uri: 'https://github.com/mbj/auom.git'
|
|
31
|
+
repo_ref: 'origin/master'
|
|
32
|
+
ruby_glob_pattern: '**/*.rb'
|
|
80
33
|
mutation_coverage: true
|
|
81
34
|
mutation_generation: true
|
|
82
35
|
expected_errors: {}
|
|
83
36
|
- name: axiom
|
|
84
37
|
namespace: Axiom
|
|
85
38
|
repo_uri: 'https://github.com/dkubb/axiom.git'
|
|
39
|
+
repo_ref: 'origin/master'
|
|
40
|
+
ruby_glob_pattern: '**/*.rb'
|
|
86
41
|
mutation_coverage: false
|
|
87
42
|
mutation_generation: true
|
|
88
43
|
expected_errors: {}
|
data/spec/support/corpus.rb
CHANGED
|
@@ -12,7 +12,6 @@ module MutantSpec
|
|
|
12
12
|
module Corpus
|
|
13
13
|
TMP = ROOT.join('tmp').freeze
|
|
14
14
|
EXCLUDE_GLOB_FORMAT = '{%s}'.freeze
|
|
15
|
-
RUBY_GLOB_PATTERN = '**/*.rb'.freeze
|
|
16
15
|
|
|
17
16
|
# Not in the docs. Number from chatting with their support.
|
|
18
17
|
# 2 processors allocated per container, 4 processes works well.
|
|
@@ -37,7 +36,9 @@ module MutantSpec
|
|
|
37
36
|
:mutation_generation,
|
|
38
37
|
:name,
|
|
39
38
|
:namespace,
|
|
40
|
-
:repo_uri
|
|
39
|
+
:repo_uri,
|
|
40
|
+
:repo_ref,
|
|
41
|
+
:ruby_glob_pattern
|
|
41
42
|
)
|
|
42
43
|
|
|
43
44
|
# Verify mutation coverage
|
|
@@ -95,18 +96,23 @@ module MutantSpec
|
|
|
95
96
|
def checkout
|
|
96
97
|
return self if noinstall?
|
|
97
98
|
TMP.mkdir unless TMP.directory?
|
|
99
|
+
|
|
98
100
|
if repo_path.exist?
|
|
99
101
|
Dir.chdir(repo_path) do
|
|
100
102
|
system(%w[git fetch origin])
|
|
101
103
|
system(%w[git reset --hard])
|
|
102
104
|
system(%w[git clean -f -d -x])
|
|
103
|
-
system(%w[git checkout origin/master])
|
|
104
|
-
system(%w[git reset --hard])
|
|
105
|
-
system(%w[git clean -f -d -x])
|
|
106
105
|
end
|
|
107
106
|
else
|
|
108
107
|
system(%W[git clone #{repo_uri} #{repo_path}])
|
|
109
108
|
end
|
|
109
|
+
|
|
110
|
+
Dir.chdir(repo_path) do
|
|
111
|
+
system(%W[git checkout #{repo_ref}])
|
|
112
|
+
system(%w[git reset --hard])
|
|
113
|
+
system(%w[git clean -f -d -x])
|
|
114
|
+
end
|
|
115
|
+
|
|
110
116
|
self
|
|
111
117
|
end
|
|
112
118
|
memoize :checkout
|
|
@@ -168,7 +174,7 @@ module MutantSpec
|
|
|
168
174
|
# @return [Array<Pathname>]
|
|
169
175
|
def effective_ruby_paths
|
|
170
176
|
Pathname
|
|
171
|
-
.glob(repo_path.join(
|
|
177
|
+
.glob(repo_path.join(ruby_glob_pattern))
|
|
172
178
|
.sort_by(&:size)
|
|
173
179
|
.reverse
|
|
174
180
|
end
|
|
@@ -300,6 +306,8 @@ module MutantSpec
|
|
|
300
306
|
s(:guard, s(:primitive, Hash)),
|
|
301
307
|
s(:hash_transform,
|
|
302
308
|
s(:key_symbolize, :repo_uri, s(:guard, s(:primitive, String))),
|
|
309
|
+
s(:key_symbolize, :repo_ref, s(:guard, s(:primitive, String))),
|
|
310
|
+
s(:key_symbolize, :ruby_glob_pattern, s(:guard, s(:primitive, String))),
|
|
303
311
|
s(:key_symbolize, :name, s(:guard, s(:primitive, String))),
|
|
304
312
|
s(:key_symbolize, :namespace, s(:guard, s(:primitive, String))),
|
|
305
313
|
s(:key_symbolize, :mutation_coverage,
|
data/spec/support/xspec.rb
CHANGED
|
@@ -77,9 +77,9 @@ module XSpec
|
|
|
77
77
|
private_class_method :assert_not_empty
|
|
78
78
|
|
|
79
79
|
def self.assert_total(event_list)
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
80
|
+
return unless event_list[0..-2].map(&:first).any?(&TERMINATE_EVENTS.method(:include?))
|
|
81
|
+
|
|
82
|
+
fail "Reaction not total: #{event_list}"
|
|
83
83
|
end
|
|
84
84
|
private_class_method :assert_total
|
|
85
85
|
end # MessageReaction
|
|
@@ -113,6 +113,11 @@ RegexpSpec.expect_mapping(/^/, :regexp_bol_anchor) do
|
|
|
113
113
|
s(:regexp_bol_anchor))
|
|
114
114
|
end
|
|
115
115
|
|
|
116
|
+
RegexpSpec.expect_mapping(/\^/, :regexp_bol_escape) do
|
|
117
|
+
s(:regexp_root_expression,
|
|
118
|
+
s(:regexp_bol_escape))
|
|
119
|
+
end
|
|
120
|
+
|
|
116
121
|
RegexpSpec.expect_mapping(/\A/, :regexp_bos_anchor) do
|
|
117
122
|
s(:regexp_root_expression,
|
|
118
123
|
s(:regexp_bos_anchor))
|
|
@@ -96,14 +96,6 @@ RSpec.describe Mutant::CLI do
|
|
|
96
96
|
it_should_behave_like 'an invalid cli run'
|
|
97
97
|
end
|
|
98
98
|
|
|
99
|
-
context 'without expressions' do
|
|
100
|
-
let(:expressions) { [] }
|
|
101
|
-
|
|
102
|
-
let(:expected_message) { 'No expressions given' }
|
|
103
|
-
|
|
104
|
-
it_should_behave_like 'an invalid cli run'
|
|
105
|
-
end
|
|
106
|
-
|
|
107
99
|
context 'with include help flag' do
|
|
108
100
|
let(:flags) { %w[--help] }
|
|
109
101
|
|
|
@@ -93,8 +93,7 @@ RSpec.describe Mutant::Env::Bootstrap do
|
|
|
93
93
|
# Fix Class#name so other specs do not see this one
|
|
94
94
|
class << invalid_class
|
|
95
95
|
undef :name
|
|
96
|
-
def name
|
|
97
|
-
end
|
|
96
|
+
def name; end
|
|
98
97
|
end
|
|
99
98
|
end
|
|
100
99
|
|
|
@@ -151,8 +150,7 @@ RSpec.describe Mutant::Env::Bootstrap do
|
|
|
151
150
|
# Fix Class#name so other specs do not see this one
|
|
152
151
|
class << invalid_class
|
|
153
152
|
undef :name
|
|
154
|
-
def name
|
|
155
|
-
end
|
|
153
|
+
def name; end
|
|
156
154
|
end
|
|
157
155
|
end
|
|
158
156
|
|
|
@@ -4,11 +4,9 @@ RSpec.describe Mutant::Matcher::Methods::Instance, '#call' do
|
|
|
4
4
|
|
|
5
5
|
let(:class_under_test) do
|
|
6
6
|
parent = Module.new do
|
|
7
|
-
def method_d
|
|
8
|
-
end
|
|
7
|
+
def method_d; end
|
|
9
8
|
|
|
10
|
-
def method_e
|
|
11
|
-
end
|
|
9
|
+
def method_e; end
|
|
12
10
|
end
|
|
13
11
|
|
|
14
12
|
Class.new do
|
|
@@ -16,18 +14,15 @@ RSpec.describe Mutant::Matcher::Methods::Instance, '#call' do
|
|
|
16
14
|
|
|
17
15
|
private :method_d
|
|
18
16
|
|
|
19
|
-
def method_a
|
|
20
|
-
end
|
|
17
|
+
def method_a; end
|
|
21
18
|
|
|
22
19
|
protected
|
|
23
20
|
|
|
24
|
-
def method_b
|
|
25
|
-
end
|
|
21
|
+
def method_b; end
|
|
26
22
|
|
|
27
23
|
private
|
|
28
24
|
|
|
29
|
-
def method_c
|
|
30
|
-
end
|
|
25
|
+
def method_c; end
|
|
31
26
|
end
|
|
32
27
|
end
|
|
33
28
|
|
|
@@ -4,25 +4,20 @@ RSpec.describe Mutant::Matcher::Methods::Singleton, '#call' do
|
|
|
4
4
|
|
|
5
5
|
let(:class_under_test) do
|
|
6
6
|
parent = Module.new do
|
|
7
|
-
def method_d
|
|
8
|
-
end
|
|
7
|
+
def method_d; end
|
|
9
8
|
|
|
10
|
-
def method_e
|
|
11
|
-
end
|
|
9
|
+
def method_e; end
|
|
12
10
|
end
|
|
13
11
|
|
|
14
12
|
Class.new do
|
|
15
13
|
extend parent
|
|
16
14
|
|
|
17
|
-
def self.method_a
|
|
18
|
-
end
|
|
15
|
+
def self.method_a; end
|
|
19
16
|
|
|
20
|
-
def self.method_b
|
|
21
|
-
end
|
|
17
|
+
def self.method_b; end
|
|
22
18
|
class << self; protected :method_b; end
|
|
23
19
|
|
|
24
|
-
def self.method_c
|
|
25
|
-
end
|
|
20
|
+
def self.method_c; end
|
|
26
21
|
private_class_method :method_c
|
|
27
22
|
|
|
28
23
|
end
|
|
@@ -20,8 +20,7 @@ RSpec.describe Mutant::Subject::Method::Instance do
|
|
|
20
20
|
@bar = :boo
|
|
21
21
|
end
|
|
22
22
|
|
|
23
|
-
def foo
|
|
24
|
-
end
|
|
23
|
+
def foo; end
|
|
25
24
|
|
|
26
25
|
def self.name
|
|
27
26
|
'Test'
|
|
@@ -84,8 +83,7 @@ RSpec.describe Mutant::Subject::Method::Instance::Memoized do
|
|
|
84
83
|
let(:scope) do
|
|
85
84
|
Class.new do
|
|
86
85
|
include Memoizable
|
|
87
|
-
def foo
|
|
88
|
-
end
|
|
86
|
+
def foo; end
|
|
89
87
|
memoize :foo
|
|
90
88
|
end
|
|
91
89
|
end
|
|
@@ -122,11 +120,6 @@ RSpec.describe Mutant::Subject::Method::Instance::Memoized do
|
|
|
122
120
|
object,
|
|
123
121
|
s(:begin,
|
|
124
122
|
s(:def, :foo, s(:args), nil), s(:send, nil, :memoize, s(:args, s(:sym, :foo))))
|
|
125
|
-
),
|
|
126
|
-
Mutant::Mutation::Evil.new(
|
|
127
|
-
object,
|
|
128
|
-
s(:begin,
|
|
129
|
-
s(:send, nil, :remove_method, s(:sym, :foo)), s(:send, nil, :memoize, s(:args, s(:sym, :foo))))
|
|
130
123
|
)
|
|
131
124
|
]
|
|
132
125
|
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.8.
|
|
4
|
+
version: 0.8.13
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Markus Schirp
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2017-06-01 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: parser
|
|
@@ -218,14 +218,14 @@ dependencies:
|
|
|
218
218
|
requirements:
|
|
219
219
|
- - "~>"
|
|
220
220
|
- !ruby/object:Gem::Version
|
|
221
|
-
version: 0.
|
|
221
|
+
version: 0.4.1
|
|
222
222
|
type: :runtime
|
|
223
223
|
prerelease: false
|
|
224
224
|
version_requirements: !ruby/object:Gem::Requirement
|
|
225
225
|
requirements:
|
|
226
226
|
- - "~>"
|
|
227
227
|
- !ruby/object:Gem::Version
|
|
228
|
-
version: 0.
|
|
228
|
+
version: 0.4.1
|
|
229
229
|
- !ruby/object:Gem::Dependency
|
|
230
230
|
name: devtools
|
|
231
231
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -284,6 +284,7 @@ files:
|
|
|
284
284
|
- ".ruby-gemset"
|
|
285
285
|
- Changelog.md
|
|
286
286
|
- Gemfile
|
|
287
|
+
- Gemfile.lock
|
|
287
288
|
- Gemfile.shared
|
|
288
289
|
- LICENSE
|
|
289
290
|
- README.md
|
|
@@ -658,6 +659,7 @@ files:
|
|
|
658
659
|
- test_app/.rspec
|
|
659
660
|
- test_app/Gemfile.rspec3.4
|
|
660
661
|
- test_app/Gemfile.rspec3.5
|
|
662
|
+
- test_app/Gemfile.rspec3.6
|
|
661
663
|
- test_app/lib/test_app.rb
|
|
662
664
|
- test_app/lib/test_app/literal.rb
|
|
663
665
|
- test_app/spec/spec_helper.rb
|
|
@@ -682,7 +684,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
682
684
|
version: '0'
|
|
683
685
|
requirements: []
|
|
684
686
|
rubyforge_project:
|
|
685
|
-
rubygems_version: 2.
|
|
687
|
+
rubygems_version: 2.6.11
|
|
686
688
|
signing_key:
|
|
687
689
|
specification_version: 4
|
|
688
690
|
summary: Mutation testing tool for ruby under MRI and Rubinius
|