diff --git a/config/flay.yml b/config/flay.yml index 3b125cc5..3c2258be 100644 --- a/config/flay.yml +++ b/config/flay.yml @@ -1,3 +1,3 @@ --- threshold: 18 -total_score: 1204 +total_score: 1208 diff --git a/config/reek.yml b/config/reek.yml index 00f151f7..76628b8a 100644 --- a/config/reek.yml +++ b/config/reek.yml @@ -130,6 +130,7 @@ UtilityFunction: - Mutant::Integration::Null#call - Mutant::Integration::Rspec#parse_example - Mutant::Meta::Example::Verification#format_mutation + - Mutant::Repository::Diff#tracks? # intentional, private - Mutant::Reporter::CLI::Format::Progressive#new_buffer - Mutant::Reporter::CLI::Printer::StatusProgressive#object # False positive calls super - Mutant::Integration::Rspec#parse_expression # intentional, private diff --git a/lib/mutant/repository.rb b/lib/mutant/repository.rb index 97b2af31..6b230e68 100644 --- a/lib/mutant/repository.rb +++ b/lib/mutant/repository.rb @@ -48,6 +48,8 @@ module Mutant # # @api private def touches?(path, line_range) + return false unless tracks?(path) + command = %W[ git log #{from}...#{to} @@ -61,6 +63,26 @@ module Mutant !stdout.empty? end + private + + # Test if path is tracked in repository + # + # FIXME: Cache results, to avoid spending time on producing redundant results. + # + # @param [Pathname] path + # + # @return [Boolean] + # + # @api private + def tracks?(path) + command = %W[git ls-files --error-unmatch -- #{path}] + Kernel.system( + *command, + out: File::NULL, + err: File::NULL + ) + end + end # Diff end # Repository end # Mutant diff --git a/spec/unit/mutant/repository/diff_spec.rb b/spec/unit/mutant/repository/diff_spec.rb index 4ff24109..92b53d40 100644 --- a/spec/unit/mutant/repository/diff_spec.rb +++ b/spec/unit/mutant/repository/diff_spec.rb @@ -11,49 +11,69 @@ describe Mutant::Repository::Diff do let(:object) { described_class.new('from_rev', 'to_rev') } let(:path) { Pathname.new('foo.rb') } let(:line_range) { 1..2 } - let(:status) { double('Status', success?: success?) } - let(:stdout) { double('Stdout', empty?: stdout_empty?) } - let(:stdout_empty?) { false } subject { object.touches?(path, line_range) } before do - expect(Open3).to receive(:capture2) + expect(Kernel).to receive(:system) .ordered - .with(*expected_git_log_command, binmode: true) - .and_return([stdout, status]) + .with( + *%w[git ls-files --error-unmatch -- foo.rb], + out: File::NULL, + err: File::NULL + ).and_return(git_ls_success?) end - let(:expected_git_log_command) do - %w[ - git log from_rev...to_rev -L 1,2:foo.rb - ] + context 'when file is NOT tracked in repository' do + let(:git_ls_success?) { false } + + it { should be(false) } end - context 'on failure of git log command' do - let(:success?) { false } + context 'when file is tracked in repository' do + let(:git_ls_success?) { true } + let(:status) { double('Status', success?: success?) } + let(:stdout) { double('Stdout', empty?: stdout_empty?) } + let(:stdout_empty?) { false } - it 'raises error' do - expect { subject }.to raise_error( - Mutant::Repository::RepositoryError, - "Command #{expected_git_log_command} failed!" - ) - end - end - - context 'on suuccess of git command' do - let(:success?) { true } - - context 'on empty stdout' do - let(:stdout_empty?) { true } - - it { should be(false) } + before do + expect(Open3).to receive(:capture2) + .ordered + .with(*expected_git_log_command, binmode: true) + .and_return([stdout, status]) end - context 'on non empty stdout' do - let(:stdout_empty?) { false } + let(:expected_git_log_command) do + %w[ + git log from_rev...to_rev -L 1,2:foo.rb + ] + end - it { should be(true) } + context 'on failure of git log command' do + let(:success?) { false } + + it 'raises error' do + expect { subject }.to raise_error( + Mutant::Repository::RepositoryError, + "Command #{expected_git_log_command} failed!" + ) + end + end + + context 'on suuccess of git command' do + let(:success?) { true } + + context 'on empty stdout' do + let(:stdout_empty?) { true } + + it { should be(false) } + end + + context 'on non empty stdout' do + let(:stdout_empty?) { false } + + it { should be(true) } + end end end end