mutant 0.5.12 → 0.5.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/Changelog.md +10 -0
- data/circle.yml +1 -1
- data/config/flay.yml +1 -1
- data/config/flog.yml +1 -1
- data/config/mutant.yml +1 -2
- data/config/reek.yml +12 -3
- data/config/rubocop.yml +4 -0
- data/lib/mutant.rb +45 -16
- data/lib/mutant/constants.rb +11 -11
- data/lib/mutant/delegator.rb +50 -0
- data/lib/mutant/{differ.rb → diff.rb} +5 -5
- data/lib/mutant/killer.rb +29 -106
- data/lib/mutant/matcher/method.rb +2 -11
- data/lib/mutant/mutation.rb +17 -3
- data/lib/mutant/mutation/evil.rb +2 -10
- data/lib/mutant/mutation/neutral.rb +4 -30
- data/lib/mutant/mutator/node/literal/fixnum.rb +0 -1
- data/lib/mutant/mutator/node/literal/float.rb +0 -1
- data/lib/mutant/mutator/node/literal/string.rb +0 -1
- data/lib/mutant/mutator/node/literal/symbol.rb +6 -2
- data/lib/mutant/mutator/node/named_value/variable_assignment.rb +8 -3
- data/lib/mutant/mutator/util/symbol.rb +3 -1
- data/lib/mutant/node_helpers.rb +1 -3
- data/lib/mutant/reporter.rb +10 -0
- data/lib/mutant/reporter/cli.rb +15 -2
- data/lib/mutant/reporter/cli/printer.rb +12 -105
- data/lib/mutant/reporter/cli/progress.rb +12 -0
- data/lib/mutant/reporter/cli/progress/config.rb +32 -0
- data/lib/mutant/reporter/cli/{printer/killer.rb → progress/mutation.rb} +9 -16
- data/lib/mutant/reporter/cli/progress/noop.rb +22 -0
- data/lib/mutant/reporter/cli/progress/subject.rb +118 -0
- data/lib/mutant/reporter/cli/registry.rb +77 -0
- data/lib/mutant/reporter/cli/report.rb +12 -0
- data/lib/mutant/reporter/cli/report/config.rb +118 -0
- data/lib/mutant/reporter/cli/report/mutation.rb +112 -0
- data/lib/mutant/reporter/cli/report/subject.rb +33 -0
- data/lib/mutant/reporter/null.rb +13 -0
- data/lib/mutant/reporter/trace.rb +41 -0
- data/lib/mutant/runner.rb +22 -20
- data/lib/mutant/runner/config.rb +6 -5
- data/lib/mutant/runner/killer.rb +59 -0
- data/lib/mutant/runner/mutation.rb +17 -10
- data/lib/mutant/runner/subject.rb +14 -4
- data/lib/mutant/strategy.rb +30 -16
- data/lib/mutant/subject/method/instance.rb +1 -1
- data/lib/mutant/test.rb +86 -0
- data/lib/mutant/version.rb +1 -1
- data/spec/integration/mutant/null_spec.rb +18 -0
- data/spec/integration/mutant/rspec_spec.rb +1 -1
- data/spec/spec_helper.rb +0 -2
- data/spec/unit/mutant/diff_spec.rb +162 -0
- data/spec/unit/mutant/mutation_spec.rb +8 -5
- data/spec/unit/mutant/mutator/node/and_asgn_spec.rb +1 -9
- data/spec/unit/mutant/mutator/node/block_spec.rb +6 -18
- data/spec/unit/mutant/mutator/node/case_spec.rb +10 -16
- data/spec/unit/mutant/mutator/node/define_spec.rb +5 -17
- data/spec/unit/mutant/mutator/node/dstr_spec.rb +0 -6
- data/spec/unit/mutant/mutator/node/dsym_spec.rb +0 -5
- data/spec/unit/mutant/mutator/node/if_spec.rb +13 -17
- data/spec/unit/mutant/mutator/node/literal/fixnum_spec.rb +1 -7
- data/spec/unit/mutant/mutator/node/literal/float_spec.rb +0 -9
- data/spec/unit/mutant/mutator/node/literal/range_spec.rb +0 -10
- data/spec/unit/mutant/mutator/node/literal/string_spec.rb +1 -5
- data/spec/unit/mutant/mutator/node/literal/symbol_spec.rb +1 -5
- data/spec/unit/mutant/mutator/node/named_value/access_spec.rb +4 -7
- data/spec/unit/mutant/mutator/node/named_value/constant_assignment_spec.rb +1 -5
- data/spec/unit/mutant/mutator/node/named_value/variable_assignment_spec.rb +4 -8
- data/spec/unit/mutant/mutator/node/op_assgn_spec.rb +0 -7
- data/spec/unit/mutant/mutator/node/or_asgn_spec.rb +1 -9
- data/spec/unit/mutant/mutator/node/rescue_spec.rb +0 -4
- data/spec/unit/mutant/reporter/null_spec.rb +11 -0
- data/spec/unit/mutant/runner/config_spec.rb +6 -7
- data/spec/unit/mutant/runner/mutation_spec.rb +101 -0
- data/spec/unit/mutant/runner/subject_spec.rb +10 -7
- data/spec/unit/mutant_spec.rb +53 -0
- metadata +65 -62
- data/lib/mutant/killer/forked.rb +0 -46
- data/lib/mutant/killer/forking.rb +0 -46
- data/lib/mutant/killer/static.rb +0 -34
- data/lib/mutant/mutator/node/literal/dynamic.rb +0 -27
- data/lib/mutant/random.rb +0 -38
- data/lib/mutant/reporter/cli/printer/config.rb +0 -154
- data/lib/mutant/reporter/cli/printer/mutation.rb +0 -103
- data/lib/mutant/reporter/cli/printer/subject.rb +0 -150
- data/spec/unit/mutant/differ/diff_spec.rb +0 -123
- data/spec/unit/mutant/differ_spec.rb +0 -42
- data/spec/unit/mutant/killer/success_predicate_spec.rb +0 -30
- data/spec/unit/mutant/rspec/killer_spec.rb +0 -57
- data/spec/unit/mutant/runner/mutation/killer_spec.rb +0 -44
@@ -1,150 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
module Mutant
|
4
|
-
class Reporter
|
5
|
-
class CLI
|
6
|
-
class Printer
|
7
|
-
|
8
|
-
# Subject results printer
|
9
|
-
class Subject < self
|
10
|
-
|
11
|
-
handle(Mutant::Subject)
|
12
|
-
|
13
|
-
# Run subject results printer
|
14
|
-
#
|
15
|
-
# @return [undefined]
|
16
|
-
#
|
17
|
-
# @api private
|
18
|
-
#
|
19
|
-
def run
|
20
|
-
info('%s', object.identification)
|
21
|
-
end
|
22
|
-
|
23
|
-
# Printer for subject runners
|
24
|
-
class Runner < self
|
25
|
-
|
26
|
-
handle(Mutant::Runner::Subject)
|
27
|
-
|
28
|
-
# Run printer
|
29
|
-
#
|
30
|
-
# @return [undefined]
|
31
|
-
#
|
32
|
-
# @api private
|
33
|
-
#
|
34
|
-
def run
|
35
|
-
print_progress_bar_finish
|
36
|
-
print_stats
|
37
|
-
self
|
38
|
-
end
|
39
|
-
|
40
|
-
private
|
41
|
-
|
42
|
-
# Return mutation time on subject
|
43
|
-
#
|
44
|
-
# @return [Float]
|
45
|
-
#
|
46
|
-
# @api private
|
47
|
-
#
|
48
|
-
def time
|
49
|
-
mutations.map(&:runtime).inject(0, :+)
|
50
|
-
end
|
51
|
-
|
52
|
-
# Return subject
|
53
|
-
#
|
54
|
-
# @return [Subject]
|
55
|
-
#
|
56
|
-
# @api private
|
57
|
-
#
|
58
|
-
def subject
|
59
|
-
object.subject
|
60
|
-
end
|
61
|
-
|
62
|
-
FORMAT = '(%02d/%02d) %3d%% - %0.02fs'.freeze
|
63
|
-
|
64
|
-
# Print stats
|
65
|
-
#
|
66
|
-
# @return [undefned
|
67
|
-
#
|
68
|
-
# @api private
|
69
|
-
#
|
70
|
-
def print_stats
|
71
|
-
status(FORMAT, amount_kills, amount_mutations, coverage, time)
|
72
|
-
end
|
73
|
-
|
74
|
-
# Print progress bar finish
|
75
|
-
#
|
76
|
-
# @return [undefined]
|
77
|
-
#
|
78
|
-
# @api private
|
79
|
-
#
|
80
|
-
def print_progress_bar_finish
|
81
|
-
puts unless amount_mutations.zero?
|
82
|
-
end
|
83
|
-
|
84
|
-
# Return kills
|
85
|
-
#
|
86
|
-
# @return [Fixnum]
|
87
|
-
#
|
88
|
-
# @api private
|
89
|
-
#
|
90
|
-
def amount_kills
|
91
|
-
fails = object.failed_mutations
|
92
|
-
fails = fails.length
|
93
|
-
amount_mutations - fails
|
94
|
-
end
|
95
|
-
|
96
|
-
# Return amount of mutations
|
97
|
-
#
|
98
|
-
# @return [Array<Mutation>]
|
99
|
-
#
|
100
|
-
# @api private
|
101
|
-
#
|
102
|
-
def amount_mutations
|
103
|
-
mutations.length
|
104
|
-
end
|
105
|
-
|
106
|
-
# Return mutations
|
107
|
-
#
|
108
|
-
# @return [Array<Mutation>]
|
109
|
-
#
|
110
|
-
# @api private
|
111
|
-
#
|
112
|
-
def mutations
|
113
|
-
object.mutations
|
114
|
-
end
|
115
|
-
|
116
|
-
# Return suject coverage
|
117
|
-
#
|
118
|
-
# @return [Float]
|
119
|
-
#
|
120
|
-
# @api private
|
121
|
-
#
|
122
|
-
def coverage
|
123
|
-
return 0 if amount_mutations.zero?
|
124
|
-
Rational(amount_kills, amount_mutations) * 100
|
125
|
-
end
|
126
|
-
|
127
|
-
# Detailed subject printer
|
128
|
-
class Details < self
|
129
|
-
|
130
|
-
# Run subject details printer
|
131
|
-
#
|
132
|
-
# @return [undefined]
|
133
|
-
#
|
134
|
-
# @api private
|
135
|
-
#
|
136
|
-
def run
|
137
|
-
puts(subject.identification)
|
138
|
-
object.failed_mutations.each do |mutation|
|
139
|
-
visit(mutation)
|
140
|
-
end
|
141
|
-
print_stats
|
142
|
-
end
|
143
|
-
|
144
|
-
end # Details
|
145
|
-
end # Runner
|
146
|
-
end # Subject
|
147
|
-
end # Printer
|
148
|
-
end # CLI
|
149
|
-
end # Reporter
|
150
|
-
end # Mutant
|
@@ -1,123 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
require 'spec_helper'
|
4
|
-
|
5
|
-
describe Mutant::Differ, '#diff' do
|
6
|
-
let(:object) { described_class.new(old, new) }
|
7
|
-
|
8
|
-
subject { object.diff }
|
9
|
-
|
10
|
-
context 'when there is a diff at begin of hunk' do
|
11
|
-
let(:old) { %w(foo bar) }
|
12
|
-
let(:new) { %w(baz bar) }
|
13
|
-
|
14
|
-
let(:expectation) do
|
15
|
-
strip_indent(<<-STR)
|
16
|
-
@@ -1,3 +1,3 @@
|
17
|
-
-foo
|
18
|
-
+baz
|
19
|
-
bar
|
20
|
-
STR
|
21
|
-
end
|
22
|
-
|
23
|
-
it { should eql(expectation) }
|
24
|
-
|
25
|
-
it_should_behave_like 'an idempotent method'
|
26
|
-
end
|
27
|
-
|
28
|
-
context 'when there is a diff NOT at begin of hunk' do
|
29
|
-
let(:old) { %w(foo bar) }
|
30
|
-
let(:new) { %w(foo baz bar) }
|
31
|
-
|
32
|
-
let(:expectation) do
|
33
|
-
strip_indent(<<-STR)
|
34
|
-
@@ -1,3 +1,4 @@
|
35
|
-
foo
|
36
|
-
+baz
|
37
|
-
bar
|
38
|
-
STR
|
39
|
-
end
|
40
|
-
|
41
|
-
it { should eql(expectation) }
|
42
|
-
|
43
|
-
it_should_behave_like 'an idempotent method'
|
44
|
-
end
|
45
|
-
|
46
|
-
context 'when the diff has a long context at begin' do
|
47
|
-
let(:old) { %w(foo bar baz boz a b c) }
|
48
|
-
let(:new) { %w(foo bar baz boz a b c other) }
|
49
|
-
|
50
|
-
let(:expectation) do
|
51
|
-
strip_indent(<<-STR)
|
52
|
-
@@ -1,8 +1,9 @@
|
53
|
-
foo
|
54
|
-
bar
|
55
|
-
baz
|
56
|
-
boz
|
57
|
-
a
|
58
|
-
b
|
59
|
-
c
|
60
|
-
+other
|
61
|
-
STR
|
62
|
-
end
|
63
|
-
|
64
|
-
it { should eql(expectation) }
|
65
|
-
|
66
|
-
it_should_behave_like 'an idempotent method'
|
67
|
-
end
|
68
|
-
|
69
|
-
context 'when the diff has a long context at end, deleting' do
|
70
|
-
let(:old) { %w(other foo bar baz boz a b c) }
|
71
|
-
let(:new) { %w(foo bar baz boz a b c) }
|
72
|
-
|
73
|
-
let(:expectation) do
|
74
|
-
strip_indent(<<-STR)
|
75
|
-
@@ -1,9 +1,8 @@
|
76
|
-
-other
|
77
|
-
foo
|
78
|
-
bar
|
79
|
-
baz
|
80
|
-
boz
|
81
|
-
a
|
82
|
-
b
|
83
|
-
c
|
84
|
-
STR
|
85
|
-
end
|
86
|
-
|
87
|
-
it { should eql(expectation) }
|
88
|
-
|
89
|
-
it_should_behave_like 'an idempotent method'
|
90
|
-
end
|
91
|
-
|
92
|
-
context 'when the diff has a long context at end, inserting' do
|
93
|
-
let(:old) { %w(foo bar baz boz a b c) }
|
94
|
-
let(:new) { %w(other foo bar baz boz a b c) }
|
95
|
-
|
96
|
-
let(:expectation) do
|
97
|
-
strip_indent(<<-STR)
|
98
|
-
@@ -1,8 +1,9 @@
|
99
|
-
+other
|
100
|
-
foo
|
101
|
-
bar
|
102
|
-
baz
|
103
|
-
boz
|
104
|
-
a
|
105
|
-
b
|
106
|
-
c
|
107
|
-
STR
|
108
|
-
end
|
109
|
-
|
110
|
-
it { should eql(expectation) }
|
111
|
-
|
112
|
-
it_should_behave_like 'an idempotent method'
|
113
|
-
end
|
114
|
-
|
115
|
-
context 'when there is no diff' do
|
116
|
-
let(:old) { '' }
|
117
|
-
let(:new) { '' }
|
118
|
-
|
119
|
-
it { should be(nil) }
|
120
|
-
|
121
|
-
it_should_behave_like 'an idempotent method'
|
122
|
-
end
|
123
|
-
end
|
@@ -1,42 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
require 'spec_helper'
|
4
|
-
|
5
|
-
describe Mutant::Differ do
|
6
|
-
let(:object) { described_class }
|
7
|
-
|
8
|
-
describe '.build' do
|
9
|
-
|
10
|
-
subject { object.build(old_string, new_string) }
|
11
|
-
|
12
|
-
let(:old_string) { "foo\nbar" }
|
13
|
-
let(:new_string) { "bar\nbaz" }
|
14
|
-
|
15
|
-
it { should eql(Mutant::Differ.new(%w(foo bar), %w(bar baz))) }
|
16
|
-
|
17
|
-
end
|
18
|
-
|
19
|
-
describe '.colorize_line' do
|
20
|
-
let(:object) { described_class }
|
21
|
-
|
22
|
-
subject { object.colorize_line(line) }
|
23
|
-
|
24
|
-
context 'line beginning with "+"' do
|
25
|
-
let(:line) { '+line' }
|
26
|
-
|
27
|
-
it { should eql(Mutant::Color::GREEN.format(line)) }
|
28
|
-
end
|
29
|
-
|
30
|
-
context 'line beginning with "-"' do
|
31
|
-
let(:line) { '-line' }
|
32
|
-
|
33
|
-
it { should eql(Mutant::Color::RED.format(line)) }
|
34
|
-
end
|
35
|
-
|
36
|
-
context 'line beginning in other char' do
|
37
|
-
let(:line) { ' line' }
|
38
|
-
|
39
|
-
it { should eql(line) }
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
@@ -1,30 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
require 'spec_helper'
|
4
|
-
|
5
|
-
describe Mutant::Killer, '#success?' do
|
6
|
-
subject { object.success? }
|
7
|
-
|
8
|
-
let(:object) { class_under_test.new(strategy, mutation) }
|
9
|
-
let(:strategy) { double('Strategy') }
|
10
|
-
let(:mutation) { double('Mutation', success?: kill_state) }
|
11
|
-
let(:kill_state) { double('Kill State') }
|
12
|
-
|
13
|
-
before do
|
14
|
-
kill_state.stub(freeze: kill_state, dup: kill_state)
|
15
|
-
end
|
16
|
-
|
17
|
-
let(:class_under_test) do
|
18
|
-
Class.new(described_class) do
|
19
|
-
def run
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
it_should_behave_like 'an idempotent method'
|
25
|
-
|
26
|
-
it 'should use kill state to gather success' do
|
27
|
-
mutation.should_receive(:success?).with(object).and_return(kill_state)
|
28
|
-
should be(kill_state)
|
29
|
-
end
|
30
|
-
end
|
@@ -1,57 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
require 'spec_helper'
|
4
|
-
require 'mutant-rspec'
|
5
|
-
|
6
|
-
describe Mutant::Rspec::Killer, '.new' do
|
7
|
-
|
8
|
-
before do
|
9
|
-
pending 'dactivated'
|
10
|
-
end
|
11
|
-
|
12
|
-
subject { object.new(strategy, mutation) }
|
13
|
-
|
14
|
-
let(:context) { double('Context') }
|
15
|
-
let(:mutation_subject) { double('Mutation Subject') }
|
16
|
-
|
17
|
-
let(:object) { described_class }
|
18
|
-
|
19
|
-
let(:mutation) do
|
20
|
-
double(
|
21
|
-
'Mutation',
|
22
|
-
subject: mutation_subject,
|
23
|
-
should_survive?: false
|
24
|
-
)
|
25
|
-
end
|
26
|
-
|
27
|
-
let(:strategy) do
|
28
|
-
double(
|
29
|
-
'Strategy',
|
30
|
-
spec_files: ['foo'],
|
31
|
-
error_stream: $stderr,
|
32
|
-
output_stream: $stdout
|
33
|
-
)
|
34
|
-
end
|
35
|
-
|
36
|
-
before do
|
37
|
-
mutation.stub(:insert)
|
38
|
-
mutation.stub(:reset)
|
39
|
-
RSpec::Core::Runner.stub(run: exit_status)
|
40
|
-
end
|
41
|
-
|
42
|
-
context 'when run exits zero' do
|
43
|
-
let(:exit_status) { 0 }
|
44
|
-
|
45
|
-
it { expect(subject.killed?).to be(false) }
|
46
|
-
|
47
|
-
it { should be_a(described_class) }
|
48
|
-
end
|
49
|
-
|
50
|
-
context 'when run exits nonzero' do
|
51
|
-
let(:exit_status) { 1 }
|
52
|
-
|
53
|
-
it { expect(subject.killed?).to be(true) }
|
54
|
-
|
55
|
-
it { should be_a(described_class) }
|
56
|
-
end
|
57
|
-
end
|
@@ -1,44 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
require 'spec_helper'
|
4
|
-
|
5
|
-
describe Mutant::Runner::Mutation, '#killer' do
|
6
|
-
let(:object) { described_class.run(config, mutation) }
|
7
|
-
|
8
|
-
let(:config) do
|
9
|
-
double(
|
10
|
-
'Config',
|
11
|
-
fail_fast: fail_fast,
|
12
|
-
reporter: reporter,
|
13
|
-
strategy: strategy
|
14
|
-
)
|
15
|
-
end
|
16
|
-
|
17
|
-
let(:reporter) { double('Reporter') }
|
18
|
-
let(:mutation) { double('Mutation', class: Mutant::Mutation) }
|
19
|
-
let(:strategy) { double('Strategy') }
|
20
|
-
let(:killer) { double('Killer', success?: success) }
|
21
|
-
let(:fail_fast) { false }
|
22
|
-
let(:success) { false }
|
23
|
-
|
24
|
-
subject { object.killer }
|
25
|
-
|
26
|
-
before do
|
27
|
-
reporter.stub(report: reporter)
|
28
|
-
strategy.stub(kill: killer)
|
29
|
-
end
|
30
|
-
|
31
|
-
it 'should call configuration to identify strategy' do
|
32
|
-
config.should_receive(:strategy).with(no_args).and_return(strategy)
|
33
|
-
should be(killer)
|
34
|
-
end
|
35
|
-
|
36
|
-
it 'should run killer' do
|
37
|
-
strategy.should_receive(:kill).with(mutation).and_return(killer)
|
38
|
-
should be(killer)
|
39
|
-
end
|
40
|
-
|
41
|
-
it { should be(killer) }
|
42
|
-
|
43
|
-
it_should_behave_like 'an idempotent method'
|
44
|
-
end
|