mutant 0.5.22 → 0.5.23

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 12466470fce5fafd680059de82205c093d93c503
4
- data.tar.gz: c374d20379cb9c81068ce205a6d43d7ddd3505ed
3
+ metadata.gz: 19cc50cff5125bbeef98eb0511a7c02c7154b4d5
4
+ data.tar.gz: 153344653cd236a26f822ea809333a881b66491b
5
5
  SHA512:
6
- metadata.gz: 3cf3581a8648769d72db4a2cee7522ebece339eef403af542c989cbac811cc3deb34fe03f25795ad80d3a9c5fa12fedc796dda3bc59565b282c1afba311302a3
7
- data.tar.gz: 61deff160b2dca8288d53a615c8c4ff5a5005612d47383d6f1d1145d6b28eb1eae898d3634e6c16eb02b837b8549fe86834a96c8a015da98a1eaeaf91845a580
6
+ metadata.gz: 1b3b1a8e57fcfc7c5423e16b1c7a375ef26494e1d6df55c12e458efcf7cc4f26be1681c379b7ce110d91f3c7179f43f294d099b1ce41203a162043ce893ba505
7
+ data.tar.gz: 43b9c7b3c628cf529316433463083163ec8ae83911575df994cdc71d604b34a6e05872be557cef18150c78c20015973bd5db37fd81ec170b377f02b220264bc0
data/.travis.yml CHANGED
@@ -7,6 +7,9 @@ rvm:
7
7
  - 2.0.0
8
8
  - 2.1.2
9
9
  - rbx-2
10
+ matrix:
11
+ allow_failures:
12
+ - rvm: 2.1.2 # still segfaults on stack overflow on define_method
10
13
  notifications:
11
14
  irc:
12
15
  channels:
data/Changelog.md CHANGED
@@ -1,3 +1,7 @@
1
+ # v0.5.23 2014-06-15
2
+
3
+ * Propagate exceptions from child-isolation-killforks to master
4
+
1
5
  # v0.5.22 2014-06-15
2
6
 
3
7
  * Fix invalid AST generation on operator method mutation with self as receiver.
data/README.md CHANGED
@@ -6,7 +6,6 @@ mutant
6
6
  [![Code Climate](https://codeclimate.com/github/mbj/mutant.png)](https://codeclimate.com/github/mbj/mutant)
7
7
  [![Inline docs](http://inch-ci.org/github/mbj/mutant.png)](http://inch-ci.org/github/mbj/mutant)
8
8
  [![Gem Version](https://img.shields.io/gem/v/mutant.svg)](https://rubygems.org/gems/mutant)
9
- [![Gittip](https://img.shields.io/gittip/mbj.svg)](https://gittip.com/mbj)
10
9
 
11
10
  Mutant is a mutation testing tool for ruby.
12
11
 
@@ -41,7 +40,7 @@ Blog-Posts
41
40
  Integrations
42
41
  ------------
43
42
 
44
- Only rspec2 and rspec-3 beta2 is supported currently.
43
+ rspec2 and rspec-3 are supported currently. Minitest support is still *planned*.
45
44
 
46
45
  Projects using Mutant
47
46
  ---------------------
@@ -147,17 +146,6 @@ current prefix level, these example groups *must* kill the mutation.
147
146
  This test selection strategy is compatible with the old `--rspec-dm2` and `--rspec-unit` strategy.
148
147
  The old flags were removed. It allows to define very fine grained specs, or coarse grained - as you like.
149
148
 
150
- Donations
151
- ---------
152
-
153
- I ([mbj](https://github.com/mbj)) build this and adjacent tools in my free time.
154
- LOTS of unaccounted time and fun already went into this project.
155
-
156
- You might consider to donate if you like this tool.
157
-
158
- * [![Gittip](https://img.shields.io/gittip/mbj.svg)](https://gittip.com/mbj)
159
- * [![Flattr this](http://api.flattr.com/button/flattr-badge-large.png)](http://flattr.com/thing/1823010/mbjmutant-on-GitHub)
160
-
161
149
  Support
162
150
  -------
163
151
 
data/config/flay.yml CHANGED
@@ -1,3 +1,3 @@
1
1
  ---
2
2
  threshold: 18
3
- total_score: 906
3
+ total_score: 899
data/lib/mutant.rb CHANGED
@@ -16,6 +16,7 @@ require 'diff/lcs/hunk'
16
16
  require 'anima'
17
17
  require 'concord'
18
18
  require 'morpher'
19
+ require 'parallel'
19
20
 
20
21
  # Library namespace
21
22
  module Mutant
@@ -24,7 +24,7 @@ module Mutant
24
24
  def matcher(cache)
25
25
  methods_matcher = MATCHERS.fetch(scope_symbol).new(cache, scope)
26
26
  method = methods_matcher.methods.detect do |meth|
27
- meth.name == method_name
27
+ meth.name.equal?(method_name)
28
28
  end or raise NameError, "Cannot find method #{identifier}"
29
29
  methods_matcher.matcher.build(cache, scope, method)
30
30
  end
@@ -16,50 +16,10 @@ module Mutant
16
16
  # @api private
17
17
  #
18
18
  def self.call(&block)
19
- reader, writer = IO.pipe.each(&:binmode)
20
-
21
- pid = fork
22
-
23
- if pid.nil?
24
- begin
25
- reader.close
26
- writer.write(Marshal.dump(block.call))
27
- Kernel.exit!(0)
28
- ensure
29
- Kernel.exit!(1)
30
- end
31
- end
32
-
33
- writer.close
34
-
35
- read_result(reader, pid)
36
- end
37
-
38
- # Read result from child process
39
- #
40
- # @param [IO] reader
41
- # @param [Fixnum] pid
42
- #
43
- # @return [Object]
44
- #
45
- # @raise [Error]
46
- #
47
- def self.read_result(reader, pid)
48
- begin
49
- data = Marshal.load(reader.read)
50
- rescue ArgumentError, TypeError
51
- raise Error, 'Childprocess wrote un-unmarshallable data'
52
- end
53
-
54
- status = Process.waitpid2(pid).last
55
-
56
- unless status.exitstatus.zero?
57
- raise Error, "Childprocess exited with nonzero exit status: #{status.exitstatus}"
58
- end
59
-
60
- data
19
+ Parallel.map([block], in_processes: 1) do |block|
20
+ block.call
21
+ end.first
61
22
  end
62
- private_class_method :read_result
63
23
 
64
24
  end # Isolator
65
25
  end # Mutant
@@ -33,7 +33,7 @@ module Mutant
33
33
  # @api private
34
34
  #
35
35
  def self.build(matchers)
36
- if matchers.length == 1
36
+ if matchers.length.equal?(1)
37
37
  return matchers.first
38
38
  end
39
39
 
@@ -49,9 +49,9 @@ module Mutant
49
49
  def match?(node)
50
50
  location = node.location || return
51
51
  expression = location.expression || return
52
- expression.line == source_line &&
53
- node.type == :def &&
54
- node.children[NAME_INDEX] == method_name
52
+ expression.line.equal?(source_line) &&
53
+ node.type.equal?(:def) &&
54
+ node.children[NAME_INDEX].equal?(method_name)
55
55
  end
56
56
 
57
57
  # Matcher for memoized instance methods
@@ -45,7 +45,7 @@ module Mutant
45
45
  def line?(node)
46
46
  expression = node.location.expression
47
47
  return false unless expression
48
- expression.line == source_line
48
+ expression.line.equal?(source_line)
49
49
  end
50
50
 
51
51
  # Test for name match
@@ -57,7 +57,7 @@ module Mutant
57
57
  # @api private
58
58
  #
59
59
  def name?(node)
60
- node.children[NAME_INDEX] == method_name
60
+ node.children[NAME_INDEX].equal?(method_name)
61
61
  end
62
62
 
63
63
  # Test for receiver match
@@ -95,7 +95,7 @@ module Mutant
95
95
  #
96
96
  def receiver_name?(node)
97
97
  name = node.children[CONST_NAME_INDEX]
98
- name.to_s == context.unqualified_name
98
+ name.to_s.eql?(context.unqualified_name)
99
99
  end
100
100
 
101
101
  end # Singleton
@@ -43,7 +43,7 @@ module Mutant
43
43
  def methods
44
44
  candidate_names.each_with_object([]) do |name, methods|
45
45
  method = access(name)
46
- methods << method if method.owner == candidate_scope
46
+ methods << method if method.owner.equal?(candidate_scope)
47
47
  end
48
48
  end
49
49
  memoize :methods
@@ -24,7 +24,7 @@ module Mutant
24
24
  emit_body_mutations
25
25
  end
26
26
  emit_body(nil)
27
- emit_body(RAISE)
27
+ emit_body(N_RAISE)
28
28
  end
29
29
 
30
30
  end # Block
@@ -22,7 +22,7 @@ module Mutant
22
22
  emit_condition_mutations
23
23
  emit_body_mutations if body
24
24
  emit_body(nil)
25
- emit_body(RAISE)
25
+ emit_body(N_RAISE)
26
26
  end
27
27
 
28
28
  end # While
@@ -14,7 +14,7 @@ module Mutant
14
14
  #
15
15
  def dispatch
16
16
  emit_arguments_mutations
17
- emit_body(RAISE)
17
+ emit_body(N_RAISE)
18
18
  emit_body(nil)
19
19
  emit_body_mutations if body
20
20
  end
@@ -22,9 +22,9 @@ module Mutant
22
22
  end
23
23
 
24
24
  SPECIAL = [
25
- NodeHelpers::NAN,
26
- NodeHelpers::NEGATIVE_INFINITY,
27
- NodeHelpers::INFINITY
25
+ N_NAN,
26
+ N_NEGATIVE_INFINITY,
27
+ N_INFINITY
28
28
  ].freeze
29
29
 
30
30
  # Emit special cases
@@ -34,9 +34,7 @@ module Mutant
34
34
  # @api private
35
35
  #
36
36
  def emit_special_cases
37
- SPECIAL.each do |value|
38
- emit(value)
39
- end
37
+ SPECIAL.each(&method(:emit))
40
38
  end
41
39
 
42
40
  # Return values to test against
@@ -48,7 +48,7 @@ module Mutant
48
48
  #
49
49
  def emit_upper_bound_mutations
50
50
  emit__end_mutations
51
- emit_type(NAN, _end)
51
+ emit_type(N_NAN, _end)
52
52
  end
53
53
 
54
54
  # Emit start mutations
@@ -59,8 +59,8 @@ module Mutant
59
59
  #
60
60
  def emit_lower_bound_mutations
61
61
  emit_start_mutations
62
- emit_type(start, INFINITY)
63
- emit_type(start, NAN)
62
+ emit_type(start, N_INFINITY)
63
+ emit_type(start, N_NAN)
64
64
  end
65
65
 
66
66
  end # Range
@@ -19,7 +19,7 @@ module Mutant
19
19
  if body
20
20
  mutate_body
21
21
  else
22
- emit_child_update(body_index, RAISE)
22
+ emit_child_update(body_index, N_RAISE)
23
23
  end
24
24
  mutate_conditions
25
25
  end
@@ -35,7 +35,7 @@ module Mutant
35
35
  # @api private
36
36
  #
37
37
  def new?(generated)
38
- input != generated
38
+ !input.eql?(generated)
39
39
  end
40
40
 
41
41
  end # Util
@@ -15,20 +15,15 @@ module Mutant
15
15
  end
16
16
  module_function :s
17
17
 
18
- NAN =
19
- s(:send, s(:float, 0.0), :/, s(:float, 0.0))
20
- INFINITY =
21
- s(:send, s(:float, 1.0), :/, s(:float, 0.0))
22
- NEGATIVE_INFINITY =
23
- s(:send, s(:float, -1.0), :/, s(:float, 0.0))
24
-
25
- RAISE = s(:send, nil, :raise)
26
-
27
- N_TRUE = s(:true)
28
- N_FALSE = s(:false)
29
- N_NIL = s(:nil)
30
- N_EMPTY = s(:empty)
31
- N_SELF = s(:self)
18
+ N_NAN = s(:send, s(:float, 0.0), :/, s(:float, 0.0))
19
+ N_INFINITY = s(:send, s(:float, 1.0), :/, s(:float, 0.0))
20
+ N_NEGATIVE_INFINITY = s(:send, s(:float, -1.0), :/, s(:float, 0.0))
21
+ N_RAISE = s(:send, nil, :raise)
22
+ N_TRUE = s(:true)
23
+ N_FALSE = s(:false)
24
+ N_NIL = s(:nil)
25
+ N_EMPTY = s(:empty)
26
+ N_SELF = s(:self)
32
27
 
33
28
  # Build a negated boolean node
34
29
  #
@@ -43,7 +43,7 @@ module Mutant
43
43
  #
44
44
  def lookup(subject)
45
45
  current = subject
46
- until current == Object
46
+ until current.equal?(Object)
47
47
  if registry.key?(current)
48
48
  return registry.fetch(current)
49
49
  end
@@ -60,7 +60,7 @@ module Mutant
60
60
  def generic_stats
61
61
  subjects.each_with_object(Hash.new(0)) do |runner, stats|
62
62
  Walker.run(runner.subject.node) do |node|
63
- if Mutator::Registry.lookup(node) == Mutator::Node::Generic
63
+ if Mutator::Registry.lookup(node).equal?(Mutator::Node::Generic)
64
64
  stats[node.type] += 1
65
65
  end
66
66
  end
@@ -48,7 +48,7 @@ module Mutant
48
48
  # @api private
49
49
  #
50
50
  def success?
51
- coverage.round(COVERAGE_PRECISION) == config.expected_coverage.round(COVERAGE_PRECISION)
51
+ coverage.round(COVERAGE_PRECISION).eql?(config.expected_coverage.round(COVERAGE_PRECISION))
52
52
  end
53
53
  memoize :success?
54
54
 
@@ -1,4 +1,4 @@
1
1
  module Mutant
2
2
  # The current mutant version
3
- VERSION = '0.5.22'.freeze
3
+ VERSION = '0.5.23'.freeze
4
4
  end # Mutant
data/mutant.gemspec CHANGED
@@ -37,7 +37,7 @@ Gem::Specification.new do |gem|
37
37
  gem.add_runtime_dependency('inflecto', '~> 0.0.2')
38
38
  gem.add_runtime_dependency('anima', '~> 0.2.0')
39
39
  gem.add_runtime_dependency('concord', '~> 0.1.5')
40
+ gem.add_runtime_dependency('parallel', '~> 1.0.0')
40
41
 
41
42
  gem.add_development_dependency('bundler', '~> 1.3', '>= 1.3.5')
42
- gem.add_development_dependency('parallel', '~> 1.0.0')
43
43
  end
@@ -1,61 +1,16 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Mutant::Isolation do
4
- describe '.isolate' do
4
+ describe '.run' do
5
5
  let(:object) { described_class }
6
6
 
7
- before do
8
- unless RUBY_VERSION.eql?('2.1.2')
9
- skip 'Series of events is indeterministic cross ruby implementations. Skipping this test under non 2.1.2'
10
- end
7
+ it 'isolates global effects from process' do
8
+ expect { object.call { ::Foo = 1 } }.not_to change { defined?(Foo) }.from(nil)
11
9
  end
12
10
 
13
- let(:expected_return) { :foo }
14
-
15
- subject { object.call(&block) }
16
-
17
- def redirect_stderr
18
- $stderr = File.open('/dev/null')
19
- end
20
-
21
- unless ENV['COVERAGE']
22
- context 'when block returns mashallable data, and process exists zero' do
23
- let(:block) do
24
- lambda do
25
- :data_from_child_process
26
- end
27
- end
28
-
29
- it { should eql(:data_from_child_process) }
30
- end
11
+ it 'return block value' do
12
+ expect(object.call { :foo }).to be(:foo)
31
13
  end
32
14
 
33
- context 'when block does return marshallable data' do
34
- let(:block) do
35
- lambda do
36
- redirect_stderr
37
- $stderr # not mashallable, nothing written to pipe and raises exception in child
38
- end
39
- end
40
-
41
- it 'raises an exception' do
42
- expect { subject }.to raise_error(described_class::Error, 'Childprocess wrote un-unmarshallable data')
43
- end
44
- end
45
-
46
- context 'when block causes the child to exit nonzero' do
47
- let(:block) do
48
- lambda do
49
- method = Kernel.method(:exit!)
50
- Kernel.define_singleton_method(:exit!) do |_status|
51
- method.call(1)
52
- end
53
- end
54
- end
55
-
56
- it 'raises an exception' do
57
- expect { subject }.to raise_error(described_class::Error, 'Childprocess exited with nonzero exit status: 1')
58
- end
59
- end
60
15
  end
61
16
  end
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.5.22
4
+ version: 0.5.23
5
5
  platform: ruby
6
6
  authors:
7
7
  - Markus Schirp
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-06-15 00:00:00.000000000 Z
11
+ date: 2014-06-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: parser
@@ -207,39 +207,39 @@ dependencies:
207
207
  - !ruby/object:Gem::Version
208
208
  version: 0.1.5
209
209
  - !ruby/object:Gem::Dependency
210
- name: bundler
210
+ name: parallel
211
211
  requirement: !ruby/object:Gem::Requirement
212
212
  requirements:
213
213
  - - "~>"
214
214
  - !ruby/object:Gem::Version
215
- version: '1.3'
216
- - - ">="
217
- - !ruby/object:Gem::Version
218
- version: 1.3.5
219
- type: :development
215
+ version: 1.0.0
216
+ type: :runtime
220
217
  prerelease: false
221
218
  version_requirements: !ruby/object:Gem::Requirement
222
219
  requirements:
223
220
  - - "~>"
224
221
  - !ruby/object:Gem::Version
225
- version: '1.3'
226
- - - ">="
227
- - !ruby/object:Gem::Version
228
- version: 1.3.5
222
+ version: 1.0.0
229
223
  - !ruby/object:Gem::Dependency
230
- name: parallel
224
+ name: bundler
231
225
  requirement: !ruby/object:Gem::Requirement
232
226
  requirements:
233
227
  - - "~>"
234
228
  - !ruby/object:Gem::Version
235
- version: 1.0.0
229
+ version: '1.3'
230
+ - - ">="
231
+ - !ruby/object:Gem::Version
232
+ version: 1.3.5
236
233
  type: :development
237
234
  prerelease: false
238
235
  version_requirements: !ruby/object:Gem::Requirement
239
236
  requirements:
240
237
  - - "~>"
241
238
  - !ruby/object:Gem::Version
242
- version: 1.0.0
239
+ version: '1.3'
240
+ - - ">="
241
+ - !ruby/object:Gem::Version
242
+ version: 1.3.5
243
243
  description: Mutation testing for ruby
244
244
  email:
245
245
  - mbj@schirp-dso.com
@@ -577,4 +577,3 @@ test_files:
577
577
  - spec/unit/mutant/warning_expectation.rb
578
578
  - spec/unit/mutant/warning_filter_spec.rb
579
579
  - spec/unit/mutant_spec.rb
580
- has_rdoc: