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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9b2d8df94331d0e76fd290e715676db4d384ef29
4
- data.tar.gz: 9f41938800fd53b682f575d423b794927646f639
3
+ metadata.gz: 89bc8e83f49c94e59ba0950d67bced72a35bb072
4
+ data.tar.gz: aa8fe5e09af20fdc68063ec8647c1188bfe27fe4
5
5
  SHA512:
6
- metadata.gz: 32830c2c2236599808a8def433256a5b4ce1413eb3e379332c362a32c2e7b0604d99c2fff8c0f10e5dd339ef151c2d7fb855b2c9bf2b854977f95c579343be21
7
- data.tar.gz: 05c78b1df03d6f0e9ab92aec42225777b00c0a9d017f616aa32dea5e1277793bdea151c03b395d51205003c015f69ecfb1ffca02a1f263a1fba4a85cbec140a4
6
+ metadata.gz: ae3957cab51a09be0c87e94e5372ecb7ee67b7c73debba0e75e5003990ebe7c39ded769a402c03f3d9162deeb24cccbb4237f95d88168e6edb104936aabe216a
7
+ data.tar.gz: 8afc1deb30fccd538d3f4d67d14ebf6afb6895cef7a013aa582fc10a9d111f7531665c2c461e6997315dfaf225091eeb19e44376f72de757e908841990d354de
data/.rspec CHANGED
@@ -1 +1,3 @@
1
1
  --color
2
+ --format progress
3
+ --order random
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. It aims to be better than existing mutation testers.
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 -v0.3.0.beta8
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
 
@@ -1,3 +1,3 @@
1
1
  ---
2
2
  threshold: 16
3
- total_score: 704
3
+ total_score: 719
@@ -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 =~ scope.name
67
+ if pattern =~ name
87
68
  yield scope
88
69
  end
89
70
  end
@@ -34,7 +34,7 @@ module Mutant
34
34
  end
35
35
  end
36
36
 
37
- end # Noop
37
+ end # Generic
38
38
  end # Node
39
39
  end # Mutator
40
40
  end # Mutant
@@ -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]
@@ -20,7 +20,7 @@ module Mutant
20
20
  info('%s', object.identification)
21
21
  end
22
22
 
23
- # Prunter for subject runners
23
+ # Printer for subject runners
24
24
  class Runner < self
25
25
 
26
26
  handle(Mutant::Runner::Subject)
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |gem|
4
4
  gem.name = 'mutant'
5
- gem.version = '0.3.0.beta17'
5
+ gem.version = '0.3.0.beta18'
6
6
  gem.authors = [ 'Markus Schirp' ]
7
7
  gem.email = [ 'mbj@schirp-dso.com' ]
8
8
 
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.beta17
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-16 00:00:00.000000000 Z
11
+ date: 2013-07-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: parser