summaryrefslogtreecommitdiff
path: root/spec/ruby/language/rescue_spec.rb
diff options
context:
space:
mode:
Diffstat (limited to 'spec/ruby/language/rescue_spec.rb')
-rw-r--r--spec/ruby/language/rescue_spec.rb135
1 files changed, 118 insertions, 17 deletions
diff --git a/spec/ruby/language/rescue_spec.rb b/spec/ruby/language/rescue_spec.rb
index b91b52fa0f..cf16d8f6f8 100644
--- a/spec/ruby/language/rescue_spec.rb
+++ b/spec/ruby/language/rescue_spec.rb
@@ -52,6 +52,16 @@ describe "The rescue keyword" do
RescueSpecs::SafeNavigationSetterCaptor.should_capture_exception
end
+ it 'using a safely navigated setter method on a nil target' do
+ target = nil
+ begin
+ raise SpecificExampleException, "Raising this to be handled below"
+ rescue SpecificExampleException => target&.captured_error
+ :caught
+ end.should == :caught
+ target.should == nil
+ end
+
it 'using a setter method' do
RescueSpecs::SetterCaptor.should_capture_exception
end
@@ -61,6 +71,82 @@ describe "The rescue keyword" do
end
end
+ describe 'capturing in a local variable (that defines it)' do
+ it 'captures successfully in a method' do
+ ScratchPad.record []
+
+ def a
+ raise "message"
+ rescue => e
+ ScratchPad << e.message
+ end
+
+ a
+ ScratchPad.recorded.should == ["message"]
+ end
+
+ it 'captures successfully in a block' do
+ ScratchPad.record []
+
+ p = proc do
+ raise "message"
+ rescue => e
+ ScratchPad << e.message
+ end
+
+ p.call
+ ScratchPad.recorded.should == ["message"]
+ end
+
+ it 'captures successfully in a class' do
+ ScratchPad.record []
+
+ class RescueSpecs::C
+ raise "message"
+ rescue => e
+ ScratchPad << e.message
+ end
+
+ ScratchPad.recorded.should == ["message"]
+ end
+
+ it 'captures successfully in a module' do
+ ScratchPad.record []
+
+ module RescueSpecs::M
+ raise "message"
+ rescue => e
+ ScratchPad << e.message
+ end
+
+ ScratchPad.recorded.should == ["message"]
+ end
+
+ it 'captures sucpcessfully in a singleton class' do
+ ScratchPad.record []
+
+ class << Object.new
+ raise "message"
+ rescue => e
+ ScratchPad << e.message
+ end
+
+ ScratchPad.recorded.should == ["message"]
+ end
+
+ it 'captures successfully at the top-level' do
+ ScratchPad.record []
+ loaded_features = $".dup
+ begin
+ require_relative 'fixtures/rescue/top_level'
+
+ ScratchPad.recorded.should == ["message"]
+ ensure
+ $".replace loaded_features
+ end
+ end
+ end
+
it "returns value from `rescue` if an exception was raised" do
begin
raise
@@ -100,7 +186,7 @@ describe "The rescue keyword" do
rescue *exception_list
caught_it = true
end
- caught_it.should be_true
+ caught_it.should == true
caught = []
[->{raise ArbitraryException}, ->{raise SpecificExampleException}].each do |block|
begin
@@ -111,7 +197,7 @@ describe "The rescue keyword" do
end
caught.size.should == 2
exception_list.each do |exception_class|
- caught.map{|e| e.class}.should include(exception_class)
+ caught.map{|e| e.class}.should.include?(exception_class)
end
end
@@ -124,7 +210,7 @@ describe "The rescue keyword" do
rescue *exceptions
caught_it = true
end
- caught_it.should be_true
+ caught_it.should == true
end
it "can combine a splatted list of exceptions with a literal list of exceptions" do
@@ -134,7 +220,7 @@ describe "The rescue keyword" do
rescue ArbitraryException, *exception_list
caught_it = true
end
- caught_it.should be_true
+ caught_it.should == true
caught = []
[->{raise ArbitraryException}, ->{raise SpecificExampleException}].each do |block|
begin
@@ -145,7 +231,7 @@ describe "The rescue keyword" do
end
caught.size.should == 2
exception_list.each do |exception_class|
- caught.map{|e| e.class}.should include(exception_class)
+ caught.map{|e| e.class}.should.include?(exception_class)
end
end
@@ -155,7 +241,7 @@ describe "The rescue keyword" do
raise OtherCustomException, "not rescued!"
rescue *exception_list
end
- end.should raise_error(OtherCustomException)
+ end.should.raise(OtherCustomException)
end
it "can rescue different types of exceptions in different ways" do
@@ -191,7 +277,7 @@ describe "The rescue keyword" do
rescue ArgumentError
end
rescue StandardError => e
- e.backtrace.first.should include ":in `raise_standard_error'"
+ e.backtrace.first.should =~ /:in [`'](?:RescueSpecs\.)?raise_standard_error'/
else
fail("exception wasn't handled by the correct rescue block")
end
@@ -259,7 +345,7 @@ describe "The rescue keyword" do
ScratchPad << :else
end
ruby
- }.should raise_error(SyntaxError, /else without rescue is useless/)
+ }.should.raise(SyntaxError, /else without rescue is useless/)
end
it "will not execute an else block if an exception was raised" do
@@ -327,7 +413,7 @@ describe "The rescue keyword" do
ScratchPad << :two
raise SpecificExampleException, "an error from else"
end
- end.should raise_error(SpecificExampleException)
+ end.should.raise(SpecificExampleException)
ScratchPad.recorded.should == [:one, :two]
end
@@ -359,7 +445,7 @@ describe "The rescue keyword" do
rescue
ScratchPad << :caught
end
- }.should raise_error(exception.class)
+ }.should.raise(exception.class)
end
ScratchPad.recorded.should == []
end
@@ -390,7 +476,7 @@ describe "The rescue keyword" do
raise "error"
rescue rescuer
end
- }.should raise_error(TypeError) { |e|
+ }.should.raise(TypeError) { |e|
e.message.should =~ /class or module required for rescue clause/
}
end
@@ -402,7 +488,7 @@ describe "The rescue keyword" do
raise "error"
rescue *rescuer
end
- }.should raise_error(TypeError) { |e|
+ }.should.raise(TypeError) { |e|
e.message.should =~ /class or module required for rescue clause/
}
end
@@ -422,7 +508,7 @@ describe "The rescue keyword" do
raise "from block"
rescue (raise "from rescue expression")
end
- }.should raise_error(RuntimeError, "from rescue expression") { |e|
+ }.should.raise(RuntimeError, "from rescue expression") { |e|
e.cause.message.should == "from block"
}
end
@@ -456,7 +542,7 @@ describe "The rescue keyword" do
:caught
}
ruby
- }.should raise_error(SyntaxError)
+ }.should.raise(SyntaxError)
end
it "allows rescue in 'do end' block" do
@@ -477,10 +563,25 @@ describe "The rescue keyword" do
end
it "requires the 'rescue' in method arguments to be wrapped in parens" do
- -> { eval '1.+(1 rescue 1)' }.should raise_error(SyntaxError)
+ -> { eval '1.+(1 rescue 1)' }.should.raise(SyntaxError)
eval('1.+((1 rescue 1))').should == 2
end
+ ruby_version_is "3.4" do
+ it "does not introduce extra backtrace entries" do
+ def foo
+ begin
+ raise "oops"
+ rescue
+ return caller(0, 2)
+ end
+ end
+ line = __LINE__
+ foo[0].should =~ /#{__FILE__}:#{line-3}:in 'foo'/
+ foo[1].should =~ /#{__FILE__}:#{line+2}:in 'block/
+ end
+ end
+
describe "inline form" do
it "can be inlined" do
a = 1/0 rescue 1
@@ -492,7 +593,7 @@ describe "The rescue keyword" do
eval <<-ruby
a = 1 rescue RuntimeError 2
ruby
- }.should raise_error(SyntaxError)
+ }.should.raise(SyntaxError)
end
it "rescues only StandardError and its subclasses" do
@@ -501,7 +602,7 @@ describe "The rescue keyword" do
-> {
a = raise(Exception) rescue 1
- }.should raise_error(Exception)
+ }.should.raise(Exception)
end
it "rescues with multiple assignment" do