mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
127 lines
3.2 KiB
Ruby
127 lines
3.2 KiB
Ruby
require_relative '../../spec_helper'
|
|
require_relative 'fixtures/classes'
|
|
|
|
describe "Kernel.catch" do
|
|
before :each do
|
|
ScratchPad.clear
|
|
end
|
|
|
|
it "executes its block and catches a thrown value matching its argument" do
|
|
catch :thrown_key do
|
|
ScratchPad.record :catch_block
|
|
throw :thrown_key
|
|
ScratchPad.record :throw_failed
|
|
end
|
|
ScratchPad.recorded.should == :catch_block
|
|
end
|
|
|
|
it "returns the second value passed to throw" do
|
|
catch(:thrown_key) { throw :thrown_key, :catch_value }.should == :catch_value
|
|
end
|
|
|
|
it "returns the last expression evaluated if throw was not called" do
|
|
catch(:thrown_key) { 1; :catch_block }.should == :catch_block
|
|
end
|
|
|
|
it "passes the given symbol to its block" do
|
|
catch :thrown_key do |tag|
|
|
ScratchPad.record tag
|
|
end
|
|
ScratchPad.recorded.should == :thrown_key
|
|
end
|
|
|
|
it "raises an ArgumentError if a Symbol is thrown for a String catch value" do
|
|
-> { catch("exit") { throw :exit } }.should raise_error(ArgumentError)
|
|
end
|
|
|
|
it "raises an ArgumentError if a String with different identity is thrown" do
|
|
-> { catch("exit") { throw "exit" } }.should raise_error(ArgumentError)
|
|
end
|
|
|
|
it "catches a Symbol when thrown a matching Symbol" do
|
|
catch :thrown_key do
|
|
ScratchPad.record :catch_block
|
|
throw :thrown_key
|
|
end
|
|
ScratchPad.recorded.should == :catch_block
|
|
end
|
|
|
|
it "catches a String when thrown a String with the same identity" do
|
|
key = "thrown_key"
|
|
catch key do
|
|
ScratchPad.record :catch_block
|
|
throw key
|
|
end
|
|
ScratchPad.recorded.should == :catch_block
|
|
end
|
|
|
|
it "accepts an object as an argument" do
|
|
catch(Object.new) { :catch_block }.should == :catch_block
|
|
end
|
|
|
|
it "yields an object when called without arguments" do
|
|
catch { |tag| tag }.should be_an_instance_of(Object)
|
|
end
|
|
|
|
it "can be used even in a method different from where throw is called" do
|
|
class CatchSpecs
|
|
def self.throwing_method
|
|
throw :blah, :thrown_value
|
|
end
|
|
def self.catching_method
|
|
catch :blah do
|
|
throwing_method
|
|
end
|
|
end
|
|
end
|
|
CatchSpecs.catching_method.should == :thrown_value
|
|
end
|
|
|
|
describe "when nested" do
|
|
before :each do
|
|
ScratchPad.record []
|
|
end
|
|
|
|
it "catches across invocation boundaries" do
|
|
catch :one do
|
|
ScratchPad << 1
|
|
catch :two do
|
|
ScratchPad << 2
|
|
catch :three do
|
|
ScratchPad << 3
|
|
throw :one
|
|
ScratchPad << 4
|
|
end
|
|
ScratchPad << 5
|
|
end
|
|
ScratchPad << 6
|
|
end
|
|
|
|
ScratchPad.recorded.should == [1, 2, 3]
|
|
end
|
|
|
|
it "catches in the nested invocation with the same key object" do
|
|
catch :thrown_key do
|
|
ScratchPad << 1
|
|
catch :thrown_key do
|
|
ScratchPad << 2
|
|
throw :thrown_key
|
|
ScratchPad << 3
|
|
end
|
|
ScratchPad << 4
|
|
end
|
|
|
|
ScratchPad.recorded.should == [1, 2, 4]
|
|
end
|
|
end
|
|
|
|
it "raises LocalJumpError if no block is given" do
|
|
-> { catch :blah }.should raise_error(LocalJumpError)
|
|
end
|
|
end
|
|
|
|
describe "Kernel#catch" do
|
|
it "is a private method" do
|
|
Kernel.should have_private_instance_method(:catch)
|
|
end
|
|
end
|