mutant 0.8.1 → 0.8.2

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: ac3f098a786f3940bb0bdc9b291994aa068fbf3d
4
- data.tar.gz: 4acf7c5f8e0d04bbbe87ad2ebfb403650372cf4a
3
+ metadata.gz: f16485d23238c84b07b2e62df8a1c4af57badb14
4
+ data.tar.gz: e0b9ddb90dccee908622683295235e177d4d7dcf
5
5
  SHA512:
6
- metadata.gz: ce34952eb570ea87bb7169785b556431eb9820dea70261f0772c89e3d648cf70a4f819b9be86448f6b4c8ea88b0721c6f3aa6c3f9e3680127f80c805826c6fb2
7
- data.tar.gz: 89eb14bfeb66f63899033195bfbec8562c821e19fea0aa51997b8e57fcb3897b7de26e0d5b642d14c7c276c50b6d28f3df0fbc23741a5944523ff6e0c5117c2e
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
- # Frequent lookups in MRI make mutation analysis getting stuck on CI
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
- task('metrics:mutant').clear
13
- namespace :metrics do
14
- task :mutant => :coverage do
15
- $stderr.puts 'Mutant self test via zombie not active on CI'
16
- end
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
@@ -1,3 +1,3 @@
1
1
  ---
2
2
  threshold: 18
3
- total_score: 1208
3
+ total_score: 1193
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::Zombifier::File#self.find
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::Integration::Rspec#parse_expression # intentional, private
136
+ - Mutant::Repository::Diff#tracks? # intentional, private
137
+ - Mutant::Repository::Diff#within_working_directory? # intentional, private
137
138
  max_helper_calls: 0
@@ -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, 'w') do |file|
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 [String]
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
- emit(left)
26
- emit(right)
27
- mutate_operator
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 mutate_operator
37
+ def emit_operator_mutations
39
38
  emit(s(INVERSE.fetch(node.type), left, right))
40
39
  end
41
40
 
42
- # Emit condition mutations
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 mutate_operands
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
@@ -16,9 +16,10 @@ module Mutant
16
16
  #
17
17
  # @api private
18
18
  def dispatch
19
- emit_expression_mutations do |node|
20
- !n_self?(node)
21
- end
19
+ emit_singletons
20
+ emit(N_TRUE)
21
+
22
+ emit_expression_mutations { |node| !n_self?(node) }
22
23
  end
23
24
 
24
25
  end # Defined
@@ -24,6 +24,7 @@ module Mutant
24
24
  to_s: %i[to_str],
25
25
  to_i: %i[to_int],
26
26
  to_a: %i[to_ary],
27
+ to_h: %i[to_hash],
27
28
  at: %i[fetch],
28
29
  :[] => %i[at fetch],
29
30
  :== => %i[eql? equal?],
@@ -16,6 +16,7 @@ module Mutant
16
16
  # @api private
17
17
  def dispatch
18
18
  emit_singletons
19
+ emit(N_EMPTY_SUPER)
19
20
  end
20
21
 
21
22
  end # ZSuper
@@ -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]
@@ -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
@@ -21,7 +21,7 @@ module Mutant
21
21
 
22
22
  # Source path
23
23
  #
24
- # @return [String]
24
+ # @return [Pathname]
25
25
  #
26
26
  # @api private
27
27
  def source_path
@@ -1,4 +1,4 @@
1
1
  module Mutant
2
2
  # Current mutant version
3
- VERSION = '0.8.1'.freeze
3
+ VERSION = '0.8.2'.freeze
4
4
  end # Mutant
@@ -114,7 +114,7 @@ module Mutant
114
114
 
115
115
  # Namespaced root node
116
116
  #
117
- # @param [Symbol] namespace
117
+ # @param [Pathname] source_path
118
118
  #
119
119
  # @return [Parser::AST::Node]
120
120
  #
data/meta/and.rb CHANGED
@@ -10,5 +10,4 @@ Mutant::Meta::Example.add do
10
10
  mutation 'false and false'
11
11
  mutation 'true and true'
12
12
  mutation '!true and false'
13
- mutation '!(true and false)'
14
13
  end
data/meta/defined.rb CHANGED
@@ -1,5 +1,7 @@
1
1
  Mutant::Meta::Example.add do
2
2
  source 'defined?(foo)'
3
3
 
4
+ singleton_mutations
4
5
  mutation 'defined?(nil)'
6
+ mutation 'true'
5
7
  end
data/meta/or.rb CHANGED
@@ -10,5 +10,4 @@ Mutant::Meta::Example.add do
10
10
  mutation 'true or true'
11
11
  mutation 'true and false'
12
12
  mutation '!true or false'
13
- mutation '!(true or false)'
14
13
  end
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
@@ -2,6 +2,7 @@ Mutant::Meta::Example.add do
2
2
  source 'super'
3
3
 
4
4
  singleton_mutations
5
+ mutation 'super()'
5
6
  end
6
7
 
7
8
  Mutant::Meta::Example.add do
@@ -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
@@ -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.with('/dev/null', 'w').and_yield(file)
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(:method_line) { 10 }
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(:method_line) { 15 }
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(:method_line) { 24 }
61
- let(:method_arity) { 1 }
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(:method_line) { 29 }
69
- let(:method_arity) { 1 }
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(:method_line) { 66 }
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(:method_line) { 61 }
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(:method_line) { 71 }
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(:method_line) { 78 }
55
- let(:scope) { base::DefinedOnConstant::OutsideNamespace }
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) { described_class.new('from_rev', 'to_rev') }
12
- let(:path) { Pathname.new('foo.rb') }
13
- let(:line_range) { 1..2 }
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
- before do
18
- expect(Kernel).to receive(:system)
19
- .ordered
20
- .with(
21
- *%w[git ls-files --error-unmatch -- foo.rb],
22
- out: File::NULL,
23
- err: File::NULL
24
- ).and_return(git_ls_success?)
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
- %w[
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.1
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-07-24 00:00:00.000000000 Z
11
+ date: 2015-08-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: parser