1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@61285 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
eregon 2017-12-15 17:44:37 +00:00
parent f941bdf263
commit 30ed82e772
39 changed files with 1078 additions and 105 deletions

View file

@ -425,6 +425,28 @@ describe "Constant resolution within a singleton class (class << obj)" do
end
end
describe "top-level constant lookup" do
context "on a class" do
ruby_version_is "" ... "2.5" do
it "searches Object successfully after searching other scopes" do
->() {
String::Hash.should == Hash
}.should complain(/toplevel constant Hash referenced by/)
end
end
ruby_version_is "2.5" do
it "does not search Object after searching other scopes" do
->() { String::Hash }.should raise_error(NameError)
end
end
end
it "searches Object unsuccessfully when searches on a module" do
->() { Enumerable::Hash }.should raise_error(NameError)
end
end
describe "Module#private_constant marked constants" do
it "remain private even when updated" do

View file

@ -7,50 +7,44 @@ describe "An ensure block inside a begin block" do
end
it "is executed when an exception is raised in it's corresponding begin block" do
begin
lambda {
begin
ScratchPad << :begin
raise "An exception occurred!"
ensure
ScratchPad << :ensure
end
}.should raise_error(RuntimeError)
lambda {
begin
ScratchPad << :begin
raise EnsureSpec::Error
ensure
ScratchPad << :ensure
end
}.should raise_error(EnsureSpec::Error)
ScratchPad.recorded.should == [:begin, :ensure]
end
ScratchPad.recorded.should == [:begin, :ensure]
end
it "is executed when an exception is raised and rescued in it's corresponding begin block" do
begin
ScratchPad << :begin
raise "An exception occurred!"
rescue
ScratchPad << :rescue
ensure
ScratchPad << :ensure
end
ScratchPad.recorded.should == [:begin, :rescue, :ensure]
end
it "is executed even when a symbol is thrown in it's corresponding begin block" do
catch(:symbol) do
begin
ScratchPad << :begin
raise "An exception occurred!"
throw(:symbol)
rescue
ScratchPad << :rescue
ensure
ScratchPad << :ensure
end
ScratchPad.recorded.should == [:begin, :rescue, :ensure]
end
end
it "is executed even when a symbol is thrown in it's corresponding begin block" do
begin
catch(:symbol) do
begin
ScratchPad << :begin
throw(:symbol)
rescue
ScratchPad << :rescue
ensure
ScratchPad << :ensure
end
end
ScratchPad.recorded.should == [:begin, :ensure]
end
ScratchPad.recorded.should == [:begin, :ensure]
end
it "is executed when nothing is raised or thrown in it's corresponding begin block" do
@ -102,7 +96,7 @@ describe "An ensure block inside a method" do
end
it "is executed when an exception is raised in the method" do
lambda { @obj.raise_in_method_with_ensure }.should raise_error(RuntimeError)
lambda { @obj.raise_in_method_with_ensure }.should raise_error(EnsureSpec::Error)
@obj.executed.should == [:method, :ensure]
end
@ -124,3 +118,176 @@ describe "An ensure block inside a method" do
@obj.explicit_return_in_method_with_ensure.should == :ensure
end
end
describe "An ensure block inside a class" do
before :each do
ScratchPad.record []
end
it "is executed when an exception is raised" do
lambda {
eval <<-ruby
class EnsureInClassExample
ScratchPad << :class
raise EnsureSpec::Error
ensure
ScratchPad << :ensure
end
ruby
}.should raise_error(EnsureSpec::Error)
ScratchPad.recorded.should == [:class, :ensure]
end
it "is executed when an exception is raised and rescued" do
eval <<-ruby
class EnsureInClassExample
ScratchPad << :class
raise
rescue
ScratchPad << :rescue
ensure
ScratchPad << :ensure
end
ruby
ScratchPad.recorded.should == [:class, :rescue, :ensure]
end
it "is executed even when a symbol is thrown" do
catch(:symbol) do
eval <<-ruby
class EnsureInClassExample
ScratchPad << :class
throw(:symbol)
rescue
ScratchPad << :rescue
ensure
ScratchPad << :ensure
end
ruby
end
ScratchPad.recorded.should == [:class, :ensure]
end
it "is executed when nothing is raised or thrown" do
eval <<-ruby
class EnsureInClassExample
ScratchPad << :class
rescue
ScratchPad << :rescue
ensure
ScratchPad << :ensure
end
ruby
ScratchPad.recorded.should == [:class, :ensure]
end
it "has no return value" do
result = eval <<-ruby
class EnsureInClassExample
:class
ensure
:ensure
end
ruby
result.should == :class
end
end
describe "An ensure block inside {} block" do
it "is not allowed" do
lambda {
eval <<-ruby
lambda {
raise
ensure
}
ruby
}.should raise_error(SyntaxError)
end
end
ruby_version_is "2.5" do
describe "An ensure block inside 'do end' block" do
before :each do
ScratchPad.record []
end
it "is executed when an exception is raised in it's corresponding begin block" do
lambda {
eval(<<-ruby).call
lambda do
ScratchPad << :begin
raise EnsureSpec::Error
ensure
ScratchPad << :ensure
end
ruby
}.should raise_error(EnsureSpec::Error)
ScratchPad.recorded.should == [:begin, :ensure]
end
it "is executed when an exception is raised and rescued in it's corresponding begin block" do
eval(<<-ruby).call
lambda do
ScratchPad << :begin
raise "An exception occurred!"
rescue
ScratchPad << :rescue
ensure
ScratchPad << :ensure
end
ruby
ScratchPad.recorded.should == [:begin, :rescue, :ensure]
end
it "is executed even when a symbol is thrown in it's corresponding begin block" do
catch(:symbol) do
eval(<<-ruby).call
lambda do
ScratchPad << :begin
throw(:symbol)
rescue
ScratchPad << :rescue
ensure
ScratchPad << :ensure
end
ruby
end
ScratchPad.recorded.should == [:begin, :ensure]
end
it "is executed when nothing is raised or thrown in it's corresponding begin block" do
eval(<<-ruby).call
lambda do
ScratchPad << :begin
rescue
ScratchPad << :rescue
ensure
ScratchPad << :ensure
end
ruby
ScratchPad.recorded.should == [:begin, :ensure]
end
it "has no return value" do
result = eval(<<-ruby).call
lambda do
:begin
ensure
:ensure
end
ruby
result.should == :begin
end
end
end

View file

@ -8,7 +8,7 @@ module EnsureSpec
def raise_in_method_with_ensure
@executed << :method
raise "An Exception"
raise EnsureSpec::Error
ensure
@executed << :ensure
end
@ -70,3 +70,8 @@ module EnsureSpec
end
end
end
module EnsureSpec
class Error < RuntimeError
end
end

View file

@ -31,6 +31,28 @@ describe "The rescue keyword" do
end
end
it "returns value from `rescue` if an exception was raised" do
begin
raise
rescue
:caught
end.should == :caught
end
it "returns value from `else` section if no exceptions were raised" do
result = begin
:begin
rescue
:rescue
else
:else
ensure
:ensure
end
result.should == :else
end
it "can rescue multiple raised exceptions with a single rescue block" do
[lambda{raise ArbitraryException}, lambda{raise SpecificExampleException}].map do |block|
begin
@ -94,6 +116,32 @@ describe "The rescue keyword" do
end.should raise_error(OtherCustomException)
end
it "can rescue different types of exceptions in different ways" do
begin
raise Exception
rescue RuntimeError
rescue StandardError
rescue Exception
ScratchPad << :exception
end
ScratchPad.recorded.should == [:exception]
end
it "rescues exception within the first suitable section in order of declaration" do
begin
raise StandardError
rescue RuntimeError
ScratchPad << :runtime_error
rescue StandardError
ScratchPad << :standard_error
rescue Exception
ScratchPad << :exception
end
ScratchPad.recorded.should == [:standard_error]
end
it "will execute an else block only if no exceptions were raised" do
result = begin
ScratchPad << :one
@ -147,6 +195,20 @@ describe "The rescue keyword" do
ScratchPad.recorded.should == [:one, :else_ran, :ensure_ran, :outside_begin]
end
it "will execute an else block even without rescue and ensure" do
lambda {
eval <<-ruby
begin
ScratchPad << :begin
else
ScratchPad << :else
end
ruby
}.should complain(/else without rescue is useless/)
ScratchPad.recorded.should == [:begin, :else]
end
it "will not execute an else block if an exception was raised" do
result = begin
ScratchPad << :one
@ -223,14 +285,31 @@ describe "The rescue keyword" do
a.should == 'ac'
end
it "without classes will not rescue Exception" do
lambda do
context "without rescue expression" do
it "will rescue only StandardError and its subclasses" do
begin
raise Exception
raise StandardError
rescue
'Exception wrongly rescued'
ScratchPad << :caught
end
end.should raise_error(Exception)
ScratchPad.recorded.should == [:caught]
end
it "will not rescue exceptions except StandardError" do
[ Exception.new, NoMemoryError.new, ScriptError.new, SecurityError.new,
SignalException.new('INT'), SystemExit.new, SystemStackError.new
].each do |exception|
lambda {
begin
raise exception
rescue
ScratchPad << :caught
end
}.should raise_error(exception.class)
end
ScratchPad.recorded.should == []
end
end
it "uses === to compare against rescued classes" do
@ -279,7 +358,7 @@ describe "The rescue keyword" do
invalid_rescuer = Object.new
begin
:foo
rescue rescuer
rescue invalid_rescuer
end.should == :foo
end
@ -291,6 +370,44 @@ describe "The rescue keyword" do
end.should == :expected
end
it "allows rescue in class" do
eval <<-ruby
class RescueInClassExample
raise SpecificExampleException
rescue SpecificExampleException
ScratchPad << :caught
end
ruby
ScratchPad.recorded.should == [:caught]
end
it "does not allow rescue in {} block" do
lambda {
eval <<-ruby
lambda {
raise SpecificExampleException
rescue SpecificExampleException
:caught
}
ruby
}.should raise_error(SyntaxError)
end
ruby_version_is "2.5" do
it "allows rescue in 'do end' block" do
lambda = eval <<-ruby
lambda do
raise SpecificExampleException
rescue SpecificExampleException
ScratchPad << :caught
end.call
ruby
ScratchPad.recorded.should == [:caught]
end
end
ruby_version_is ""..."2.4" do
it "fails when using 'rescue' in method arguments" do
lambda { eval '1.+ (1 rescue 1)' }.should raise_error(SyntaxError)
@ -305,6 +422,31 @@ describe "The rescue keyword" do
it "requires the 'rescue' in method arguments to be wrapped in parens" do
lambda { eval '1.+(1 rescue 1)' }.should raise_error(SyntaxError)
eval('1.+((1 rescue 1))').should == 2
end
end
describe "inline form" do
it "can be inlined" do
a = 1/0 rescue 1
a.should == 1
end
it "doesn't except rescue expression" do
lambda {
eval <<-ruby
a = 1 rescue RuntimeError 2
ruby
}.should raise_error(SyntaxError)
end
it "rescues only StandardError and its subclasses" do
a = raise(StandardError) rescue 1
a.should == 1
lambda {
a = raise(Exception) rescue 1
}.should raise_error(Exception)
end
end
end