mutant 0.8.1 → 0.8.2
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 +4 -4
- data/Changelog.md +12 -0
- data/README.md +73 -0
- data/Rakefile +14 -9
- data/config/flay.yml +1 -1
- data/config/reek.yml +13 -12
- data/lib/mutant/isolation.rb +2 -1
- data/lib/mutant/matcher/method.rb +3 -2
- data/lib/mutant/mutator/node/binary.rb +28 -8
- data/lib/mutant/mutator/node/defined.rb +4 -3
- data/lib/mutant/mutator/node/send.rb +1 -0
- data/lib/mutant/mutator/node/zsuper.rb +1 -0
- data/lib/mutant/reporter/cli/printer/subject_progress.rb +0 -12
- data/lib/mutant/repository.rb +13 -1
- data/lib/mutant/subject.rb +1 -1
- data/lib/mutant/version.rb +1 -1
- data/lib/mutant/zombifier.rb +1 -1
- data/meta/and.rb +0 -1
- data/meta/defined.rb +2 -0
- data/meta/or.rb +0 -1
- data/meta/send.rb +9 -0
- data/meta/super.rb +1 -0
- data/spec/shared/method_matcher_behavior.rb +4 -0
- data/spec/support/corpus.rb +2 -1
- data/spec/unit/mutant/isolation_spec.rb +3 -1
- data/spec/unit/mutant/matcher/method/instance_spec.rb +15 -10
- data/spec/unit/mutant/matcher/method/singleton_spec.rb +13 -8
- data/spec/unit/mutant/reporter/cli/printer/status_spec.rb +0 -2
- data/spec/unit/mutant/reporter/cli/printer/subject_progress_spec.rb +0 -3
- data/spec/unit/mutant/repository/diff_spec.rb +28 -14
- 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: f16485d23238c84b07b2e62df8a1c4af57badb14
|
4
|
+
data.tar.gz: e0b9ddb90dccee908622683295235e177d4d7dcf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 992b3447fda4a045e9462f292f17da506141b386e9c494d94c13a6807450f9b73826f230e468a883f1177df70db409de9b400d107183d053444061c96ba7193f
|
7
|
+
data.tar.gz: 3c8319ee768ca67e2a0cd9fbf65c5a3652425f73ecc8206bdca143da85f6a16fbf875505f5f14f9038319b5e35615e6a4e8ec0bf5ad2620cca4ed1d8c6e57f0c
|
data/Changelog.md
CHANGED
@@ -1,3 +1,15 @@
|
|
1
|
+
# v0.8.2 2015-08-11
|
2
|
+
|
3
|
+
* Remove invalid mutation `foo or bar` to `!(foo or bar)` see #287
|
4
|
+
* Add mutation from `#to_h` to `#to_hash` #218
|
5
|
+
<<<<<<< 2914e9c8d906540edc1cc7d4bc6393f68db39b8d
|
6
|
+
* Add mutation from `#defined?` to `true` / `false` #334
|
7
|
+
* Add mutation from `super` to `super()` #309
|
8
|
+
=======
|
9
|
+
* Add mutation from `#defined?` to `true` / `false` #399
|
10
|
+
* Reduce framed (multiline) progress reporter noise
|
11
|
+
>>>>>>> Reduce framed progress reporter noise
|
12
|
+
|
1
13
|
# v0.8.1 2015-07-24
|
2
14
|
|
3
15
|
* Add --since flag to constrain mutated subjects based on
|
data/README.md
CHANGED
@@ -118,6 +118,79 @@ Example for a subject like `Foo::Bar#baz` it will run all example groups with de
|
|
118
118
|
`Foo::Bar#baz`, `Foo::Bar` and `Foo`. The order is important, so if mutant finds example groups in the
|
119
119
|
current prefix level, these example groups *must* kill the mutation.
|
120
120
|
|
121
|
+
Reading Reports
|
122
|
+
---------------
|
123
|
+
|
124
|
+
Mutation output is grouped by selection groups. Each group contains three sections:
|
125
|
+
|
126
|
+
1. An identifier for the current group.
|
127
|
+
|
128
|
+
**Format**:
|
129
|
+
|
130
|
+
```text
|
131
|
+
[SUBJECT EXPRESSION]:[SOURCE LOCATION]:[LINENO]
|
132
|
+
```
|
133
|
+
|
134
|
+
**Example**:
|
135
|
+
|
136
|
+
```text
|
137
|
+
Book#add_page:Book#add_page:/home/dev/mutant-examples/lib/book.rb:18
|
138
|
+
```
|
139
|
+
|
140
|
+
2. A list of specs that mutant ran to try to kill mutations for the current group.
|
141
|
+
|
142
|
+
**Format**:
|
143
|
+
|
144
|
+
```text
|
145
|
+
- [INTEGRATION]:0:[SPEC LOCATION]:[SPEC DESCRIPTION]
|
146
|
+
- [INTEGRATION]:1:[SPEC LOCATION]:[SPEC DESCRIPTION]
|
147
|
+
```
|
148
|
+
|
149
|
+
**Example**:
|
150
|
+
|
151
|
+
```text
|
152
|
+
- rspec:0:./spec/unit/book_spec.rb:9/Book#add_page should return self
|
153
|
+
- rspec:1:./spec/unit/book_spec.rb:13/Book#add_page should add page to book
|
154
|
+
```
|
155
|
+
|
156
|
+
3. A list of unkilled mutations diffed against the original unparsed source
|
157
|
+
|
158
|
+
**Format**:
|
159
|
+
|
160
|
+
```text
|
161
|
+
[MUTATION TYPE]:[SUBJECT EXPRESSION]:[SOURCE LOCATION]:[SOURCE LINENO]:[IDENTIFIER]
|
162
|
+
[DIFF]
|
163
|
+
-----------------------
|
164
|
+
```
|
165
|
+
|
166
|
+
- `[MUTATION TYPE]` will be one of the following:
|
167
|
+
- `evil` - a mutation of your source was not killed by your tests
|
168
|
+
- `neutral` your original source was injected and one or more tests failed
|
169
|
+
- `[IDENTIFIER]` - Unique identifier for this mutation
|
170
|
+
|
171
|
+
**Example**:
|
172
|
+
|
173
|
+
```diff
|
174
|
+
evil:Book#add_page:Book#add_page:/home/dev/mutant-examples/lib/book.rb:18:01f69
|
175
|
+
@@ -1,6 +1,6 @@
|
176
|
+
def add_page(page)
|
177
|
+
- @pages << page
|
178
|
+
+ @pages
|
179
|
+
@index[page.number] = page
|
180
|
+
self
|
181
|
+
end
|
182
|
+
-----------------------
|
183
|
+
evil:Book#add_page:Book#add_page:/home/dev/mutant-examples/lib/book.rb:18:b1ff2
|
184
|
+
@@ -1,6 +1,6 @@
|
185
|
+
def add_page(page)
|
186
|
+
- @pages << page
|
187
|
+
+ self
|
188
|
+
@index[page.number] = page
|
189
|
+
self
|
190
|
+
end
|
191
|
+
-----------------------
|
192
|
+
```
|
193
|
+
|
121
194
|
Rails
|
122
195
|
-------
|
123
196
|
|
data/Rakefile
CHANGED
@@ -4,16 +4,21 @@ require 'devtools'
|
|
4
4
|
|
5
5
|
Devtools.init_rake_tasks
|
6
6
|
|
7
|
-
|
8
|
-
# See: https://github.com/mbj/mutant/issues/265
|
9
|
-
if ENV['CI']
|
10
|
-
Rake.application.load_imports
|
7
|
+
Rake.application.load_imports
|
11
8
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
9
|
+
task('metrics:mutant').clear
|
10
|
+
namespace :metrics do
|
11
|
+
task :mutant => :coverage do
|
12
|
+
success = Kernel.system(*%w[
|
13
|
+
bundle exec mutant
|
14
|
+
--zombie
|
15
|
+
--use rspec
|
16
|
+
--include lib
|
17
|
+
--require mutant
|
18
|
+
--since HEAD~1
|
19
|
+
--
|
20
|
+
Mutant*
|
21
|
+
]) or fail 'Mutant task is not successful'
|
17
22
|
end
|
18
23
|
end
|
19
24
|
|
data/config/flay.yml
CHANGED
data/config/reek.yml
CHANGED
@@ -43,12 +43,12 @@ NestedIterators:
|
|
43
43
|
- Mutant#self.singleton_subclass_instance
|
44
44
|
- Mutant::CLI#parse
|
45
45
|
- Mutant::Isolation::Fork#self.call
|
46
|
-
- Mutant::Mutator::Util::Array::Element#dispatch
|
47
|
-
- Mutant::Mutator::Node::Resbody#mutate_captures
|
48
46
|
- Mutant::Mutator::Node::Arguments#emit_argument_mutations
|
47
|
+
- Mutant::Mutator::Node::Resbody#mutate_captures
|
48
|
+
- Mutant::Mutator::Util::Array::Element#dispatch
|
49
|
+
- Mutant::Parallel::Master#run
|
49
50
|
- Mutant::RequireHighjack#self.call
|
50
51
|
- Mutant::Selector::Expression#call
|
51
|
-
- Mutant::Parallel::Master#run
|
52
52
|
- Parser::Lexer#self.new
|
53
53
|
max_allowed_nesting: 1
|
54
54
|
ignore_iterators: []
|
@@ -70,26 +70,26 @@ TooManyMethods:
|
|
70
70
|
enabled: true
|
71
71
|
exclude:
|
72
72
|
- Mutant::CLI
|
73
|
-
- Mutant::Mutator::Node
|
74
73
|
- Mutant::Meta::Example::Verification
|
74
|
+
- Mutant::Mutator::Node
|
75
75
|
- Mutant::Parallel::Master
|
76
76
|
max_methods: 10
|
77
77
|
TooManyStatements:
|
78
78
|
enabled: true
|
79
79
|
exclude:
|
80
|
+
- Mutant::CLI#add_debug_options
|
81
|
+
- Mutant::CLI#add_environment_options
|
80
82
|
- Mutant::Isolation::Fork#self.call
|
81
|
-
- Mutant::Reporter::CLI::Printer::EnvProgress#run
|
82
83
|
- Mutant::Reporter::CLI::Printer::Config#run
|
83
|
-
- Mutant::
|
84
|
-
- Mutant::CLI#add_environment_options
|
85
|
-
- Mutant::CLI#add_debug_options
|
84
|
+
- Mutant::Reporter::CLI::Printer::EnvProgress#run
|
86
85
|
- Mutant::Runner#run_driver
|
86
|
+
- Mutant::Zombifier::File#self.find
|
87
87
|
max_statements: 7
|
88
88
|
UncommunicativeMethodName:
|
89
89
|
enabled: true
|
90
90
|
exclude:
|
91
|
-
- Mutant::Mutation#sha1
|
92
91
|
- Mutant::AST::Sexp#s
|
92
|
+
- Mutant::Mutation#sha1
|
93
93
|
reject:
|
94
94
|
- !ruby/regexp /^[a-z]$/
|
95
95
|
- !ruby/regexp /[0-9]$/
|
@@ -124,14 +124,15 @@ UnusedParameters:
|
|
124
124
|
UtilityFunction:
|
125
125
|
enabled: true
|
126
126
|
exclude:
|
127
|
-
- Mutant::Actor::Env#new_mailbox
|
128
127
|
- Mutant::AST::Sexp#s
|
128
|
+
- Mutant::Actor::Env#new_mailbox
|
129
129
|
- Mutant::CLI#reporter
|
130
130
|
- Mutant::Integration::Null#call
|
131
131
|
- Mutant::Integration::Rspec#parse_example
|
132
|
+
- Mutant::Integration::Rspec#parse_expression # intentional, private
|
132
133
|
- Mutant::Meta::Example::Verification#format_mutation
|
133
|
-
- Mutant::Repository::Diff#tracks? # intentional, private
|
134
134
|
- Mutant::Reporter::CLI::Format::Progressive#new_buffer
|
135
135
|
- Mutant::Reporter::CLI::Printer::StatusProgressive#object # False positive calls super
|
136
|
-
- Mutant::
|
136
|
+
- Mutant::Repository::Diff#tracks? # intentional, private
|
137
|
+
- Mutant::Repository::Diff#within_working_directory? # intentional, private
|
137
138
|
max_helper_calls: 0
|
data/lib/mutant/isolation.rb
CHANGED
@@ -39,9 +39,10 @@ module Mutant
|
|
39
39
|
# @api private
|
40
40
|
def self.call(&block)
|
41
41
|
IO.pipe(binmode: true) do |reader, writer|
|
42
|
+
writer.binmode
|
42
43
|
begin
|
43
44
|
pid = Process.fork do
|
44
|
-
File.open(File::NULL,
|
45
|
+
File.open(File::NULL, File::WRONLY) do |file|
|
45
46
|
$stderr.reopen(file)
|
46
47
|
reader.close
|
47
48
|
writer.write(Marshal.dump(block.call))
|
@@ -77,12 +77,13 @@ module Mutant
|
|
77
77
|
|
78
78
|
# Path to source
|
79
79
|
#
|
80
|
-
# @return [
|
80
|
+
# @return [Pathname]
|
81
81
|
#
|
82
82
|
# @api private
|
83
83
|
def source_path
|
84
|
-
source_location.first
|
84
|
+
Pathname.new(source_location.first)
|
85
85
|
end
|
86
|
+
memoize :source_path
|
86
87
|
|
87
88
|
# Source file line
|
88
89
|
#
|
@@ -22,10 +22,9 @@ module Mutant
|
|
22
22
|
# @api private
|
23
23
|
def dispatch
|
24
24
|
emit_singletons
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
mutate_operands
|
25
|
+
emit_promotions
|
26
|
+
emit_operator_mutations
|
27
|
+
emit_left_negation
|
29
28
|
emit_left_mutations
|
30
29
|
emit_right_mutations
|
31
30
|
end
|
@@ -35,18 +34,39 @@ module Mutant
|
|
35
34
|
# @return [undefined]
|
36
35
|
#
|
37
36
|
# @api private
|
38
|
-
def
|
37
|
+
def emit_operator_mutations
|
39
38
|
emit(s(INVERSE.fetch(node.type), left, right))
|
40
39
|
end
|
41
40
|
|
42
|
-
# Emit
|
41
|
+
# Emit promotions
|
42
|
+
#
|
43
|
+
# @return [undefined]
|
44
|
+
#
|
45
|
+
# @api private
|
46
|
+
#
|
47
|
+
def emit_promotions
|
48
|
+
emit(left)
|
49
|
+
emit(right)
|
50
|
+
end
|
51
|
+
|
52
|
+
# Emit left negation
|
53
|
+
#
|
54
|
+
# We do not emit right negation as the `and` and `or` nodes
|
55
|
+
# in ruby are also used for control flow.
|
56
|
+
#
|
57
|
+
# Irrespectable of their syntax, aka `||` parses internally to `or`.
|
58
|
+
#
|
59
|
+
# `do_a or do_b`. Negating left makes sense, negating right
|
60
|
+
# only when the result is actualy used.
|
61
|
+
#
|
62
|
+
# It *would* be possible to emit the right negation in case the use of the result is proved.
|
63
|
+
# Like parent is an assignment to an {l,i}var. Dunno if we ever get the time to do that.
|
43
64
|
#
|
44
65
|
# @return [undefined]
|
45
66
|
#
|
46
67
|
# @api private
|
47
|
-
def
|
68
|
+
def emit_left_negation
|
48
69
|
emit(s(node.type, n_not(left), right))
|
49
|
-
emit(n_not(node))
|
50
70
|
end
|
51
71
|
|
52
72
|
end # Binary
|
@@ -28,7 +28,6 @@ module Mutant
|
|
28
28
|
print_mutation_results
|
29
29
|
print_progress_bar_finish
|
30
30
|
print_stats
|
31
|
-
print_tests
|
32
31
|
end
|
33
32
|
|
34
33
|
private
|
@@ -50,17 +49,6 @@ module Mutant
|
|
50
49
|
)
|
51
50
|
end
|
52
51
|
|
53
|
-
# Print tests
|
54
|
-
#
|
55
|
-
# @return [undefined]
|
56
|
-
#
|
57
|
-
# @api private
|
58
|
-
def print_tests
|
59
|
-
tests.each do |test|
|
60
|
-
puts "- #{test.identification}"
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
52
|
# Print progress bar finish
|
65
53
|
#
|
66
54
|
# @return [undefined]
|
data/lib/mutant/repository.rb
CHANGED
@@ -48,7 +48,7 @@ module Mutant
|
|
48
48
|
#
|
49
49
|
# @api private
|
50
50
|
def touches?(path, line_range)
|
51
|
-
return false unless tracks?(path)
|
51
|
+
return false unless within_working_directory?(path) && tracks?(path)
|
52
52
|
|
53
53
|
command = %W[
|
54
54
|
git log
|
@@ -83,6 +83,18 @@ module Mutant
|
|
83
83
|
)
|
84
84
|
end
|
85
85
|
|
86
|
+
# Test if the path is within the current working directory
|
87
|
+
#
|
88
|
+
# @param [Pathname] path
|
89
|
+
#
|
90
|
+
# @return [TrueClass, nil]
|
91
|
+
#
|
92
|
+
# @api private
|
93
|
+
def within_working_directory?(path)
|
94
|
+
working_directory = Pathname.pwd
|
95
|
+
path.ascend { |parent| return true if working_directory.eql?(parent) }
|
96
|
+
end
|
97
|
+
|
86
98
|
end # Diff
|
87
99
|
end # Repository
|
88
100
|
end # Mutant
|
data/lib/mutant/subject.rb
CHANGED
data/lib/mutant/version.rb
CHANGED
data/lib/mutant/zombifier.rb
CHANGED
data/meta/and.rb
CHANGED
data/meta/defined.rb
CHANGED
data/meta/or.rb
CHANGED
data/meta/send.rb
CHANGED
@@ -118,6 +118,15 @@ Mutant::Meta::Example.add do
|
|
118
118
|
mutation 'foo.to_int'
|
119
119
|
end
|
120
120
|
|
121
|
+
Mutant::Meta::Example.add do
|
122
|
+
source 'foo.to_h'
|
123
|
+
|
124
|
+
singleton_mutations
|
125
|
+
mutation 'foo'
|
126
|
+
mutation 'self.to_h'
|
127
|
+
mutation 'foo.to_hash'
|
128
|
+
end
|
129
|
+
|
121
130
|
Mutant::Meta::Example.add do
|
122
131
|
source 'foo == bar'
|
123
132
|
|
data/meta/super.rb
CHANGED
@@ -28,6 +28,10 @@ RSpec.shared_examples_for 'a method matcher' do
|
|
28
28
|
expect(context.scope).to eql(scope)
|
29
29
|
end
|
30
30
|
|
31
|
+
it 'should have the correct source path in context' do
|
32
|
+
expect(context.source_path).to eql(source_path)
|
33
|
+
end
|
34
|
+
|
31
35
|
it 'should have the correct node type' do
|
32
36
|
expect(node.type).to be(type)
|
33
37
|
end
|
data/spec/support/corpus.rb
CHANGED
@@ -3,13 +3,14 @@ require 'anima'
|
|
3
3
|
require 'mutant'
|
4
4
|
|
5
5
|
module MutantSpec
|
6
|
+
ROOT = Pathname.new(__FILE__).parent.parent.parent
|
7
|
+
|
6
8
|
# Namespace module for corpus testing
|
7
9
|
#
|
8
10
|
# rubocop:disable MethodLength
|
9
11
|
module Corpus
|
10
12
|
# Project under corpus test
|
11
13
|
# rubocop:disable ClassLength
|
12
|
-
ROOT = Pathname.new(__FILE__).parent.parent.parent
|
13
14
|
TMP = ROOT.join('tmp').freeze
|
14
15
|
|
15
16
|
class Project
|
@@ -72,13 +72,15 @@ RSpec.describe Mutant::Isolation::Fork do
|
|
72
72
|
expect(IO).to receive(:pipe).with(binmode: true).ordered do |&block|
|
73
73
|
block.call([reader, writer])
|
74
74
|
end
|
75
|
+
expect(writer).to receive(:binmode).ordered
|
75
76
|
end
|
76
77
|
|
77
78
|
it 'when fork succeeds' do
|
78
79
|
pid = double('PID')
|
79
80
|
expect(Process).to receive(:fork).ordered.and_yield.and_return(pid)
|
80
81
|
file = double('file')
|
81
|
-
expect(File).to receive(:open).ordered
|
82
|
+
expect(File).to receive(:open).ordered
|
83
|
+
.with(File::NULL, File::WRONLY).and_yield(file)
|
82
84
|
expect($stderr).to receive(:reopen).ordered.with(file)
|
83
85
|
expect(reader).to receive(:close).ordered
|
84
86
|
expect(writer).to receive(:write).ordered.with(Marshal.dump(:foo))
|
@@ -41,38 +41,43 @@ RSpec.describe Mutant::Matcher::Method::Instance do
|
|
41
41
|
end
|
42
42
|
|
43
43
|
context 'when method is defined once' do
|
44
|
-
let(:scope) { base::DefinedOnce
|
45
|
-
let(:
|
44
|
+
let(:scope) { base::DefinedOnce }
|
45
|
+
let(:source_path) { MutantSpec::ROOT.join('test_app/lib/test_app.rb') }
|
46
|
+
let(:method_line) { 10 }
|
46
47
|
|
47
48
|
it_should_behave_like 'a method matcher'
|
48
49
|
end
|
49
50
|
|
50
51
|
context 'when method is defined once with a memoizer' do
|
51
|
-
let(:scope) { base::WithMemoizer
|
52
|
-
let(:
|
52
|
+
let(:scope) { base::WithMemoizer }
|
53
|
+
let(:source_path) { MutantSpec::ROOT.join('test_app/lib/test_app.rb') }
|
54
|
+
let(:method_line) { 15 }
|
53
55
|
|
54
56
|
it_should_behave_like 'a method matcher'
|
55
57
|
end
|
56
58
|
|
57
59
|
context 'when method is defined multiple times' do
|
58
60
|
context 'on different lines' do
|
59
|
-
let(:scope) { base::DefinedMultipleTimes::DifferentLines
|
60
|
-
let(:
|
61
|
-
let(:
|
61
|
+
let(:scope) { base::DefinedMultipleTimes::DifferentLines }
|
62
|
+
let(:source_path) { MutantSpec::ROOT.join('test_app/lib/test_app.rb') }
|
63
|
+
let(:method_line) { 24 }
|
64
|
+
let(:method_arity) { 1 }
|
62
65
|
|
63
66
|
it_should_behave_like 'a method matcher'
|
64
67
|
end
|
65
68
|
|
66
69
|
context 'on the same line' do
|
67
|
-
let(:scope) { base::DefinedMultipleTimes::SameLineSameScope
|
68
|
-
let(:
|
69
|
-
let(:
|
70
|
+
let(:scope) { base::DefinedMultipleTimes::SameLineSameScope }
|
71
|
+
let(:source_path) { MutantSpec::ROOT.join('test_app/lib/test_app.rb') }
|
72
|
+
let(:method_line) { 29 }
|
73
|
+
let(:method_arity) { 1 }
|
70
74
|
|
71
75
|
it_should_behave_like 'a method matcher'
|
72
76
|
end
|
73
77
|
|
74
78
|
context 'on the same line with different scope' do
|
75
79
|
let(:scope) { base::DefinedMultipleTimes::SameLineDifferentScope }
|
80
|
+
let(:source_path) { MutantSpec::ROOT.join('test_app/lib/test_app.rb') }
|
76
81
|
let(:method_line) { 33 }
|
77
82
|
let(:method_arity) { 1 }
|
78
83
|
|
@@ -21,8 +21,9 @@ RSpec.describe Mutant::Matcher::Method::Singleton, '#each' do
|
|
21
21
|
context 'on singleton methods' do
|
22
22
|
|
23
23
|
context 'when also defined on lvar' do
|
24
|
-
let(:scope) { base::AlsoDefinedOnLvar
|
25
|
-
let(:
|
24
|
+
let(:scope) { base::AlsoDefinedOnLvar }
|
25
|
+
let(:source_path) { MutantSpec::ROOT.join('test_app/lib/test_app.rb') }
|
26
|
+
let(:method_line) { 66 }
|
26
27
|
|
27
28
|
it_should_behave_like 'a method matcher'
|
28
29
|
|
@@ -35,8 +36,9 @@ RSpec.describe Mutant::Matcher::Method::Singleton, '#each' do
|
|
35
36
|
end
|
36
37
|
|
37
38
|
context 'when defined on self' do
|
38
|
-
let(:scope) { base::DefinedOnSelf
|
39
|
-
let(:
|
39
|
+
let(:scope) { base::DefinedOnSelf }
|
40
|
+
let(:source_path) { MutantSpec::ROOT.join('test_app/lib/test_app.rb') }
|
41
|
+
let(:method_line) { 61 }
|
40
42
|
|
41
43
|
it_should_behave_like 'a method matcher'
|
42
44
|
end
|
@@ -44,15 +46,17 @@ RSpec.describe Mutant::Matcher::Method::Singleton, '#each' do
|
|
44
46
|
context 'when defined on constant' do
|
45
47
|
|
46
48
|
context 'inside namespace' do
|
47
|
-
let(:scope) { base::DefinedOnConstant::InsideNamespace
|
48
|
-
let(:
|
49
|
+
let(:scope) { base::DefinedOnConstant::InsideNamespace }
|
50
|
+
let(:source_path) { MutantSpec::ROOT.join('test_app/lib/test_app.rb') }
|
51
|
+
let(:method_line) { 71 }
|
49
52
|
|
50
53
|
it_should_behave_like 'a method matcher'
|
51
54
|
end
|
52
55
|
|
53
56
|
context 'outside namespace' do
|
54
|
-
let(:
|
55
|
-
let(:
|
57
|
+
let(:scope) { base::DefinedOnConstant::OutsideNamespace }
|
58
|
+
let(:source_path) { MutantSpec::ROOT.join('test_app/lib/test_app.rb') }
|
59
|
+
let(:method_line) { 78 }
|
56
60
|
|
57
61
|
it_should_behave_like 'a method matcher'
|
58
62
|
end
|
@@ -61,6 +65,7 @@ RSpec.describe Mutant::Matcher::Method::Singleton, '#each' do
|
|
61
65
|
context 'when defined multiple times in the same line' do
|
62
66
|
context 'with method on different scope' do
|
63
67
|
let(:scope) { base::DefinedMultipleTimes::SameLine::DifferentScope }
|
68
|
+
let(:source_path) { MutantSpec::ROOT.join('test_app/lib/test_app.rb') }
|
64
69
|
let(:method_line) { 97 }
|
65
70
|
let(:method_arity) { 1 }
|
66
71
|
|
@@ -107,7 +107,6 @@ RSpec.describe Mutant::Reporter::CLI::Printer::Status do
|
|
107
107
|
subject-a mutations: 2
|
108
108
|
F.
|
109
109
|
(01/02) 50% - killtime: 2.00s runtime: 2.00s overhead: 0.00s
|
110
|
-
- test-a
|
111
110
|
REPORT
|
112
111
|
end
|
113
112
|
|
@@ -136,7 +135,6 @@ RSpec.describe Mutant::Reporter::CLI::Printer::Status do
|
|
136
135
|
subject-a mutations: 2
|
137
136
|
..
|
138
137
|
(02/02) 100% - killtime: 2.00s runtime: 2.00s overhead: 0.00s
|
139
|
-
- test-a
|
140
138
|
REPORT
|
141
139
|
end
|
142
140
|
end
|
@@ -9,7 +9,6 @@ RSpec.describe Mutant::Reporter::CLI::Printer::SubjectProgress do
|
|
9
9
|
subject-a mutations: 2
|
10
10
|
..
|
11
11
|
(02/02) 100% - killtime: 2.00s runtime: 2.00s overhead: 0.00s
|
12
|
-
- test-a
|
13
12
|
STR
|
14
13
|
end
|
15
14
|
|
@@ -20,7 +19,6 @@ RSpec.describe Mutant::Reporter::CLI::Printer::SubjectProgress do
|
|
20
19
|
subject-a mutations: 2
|
21
20
|
F.
|
22
21
|
(01/02) 50% - killtime: 2.00s runtime: 2.00s overhead: 0.00s
|
23
|
-
- test-a
|
24
22
|
STR
|
25
23
|
end
|
26
24
|
|
@@ -30,7 +28,6 @@ RSpec.describe Mutant::Reporter::CLI::Printer::SubjectProgress do
|
|
30
28
|
it_reports <<-'STR'
|
31
29
|
subject-a mutations: 2
|
32
30
|
(00/02) 100% - killtime: 0.00s runtime: 0.00s overhead: 0.00s
|
33
|
-
- test-a
|
34
31
|
STR
|
35
32
|
end
|
36
33
|
end
|
@@ -8,25 +8,39 @@ describe Mutant::Repository::Diff do
|
|
8
8
|
end
|
9
9
|
|
10
10
|
describe '#touches?' do
|
11
|
-
let(:object)
|
12
|
-
let(:path)
|
13
|
-
let(:line_range)
|
11
|
+
let(:object) { described_class.new('from_rev', 'to_rev') }
|
12
|
+
let(:path) { Pathname.pwd.join('foo.rb') }
|
13
|
+
let(:line_range) { 1..2 }
|
14
14
|
|
15
15
|
subject { object.touches?(path, line_range) }
|
16
16
|
|
17
|
-
|
18
|
-
|
19
|
-
.
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
17
|
+
shared_context 'test if git tracks the file' do
|
18
|
+
before do
|
19
|
+
expect(Kernel).to receive(:system)
|
20
|
+
.ordered
|
21
|
+
.with(
|
22
|
+
*%W[git ls-files --error-unmatch -- #{path}],
|
23
|
+
out: File::NULL,
|
24
|
+
err: File::NULL
|
25
|
+
).and_return(git_ls_success?)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
context 'when file is in a different subdirectory' do
|
30
|
+
let(:path) { Pathname.new('/foo.rb') }
|
31
|
+
|
32
|
+
before do
|
33
|
+
expect(Kernel).to_not receive(:system)
|
34
|
+
end
|
35
|
+
|
36
|
+
it { should be(false) }
|
25
37
|
end
|
26
38
|
|
27
39
|
context 'when file is NOT tracked in repository' do
|
28
40
|
let(:git_ls_success?) { false }
|
29
41
|
|
42
|
+
include_context 'test if git tracks the file'
|
43
|
+
|
30
44
|
it { should be(false) }
|
31
45
|
end
|
32
46
|
|
@@ -36,6 +50,8 @@ describe Mutant::Repository::Diff do
|
|
36
50
|
let(:stdout) { double('Stdout', empty?: stdout_empty?) }
|
37
51
|
let(:stdout_empty?) { false }
|
38
52
|
|
53
|
+
include_context 'test if git tracks the file'
|
54
|
+
|
39
55
|
before do
|
40
56
|
expect(Open3).to receive(:capture2)
|
41
57
|
.ordered
|
@@ -44,9 +60,7 @@ describe Mutant::Repository::Diff do
|
|
44
60
|
end
|
45
61
|
|
46
62
|
let(:expected_git_log_command) do
|
47
|
-
%
|
48
|
-
git log from_rev...to_rev -L 1,2:foo.rb
|
49
|
-
]
|
63
|
+
%W[git log from_rev...to_rev -L 1,2:#{path}]
|
50
64
|
end
|
51
65
|
|
52
66
|
context 'on failure of git log command' do
|
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.8.
|
4
|
+
version: 0.8.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Markus Schirp
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-08-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: parser
|