blob: 5c87ed5d41d560c43bc57979e61e0193e733a5dd (
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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
|
require_relative '../../spec_helper'
ruby_version_is "3.2" do
describe "Fiber.new(storage:)" do
it "creates a Fiber with the given storage" do
storage = {life: 42}
fiber = Fiber.new(storage: storage) { Fiber.current.storage }
fiber.resume.should == storage
end
it "creates a fiber with lazily initialized storage" do
Fiber.new(storage: nil) { Fiber[:x] = 10; Fiber.current.storage }.resume.should == {x: 10}
end
it "creates a fiber by inheriting the storage of the parent fiber" do
fiber = Fiber.new(storage: {life: 42}) do
Fiber.new { Fiber.current.storage }.resume
end
fiber.resume.should == {life: 42}
end
it "cannot create a fiber with non-hash storage" do
-> { Fiber.new(storage: 42) {} }.should raise_error(TypeError)
end
it "cannot create a fiber with a frozen hash as storage" do
-> { Fiber.new(storage: {life: 43}.freeze) {} }.should raise_error(FrozenError)
end
it "cannot create a fiber with a storage hash with non-symbol keys" do
-> { Fiber.new(storage: {life: 43, Object.new => 44}) {} }.should raise_error(TypeError)
end
end
describe "Fiber#storage" do
it "cannot be accessed from a different fiber" do
f = Fiber.new(storage: {life: 42}) { nil }
-> {
f.storage
}.should raise_error(ArgumentError, /Fiber storage can only be accessed from the Fiber it belongs to/)
end
end
describe "Fiber#storage=" do
it "can clear the storage of the fiber" do
fiber = Fiber.new(storage: {life: 42}) do
Fiber.current.storage = nil
Fiber[:x] = 10
Fiber.current.storage
end
fiber.resume.should == {x: 10}
end
it "can set the storage of the fiber" do
fiber = Fiber.new(storage: {life: 42}) do
Fiber.current.storage = {life: 43}
Fiber.current.storage
end
fiber.resume.should == {life: 43}
end
it "can't set the storage of the fiber to non-hash" do
-> { Fiber.current.storage = 42 }.should raise_error(TypeError)
end
it "can't set the storage of the fiber to a frozen hash" do
-> { Fiber.current.storage = {life: 43}.freeze }.should raise_error(FrozenError)
end
it "can't set the storage of the fiber to a hash with non-symbol keys" do
-> { Fiber.current.storage = {life: 43, Object.new => 44} }.should raise_error(TypeError)
end
end
describe "Fiber.[]" do
it "returns the value of the given key in the storage of the current fiber" do
Fiber.new(storage: {life: 42}) { Fiber[:life] }.resume.should == 42
end
it "returns nil if the key is not present in the storage of the current fiber" do
Fiber.new(storage: {life: 42}) { Fiber[:death] }.resume.should be_nil
end
it "returns nil if the current fiber has no storage" do
Fiber.new { Fiber[:life] }.resume.should be_nil
end
ruby_version_is "3.2.3" do
it "can use dynamically defined keys" do
key = :"#{self.class.name}#.#{self.object_id}"
Fiber.new { Fiber[key] = 42; Fiber[key] }.resume.should == 42
end
it "can't use invalid keys" do
invalid_keys = [Object.new, "Foo", 12]
invalid_keys.each do |key|
-> { Fiber[key] }.should raise_error(TypeError)
end
end
end
it "can access the storage of the parent fiber" do
f = Fiber.new(storage: {life: 42}) do
Fiber.new { Fiber[:life] }.resume
end
f.resume.should == 42
end
it "can't access the storage of the fiber with non-symbol keys" do
-> { Fiber[Object.new] }.should raise_error(TypeError)
end
end
describe "Fiber.[]=" do
it "sets the value of the given key in the storage of the current fiber" do
Fiber.new(storage: {life: 42}) { Fiber[:life] = 43; Fiber[:life] }.resume.should == 43
end
it "sets the value of the given key in the storage of the current fiber" do
Fiber.new(storage: {life: 42}) { Fiber[:death] = 43; Fiber[:death] }.resume.should == 43
end
it "sets the value of the given key in the storage of the current fiber" do
Fiber.new { Fiber[:life] = 43; Fiber[:life] }.resume.should == 43
end
it "does not overwrite the storage of the parent fiber" do
f = Fiber.new(storage: {life: 42}) do
Fiber.yield Fiber.new { Fiber[:life] = 43; Fiber[:life] }.resume
Fiber[:life]
end
f.resume.should == 43 # Value of the inner fiber
f.resume.should == 42 # Value of the outer fiber
end
it "can't access the storage of the fiber with non-symbol keys" do
-> { Fiber[Object.new] = 44 }.should raise_error(TypeError)
end
ruby_version_is "3.3" do
it "deletes the fiber storage key when assigning nil" do
Fiber.new(storage: {life: 42}) {
Fiber[:life] = nil
Fiber.current.storage
}.resume.should == {}
end
end
end
describe "Thread.new" do
it "creates a thread with the storage of the current fiber" do
fiber = Fiber.new(storage: {life: 42}) do
Thread.new { Fiber.current.storage }.value
end
fiber.resume.should == {life: 42}
end
end
end
|