mutant 0.5.24 → 0.5.25
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Changelog.md +8 -0
- data/config/flay.yml +1 -1
- data/config/flog.yml +1 -1
- data/config/reek.yml +15 -13
- data/lib/mutant.rb +28 -12
- data/lib/mutant/ast/meta.rb +0 -10
- data/lib/mutant/ast/named_children.rb +1 -0
- data/lib/mutant/ast/types.rb +5 -5
- data/lib/mutant/cli.rb +84 -64
- data/lib/mutant/config.rb +7 -39
- data/lib/mutant/delegator.rb +2 -0
- data/lib/mutant/env.rb +119 -16
- data/lib/mutant/expression.rb +8 -2
- data/lib/mutant/expression/method.rb +6 -16
- data/lib/mutant/expression/methods.rb +5 -5
- data/lib/mutant/expression/namespace.rb +7 -7
- data/lib/mutant/integration.rb +0 -10
- data/lib/mutant/isolation.rb +41 -15
- data/lib/mutant/matcher/chain.rb +1 -17
- data/lib/mutant/matcher/compiler.rb +108 -0
- data/lib/mutant/matcher/config.rb +28 -0
- data/lib/mutant/matcher/method.rb +1 -1
- data/lib/mutant/matcher/namespace.rb +5 -52
- data/lib/mutant/matcher/null.rb +1 -1
- data/lib/mutant/matcher/scope.rb +1 -1
- data/lib/mutant/mutation.rb +29 -13
- data/lib/mutant/mutator/node.rb +2 -12
- data/lib/mutant/mutator/node/named_value/variable_assignment.rb +1 -1
- data/lib/mutant/reporter/cli.rb +0 -2
- data/lib/mutant/reporter/cli/printer.rb +14 -0
- data/lib/mutant/reporter/cli/progress.rb +1 -3
- data/lib/mutant/reporter/cli/progress/config.rb +5 -9
- data/lib/mutant/reporter/cli/progress/env.rb +30 -0
- data/lib/mutant/reporter/cli/progress/noop.rb +4 -1
- data/lib/mutant/reporter/cli/progress/result.rb +12 -0
- data/lib/mutant/reporter/cli/progress/result/mutation.rb +45 -0
- data/lib/mutant/reporter/cli/progress/result/subject.rb +54 -0
- data/lib/mutant/reporter/cli/progress/subject.rb +7 -90
- data/lib/mutant/reporter/cli/registry.rb +2 -0
- data/lib/mutant/reporter/cli/report/env.rb +92 -0
- data/lib/mutant/reporter/cli/report/mutation.rb +58 -77
- data/lib/mutant/reporter/cli/report/subject.rb +4 -3
- data/lib/mutant/reporter/cli/report/test.rb +28 -0
- data/lib/mutant/reporter/null.rb +1 -1
- data/lib/mutant/reporter/trace.rb +16 -3
- data/lib/mutant/result.rb +302 -0
- data/lib/mutant/runner.rb +77 -123
- data/lib/mutant/subject.rb +32 -16
- data/lib/mutant/subject/method.rb +0 -15
- data/lib/mutant/subject/method/instance.rb +3 -3
- data/lib/mutant/version.rb +1 -1
- data/lib/mutant/warning_expectation.rb +12 -5
- data/spec/integration/mutant/corpus_spec.rb +1 -1
- data/spec/spec_helper.rb +5 -1
- data/spec/unit/mutant/cli_spec.rb +248 -0
- data/spec/unit/mutant/expression/namespace/flat_spec.rb +1 -1
- data/spec/unit/mutant/expression_spec.rb +55 -0
- data/spec/unit/mutant/integration_spec.rb +0 -5
- data/spec/unit/mutant/isolation_spec.rb +36 -5
- data/spec/unit/mutant/matcher/chain_spec.rb +1 -13
- data/spec/unit/mutant/matcher/compiler_spec.rb +95 -0
- data/spec/unit/mutant/matcher/filter_spec.rb +31 -0
- data/spec/unit/mutant/matcher/method/instance_spec.rb +33 -2
- data/spec/unit/mutant/matcher/method/singleton_spec.rb +1 -1
- data/spec/unit/mutant/matcher/methods/instance_spec.rb +1 -1
- data/spec/unit/mutant/matcher/methods/singleton_spec.rb +1 -1
- data/spec/unit/mutant/matcher/namespace_spec.rb +10 -6
- data/spec/unit/mutant/matcher/null_spec.rb +26 -0
- data/spec/unit/mutant/reporter/cli_spec.rb +337 -0
- data/spec/unit/mutant/reporter/null_spec.rb +12 -0
- data/spec/unit/mutant/runner_spec.rb +130 -0
- data/spec/unit/mutant/subject/context_spec.rb +4 -3
- data/spec/unit/mutant/subject/method/instance_spec.rb +5 -3
- data/spec/unit/mutant/subject/method/singleton_spec.rb +3 -2
- data/spec/unit/mutant/subject_spec.rb +36 -1
- data/spec/unit/mutant/test_spec.rb +25 -0
- data/spec/unit/mutant/warning_expectation.rb +11 -8
- data/spec/unit/mutant_spec.rb +11 -2
- metadata +27 -28
- data/lib/mutant/killer.rb +0 -44
- data/lib/mutant/matcher/builder.rb +0 -142
- data/lib/mutant/mutation/evil.rb +0 -23
- data/lib/mutant/mutation/neutral.rb +0 -18
- data/lib/mutant/reporter/cli/progress/mutation.rb +0 -46
- data/lib/mutant/reporter/cli/report/config.rb +0 -116
- data/lib/mutant/rspec.rb +0 -0
- data/lib/mutant/runner/config.rb +0 -138
- data/lib/mutant/runner/killer.rb +0 -75
- data/lib/mutant/runner/mutation.rb +0 -78
- data/lib/mutant/runner/subject.rb +0 -85
- data/lib/mutant/test/report.rb +0 -59
- data/spec/unit/mutant/cli_new_spec.rb +0 -147
- data/spec/unit/mutant/cli_run_spec.rb +0 -46
- data/spec/unit/mutant/runner/config_spec.rb +0 -157
- data/spec/unit/mutant/runner/mutation_spec.rb +0 -101
- data/spec/unit/mutant/runner/subject_spec.rb +0 -59
- data/spec/unit/mutant/subject/mutations_spec.rb +0 -23
- data/spec/unit/mutant/subject/node_spec.rb +0 -17
data/lib/mutant/mutation/evil.rb
DELETED
@@ -1,23 +0,0 @@
|
|
1
|
-
module Mutant
|
2
|
-
class Mutation
|
3
|
-
# Evul mutation
|
4
|
-
class Evil < self
|
5
|
-
|
6
|
-
SHOULD_FAIL = true
|
7
|
-
SYMBOL = 'evil'.freeze
|
8
|
-
|
9
|
-
# Test if killer is successful
|
10
|
-
#
|
11
|
-
# @param [Killer] killer
|
12
|
-
#
|
13
|
-
# @return [Boolean]
|
14
|
-
#
|
15
|
-
# @api private
|
16
|
-
#
|
17
|
-
def success?(killer)
|
18
|
-
killer.killed?
|
19
|
-
end
|
20
|
-
|
21
|
-
end # Evil
|
22
|
-
end # Mutation
|
23
|
-
end # Mutant
|
@@ -1,18 +0,0 @@
|
|
1
|
-
module Mutant
|
2
|
-
class Mutation
|
3
|
-
# Neutral mutation
|
4
|
-
class Neutral < self
|
5
|
-
|
6
|
-
SYMBOL = 'neutral'.freeze
|
7
|
-
SHOULD_FAIL = false
|
8
|
-
|
9
|
-
# Noop mutation, special case of neutral
|
10
|
-
class Noop < self
|
11
|
-
|
12
|
-
SYMBOL = 'noop'.freeze
|
13
|
-
|
14
|
-
end # Noop
|
15
|
-
|
16
|
-
end # Neutral
|
17
|
-
end # Mutation
|
18
|
-
end # Mutant
|
@@ -1,46 +0,0 @@
|
|
1
|
-
module Mutant
|
2
|
-
class Reporter
|
3
|
-
class CLI
|
4
|
-
class Progress
|
5
|
-
|
6
|
-
# Mutation progress reporter
|
7
|
-
class Mutation < self
|
8
|
-
|
9
|
-
handle(Runner::Mutation)
|
10
|
-
|
11
|
-
SUCCESS = '.'.freeze
|
12
|
-
FAILURE = 'F'.freeze
|
13
|
-
|
14
|
-
# Run printer
|
15
|
-
#
|
16
|
-
# @return [self]
|
17
|
-
#
|
18
|
-
# @api private
|
19
|
-
#
|
20
|
-
def run
|
21
|
-
unless running?
|
22
|
-
char(success? ? SUCCESS : FAILURE)
|
23
|
-
end
|
24
|
-
self
|
25
|
-
end
|
26
|
-
|
27
|
-
private
|
28
|
-
|
29
|
-
# Write colorized char
|
30
|
-
#
|
31
|
-
# @param [String] char
|
32
|
-
#
|
33
|
-
# @return [undefined]
|
34
|
-
#
|
35
|
-
# @api private
|
36
|
-
#
|
37
|
-
def char(char)
|
38
|
-
output.write(colorize(status_color, char))
|
39
|
-
output.flush
|
40
|
-
end
|
41
|
-
|
42
|
-
end # Mutation
|
43
|
-
end # Progress
|
44
|
-
end # CLI
|
45
|
-
end # Reporter
|
46
|
-
end # Mutant
|
@@ -1,116 +0,0 @@
|
|
1
|
-
module Mutant
|
2
|
-
class Reporter
|
3
|
-
class CLI
|
4
|
-
class Report
|
5
|
-
|
6
|
-
# Printer for configuration
|
7
|
-
class Config < self
|
8
|
-
|
9
|
-
handle(Mutant::Runner::Config)
|
10
|
-
|
11
|
-
delegate(
|
12
|
-
:amount_kills, :amount_mutations, :amount_kils,
|
13
|
-
:coverage, :subjects, :failed_subjects, :runtime, :mutations
|
14
|
-
)
|
15
|
-
|
16
|
-
# Run printer
|
17
|
-
#
|
18
|
-
# @return [self]
|
19
|
-
#
|
20
|
-
# @api private
|
21
|
-
#
|
22
|
-
def run
|
23
|
-
failed_subjects.each(&method(:visit))
|
24
|
-
info 'Subjects: %s', amount_subjects
|
25
|
-
info 'Mutations: %s', amount_mutations
|
26
|
-
info 'Kills: %s', amount_kills
|
27
|
-
info 'Alive: %s', amount_alive
|
28
|
-
info 'Runtime: %0.2fs', runtime
|
29
|
-
info 'Killtime: %0.2fs', killtime
|
30
|
-
info 'Overhead: %0.2f%%', overhead
|
31
|
-
status 'Coverage: %0.2f%%', coverage
|
32
|
-
status 'Expected: %0.2f%%', object.config.expected_coverage
|
33
|
-
print_generic_stats
|
34
|
-
self
|
35
|
-
end
|
36
|
-
|
37
|
-
private
|
38
|
-
|
39
|
-
# Print generic stats
|
40
|
-
#
|
41
|
-
# @return [undefined]
|
42
|
-
#
|
43
|
-
# @api private
|
44
|
-
#
|
45
|
-
def print_generic_stats
|
46
|
-
stats = generic_stats.to_a.sort_by(&:last)
|
47
|
-
return if stats.empty?
|
48
|
-
info('Nodes handled by generic mutator (type:occurrences):')
|
49
|
-
stats.reverse_each do |type, amount|
|
50
|
-
info('%-10s: %d', type, amount)
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
# Return stats for nodes handled by generic mutator
|
55
|
-
#
|
56
|
-
# @return [Hash<Symbo, Fixnum>]
|
57
|
-
#
|
58
|
-
# @api private
|
59
|
-
#
|
60
|
-
def generic_stats
|
61
|
-
subjects.each_with_object(Hash.new(0)) do |runner, stats|
|
62
|
-
Walker.run(runner.subject.node) do |node|
|
63
|
-
if Mutator::Registry.lookup(node).equal?(Mutator::Node::Generic)
|
64
|
-
stats[node.type] += 1
|
65
|
-
end
|
66
|
-
end
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
# Return amount of subjects
|
71
|
-
#
|
72
|
-
# @return [Fixnum]
|
73
|
-
#
|
74
|
-
# @api private
|
75
|
-
#
|
76
|
-
def amount_subjects
|
77
|
-
subjects.length
|
78
|
-
end
|
79
|
-
|
80
|
-
# Return amount of time in killers
|
81
|
-
#
|
82
|
-
# @return [Float]
|
83
|
-
#
|
84
|
-
# @api private
|
85
|
-
#
|
86
|
-
def killtime
|
87
|
-
mutations.map(&:runtime).inject(0, :+)
|
88
|
-
end
|
89
|
-
memoize :killtime
|
90
|
-
|
91
|
-
# Return mutant overhead
|
92
|
-
#
|
93
|
-
# @return [Float]
|
94
|
-
#
|
95
|
-
# @api private
|
96
|
-
#
|
97
|
-
def overhead
|
98
|
-
return 0 if runtime.zero?
|
99
|
-
Rational(runtime - killtime, runtime) * 100
|
100
|
-
end
|
101
|
-
|
102
|
-
# Return amount of alive mutations
|
103
|
-
#
|
104
|
-
# @return [Fixnum]
|
105
|
-
#
|
106
|
-
# @api private
|
107
|
-
#
|
108
|
-
def amount_alive
|
109
|
-
object.amount_mutations - amount_kills
|
110
|
-
end
|
111
|
-
|
112
|
-
end # Config
|
113
|
-
end # Report
|
114
|
-
end # CLI
|
115
|
-
end # Reporter
|
116
|
-
end # Mutant
|
data/lib/mutant/rspec.rb
DELETED
File without changes
|
data/lib/mutant/runner/config.rb
DELETED
@@ -1,138 +0,0 @@
|
|
1
|
-
module Mutant
|
2
|
-
class Runner
|
3
|
-
# Runner for object config
|
4
|
-
class Config < self
|
5
|
-
|
6
|
-
# The expected coverage precision
|
7
|
-
COVERAGE_PRECISION = 1
|
8
|
-
|
9
|
-
register Mutant::Config
|
10
|
-
|
11
|
-
# Run runner for object
|
12
|
-
#
|
13
|
-
# @param [Config] config
|
14
|
-
# @param [Object] object
|
15
|
-
#
|
16
|
-
# @return [Runner]
|
17
|
-
#
|
18
|
-
# @api private
|
19
|
-
#
|
20
|
-
def self.run(config)
|
21
|
-
handler = lookup(config.class)
|
22
|
-
handler.new(config)
|
23
|
-
end
|
24
|
-
|
25
|
-
# Return subject runners
|
26
|
-
#
|
27
|
-
# @return [Enumerable<Runner::Subject>]
|
28
|
-
#
|
29
|
-
# @api private
|
30
|
-
#
|
31
|
-
attr_reader :subjects
|
32
|
-
|
33
|
-
# Return failed subjects
|
34
|
-
#
|
35
|
-
# @return [Enumerable<Subject>]
|
36
|
-
#
|
37
|
-
# @api private
|
38
|
-
#
|
39
|
-
def failed_subjects
|
40
|
-
subjects.reject(&:success?)
|
41
|
-
end
|
42
|
-
memoize :failed_subjects
|
43
|
-
|
44
|
-
# Test if run was successful
|
45
|
-
#
|
46
|
-
# @return [Boolean]
|
47
|
-
#
|
48
|
-
# @api private
|
49
|
-
#
|
50
|
-
def success?
|
51
|
-
coverage.round(COVERAGE_PRECISION).eql?(config.expected_coverage.round(COVERAGE_PRECISION))
|
52
|
-
end
|
53
|
-
memoize :success?
|
54
|
-
|
55
|
-
# Return integration
|
56
|
-
#
|
57
|
-
# @return [Integration]
|
58
|
-
#
|
59
|
-
# @api private
|
60
|
-
#
|
61
|
-
def integration
|
62
|
-
config.integration
|
63
|
-
end
|
64
|
-
|
65
|
-
# Return coverage
|
66
|
-
#
|
67
|
-
# @return [Float]
|
68
|
-
#
|
69
|
-
# @api private
|
70
|
-
#
|
71
|
-
def coverage
|
72
|
-
return 0.0 if amount_mutations.zero? && amount_kills.zero?
|
73
|
-
(amount_kills.to_f / amount_mutations) * 100
|
74
|
-
end
|
75
|
-
memoize :coverage
|
76
|
-
|
77
|
-
# Return amount of kills
|
78
|
-
#
|
79
|
-
# @return [Fixnum]
|
80
|
-
#
|
81
|
-
# @api private
|
82
|
-
#
|
83
|
-
def amount_kills
|
84
|
-
mutations.select(&:success?).length
|
85
|
-
end
|
86
|
-
memoize :amount_kills
|
87
|
-
|
88
|
-
# Return mutations
|
89
|
-
#
|
90
|
-
# @return [Array<Mutation>]
|
91
|
-
#
|
92
|
-
# @api private
|
93
|
-
#
|
94
|
-
def mutations
|
95
|
-
subjects.map(&:mutations).flatten
|
96
|
-
end
|
97
|
-
memoize :mutations
|
98
|
-
|
99
|
-
# Return amount of mutations
|
100
|
-
#
|
101
|
-
# @return [Fixnum]
|
102
|
-
#
|
103
|
-
# @api private
|
104
|
-
#
|
105
|
-
def amount_mutations
|
106
|
-
mutations.length
|
107
|
-
end
|
108
|
-
|
109
|
-
private
|
110
|
-
|
111
|
-
# Run config
|
112
|
-
#
|
113
|
-
# @return [undefined]
|
114
|
-
#
|
115
|
-
# @api private
|
116
|
-
#
|
117
|
-
def run_subjects
|
118
|
-
integration = self.integration
|
119
|
-
integration.setup
|
120
|
-
@subjects = visit_collection(config.subjects)
|
121
|
-
integration.teardown
|
122
|
-
end
|
123
|
-
|
124
|
-
# Run configuration
|
125
|
-
#
|
126
|
-
# @return [undefined]
|
127
|
-
#
|
128
|
-
# @api private
|
129
|
-
#
|
130
|
-
def run
|
131
|
-
run_subjects
|
132
|
-
@end = Time.now
|
133
|
-
reporter.report(self)
|
134
|
-
end
|
135
|
-
|
136
|
-
end # Config
|
137
|
-
end # Runner
|
138
|
-
end # Mutant
|
data/lib/mutant/runner/killer.rb
DELETED
@@ -1,75 +0,0 @@
|
|
1
|
-
module Mutant
|
2
|
-
class Runner
|
3
|
-
# Killer runner
|
4
|
-
class Killer < self
|
5
|
-
include Equalizer.new(:config, :killer)
|
6
|
-
|
7
|
-
register Mutant::Killer
|
8
|
-
|
9
|
-
# Return killer
|
10
|
-
#
|
11
|
-
# @return [Killer]
|
12
|
-
#
|
13
|
-
# @api private
|
14
|
-
#
|
15
|
-
attr_reader :killer
|
16
|
-
protected :killer
|
17
|
-
|
18
|
-
# Return kill report
|
19
|
-
#
|
20
|
-
# @return [Killer::Report]
|
21
|
-
#
|
22
|
-
# @api private
|
23
|
-
#
|
24
|
-
attr_reader :report
|
25
|
-
|
26
|
-
# Test if killer ran successfully
|
27
|
-
#
|
28
|
-
# @return [Boolean]
|
29
|
-
#
|
30
|
-
# @api private
|
31
|
-
#
|
32
|
-
def success?
|
33
|
-
@report.success?
|
34
|
-
end
|
35
|
-
|
36
|
-
# Test if this killer ALONE can determine if mutation is dead
|
37
|
-
#
|
38
|
-
# @return [Boolean]
|
39
|
-
#
|
40
|
-
# @api private
|
41
|
-
#
|
42
|
-
def mutation_dead?
|
43
|
-
test_report = report.test_report
|
44
|
-
killer.mutation.should_fail? && test_report.failed?
|
45
|
-
end
|
46
|
-
|
47
|
-
# Initialize object
|
48
|
-
#
|
49
|
-
# @param [Config] config
|
50
|
-
# @param [Mutation] mutation
|
51
|
-
#
|
52
|
-
# @return [undefined]
|
53
|
-
#
|
54
|
-
# @api private
|
55
|
-
#
|
56
|
-
def initialize(config, killer)
|
57
|
-
@killer = killer
|
58
|
-
super(config)
|
59
|
-
end
|
60
|
-
|
61
|
-
private
|
62
|
-
|
63
|
-
# Run killer
|
64
|
-
#
|
65
|
-
# @return [undefined]
|
66
|
-
#
|
67
|
-
# @api private
|
68
|
-
#
|
69
|
-
def run
|
70
|
-
@report = killer.run
|
71
|
-
end
|
72
|
-
|
73
|
-
end # Killer
|
74
|
-
end # Runner
|
75
|
-
end # Mutant
|
@@ -1,78 +0,0 @@
|
|
1
|
-
module Mutant
|
2
|
-
class Runner
|
3
|
-
# Mutation runner
|
4
|
-
class Mutation < self
|
5
|
-
include Equalizer.new(:config, :mutation, :tests)
|
6
|
-
|
7
|
-
register Mutant::Mutation
|
8
|
-
|
9
|
-
# Return mutation
|
10
|
-
#
|
11
|
-
# @return [Mutation]
|
12
|
-
#
|
13
|
-
# @api private
|
14
|
-
#
|
15
|
-
attr_reader :mutation
|
16
|
-
|
17
|
-
# Return killers
|
18
|
-
#
|
19
|
-
# @return [Enumerable<Runner::Killer>]
|
20
|
-
#
|
21
|
-
# @api private
|
22
|
-
#
|
23
|
-
attr_reader :killers
|
24
|
-
|
25
|
-
# Initialize object
|
26
|
-
#
|
27
|
-
# @param [Config] config
|
28
|
-
# @param [Mutation] mutation
|
29
|
-
# @param [Enumerable<Test>] tests
|
30
|
-
#
|
31
|
-
# @return [undefined]
|
32
|
-
#
|
33
|
-
# @api private
|
34
|
-
#
|
35
|
-
def initialize(config, mutation, tests)
|
36
|
-
@mutation, @tests = mutation, tests
|
37
|
-
super(config)
|
38
|
-
@stop = config.fail_fast && !success?
|
39
|
-
end
|
40
|
-
|
41
|
-
# Test if mutation was handeled successfully
|
42
|
-
#
|
43
|
-
# @return [Boolean]
|
44
|
-
#
|
45
|
-
# @api private
|
46
|
-
#
|
47
|
-
def success?
|
48
|
-
killers.any?(&:success?)
|
49
|
-
end
|
50
|
-
|
51
|
-
private
|
52
|
-
|
53
|
-
# Perform operation
|
54
|
-
#
|
55
|
-
# @return [undefined]
|
56
|
-
#
|
57
|
-
# @api private
|
58
|
-
#
|
59
|
-
def run
|
60
|
-
@killers = []
|
61
|
-
|
62
|
-
killers = @tests.map do |test|
|
63
|
-
Mutant::Killer.new(
|
64
|
-
mutation: mutation,
|
65
|
-
test: test
|
66
|
-
)
|
67
|
-
end
|
68
|
-
|
69
|
-
killers.each do |killer|
|
70
|
-
runner = visit(killer)
|
71
|
-
@killers << runner
|
72
|
-
return if runner.mutation_dead?
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
end # Mutation
|
77
|
-
end # Runner
|
78
|
-
end # Mutant
|