blob: 9f59d3b384e03277bdd730112b9812c93bbca54f (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
|
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".dup) { throw "exit".dup } }.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
|