From 99ad590af3a19824b1bf0c65faeecf3a0d570501 Mon Sep 17 00:00:00 2001 From: matrinox Date: Mon, 12 Dec 2016 10:49:57 -0800 Subject: [PATCH 1/3] Default example status to unknown if corrupt ----------------------------------------------------------- On branch master - Mon 12 Dec 2016 10:49:57 PST by matrinox --- lib/rspec/core/configuration.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/rspec/core/configuration.rb b/lib/rspec/core/configuration.rb index 10a59a85a4..5ff58726cd 100644 --- a/lib/rspec/core/configuration.rb +++ b/lib/rspec/core/configuration.rb @@ -980,7 +980,7 @@ def last_run_statuses if (path = example_status_persistence_file_path) begin ExampleStatusPersister.load_from(path).inject(statuses) do |hash, example| - hash[example.fetch(:example_id)] = example.fetch(:status) + hash[example.fetch(:example_id)] = example.fetch(:status, UNKNOWN_STATUS) hash end rescue SystemCallError => e From 8a38e97d117b20c29c5d95a15772c913807eeda4 Mon Sep 17 00:00:00 2001 From: matrinox Date: Mon, 20 Mar 2017 12:01:23 -0700 Subject: [PATCH 2/3] Add spec for when examples.txt file are corrupted ----------------------------------------------------------- On branch master - Mon 20 Mar 2017 12:01:23 PDT by matrinox --- spec/examples-corrupted.txt | 11 +++++++++++ spec/rspec/core/configuration_spec.rb | 18 ++++++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 spec/examples-corrupted.txt diff --git a/spec/examples-corrupted.txt b/spec/examples-corrupted.txt new file mode 100644 index 0000000000..aa13fb2745 --- /dev/null +++ b/spec/examples-corrupted.txt @@ -0,0 +1,11 @@ +example_id | +---------------------------------------------------------------------- | ------- | --------------- | +./spec/integration/bisect_spec.rb[1:1:1] | passed | 5.78 seconds | +./spec/rspec/core/suite_hooks_spec.rb[1:2:4] | passed | 0.00099 seconds | +./spec/rspec/core/suite_hooks_spec.rb[1:2:5] | passed | 0.00102 seconds | +./spec/rspec/core/suite_hooks_spec.rb[1:2:6] | passed | 0.00111 seconds | +./spec/rspec/core/suite_hooks_spec.rb[1:2:7:1] | passed | 0.00286 seconds | +./spec/rspec/core/suite_hooks_spec.rb[1:2:8:1] | passed | 0.00059 seconds | +./spec/rspec/core/suite_hooks_spec.rb[1:3:1] | passed | 0.00044 seconds | +./spec/rspec/core/suite_hooks_spec.rb[1:3:2] | passed | 0.0013 seconds | +./spec/rspec/core/suite_hooks_spec.rb[1:3:3] | passed | 0.00128 seconds | diff --git a/spec/rspec/core/configuration_spec.rb b/spec/rspec/core/configuration_spec.rb index 5b8ca810a3..a25f42934f 100644 --- a/spec/rspec/core/configuration_spec.rb +++ b/spec/rspec/core/configuration_spec.rb @@ -36,6 +36,24 @@ module RSpec::Core end end + describe 'Corrupt examples.txt file' do + before do + RSpec.configure do |c| + c.example_status_persistence_file_path = "spec/examples-corrupted.txt" + end + end + + it 'should not crash' do + Array.new(9) do |i| + RSpec.describe("group") { it "example #{i}" do; end} + end + expectation = expect do + RSpec.world.example_groups + end + expectation.not_to raise_error + end + end + describe "#fail_fast" do it "defaults to `nil`" do expect(RSpec::Core::Configuration.new.fail_fast).to be(nil) From 8862a616bad63b455bdb32e1a45e10bb521f0737 Mon Sep 17 00:00:00 2001 From: matrinox Date: Thu, 23 Mar 2017 14:46:27 -0700 Subject: [PATCH 3/3] Default status to UNKNOWN_STATUS if it's valid or nil Made changes based on @myronmarston feedback ----------------------------------------------------------- On branch master - Thu 23 Mar 2017 14:46:27 PDT by matrinox --- lib/rspec/core/configuration.rb | 10 ++++- spec/examples-corrupted.txt | 11 ------ .../only_failures_support_spec.rb | 38 +++++++++++++++++++ spec/rspec/core/configuration_spec.rb | 19 ---------- 4 files changed, 47 insertions(+), 31 deletions(-) delete mode 100644 spec/examples-corrupted.txt diff --git a/lib/rspec/core/configuration.rb b/lib/rspec/core/configuration.rb index 5ff58726cd..5ee32ef741 100644 --- a/lib/rspec/core/configuration.rb +++ b/lib/rspec/core/configuration.rb @@ -980,7 +980,9 @@ def last_run_statuses if (path = example_status_persistence_file_path) begin ExampleStatusPersister.load_from(path).inject(statuses) do |hash, example| - hash[example.fetch(:example_id)] = example.fetch(:status, UNKNOWN_STATUS) + status = example[:status] + status = UNKNOWN_STATUS unless VALID_STATUSES.include?(status) + hash[example.fetch(:example_id)] = status hash end rescue SystemCallError => e @@ -1000,6 +1002,12 @@ def last_run_statuses # @private FAILED_STATUS = "failed".freeze + # @private + PASSED_STATUS = "passed".freeze + + # @private + VALID_STATUSES = [UNKNOWN_STATUS, FAILED_STATUS, PASSED_STATUS] + # @private def spec_files_with_failures @spec_files_with_failures ||= last_run_statuses.inject(Set.new) do |files, (id, status)| diff --git a/spec/examples-corrupted.txt b/spec/examples-corrupted.txt deleted file mode 100644 index aa13fb2745..0000000000 --- a/spec/examples-corrupted.txt +++ /dev/null @@ -1,11 +0,0 @@ -example_id | ----------------------------------------------------------------------- | ------- | --------------- | -./spec/integration/bisect_spec.rb[1:1:1] | passed | 5.78 seconds | -./spec/rspec/core/suite_hooks_spec.rb[1:2:4] | passed | 0.00099 seconds | -./spec/rspec/core/suite_hooks_spec.rb[1:2:5] | passed | 0.00102 seconds | -./spec/rspec/core/suite_hooks_spec.rb[1:2:6] | passed | 0.00111 seconds | -./spec/rspec/core/suite_hooks_spec.rb[1:2:7:1] | passed | 0.00286 seconds | -./spec/rspec/core/suite_hooks_spec.rb[1:2:8:1] | passed | 0.00059 seconds | -./spec/rspec/core/suite_hooks_spec.rb[1:3:1] | passed | 0.00044 seconds | -./spec/rspec/core/suite_hooks_spec.rb[1:3:2] | passed | 0.0013 seconds | -./spec/rspec/core/suite_hooks_spec.rb[1:3:3] | passed | 0.00128 seconds | diff --git a/spec/rspec/core/configuration/only_failures_support_spec.rb b/spec/rspec/core/configuration/only_failures_support_spec.rb index 095fdb318e..dc7a29b511 100644 --- a/spec/rspec/core/configuration/only_failures_support_spec.rb +++ b/spec/rspec/core/configuration/only_failures_support_spec.rb @@ -110,6 +110,44 @@ def spec_files_with_failures end end + context 'when the file at `example_status_persistence_file_path` is corrupt' do + before do + simulate_persisted_examples( + { :example_id => "./spec_1.rb[1:1]" }, + { :example_id => "./spec_1.rb[1:2]", :status => "" }, + { :example_id => "./spec_2.rb[1:2]", :status => nil }, + { :example_id => "./spec_3.rb[1:2]", :status => "wrong" }, + { :example_id => "./spec_4.rb[1:2]", :status => "unknown" }, + :example_id => "./spec_5.rb[1:2]", :status => "failed" + ) + end + + it 'should not crash' do + Array.new(9) do |i| + RSpec.describe("group") { it "example #{i}" do; end } + end + expectation = expect do + RSpec.world.example_groups + end + expectation.not_to raise_error + end + it 'should default invalid statuses to unknown' do + expect(spec_files_with_failures).to( + be_an(Array) & + contain_exactly("./spec_5.rb") + ) + # Check that each example has the correct status + expect(config.last_run_statuses).to eq( + './spec_1.rb[1:1]' => 'unknown', + './spec_1.rb[1:2]' => 'unknown', + './spec_2.rb[1:2]' => 'unknown', + './spec_3.rb[1:2]' => 'unknown', + './spec_4.rb[1:2]' => 'unknown', + './spec_5.rb[1:2]' => 'failed' + ) + end + end + context "when `example_status_persistence_file_path` is not configured" do it "returns a memoized blank array" do config.example_status_persistence_file_path = nil diff --git a/spec/rspec/core/configuration_spec.rb b/spec/rspec/core/configuration_spec.rb index a25f42934f..320d997ce7 100644 --- a/spec/rspec/core/configuration_spec.rb +++ b/spec/rspec/core/configuration_spec.rb @@ -2,7 +2,6 @@ require 'rspec/support/spec/in_sub_process' module RSpec::Core - RSpec.describe Configuration do include RSpec::Support::InSubProcess @@ -36,24 +35,6 @@ module RSpec::Core end end - describe 'Corrupt examples.txt file' do - before do - RSpec.configure do |c| - c.example_status_persistence_file_path = "spec/examples-corrupted.txt" - end - end - - it 'should not crash' do - Array.new(9) do |i| - RSpec.describe("group") { it "example #{i}" do; end} - end - expectation = expect do - RSpec.world.example_groups - end - expectation.not_to raise_error - end - end - describe "#fail_fast" do it "defaults to `nil`" do expect(RSpec::Core::Configuration.new.fail_fast).to be(nil)