Skip to content
This repository was archived by the owner on Nov 30, 2024. It is now read-only.

Commit 5538510

Browse files
committed
Ensure execution result timing is populated
In the case where RSpec does not handle an error (e.g. SystemExit), we still want to capture the example timing data to not break profiling information that may get generated via `--profile`. Fixes #2142
1 parent a575b9b commit 5538510

File tree

2 files changed

+29
-3
lines changed

2 files changed

+29
-3
lines changed

lib/rspec/core/example.rb

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,7 @@ def run(example_group_instance, reporter)
260260

261261
finish(reporter)
262262
ensure
263+
execution_result.ensure_timing_set(clock)
263264
RSpec.current_example = nil
264265
end
265266

@@ -565,13 +566,23 @@ def example_skipped?
565566
# @api private
566567
# Records the finished status of the example.
567568
def record_finished(status, finished_at)
568-
self.status = status
569-
self.finished_at = finished_at
570-
self.run_time = (finished_at - started_at).to_f
569+
self.status = status
570+
calculate_run_time(finished_at)
571+
end
572+
573+
# @api private
574+
# Populates finished_at and run_time if it has not yet been set
575+
def ensure_timing_set(clock)
576+
calculate_run_time(clock.now) unless finished_at
571577
end
572578

573579
private
574580

581+
def calculate_run_time(finished_at)
582+
self.finished_at = finished_at
583+
self.run_time = (finished_at - started_at).to_f
584+
end
585+
575586
# For backwards compatibility we present `status` as a string
576587
# when presenting the legacy hash interface.
577588
def hash_for_delegation

spec/rspec/core/example_spec.rb

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,21 @@ def metadata_hash(*args)
5858
end
5959
end
6060

61+
it "captures example timing even for exceptions unhandled by RSpec" do
62+
rescued = false
63+
unhandled = RSpec::Support::AllExceptionsExceptOnesWeMustNotRescue::AVOID_RESCUING.first
64+
example = example_group.example { raise unhandled }
65+
66+
begin
67+
example_group.run
68+
rescue unhandled
69+
# can't use raise_error matcher since RSpec won't rescue unhandled
70+
rescued = true
71+
end
72+
expect(example.execution_result.finished_at).not_to be_nil
73+
expect(rescued).to be_truthy
74+
end
75+
6176
describe "#exception" do
6277
it "supplies the exception raised, if there is one" do
6378
example = example_group.example { raise "first" }

0 commit comments

Comments
 (0)