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 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