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
128
129
130
131
132
133
134
135
136
137
138
|
require_relative '../../spec_helper'
require_relative 'fixtures/classes'
require_relative '../../shared/kernel/raise'
describe "Fiber#raise" do
it_behaves_like :kernel_raise, :raise, FiberSpecs::NewFiberToRaise
end
describe "Fiber#raise" do
it 'raises RuntimeError by default' do
-> { FiberSpecs::NewFiberToRaise.raise }.should raise_error(RuntimeError)
end
it "raises FiberError if Fiber is not born" do
fiber = Fiber.new { true }
-> { fiber.raise }.should raise_error(FiberError, "cannot raise exception on unborn fiber")
end
it "raises FiberError if Fiber is dead" do
fiber = Fiber.new { true }
fiber.resume
-> { fiber.raise }.should raise_error(FiberError, /dead fiber called|attempt to resume a terminated fiber/)
end
it 'accepts error class' do
-> { FiberSpecs::NewFiberToRaise.raise FiberSpecs::CustomError }.should raise_error(FiberSpecs::CustomError)
end
it 'accepts error message' do
-> { FiberSpecs::NewFiberToRaise.raise "error message" }.should raise_error(RuntimeError, "error message")
end
it 'does not accept array of backtrace information only' do
-> { FiberSpecs::NewFiberToRaise.raise ['foo'] }.should raise_error(TypeError)
end
it 'does not accept integer' do
-> { FiberSpecs::NewFiberToRaise.raise 100 }.should raise_error(TypeError)
end
it 'accepts error class with error message' do
-> { FiberSpecs::NewFiberToRaise.raise FiberSpecs::CustomError, 'test error' }.should raise_error(FiberSpecs::CustomError, 'test error')
end
it 'accepts error class with error message and backtrace information' do
-> {
FiberSpecs::NewFiberToRaise.raise FiberSpecs::CustomError, 'test error', ['foo', 'boo']
}.should raise_error(FiberSpecs::CustomError) { |e|
e.message.should == 'test error'
e.backtrace.should == ['foo', 'boo']
}
end
it 'does not accept only error message and backtrace information' do
-> { FiberSpecs::NewFiberToRaise.raise 'test error', ['foo', 'boo'] }.should raise_error(TypeError)
end
it "raises a FiberError if invoked from a different Thread" do
fiber = Fiber.new { Fiber.yield }
fiber.resume
Thread.new do
-> {
fiber.raise
}.should raise_error(FiberError, "fiber called across threads")
end.join
end
it "kills Fiber" do
fiber = Fiber.new { Fiber.yield :first; :second }
fiber.resume
-> { fiber.raise }.should raise_error
-> { fiber.resume }.should raise_error(FiberError, /dead fiber called|attempt to resume a terminated fiber/)
end
it "returns to calling fiber after raise" do
fiber_one = Fiber.new do
Fiber.yield :yield_one
:unreachable
end
fiber_two = Fiber.new do
results = []
results << fiber_one.resume
begin
fiber_one.raise
rescue
results << :rescued
end
results
end
fiber_two.resume.should == [:yield_one, :rescued]
end
ruby_version_is "3.4" do
it "raises on the resumed fiber" do
root_fiber = Fiber.current
f1 = Fiber.new { root_fiber.transfer }
f2 = Fiber.new { f1.resume }
f2.transfer
-> do
f2.raise(RuntimeError, "Expected error")
end.should raise_error(RuntimeError, "Expected error")
end
it "raises on itself" do
-> do
Fiber.current.raise(RuntimeError, "Expected error")
end.should raise_error(RuntimeError, "Expected error")
end
it "should raise on parent fiber" do
f2 = nil
f1 = Fiber.new do
# This is equivalent to Kernel#raise:
f2.raise(RuntimeError, "Expected error")
end
f2 = Fiber.new do
f1.resume
end
-> do
f2.resume
end.should raise_error(RuntimeError, "Expected error")
end
end
end
describe "Fiber#raise" do
it "transfers and raises on a transferring fiber" do
root = Fiber.current
fiber = Fiber.new { root.transfer }
fiber.transfer
-> { fiber.raise "msg" }.should raise_error(RuntimeError, "msg")
end
end
|