Skip to content

Commit

Permalink
Fixes #493 Capture exit exception for reference
Browse files Browse the repository at this point in the history
This stores any exit exception that may have occurred. The idea is to
expose this exception to the user supplied ```at_exit``` block.

```ruby
SimpleCov.at_exit do
  if SimpleCov.exit_exception
    # Do something or nothing due to an exception
  else
    # Do something or nothing due to no exception
  end
end
```

Another method was added: ```exit_status_from_exception``` to reduce the
logic in the at_exit block. I am not sure if it's worth adding this
method though. There is still opportunity to refactor the ```at_exit```
block. I first attempted to refactor the @exit_status logic more but
it will be a bigger change. If you want I can remove the
```exit_status_from_exception``` method from this PR
  • Loading branch information
thomas07vt committed Nov 1, 2017
1 parent 4fe7a17 commit eb7e5b8
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 10 deletions.
24 changes: 24 additions & 0 deletions lib/simplecov.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# frozen_string_literal: true

require "English"

#
# Code coverage for ruby 1.9. Please check out README for a full introduction.
#
Expand All @@ -22,6 +24,7 @@ module SimpleCov
class << self
attr_accessor :running
attr_accessor :pid
attr_reader :exit_exception

#
# Sets up SimpleCov to run against your project.
Expand Down Expand Up @@ -165,6 +168,27 @@ def usable?
def clear_result
@result = nil
end

#
# Capture the current exception if it exists
# This will get called inside the at_exit block
#
def set_exit_exception
@exit_exception = $ERROR_INFO
end

#
# Returns the exit status from the exit exception
#
def exit_status_from_exception
return SimpleCov::ExitCodes::SUCCESS unless exit_exception

if exit_exception.is_a?(SystemExit)
exit_exception.status
else
SimpleCov::ExitCodes::EXCEPTION
end
end
end
end

Expand Down
13 changes: 3 additions & 10 deletions lib/simplecov/defaults.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,9 @@
# If we are in a different process than called start, don't interfere.
next if SimpleCov.pid != Process.pid

@exit_status = if $! # was an exception thrown?
# if it was a SystemExit, use the accompanying status
# otherwise set a non-zero status representing termination by
# some other exception (see github issue 41)
$!.is_a?(SystemExit) ? $!.status : SimpleCov::ExitCodes::EXCEPTION
else
# Store the exit status of the test run since it goes away
# after calling the at_exit proc...
SimpleCov::ExitCodes::SUCCESS
end
SimpleCov.set_exit_exception

@exit_status = SimpleCov.exit_status_from_exception

SimpleCov.at_exit.call

Expand Down
84 changes: 84 additions & 0 deletions spec/simplecov_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -107,5 +107,89 @@
end
end
end

describe ".set_exit_exception" do
context "when an exception has occurred" do
let(:error) { StandardError.new "SomeError" }

after do
# Clear the exit_exception
SimpleCov.set_exit_exception
end

it "captures the current exception" do
begin
raise error
rescue
SimpleCov.set_exit_exception
expect(SimpleCov.exit_exception).to be(error)
end
end
end

context "when an exception has not occurred" do
it "does set the exit_exception" do
SimpleCov.set_exit_exception
expect(SimpleCov.exit_exception).to eq(nil)
end
end
end

describe ".exit_exception" do
let(:error) { StandardError.new "SomeError" }

before do
begin
raise error
rescue
SimpleCov.set_exit_exception
end
end

after do
# Clear the exit_exception
SimpleCov.set_exit_exception
end

it "returns the exit exception" do
expect(SimpleCov.exit_exception).to be(error)
end
end

describe ".exit_status_from_exception" do
context "when no exception has occurred" do
before do
allow(SimpleCov).to receive(:exit_exception).and_return(nil)
end

it "returns SimpleCov::ExitCodes::SUCCESS" do
expect(SimpleCov.exit_status_from_exception).to eq(SimpleCov::ExitCodes::SUCCESS)
end
end

context "when a SystemExit has occurred" do
let(:system_exit) { SystemExit.new(1) }

before do
allow(SimpleCov).to receive(:exit_exception).and_return(system_exit)
end

it "returns the SystemExit status" do
expect(SimpleCov.exit_status_from_exception).to eq(system_exit.status)
end
end

context "when a non SystemExit occurrs" do
let(:error) { StandardError.new "NonSystemExit" }

before do
allow(SimpleCov).to receive(:exit_exception).and_return(error)
end

it "return SimpleCov::ExitCodes::EXCEPTION" do
expect(SimpleCov.exit_status_from_exception).to eq(SimpleCov::ExitCodes::EXCEPTION)
end
end
end
end
end

0 comments on commit eb7e5b8

Please sign in to comment.