Skip to content

Add tests for exotic rescued error capturing #774

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jun 25, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
106 changes: 106 additions & 0 deletions language/fixtures/rescue.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,110 @@
module RescueSpecs
class Captor
attr_accessor :captured_error

def self.should_capture_exception
captor = new
captor.capture('some text').should == :caught # Ensure rescue body still runs
captor.captured_error.message.should == 'some text'
end
end

class ClassVariableCaptor < Captor
def capture(msg)
raise msg
rescue => @@captured_error
:caught
end

def captured_error
self.class.remove_class_variable(:@@captured_error)
end
end

class ConstantCaptor < Captor
# Using lambda gets around the dynamic constant assignment warning
CAPTURE = -> msg {
begin
raise msg
rescue => CapturedError
:caught
end
}

def capture(msg)
CAPTURE.call(msg)
end

def captured_error
self.class.send(:remove_const, :CapturedError)
end
end

class GlobalVariableCaptor < Captor
def capture(msg)
raise msg
rescue => $captured_error
:caught
end

def captured_error
$captured_error.tap do
$captured_error = nil # Can't remove globals, only nil them out
end
end
end

class InstanceVariableCaptor < Captor
def capture(msg)
raise msg
rescue => @captured_error
:caught
end
end

class LocalVariableCaptor < Captor
def capture(msg)
raise msg
rescue => captured_error
@captured_error = captured_error
:caught
end
end

class SafeNavigationSetterCaptor < Captor
def capture(msg)
raise msg
rescue => self&.captured_error
:caught
end
end

class SetterCaptor < Captor
def capture(msg)
raise msg
rescue => self.captured_error
:caught
end
end

class SquareBracketsCaptor < Captor
def capture(msg)
@hash = {}

raise msg
rescue => self[:error]
:caught
end

def []=(key, value)
@hash[key] = value
end

def captured_error
@hash[:error]
end
end

def self.begin_else(raise_exception)
begin
ScratchPad << :one
Expand Down
36 changes: 31 additions & 5 deletions language/rescue_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,37 @@ class ArbitraryException < StandardError
end.should == :caught
end

it "can capture the raised exception in a local variable" do
begin
raise SpecificExampleException, "some text"
rescue SpecificExampleException => e
e.message.should == "some text"
describe 'can capture the raised exception' do
it 'in a local variable' do
RescueSpecs::LocalVariableCaptor.should_capture_exception
end

it 'in a class variable' do
RescueSpecs::ClassVariableCaptor.should_capture_exception
end

it 'in a constant' do
RescueSpecs::ConstantCaptor.should_capture_exception
end

it 'in a global variable' do
RescueSpecs::GlobalVariableCaptor.should_capture_exception
end

it 'in an instance variable' do
RescueSpecs::InstanceVariableCaptor.should_capture_exception
end

it 'using a safely navigated setter method' do
RescueSpecs::SafeNavigationSetterCaptor.should_capture_exception
end

it 'using a setter method' do
RescueSpecs::SetterCaptor.should_capture_exception
end

it 'using a square brackets setter' do
RescueSpecs::SquareBracketsCaptor.should_capture_exception
end
end

Expand Down