diff options
Diffstat (limited to 'spec/ruby/language/return_spec.rb')
-rw-r--r-- | spec/ruby/language/return_spec.rb | 223 |
1 files changed, 222 insertions, 1 deletions
diff --git a/spec/ruby/language/return_spec.rb b/spec/ruby/language/return_spec.rb index 323f74aad3..6a98fa6d12 100644 --- a/spec/ruby/language/return_spec.rb +++ b/spec/ruby/language/return_spec.rb @@ -24,7 +24,14 @@ describe "The return keyword" do describe "in a Thread" do it "raises a LocalJumpError if used to exit a thread" do - lambda { Thread.new { return }.join }.should raise_error(LocalJumpError) + t = Thread.new { + begin + return + rescue LocalJumpError => e + e + end + } + t.value.should be_an_instance_of(LocalJumpError) end end @@ -242,4 +249,218 @@ describe "The return keyword" do ReturnSpecs::MethodWithBlock.new.method2.should == [0, 1, 2] end end + + ruby_version_is '2.4.2' do + describe "at top level" do + before :each do + @filename = tmp("top_return.rb") + ScratchPad.record [] + end + + after do + rm_r @filename + end + + it "stops file execution" do + ruby_exe(<<-END_OF_CODE).should == "before return\n" + puts "before return" + return + + puts "after return" + END_OF_CODE + + $?.exitstatus.should == 0 + end + + describe "within if" do + it "is allowed" do + File.write(@filename, <<-END_OF_CODE) + ScratchPad << "before if" + if true + return + end + + ScratchPad << "after if" + END_OF_CODE + + load @filename + ScratchPad.recorded.should == ["before if"] + end + end + + describe "within while loop" do + it "is allowed" do + File.write(@filename, <<-END_OF_CODE) + ScratchPad << "before while" + while true + return + end + + ScratchPad << "after while" + END_OF_CODE + + load @filename + ScratchPad.recorded.should == ["before while"] + end + end + + describe "within a begin" do + it "is allowed in begin block" do + File.write(@filename, <<-END_OF_CODE) + ScratchPad << "before begin" + begin + return + end + + ScratchPad << "after begin" + END_OF_CODE + + load @filename + ScratchPad.recorded.should == ["before begin"] + end + + it "is allowed in ensure block" do + File.write(@filename, <<-END_OF_CODE) + ScratchPad << "before begin" + begin + ensure + return + end + + ScratchPad << "after begin" + END_OF_CODE + + load @filename + ScratchPad.recorded.should == ["before begin"] + end + + it "is allowed in rescue block" do + File.write(@filename, <<-END_OF_CODE) + ScratchPad << "before begin" + begin + raise + rescue RuntimeError + return + end + + ScratchPad << "after begin" + END_OF_CODE + + load @filename + ScratchPad.recorded.should == ["before begin"] + end + + it "fires ensure block before returning" do + ruby_exe(<<-END_OF_CODE).should == "within ensure\n" + begin + return + ensure + puts "within ensure" + end + + puts "after begin" + END_OF_CODE + end + + ruby_bug "#14061", "2.4"..."2.6" do + it "fires ensure block before returning while loads file" do + File.write(@filename, <<-END_OF_CODE) + ScratchPad << "before begin" + begin + return + ensure + ScratchPad << "within ensure" + end + + ScratchPad << "after begin" + END_OF_CODE + + load @filename + ScratchPad.recorded.should == ["before begin", "within ensure"] + end + end + + it "swallows exception if returns in ensure block" do + File.write(@filename, <<-END_OF_CODE) + begin + raise + ensure + ScratchPad << "before return" + return + end + END_OF_CODE + + load @filename + ScratchPad.recorded.should == ["before return"] + end + end + + describe "within a block" do + it "is allowed" do + File.write(@filename, <<-END_OF_CODE) + ScratchPad << "before call" + proc { return }.call + + ScratchPad << "after call" + END_OF_CODE + + load @filename + ScratchPad.recorded.should == ["before call"] + end + end + + describe "within a class" do + it "is allowed" do + File.write(@filename, <<-END_OF_CODE) + class A + ScratchPad << "before return" + return + + ScratchPad << "after return" + end + END_OF_CODE + + load @filename + ScratchPad.recorded.should == ["before return"] + end + end + + describe "file loading" do + it "stops file loading and execution" do + File.write(@filename, <<-END_OF_CODE) + ScratchPad << "before return" + return + ScratchPad << "after return" + END_OF_CODE + + load @filename + ScratchPad.recorded.should == ["before return"] + end + end + + describe "file requiring" do + it "stops file loading and execution" do + File.write(@filename, <<-END_OF_CODE) + ScratchPad << "before return" + return + ScratchPad << "after return" + END_OF_CODE + + require @filename + ScratchPad.recorded.should == ["before return"] + end + end + + describe "return with argument" do + # https://bugs.ruby-lang.org/issues/14062 + it "does not affect exit status" do + ruby_exe(<<-END_OF_CODE).should == "" + return 10 + END_OF_CODE + + $?.exitstatus.should == 0 + end + end + end + end end |