Skip to content

Commit

Permalink
Merge pull request #244 from slowjack2k/243_fix_example_groups
Browse files Browse the repository at this point in the history
Fix #234
Rerun failed spec with example groups in different files does not work.
  • Loading branch information
thibaudgg committed Jan 9, 2014
2 parents 17c87e9 + ef3734a commit d5a63f2
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 10 deletions.
38 changes: 35 additions & 3 deletions lib/guard/rspec/formatter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,37 @@ class RSpec
class Formatter < ::RSpec::Core::Formatters::BaseFormatter
TEMPORARY_FILE_PATH = './tmp/rspec_guard_result'

# rspec issue https://github.com/rspec/rspec-core/issues/793
def self.extract_spec_location(metadata)
root_metadata = metadata
location = metadata[:location]

until spec_path?(location)
metadata = metadata[:example_group]

if !metadata
Guard::UI.warning "no spec file found for #{root_metadata[:location]}"
return root_metadata[:location]
end

location = (metadata[:location] || "").split(':').first # rspec issue https://github.com/rspec/rspec-core/issues/1243
end

location
end

def self.spec_path?(path)
path ||= ""
flags = File::FNM_PATHNAME | File::FNM_DOTMATCH
if File.const_defined?(:FNM_EXTGLOB) # ruby >= 2
flags |= File::FNM_EXTGLOB
end
File.fnmatch(::RSpec.configuration.pattern, path.sub(/:\d+\z/, ''), flags)
end

# Write summary to temporary file for runner
def dump_summary(duration, total, failures, pending)
FileUtils.mkdir_p('tmp')
File.open(TEMPORARY_FILE_PATH, 'w') do |f|
write do |f|
f.puts _message(total, failures, pending, duration)
f.puts _failed_paths.join("\n") if failures > 0
end
Expand All @@ -19,9 +46,14 @@ def dump_summary(duration, total, failures, pending)

private

def write(&block)
FileUtils.mkdir_p('tmp')
File.open(TEMPORARY_FILE_PATH, 'w', &block)
end

def _failed_paths
failed = examples.select { |e| e.execution_result[:status] == 'failed' }
failed.map { |e| e.metadata[:location] }
failed.map { |e| self.class.extract_spec_location(e.metadata) }.sort.uniq
end

def _message(example_count, failure_count, pending_count, duration)
Expand Down
60 changes: 53 additions & 7 deletions spec/lib/guard/rspec/formatter_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,37 +3,83 @@
require 'guard/rspec/formatter'

describe Guard::RSpec::Formatter do
let(:formatter) { Guard::RSpec::Formatter.new(StringIO.new) }
let(:writer){
StringIO.new
}
let(:formatter) {
Guard::RSpec::Formatter.new(StringIO.new).tap{|formatter|
formatter.stub(:write) do |&block|
block.call writer
end
}
}

describe '#dump_summary' do
after { File.delete('./tmp/rspec_guard_result') }

let(:result){
writer.rewind
writer.read
}


context 'with failures' do
let(:spec_filename){
'failed_location_spec.rb'
}

let(:failed_example) { double(
execution_result: { status: 'failed' },
metadata: { location: 'failed_location' }
metadata: { location: spec_filename }
) }

it 'writes summary line and failed location in tmp dir' do
allow(formatter).to receive(:examples) { [failed_example] }
formatter.dump_summary(123, 3, 1, 0)
result = File.open('./tmp/rspec_guard_result').read
expect(result).to match /^3 examples, 1 failures in 123\.0 seconds\nfailed_location\n$/
expect(result).to match /^3 examples, 1 failures in 123\.0 seconds\n#{spec_filename}\n$/
end

it 'writes only uniq filenames out' do
allow(formatter).to receive(:examples) { [failed_example, failed_example] }
formatter.dump_summary(123, 3, 1, 0)
expect(result).to match /^3 examples, 1 failures in 123\.0 seconds\n#{spec_filename}\n$/
end

end

it "should find the spec file for shared examples" do
metadata = {:location => './spec/support/breadcrumbs.rb:75',
:example_group => {:location => './spec/requests/breadcrumbs_spec.rb:218'}
}

expect(described_class.extract_spec_location(metadata)).to start_with './spec/requests/breadcrumbs_spec.rb'
end

it "should return only the spec file without line number for shared examples" do
metadata = {:location => './spec/support/breadcrumbs.rb:75',
:example_group => {:location => './spec/requests/breadcrumbs_spec.rb:218'}
}

expect(described_class.extract_spec_location(metadata)).to eq './spec/requests/breadcrumbs_spec.rb'
end

it "should return location of the root spec when a shared examples has no location" do
metadata = {:location => './spec/support/breadcrumbs.rb:75',
:example_group => {}
}

expect(described_class.extract_spec_location(metadata)).to eq metadata[:location]
end

context 'with only success' do
it 'notifies success' do
formatter.dump_summary(123, 3, 0, 0)
result = File.open('./tmp/rspec_guard_result').read
expect(result).to match /^3 examples, 0 failures in 123\.0 seconds\n$/
end
end

context 'with pending' do
it "notifies pending too" do
formatter.dump_summary(123, 3, 0, 1)
result = File.open('./tmp/rspec_guard_result').read
expect(result).to match /^3 examples, 0 failures \(1 pending\) in 123\.0 seconds\n$/
end
end
Expand Down

0 comments on commit d5a63f2

Please sign in to comment.