mutant 0.3.0.beta17 → 0.3.0.beta18
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rspec +2 -0
- data/README.md +34 -2
- data/config/flay.yml +1 -1
- data/config/reek.yml +1 -0
- data/lib/mutant/matcher/namespace.rb +2 -21
- data/lib/mutant/mutator/node/generic.rb +1 -1
- data/lib/mutant/reporter/cli/printer/config.rb +76 -0
- data/lib/mutant/reporter/cli/printer/subject.rb +1 -1
- data/mutant.gemspec +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 89bc8e83f49c94e59ba0950d67bced72a35bb072
|
4
|
+
data.tar.gz: aa8fe5e09af20fdc68063ec8647c1188bfe27fe4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ae3957cab51a09be0c87e94e5372ecb7ee67b7c73debba0e75e5003990ebe7c39ded769a402c03f3d9162deeb24cccbb4237f95d88168e6edb104936aabe216a
|
7
|
+
data.tar.gz: 8afc1deb30fccd538d3f4d67d14ebf6afb6895cef7a013aa582fc10a9d111f7531665c2c461e6997315dfaf225091eeb19e44376f72de757e908841990d354de
|
data/.rspec
CHANGED
data/README.md
CHANGED
@@ -5,11 +5,13 @@ mutant
|
|
5
5
|
[![Dependency Status](https://gemnasium.com/mbj/mutant.png)](https://gemnasium.com/mbj/mutant)
|
6
6
|
[![Code Climate](https://codeclimate.com/github/mbj/mutant.png)](https://codeclimate.com/github/mbj/mutant)
|
7
7
|
|
8
|
-
Mutant is a mutation testing tool for ruby.
|
8
|
+
Mutant is a mutation testing tool for ruby.
|
9
9
|
|
10
10
|
The idea is that if code can be changed and your tests do not notice, either that code isn't being covered
|
11
11
|
or it does not have a speced side effect.
|
12
12
|
|
13
|
+
A more readable introduction can be found under: http://solnic.eu/2013/01/23/mutation-testing-with-mutant.html
|
14
|
+
|
13
15
|
Mutant supports MRI and RBX 1.9 and 2.0, while support for jruby is planned. It should also work under
|
14
16
|
any ruby engine that supports POSIX-fork(2) semantics.
|
15
17
|
|
@@ -45,9 +47,39 @@ Install the gem `mutant` via your preferred method.
|
|
45
47
|
The 0.2 series is stable but has outdated dependencies. The 0.3 series is in beta phase currently.
|
46
48
|
|
47
49
|
```ruby
|
48
|
-
gem install mutant
|
50
|
+
gem install mutant --pre
|
49
51
|
```
|
50
52
|
|
53
|
+
Mutations
|
54
|
+
---------
|
55
|
+
|
56
|
+
Mutant supports a very wide range of mutation operators. Listing them all in detail would blow this document up.
|
57
|
+
|
58
|
+
It is planned to parse a list of mutation operators from the source. In the meantime please refer to the
|
59
|
+
[code](https://github.com/mbj/mutant/tree/master/lib/mutant/mutator/node) each subclass of `Mutant::Mutator::Node`
|
60
|
+
emits around 3-6 mutations.
|
61
|
+
|
62
|
+
Currently mutant covers the majority of ruby's complex nodes that often occur in method bodies.
|
63
|
+
|
64
|
+
A some stats from the [axiom](https://github.com/dkubb/axiom) library:
|
65
|
+
|
66
|
+
```
|
67
|
+
Subjects: 417 # Amount of subjects being mutated (currently only methods)
|
68
|
+
Mutations: 5442 # Amount of mutations mutant generated (~13 mutations per method)
|
69
|
+
Kills: 5385 # Amount of successfully killed mutations
|
70
|
+
Runtime: 1898.11s # Total runtime
|
71
|
+
Killtime: 1884.17s # Time spend killing mutations
|
72
|
+
Overhead: 0.73%
|
73
|
+
Coverage: 98.95% # Coverage score
|
74
|
+
Alive: 57 # Amount of alive mutations.
|
75
|
+
```
|
76
|
+
|
77
|
+
|
78
|
+
Nodes still missing a dedicated mutator are handled via the
|
79
|
+
[Generic](https://github.com/mbj/mutant/blob/master/lib/mutant/mutator/node/generic.rb) mutator.
|
80
|
+
The goal is to remove this mutator and have dedicated mutator for every type of node and removing
|
81
|
+
the Generic handler altogether.
|
82
|
+
|
51
83
|
Examples
|
52
84
|
--------
|
53
85
|
|
data/config/flay.yml
CHANGED
data/config/reek.yml
CHANGED
@@ -47,6 +47,7 @@ NestedIterators:
|
|
47
47
|
exclude:
|
48
48
|
- Mutant#self.singleton_subclass_instance
|
49
49
|
- Mutant::Mutator::Util::Array::Element#dispatch
|
50
|
+
- Mutant::Reporter::CLI::Printer::Config::Runner#generic_stats
|
50
51
|
- Mutant::CLI#parse
|
51
52
|
max_allowed_nesting: 1
|
52
53
|
ignore_iterators: []
|
@@ -52,24 +52,6 @@ module Mutant
|
|
52
52
|
end
|
53
53
|
end
|
54
54
|
|
55
|
-
# Test for bogus class
|
56
|
-
#
|
57
|
-
# FIXME: Remove this hack once bogus is fixed!
|
58
|
-
#
|
59
|
-
# @param [Object] object
|
60
|
-
#
|
61
|
-
# @return [true]
|
62
|
-
# if is a bogous class
|
63
|
-
#
|
64
|
-
# @return [false]
|
65
|
-
# otherwise
|
66
|
-
#
|
67
|
-
# @api private
|
68
|
-
#
|
69
|
-
def self.bogous?(object)
|
70
|
-
defined?(Bogus::Fake) && object == Bogus::Fake
|
71
|
-
end
|
72
|
-
|
73
55
|
# Yield scope if name matches pattern
|
74
56
|
#
|
75
57
|
# @param [Module,Class] scope
|
@@ -79,11 +61,10 @@ module Mutant
|
|
79
61
|
# @api private
|
80
62
|
#
|
81
63
|
def emit_scope(scope)
|
82
|
-
return if self.class.bogous?(scope)
|
83
64
|
name = scope.name
|
84
|
-
# FIXME Fix nokogiri
|
65
|
+
# FIXME Fix nokogiri to return a string here
|
85
66
|
return unless name.kind_of?(String)
|
86
|
-
if pattern =~
|
67
|
+
if pattern =~ name
|
87
68
|
yield scope
|
88
69
|
end
|
89
70
|
end
|
@@ -45,6 +45,7 @@ module Mutant
|
|
45
45
|
info 'Overhead: %0.2f%%', overhead
|
46
46
|
status 'Coverage: %0.2f%%', coverage
|
47
47
|
status 'Alive: %s', amount_alive
|
48
|
+
print_generic_stats
|
48
49
|
self
|
49
50
|
end
|
50
51
|
|
@@ -60,6 +61,81 @@ module Mutant
|
|
60
61
|
object.subjects
|
61
62
|
end
|
62
63
|
|
64
|
+
# Walker for all ast nodes
|
65
|
+
class Walker
|
66
|
+
|
67
|
+
# Run walkter
|
68
|
+
#
|
69
|
+
# @param [Parser::AST::Node] root
|
70
|
+
#
|
71
|
+
# @return [self]
|
72
|
+
#
|
73
|
+
# @api private
|
74
|
+
#
|
75
|
+
def self.run(root, &block)
|
76
|
+
new(root, block)
|
77
|
+
self
|
78
|
+
end
|
79
|
+
|
80
|
+
private_class_method :new
|
81
|
+
|
82
|
+
# Initialize and run walker
|
83
|
+
#
|
84
|
+
# @param [Parser::AST::Node] root
|
85
|
+
# @param [#call(node)] block
|
86
|
+
#
|
87
|
+
# @return [undefined]
|
88
|
+
#
|
89
|
+
# @api private
|
90
|
+
#
|
91
|
+
def initialize(root, block)
|
92
|
+
@root, @block = root, block
|
93
|
+
dispatch(root)
|
94
|
+
end
|
95
|
+
|
96
|
+
private
|
97
|
+
|
98
|
+
# Perform dispatch
|
99
|
+
#
|
100
|
+
# @return [undefined]
|
101
|
+
#
|
102
|
+
# @api private
|
103
|
+
#
|
104
|
+
def dispatch(node)
|
105
|
+
@block.call(node)
|
106
|
+
node.children.grep(Parser::AST::Node).each(&method(:dispatch))
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
# Print generic stats
|
111
|
+
#
|
112
|
+
# @return [undefined]
|
113
|
+
#
|
114
|
+
# @api private
|
115
|
+
#
|
116
|
+
def print_generic_stats
|
117
|
+
stats = generic_stats.to_a.sort_by(&:last)
|
118
|
+
info('Nodes handled by genric mutator (type:occurances):')
|
119
|
+
stats.reverse_each do |type, amount|
|
120
|
+
info('%-10s: %d', type, amount)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
# Return stats for nodes handled by generic mutator
|
125
|
+
#
|
126
|
+
# @return [Hash<Symbo, Fixnum>]
|
127
|
+
#
|
128
|
+
# @api private
|
129
|
+
#
|
130
|
+
def generic_stats
|
131
|
+
object.subjects.each_with_object(Hash.new(0)) do |runner, stats|
|
132
|
+
Walker.run(runner.subject.node) do |node|
|
133
|
+
next unless Mutator::Registry.lookup(node) == Mutator::Node::Generic
|
134
|
+
stats[node.type] += 1
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
63
139
|
# Return amount of subjects
|
64
140
|
#
|
65
141
|
# @return [Fixnum]
|
data/mutant.gemspec
CHANGED
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.3.0.
|
4
|
+
version: 0.3.0.beta18
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Markus Schirp
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-07-
|
11
|
+
date: 2013-07-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: parser
|