mutant-rspec 0.5.0
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 +7 -0
- data/LICENSE +20 -0
- data/TODO +39 -0
- data/lib/mutant-rspec.rb +5 -0
- data/lib/mutant/rspec.rb +9 -0
- data/lib/mutant/rspec/killer.rb +95 -0
- data/lib/mutant/rspec/strategy.rb +77 -0
- data/spec/unit/mutant/rspec/killer_spec.rb +57 -0
- metadata +103 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 304c77b0e3a947d35a7c2f7eb30dc41e7658e842
|
4
|
+
data.tar.gz: 3fd8950a3f0019550a8583221974d65ed52c85cd
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: f7355ff3af44d76def593142b77aa3439d515d0f1228782c8d516b1f0645769504e508422547c2bcf7047ccc5a0a9daf6c49b518a00e61207ee02f600e2d3a8a
|
7
|
+
data.tar.gz: 06114be8af316a7e89ab54a93ad297d040b5583ccf9bcba4cf02a9b6b68771ebc345fdda8fc8c44e78802859e84aef3fb230582df6183dc7af9a8bb287ace43d
|
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2012-2014 Markus Schirp
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/TODO
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
Code:
|
2
|
+
* Test mutant with dynamically created zombie.
|
3
|
+
* Log all warnings through reporter, so remove random $stderr.puts calls
|
4
|
+
|
5
|
+
Mutations:
|
6
|
+
* Add true masgn mutations
|
7
|
+
* Add binary operator specific mutations (YAY, finally reached this point)
|
8
|
+
* Add some kind of a "do not touch me object" that raises on all messages.
|
9
|
+
It can be used to make sure each literal value is touched.
|
10
|
+
* Replace nil or add "do not touch me object" to literal mutations.
|
11
|
+
* Mutate options on Regexp literals
|
12
|
+
* Add mutations for dynamic regexp symbol and string literals
|
13
|
+
* Mutate "def foo; bar; end" to "def foo; self; end"?
|
14
|
+
* Mutate Block catch "def foo(&block)" and block pass "foo(&block)"
|
15
|
+
* Binary operator mutations
|
16
|
+
* Add timeout to terminate infinite loops
|
17
|
+
|
18
|
+
Example of a negative mutation:
|
19
|
+
Mutations on local variables and arguments prefixed with an underscore would be emitted as
|
20
|
+
negative mutations that must be alive.
|
21
|
+
|
22
|
+
Loader:
|
23
|
+
* Make sure loader does not change visibility of injected mutants
|
24
|
+
|
25
|
+
Killers:
|
26
|
+
* Move test framework specific stuff to strategy
|
27
|
+
* Add a general master <=> killer IPC interface. So different strategies of isolation
|
28
|
+
(fork, vs jruby runtime creation) will work without big impact.
|
29
|
+
|
30
|
+
Strategy:
|
31
|
+
* Aggregate warnings on missing spec files
|
32
|
+
* Provide "expicit files to kill with" strategy
|
33
|
+
|
34
|
+
Matcher:
|
35
|
+
* Allow matches on attr_reader with literal name argument(s)?
|
36
|
+
* Allow matches on define_method with literal name argument?
|
37
|
+
|
38
|
+
jruby-support:
|
39
|
+
* Create a runtime per mutation to kill mutations in isolation
|
data/lib/mutant-rspec.rb
ADDED
data/lib/mutant/rspec.rb
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Mutant
|
4
|
+
module Rspec
|
5
|
+
# Runner for rspec tests
|
6
|
+
class Killer < Mutant::Killer
|
7
|
+
|
8
|
+
private
|
9
|
+
|
10
|
+
# Run rspec test
|
11
|
+
#
|
12
|
+
# @return [true]
|
13
|
+
# when test is NOT successful
|
14
|
+
#
|
15
|
+
# @return [false]
|
16
|
+
# otherwise
|
17
|
+
#
|
18
|
+
# @api private
|
19
|
+
#
|
20
|
+
def run
|
21
|
+
mutation.insert
|
22
|
+
|
23
|
+
groups =
|
24
|
+
if mutation.is_a?(Mutation::Neutral::Noop)
|
25
|
+
[example_groups.first]
|
26
|
+
else
|
27
|
+
example_groups
|
28
|
+
end
|
29
|
+
|
30
|
+
unless groups
|
31
|
+
$stderr.puts("No rspec example groups found for: #{match_prefixes.join(', ')}")
|
32
|
+
return false
|
33
|
+
end
|
34
|
+
|
35
|
+
reporter = RSpec::Core::Reporter.new
|
36
|
+
|
37
|
+
example_groups.each do |group|
|
38
|
+
return true unless group.run(reporter)
|
39
|
+
end
|
40
|
+
|
41
|
+
false
|
42
|
+
end
|
43
|
+
|
44
|
+
# Return match prefixes
|
45
|
+
#
|
46
|
+
# @return [Enumerble<String>]
|
47
|
+
#
|
48
|
+
# @api private
|
49
|
+
#
|
50
|
+
def match_prefixes
|
51
|
+
subject.match_prefixes
|
52
|
+
end
|
53
|
+
|
54
|
+
# Return example groups
|
55
|
+
#
|
56
|
+
# @return [Array<RSpec::Example>]
|
57
|
+
#
|
58
|
+
# @api private
|
59
|
+
#
|
60
|
+
def example_groups
|
61
|
+
match_prefixes.each do |match_expression|
|
62
|
+
example_groups = find_with(match_expression)
|
63
|
+
return example_groups unless example_groups.empty?
|
64
|
+
end
|
65
|
+
|
66
|
+
nil
|
67
|
+
end
|
68
|
+
|
69
|
+
# Return example groups that match expression
|
70
|
+
#
|
71
|
+
# @param [String] match_expression
|
72
|
+
#
|
73
|
+
# @return [Enumerable<String>]
|
74
|
+
#
|
75
|
+
# @api private
|
76
|
+
#
|
77
|
+
def find_with(match_expression)
|
78
|
+
all_example_groups.select do |example_group|
|
79
|
+
example_group.description.start_with?(match_expression)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
# Return all example groups
|
84
|
+
#
|
85
|
+
# @return [Enumerable<RSpec::Example>]
|
86
|
+
#
|
87
|
+
# @api private
|
88
|
+
#
|
89
|
+
def all_example_groups
|
90
|
+
strategy.example_groups
|
91
|
+
end
|
92
|
+
|
93
|
+
end # Killer
|
94
|
+
end # Rspec
|
95
|
+
end # Mutant
|
@@ -0,0 +1,77 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Mutant
|
4
|
+
module Rspec
|
5
|
+
# Rspec killer strategy
|
6
|
+
class Strategy < Mutant::Strategy
|
7
|
+
|
8
|
+
register 'rspec'
|
9
|
+
|
10
|
+
KILLER = Killer::Forking.new(Rspec::Killer)
|
11
|
+
|
12
|
+
# Setup rspec strategy
|
13
|
+
#
|
14
|
+
# @return [self]
|
15
|
+
#
|
16
|
+
# @api private
|
17
|
+
#
|
18
|
+
def setup
|
19
|
+
output = StringIO.new
|
20
|
+
configuration.error_stream = output
|
21
|
+
configuration.output_stream = output
|
22
|
+
options.configure(configuration)
|
23
|
+
configuration.load_spec_files
|
24
|
+
self
|
25
|
+
end
|
26
|
+
memoize :setup
|
27
|
+
|
28
|
+
# Return configuration
|
29
|
+
#
|
30
|
+
# @return [RSpec::Core::Configuration]
|
31
|
+
#
|
32
|
+
# @api private
|
33
|
+
#
|
34
|
+
def configuration
|
35
|
+
RSpec::Core::Configuration.new
|
36
|
+
end
|
37
|
+
memoize :configuration, freezer: :noop
|
38
|
+
|
39
|
+
# Return example groups
|
40
|
+
#
|
41
|
+
# @return [Enumerable<RSpec::Core::ExampleGroup>]
|
42
|
+
#
|
43
|
+
# @api private
|
44
|
+
#
|
45
|
+
def example_groups
|
46
|
+
world.example_groups
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
# Return world
|
52
|
+
#
|
53
|
+
# @return [RSpec::Core::World]
|
54
|
+
#
|
55
|
+
# @api private
|
56
|
+
#
|
57
|
+
def world
|
58
|
+
RSpec.world
|
59
|
+
end
|
60
|
+
memoize :world, freezer: :noop
|
61
|
+
|
62
|
+
# Return options
|
63
|
+
#
|
64
|
+
# @return [RSpec::Core::ConfigurationOptions]
|
65
|
+
#
|
66
|
+
# @api private
|
67
|
+
#
|
68
|
+
def options
|
69
|
+
options = RSpec::Core::ConfigurationOptions.new(%w(--fail-fast spec))
|
70
|
+
options.parse_options
|
71
|
+
options
|
72
|
+
end
|
73
|
+
memoize :options, freezer: :noop
|
74
|
+
|
75
|
+
end # Strategy
|
76
|
+
end # Rspec
|
77
|
+
end # Mutant
|
@@ -0,0 +1,57 @@
|
|
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
|
+
its(:killed?) { should 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
|
+
its(:killed?) { should be(true) }
|
54
|
+
|
55
|
+
it { should be_a(described_class) }
|
56
|
+
end
|
57
|
+
end
|
metadata
ADDED
@@ -0,0 +1,103 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: mutant-rspec
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.5.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Markus Schirp
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-03-02 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: mutant
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 0.5.0
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 0.5.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rspec-core
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 2.14.1
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ~>
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 2.14.1
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: bundler
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ~>
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.3'
|
48
|
+
- - '>='
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
version: 1.3.5
|
51
|
+
type: :development
|
52
|
+
prerelease: false
|
53
|
+
version_requirements: !ruby/object:Gem::Requirement
|
54
|
+
requirements:
|
55
|
+
- - ~>
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: '1.3'
|
58
|
+
- - '>='
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: 1.3.5
|
61
|
+
description: Rspec integration for mutant
|
62
|
+
email:
|
63
|
+
- mbj@schirp-dso.com
|
64
|
+
executables: []
|
65
|
+
extensions: []
|
66
|
+
extra_rdoc_files:
|
67
|
+
- TODO
|
68
|
+
- LICENSE
|
69
|
+
files:
|
70
|
+
- lib/mutant-rspec.rb
|
71
|
+
- lib/mutant/rspec.rb
|
72
|
+
- lib/mutant/rspec/killer.rb
|
73
|
+
- lib/mutant/rspec/strategy.rb
|
74
|
+
- TODO
|
75
|
+
- LICENSE
|
76
|
+
- spec/unit/mutant/rspec/killer_spec.rb
|
77
|
+
homepage: https://github.com/mbj/mutant
|
78
|
+
licenses:
|
79
|
+
- MIT
|
80
|
+
metadata: {}
|
81
|
+
post_install_message:
|
82
|
+
rdoc_options: []
|
83
|
+
require_paths:
|
84
|
+
- lib
|
85
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - '>='
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
91
|
+
requirements:
|
92
|
+
- - '>='
|
93
|
+
- !ruby/object:Gem::Version
|
94
|
+
version: '0'
|
95
|
+
requirements: []
|
96
|
+
rubyforge_project:
|
97
|
+
rubygems_version: 2.0.14
|
98
|
+
signing_key:
|
99
|
+
specification_version: 4
|
100
|
+
summary: Rspec integration for mutant
|
101
|
+
test_files:
|
102
|
+
- spec/unit/mutant/rspec/killer_spec.rb
|
103
|
+
has_rdoc:
|