diff --git a/language/fixtures/rescue.rb b/language/fixtures/rescue.rb index b906e17a2f..a2d849debc 100644 --- a/language/fixtures/rescue.rb +++ b/language/fixtures/rescue.rb @@ -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 diff --git a/language/rescue_spec.rb b/language/rescue_spec.rb index 7fa674d009..5d43fdfbe3 100644 --- a/language/rescue_spec.rb +++ b/language/rescue_spec.rb @@ -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