diff --git a/lib/guard/rspec_formatter.rb b/lib/guard/rspec_formatter.rb index ba645fc8..d615e9d2 100644 --- a/lib/guard/rspec_formatter.rb +++ b/lib/guard/rspec_formatter.rb @@ -60,21 +60,19 @@ def self.spec_path?(path) end def dump_summary(*args) - if self.class.rspec_3? - notification = args[0] - write_summary( - notification.duration, - notification.example_count, - notification.failure_count, - notification.pending_count - ) - else - write_summary(*args) - end - rescue - # nothing really we can do, at least don"t kill the test runner + return write_summary(*args) unless self.class.rspec_3? + + notification = args[0] + write_summary( + notification.duration, + notification.example_count, + notification.failure_count, + notification.pending_count + ) end + private + # Write summary to temporary file for runner def write_summary(duration, total, failures, pending) _write do |f| @@ -83,8 +81,6 @@ def write_summary(duration, total, failures, pending) end end - private - def _write(&block) file = File.expand_path(TEMPORARY_FILE_PATH) FileUtils.mkdir_p(File.dirname(file)) diff --git a/spec/lib/guard/rspec_formatter_spec.rb b/spec/lib/guard/rspec_formatter_spec.rb index 504cb5ad..3ba41a4e 100644 --- a/spec/lib/guard/rspec_formatter_spec.rb +++ b/spec/lib/guard/rspec_formatter_spec.rb @@ -6,7 +6,29 @@ it { is_expected.to be_relative } end - describe "#write_summary" do + describe "#dump_summary" do + def rspec_summary_args(*args) + return args unless ::RSpec::Core::Version::STRING.start_with?("3.") + + n = Struct.new(:duration, :example_count, :failure_count, :pending_count) + [n.new(*args)] + end + + let(:example_dump_summary_args) { rspec_summary_args(123, 3, 1, 0) } + let(:summary_with_no_failures) { rspec_summary_args(123, 3, 0, 0) } + let(:summary_with_only_pending) { rspec_summary_args(123, 3, 0, 1) } + + let(:failed_example) do + result = + if ::RSpec::Core::Version::STRING.start_with?("3.") + double(status: "failed") + else + { status: "failed" } + end + + double(execution_result: result, metadata: { location: spec_filename }) + end + let(:writer) do StringIO.new end @@ -42,23 +64,30 @@ block.call writer end - formatter.write_summary(123, 1, 2, 3) + formatter.dump_summary(*example_dump_summary_args) end - end - - context "with failures" do - let(:spec_filename) { "failed_location_spec.rb" } - let(:failed_example) do - double( - execution_result: { status: "failed" }, - metadata: { location: spec_filename } - ) + context "when writing file fails" do + it "outputs an error" do + allow(FileUtils).to receive(:mkdir_p).and_raise(Errno::EACCES) + expect do + formatter.dump_summary(*example_dump_summary_args) + end.to raise_error(Errno::EACCES) + end end - before do - allow(formatter.class).to receive(:rspec_3?).and_return(false) + context "when writer fails" do + it "outputs an error" do + allow(FileUtils).to receive(:mkdir_p).and_raise(TypeError, "foo") + expect do + formatter.dump_summary(*example_dump_summary_args) + end.to raise_error(TypeError, "foo") + end end + end + + context "with failures" do + let(:spec_filename) { "failed_location_spec.rb" } def expected_output(spec_filename) /^3 examples, 1 failures in 123\.0 seconds\n#{spec_filename}\n$/ @@ -66,7 +95,7 @@ def expected_output(spec_filename) it "writes summary line and failed location in tmp dir" do allow(formatter).to receive(:examples) { [failed_example] } - formatter.write_summary(123, 3, 1, 0) + formatter.dump_summary(*example_dump_summary_args) expect(result).to match expected_output(spec_filename) end @@ -74,31 +103,16 @@ def expected_output(spec_filename) allow(formatter).to receive(:examples). and_return([failed_example, failed_example]) - formatter.write_summary(123, 3, 1, 0) + formatter.dump_summary(*example_dump_summary_args) expect(result).to match expected_output(spec_filename) end - context "for rspec 3" do - let(:notification) do - Struct.new(:duration, :example_count, :failure_count, :pending_count). - new(123, 3, 1, 0) - end - before do - allow(formatter.class).to receive(:rspec_3?).and_return(true) - end - - let(:failed_example) do - double( - execution_result: double(status: "failed"), - metadata: { location: spec_filename } - ) - end + let(:notification) { example_dump_summary_args } - it "writes summary line and failed location" do - allow(formatter).to receive(:examples) { [failed_example] } - formatter.dump_summary(notification) - expect(result).to match expected_output(spec_filename) - end + it "writes summary line and failed location" do + allow(formatter).to receive(:examples) { [failed_example] } + formatter.dump_summary(*notification) + expect(result).to match expected_output(spec_filename) end end @@ -140,14 +154,14 @@ def expected_output(spec_filename) context "with only success" do it "notifies success" do - formatter.write_summary(123, 3, 0, 0) + formatter.dump_summary(*summary_with_no_failures) 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.write_summary(123, 3, 0, 1) + formatter.dump_summary(*summary_with_only_pending) expect(result).to match( /^3 examples, 0 failures \(1 pending\) in 123\.0 seconds\n$/ )