mutest 0.0.6 → 0.0.7
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/.buildkite/hooks/pre-command +1 -1
- data/.buildkite/pipeline.yml +9 -22
- data/.gitmodules +3 -0
- data/CHANGELOG.md +14 -1
- data/Gemfile +11 -6
- data/Gemfile.lock +27 -101
- data/README.md +42 -2
- data/Rakefile +2 -8
- data/circle.yml +4 -1
- data/lib/mutest.rb +1 -1
- data/lib/mutest/ast/meta/send.rb +6 -0
- data/lib/mutest/ast/named_children.rb +1 -1
- data/lib/mutest/ast/nodes.rb +0 -2
- data/lib/mutest/ast/regexp.rb +4 -4
- data/lib/mutest/ast/regexp/transformer.rb +4 -4
- data/lib/mutest/ast/regexp/transformer/character_set.rb +1 -1
- data/lib/mutest/ast/regexp/transformer/direct.rb +1 -1
- data/lib/mutest/ast/regexp/transformer/quantifier.rb +3 -3
- data/lib/mutest/ast/regexp/transformer/recursive.rb +1 -1
- data/lib/mutest/ast/regexp/transformer/text.rb +1 -1
- data/lib/mutest/ast/types.rb +0 -1
- data/lib/mutest/cli.rb +1 -1
- data/lib/mutest/context.rb +1 -1
- data/lib/mutest/matcher/config.rb +0 -2
- data/lib/mutest/matcher/method.rb +1 -3
- data/lib/mutest/matcher/method/instance.rb +1 -1
- data/lib/mutest/matcher/methods.rb +1 -1
- data/lib/mutest/mutator.rb +0 -2
- data/lib/mutest/mutator/node/block_pass.rb +29 -0
- data/lib/mutest/mutator/node/generic.rb +1 -0
- data/lib/mutest/mutator/node/literal/boolean.rb +0 -1
- data/lib/mutest/mutator/node/literal/range.rb +1 -1
- data/lib/mutest/mutator/node/literal/regex.rb +1 -1
- data/lib/mutest/mutator/node/literal/string.rb +3 -0
- data/lib/mutest/mutator/node/literal/symbol.rb +0 -2
- data/lib/mutest/mutator/node/send.rb +35 -6
- data/lib/mutest/mutator/node/splat.rb +3 -1
- data/lib/mutest/parallel/worker.rb +1 -1
- data/lib/mutest/reporter/cli.rb +0 -2
- data/lib/mutest/reporter/cli/format.rb +1 -1
- data/lib/mutest/reporter/cli/printer.rb +2 -2
- data/lib/mutest/reporter/cli/printer/mutation_result.rb +0 -2
- data/lib/mutest/version.rb +1 -1
- data/meta/and.rb +0 -2
- data/meta/array.rb +0 -3
- data/meta/begin.rb +0 -3
- data/meta/block.rb +0 -1
- data/meta/block_pass.rb +30 -1
- data/meta/break.rb +0 -1
- data/meta/case.rb +0 -6
- data/meta/casgn.rb +0 -3
- data/meta/cvasgn.rb +0 -1
- data/meta/def.rb +0 -7
- data/meta/dstr.rb +2 -0
- data/meta/dsym.rb +2 -0
- data/meta/ensure.rb +0 -1
- data/meta/false.rb +0 -1
- data/meta/gvasgn.rb +0 -1
- data/meta/hash.rb +0 -4
- data/meta/if.rb +0 -5
- data/meta/ivasgn.rb +0 -1
- data/meta/kwbegin.rb +0 -1
- data/meta/lvasgn.rb +0 -1
- data/meta/match_current_line.rb +0 -1
- data/meta/next.rb +0 -1
- data/meta/or.rb +0 -2
- data/meta/regexp.rb +0 -1
- data/meta/rescue.rb +0 -6
- data/meta/send.rb +60 -16
- data/meta/splat.rb +25 -0
- data/meta/str.rb +1 -0
- data/meta/true.rb +0 -1
- data/meta/until.rb +0 -1
- data/meta/while.rb +0 -2
- data/meta/yield.rb +0 -1
- data/mutest-rspec.gemspec +1 -1
- data/mutest.gemspec +0 -4
- data/spec/integration/mutest/rspec_spec.rb +1 -1
- data/spec/integrations.yml +1 -1
- data/spec/shared/command_method_behavior.rb +5 -0
- data/spec/shared/idempotent_method_behavior.rb +10 -0
- data/spec/spec_helper.rb +21 -1
- data/spec/support/xspec.rb +1 -1
- data/spec/unit/mutest/actor/sender_spec.rb +1 -1
- data/spec/unit/mutest/ast/meta/send_spec.rb +23 -11
- data/spec/unit/mutest/cli_spec.rb +13 -13
- data/spec/unit/mutest/context_spec.rb +2 -2
- data/spec/unit/mutest/diff_spec.rb +9 -9
- data/spec/unit/mutest/integration/null_spec.rb +1 -1
- data/spec/unit/mutest/integration_spec.rb +1 -1
- data/spec/unit/mutest/matcher/method/instance_spec.rb +5 -5
- data/spec/unit/mutest/matcher/method/singleton_spec.rb +5 -5
- data/spec/unit/mutest/meta/example_spec.rb +3 -3
- data/spec/unit/mutest/mutation_spec.rb +5 -5
- data/spec/unit/mutest/mutator/node_spec.rb +6 -9
- data/spec/unit/mutest/parallel/driver_spec.rb +1 -1
- data/spec/unit/mutest/reporter/null_spec.rb +1 -1
- data/spec/unit/mutest/reporter/sequence_spec.rb +1 -1
- data/spec/unit/mutest/result_spec.rb +1 -1
- data/spec/unit/mutest/runner/sink_spec.rb +1 -1
- data/spec/unit/mutest/subject/method/instance/memoized_spec.rb +1 -1
- data/spec/unit/mutest/subject/method/instance_spec.rb +3 -3
- data/spec/unit/mutest/subject/method/singleton_spec.rb +3 -3
- data/spec/unit/mutest/subject_spec.rb +2 -2
- data/test_app/Gemfile.rspec3.6 +7 -0
- metadata +9 -57
- data/build/Dockerfile +0 -71
- data/build/docker-bootstrap.sh +0 -85
- data/build/docker-exec +0 -29
- data/build/make-docker +0 -3
- data/build/ruby_matrix +0 -1
- data/build/run +0 -5
- data/build/strict-mode.sh +0 -16
- data/config/devtools.yml +0 -2
- data/config/flay.yml +0 -3
- data/config/flog.yml +0 -2
- data/config/reek.yml +0 -137
- data/lib/mutest/mutator/node/noop.rb +0 -19
@@ -87,14 +87,14 @@ RSpec.describe Mutest::Matcher::Method::Instance, '#call' do
|
|
87
87
|
let(:scope) { base::WithMemoizer }
|
88
88
|
let(:method_line) { 13 }
|
89
89
|
|
90
|
-
|
90
|
+
it_behaves_like 'a method matcher'
|
91
91
|
end
|
92
92
|
|
93
93
|
context 'when method is defined once with a memoizer' do
|
94
94
|
let(:scope) { base::WithMemoizer }
|
95
95
|
let(:method_line) { 15 }
|
96
96
|
|
97
|
-
|
97
|
+
it_behaves_like 'a method matcher'
|
98
98
|
end
|
99
99
|
|
100
100
|
context 'when method is defined multiple times' do
|
@@ -103,7 +103,7 @@ RSpec.describe Mutest::Matcher::Method::Instance, '#call' do
|
|
103
103
|
let(:method_line) { 24 }
|
104
104
|
let(:method_arity) { 1 }
|
105
105
|
|
106
|
-
|
106
|
+
it_behaves_like 'a method matcher'
|
107
107
|
end
|
108
108
|
|
109
109
|
context 'on the same line' do
|
@@ -111,7 +111,7 @@ RSpec.describe Mutest::Matcher::Method::Instance, '#call' do
|
|
111
111
|
let(:method_line) { 29 }
|
112
112
|
let(:method_arity) { 1 }
|
113
113
|
|
114
|
-
|
114
|
+
it_behaves_like 'a method matcher'
|
115
115
|
end
|
116
116
|
|
117
117
|
context 'on the same line with different scope' do
|
@@ -119,7 +119,7 @@ RSpec.describe Mutest::Matcher::Method::Instance, '#call' do
|
|
119
119
|
let(:method_line) { 33 }
|
120
120
|
let(:method_arity) { 1 }
|
121
121
|
|
122
|
-
|
122
|
+
it_behaves_like 'a method matcher'
|
123
123
|
end
|
124
124
|
end
|
125
125
|
end
|
@@ -47,7 +47,7 @@ RSpec.describe Mutest::Matcher::Method::Singleton, '#call' do
|
|
47
47
|
let(:scope) { base::DefinedOnSelf }
|
48
48
|
let(:method_line) { 61 }
|
49
49
|
|
50
|
-
|
50
|
+
it_behaves_like 'a method matcher'
|
51
51
|
end
|
52
52
|
|
53
53
|
context 'when defined on constant' do
|
@@ -55,14 +55,14 @@ RSpec.describe Mutest::Matcher::Method::Singleton, '#call' do
|
|
55
55
|
let(:scope) { base::DefinedOnConstant::InsideNamespace }
|
56
56
|
let(:method_line) { 71 }
|
57
57
|
|
58
|
-
|
58
|
+
it_behaves_like 'a method matcher'
|
59
59
|
end
|
60
60
|
|
61
61
|
context 'outside namespace' do
|
62
62
|
let(:scope) { base::DefinedOnConstant::OutsideNamespace }
|
63
63
|
let(:method_line) { 78 }
|
64
64
|
|
65
|
-
|
65
|
+
it_behaves_like 'a method matcher'
|
66
66
|
end
|
67
67
|
end
|
68
68
|
|
@@ -72,14 +72,14 @@ RSpec.describe Mutest::Matcher::Method::Singleton, '#call' do
|
|
72
72
|
let(:method_line) { 97 }
|
73
73
|
let(:method_arity) { 1 }
|
74
74
|
|
75
|
-
|
75
|
+
it_behaves_like 'a method matcher'
|
76
76
|
end
|
77
77
|
|
78
78
|
context 'with different name' do
|
79
79
|
let(:scope) { base::DefinedMultipleTimes::SameLine::DifferentName }
|
80
80
|
let(:method_line) { 101 }
|
81
81
|
|
82
|
-
|
82
|
+
it_behaves_like 'a method matcher'
|
83
83
|
end
|
84
84
|
end
|
85
85
|
end
|
@@ -8,9 +8,9 @@ RSpec.describe Mutest::Meta::Example do
|
|
8
8
|
)
|
9
9
|
end
|
10
10
|
|
11
|
-
let(:file) { 'foo/bar.rb'
|
12
|
-
let(:node) { s(:true)
|
13
|
-
let(:mutation_nodes) { [s(:
|
11
|
+
let(:file) { 'foo/bar.rb' }
|
12
|
+
let(:node) { s(:true) }
|
13
|
+
let(:mutation_nodes) { [s(:false)] }
|
14
14
|
|
15
15
|
let(:mutations) do
|
16
16
|
mutation_nodes.map do |node|
|
@@ -47,7 +47,7 @@ RSpec.describe Mutest::Mutation do
|
|
47
47
|
.and_return(Mutest::Loader)
|
48
48
|
end
|
49
49
|
|
50
|
-
|
50
|
+
it_behaves_like 'a command method'
|
51
51
|
end
|
52
52
|
|
53
53
|
describe '#code' do
|
@@ -55,7 +55,7 @@ RSpec.describe Mutest::Mutation do
|
|
55
55
|
|
56
56
|
it { is_expected.to eql('8771a') }
|
57
57
|
|
58
|
-
|
58
|
+
it_behaves_like 'an idempotent method'
|
59
59
|
end
|
60
60
|
|
61
61
|
describe '#original_source' do
|
@@ -63,7 +63,7 @@ RSpec.describe Mutest::Mutation do
|
|
63
63
|
|
64
64
|
it { is_expected.to eql('original') }
|
65
65
|
|
66
|
-
|
66
|
+
it_behaves_like 'an idempotent method'
|
67
67
|
end
|
68
68
|
|
69
69
|
describe '#source' do
|
@@ -71,7 +71,7 @@ RSpec.describe Mutest::Mutation do
|
|
71
71
|
|
72
72
|
it { is_expected.to eql('nil') }
|
73
73
|
|
74
|
-
|
74
|
+
it_behaves_like 'an idempotent method'
|
75
75
|
end
|
76
76
|
|
77
77
|
describe '.success?' do
|
@@ -124,6 +124,6 @@ RSpec.describe Mutest::Mutation do
|
|
124
124
|
|
125
125
|
it { is_expected.to eql('test:subject:8771a') }
|
126
126
|
|
127
|
-
|
127
|
+
it_behaves_like 'an idempotent method'
|
128
128
|
end
|
129
129
|
end
|
@@ -20,9 +20,8 @@ RSpec.describe Mutest::Mutator::Node do
|
|
20
20
|
def dispatch
|
21
21
|
left
|
22
22
|
emit_left(s(:nil))
|
23
|
-
|
24
|
-
|
25
|
-
end
|
23
|
+
emit_left_mutations
|
24
|
+
emit_right_mutations { false }
|
26
25
|
end
|
27
26
|
end
|
28
27
|
end
|
@@ -32,12 +31,10 @@ RSpec.describe Mutest::Mutator::Node do
|
|
32
31
|
end
|
33
32
|
|
34
33
|
specify do
|
35
|
-
expect(apply).to eql(
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
].to_set
|
40
|
-
)
|
34
|
+
expect(apply).to eql([
|
35
|
+
s(:and, s(:nil), s(:true)),
|
36
|
+
s(:and, s(:false), s(:true))
|
37
|
+
].to_set)
|
41
38
|
end
|
42
39
|
end
|
43
40
|
end
|
@@ -36,7 +36,7 @@ RSpec.describe Mutest::Subject::Method::Instance::Memoized do
|
|
36
36
|
expect { subject }.to change { scope.instance_methods.include?(:foo) }.from(true).to(false)
|
37
37
|
end
|
38
38
|
|
39
|
-
|
39
|
+
it_behaves_like 'a command method'
|
40
40
|
end
|
41
41
|
|
42
42
|
describe '#mutations', mutest_expression: 'Mutest::Subject#mutations' do
|
@@ -31,7 +31,7 @@ RSpec.describe Mutest::Subject::Method::Instance do
|
|
31
31
|
|
32
32
|
it { is_expected.to eql(parse_expression('Test#foo')) }
|
33
33
|
|
34
|
-
|
34
|
+
it_behaves_like 'an idempotent method'
|
35
35
|
end
|
36
36
|
|
37
37
|
describe '#match_expression' do
|
@@ -39,7 +39,7 @@ RSpec.describe Mutest::Subject::Method::Instance do
|
|
39
39
|
|
40
40
|
it { is_expected.to eql(%w[Test#foo Test*].map(&method(:parse_expression))) }
|
41
41
|
|
42
|
-
|
42
|
+
it_behaves_like 'an idempotent method'
|
43
43
|
end
|
44
44
|
|
45
45
|
describe '#prepare' do
|
@@ -53,7 +53,7 @@ RSpec.describe Mutest::Subject::Method::Instance do
|
|
53
53
|
expect { subject }.to change { scope.instance_methods.include?(:foo) }.from(true).to(false)
|
54
54
|
end
|
55
55
|
|
56
|
-
|
56
|
+
it_behaves_like 'a command method'
|
57
57
|
end
|
58
58
|
|
59
59
|
describe '#source' do
|
@@ -22,7 +22,7 @@ RSpec.describe Mutest::Subject::Method::Singleton do
|
|
22
22
|
|
23
23
|
it { is_expected.to eql(parse_expression('Test.foo')) }
|
24
24
|
|
25
|
-
|
25
|
+
it_behaves_like 'an idempotent method'
|
26
26
|
end
|
27
27
|
|
28
28
|
describe '#match_expression' do
|
@@ -30,7 +30,7 @@ RSpec.describe Mutest::Subject::Method::Singleton do
|
|
30
30
|
|
31
31
|
it { is_expected.to eql(%w[Test.foo Test*].map(&method(:parse_expression))) }
|
32
32
|
|
33
|
-
|
33
|
+
it_behaves_like 'an idempotent method'
|
34
34
|
end
|
35
35
|
|
36
36
|
describe '#prepare' do
|
@@ -40,7 +40,7 @@ RSpec.describe Mutest::Subject::Method::Singleton do
|
|
40
40
|
expect { subject }.to change { scope.methods.include?(:foo) }.from(true).to(false)
|
41
41
|
end
|
42
42
|
|
43
|
-
|
43
|
+
it_behaves_like 'a command method'
|
44
44
|
end
|
45
45
|
|
46
46
|
describe '#source' do
|
@@ -52,7 +52,7 @@ RSpec.describe Mutest::Subject do
|
|
52
52
|
describe '#prepare' do
|
53
53
|
subject { object.prepare }
|
54
54
|
|
55
|
-
|
55
|
+
it_behaves_like 'a command method'
|
56
56
|
end
|
57
57
|
|
58
58
|
describe '#node' do
|
@@ -60,7 +60,7 @@ RSpec.describe Mutest::Subject do
|
|
60
60
|
|
61
61
|
it { is_expected.to be(node) }
|
62
62
|
|
63
|
-
|
63
|
+
it_behaves_like 'an idempotent method'
|
64
64
|
end
|
65
65
|
|
66
66
|
describe '#mutations' do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mutest
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daniel Gollahon
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2017-
|
12
|
+
date: 2017-06-18 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: parser
|
@@ -227,48 +227,6 @@ dependencies:
|
|
227
227
|
- - "~>"
|
228
228
|
- !ruby/object:Gem::Version
|
229
229
|
version: 0.4.1
|
230
|
-
- !ruby/object:Gem::Dependency
|
231
|
-
name: rubocop-rspec
|
232
|
-
requirement: !ruby/object:Gem::Requirement
|
233
|
-
requirements:
|
234
|
-
- - "~>"
|
235
|
-
- !ruby/object:Gem::Version
|
236
|
-
version: 1.10.0
|
237
|
-
type: :development
|
238
|
-
prerelease: false
|
239
|
-
version_requirements: !ruby/object:Gem::Requirement
|
240
|
-
requirements:
|
241
|
-
- - "~>"
|
242
|
-
- !ruby/object:Gem::Version
|
243
|
-
version: 1.10.0
|
244
|
-
- !ruby/object:Gem::Dependency
|
245
|
-
name: devtools
|
246
|
-
requirement: !ruby/object:Gem::Requirement
|
247
|
-
requirements:
|
248
|
-
- - "~>"
|
249
|
-
- !ruby/object:Gem::Version
|
250
|
-
version: 0.1.16
|
251
|
-
type: :development
|
252
|
-
prerelease: false
|
253
|
-
version_requirements: !ruby/object:Gem::Requirement
|
254
|
-
requirements:
|
255
|
-
- - "~>"
|
256
|
-
- !ruby/object:Gem::Version
|
257
|
-
version: 0.1.16
|
258
|
-
- !ruby/object:Gem::Dependency
|
259
|
-
name: bundler
|
260
|
-
requirement: !ruby/object:Gem::Requirement
|
261
|
-
requirements:
|
262
|
-
- - "~>"
|
263
|
-
- !ruby/object:Gem::Version
|
264
|
-
version: '1.10'
|
265
|
-
type: :development
|
266
|
-
prerelease: false
|
267
|
-
version_requirements: !ruby/object:Gem::Requirement
|
268
|
-
requirements:
|
269
|
-
- - "~>"
|
270
|
-
- !ruby/object:Gem::Version
|
271
|
-
version: '1.10'
|
272
230
|
description: Mutation testing for ruby
|
273
231
|
email:
|
274
232
|
- johncbackus@gmail.com
|
@@ -283,6 +241,7 @@ files:
|
|
283
241
|
- ".buildkite/pipeline.yml"
|
284
242
|
- ".gitattributes"
|
285
243
|
- ".gitignore"
|
244
|
+
- ".gitmodules"
|
286
245
|
- ".rspec"
|
287
246
|
- CHANGELOG.md
|
288
247
|
- Gemfile
|
@@ -292,18 +251,7 @@ files:
|
|
292
251
|
- README.md
|
293
252
|
- Rakefile
|
294
253
|
- bin/mutest
|
295
|
-
- build/Dockerfile
|
296
|
-
- build/docker-bootstrap.sh
|
297
|
-
- build/docker-exec
|
298
|
-
- build/make-docker
|
299
|
-
- build/ruby_matrix
|
300
|
-
- build/run
|
301
|
-
- build/strict-mode.sh
|
302
254
|
- circle.yml
|
303
|
-
- config/devtools.yml
|
304
|
-
- config/flay.yml
|
305
|
-
- config/flog.yml
|
306
|
-
- config/reek.yml
|
307
255
|
- config/rubocop.yml
|
308
256
|
- config/triage.yml
|
309
257
|
- config/yardstick.yml
|
@@ -380,6 +328,7 @@ files:
|
|
380
328
|
- lib/mutest/mutator/node/begin.rb
|
381
329
|
- lib/mutest/mutator/node/binary.rb
|
382
330
|
- lib/mutest/mutator/node/block.rb
|
331
|
+
- lib/mutest/mutator/node/block_pass.rb
|
383
332
|
- lib/mutest/mutator/node/break.rb
|
384
333
|
- lib/mutest/mutator/node/case.rb
|
385
334
|
- lib/mutest/mutator/node/class.rb
|
@@ -410,7 +359,6 @@ files:
|
|
410
359
|
- lib/mutest/mutator/node/named_value/constant_assignment.rb
|
411
360
|
- lib/mutest/mutator/node/named_value/variable_assignment.rb
|
412
361
|
- lib/mutest/mutator/node/next.rb
|
413
|
-
- lib/mutest/mutator/node/noop.rb
|
414
362
|
- lib/mutest/mutator/node/nthref.rb
|
415
363
|
- lib/mutest/mutator/node/op_asgn.rb
|
416
364
|
- lib/mutest/mutator/node/or_asgn.rb
|
@@ -546,6 +494,7 @@ files:
|
|
546
494
|
- meta/return.rb
|
547
495
|
- meta/self.rb
|
548
496
|
- meta/send.rb
|
497
|
+
- meta/splat.rb
|
549
498
|
- meta/str.rb
|
550
499
|
- meta/super.rb
|
551
500
|
- meta/sym.rb
|
@@ -562,7 +511,9 @@ files:
|
|
562
511
|
- spec/integration/mutest/test_mutator_handles_types_spec.rb
|
563
512
|
- spec/integrations.yml
|
564
513
|
- spec/rcov.opts
|
514
|
+
- spec/shared/command_method_behavior.rb
|
565
515
|
- spec/shared/framework_integration_behavior.rb
|
516
|
+
- spec/shared/idempotent_method_behavior.rb
|
566
517
|
- spec/shared/method_matcher_behavior.rb
|
567
518
|
- spec/spec_helper.rb
|
568
519
|
- spec/support/compress_helper.rb
|
@@ -676,6 +627,7 @@ files:
|
|
676
627
|
- test_app/.rspec
|
677
628
|
- test_app/Gemfile.rspec3.4
|
678
629
|
- test_app/Gemfile.rspec3.5
|
630
|
+
- test_app/Gemfile.rspec3.6
|
679
631
|
- test_app/lib/test_app.rb
|
680
632
|
- test_app/lib/test_app/literal.rb
|
681
633
|
- test_app/spec/spec_helper.rb
|
@@ -700,7 +652,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
700
652
|
version: '0'
|
701
653
|
requirements: []
|
702
654
|
rubyforge_project:
|
703
|
-
rubygems_version: 2.6.
|
655
|
+
rubygems_version: 2.6.11
|
704
656
|
signing_key:
|
705
657
|
specification_version: 4
|
706
658
|
summary: Mutation testing for ruby
|