1assert('Fiber.new') do 2 f = Fiber.new{} 3 assert_kind_of Fiber, f 4end 5 6assert('Fiber#resume') do 7 f = Fiber.new{|x| x } 8 assert_equal 2, f.resume(2) 9end 10 11assert('Fiber#transfer') do 12 f2 = nil 13 f1 = Fiber.new do |v| 14 Fiber.yield v 15 f2.transfer 16 end 17 f2 = Fiber.new do 18 f1.transfer(1) 19 f1.transfer(1) 20 Fiber.yield 2 21 end 22 assert_equal 1, f2.resume 23 assert_raise(FiberError) { f2.resume } 24 assert_equal 2, f2.transfer 25 assert_raise(FiberError) { f1.resume } 26 f1.transfer 27 f2.resume 28 assert_false f1.alive? 29 assert_false f2.alive? 30end 31 32assert('Fiber#alive?') do 33 f = Fiber.new{ Fiber.yield } 34 f.resume 35 assert_true f.alive? 36 f.resume 37 assert_false f.alive? 38end 39 40assert('Fiber#==') do 41 root = Fiber.current 42 assert_equal root, root 43 assert_equal root, Fiber.current 44 assert_false root != Fiber.current 45 f = Fiber.new { 46 assert_false root == Fiber.current 47 } 48 f.resume 49 assert_false f == root 50 assert_true f != root 51end 52 53assert('Fiber.yield') do 54 f = Fiber.new{|x| Fiber.yield x } 55 assert_equal 3, f.resume(3) 56 assert_true f.alive? 57end 58 59assert('FiberError') do 60 assert_equal StandardError, FiberError.superclass 61end 62 63assert('Fiber iteration') do 64 f1 = Fiber.new{ 65 [1,2,3].each{|x| Fiber.yield(x)} 66 } 67 f2 = Fiber.new{ 68 [9,8,7].each{|x| Fiber.yield(x)} 69 } 70 a = [] 71 3.times { 72 a << f1.resume 73 a << f2.resume 74 } 75 assert_equal [1,9,2,8,3,7], a 76end 77 78assert('Fiber with splat in the block argument list') { 79 Fiber.new{|*x|x}.resume(1) == [1] 80} 81 82assert('Fiber raises on resume when dead') do 83 assert_raise(FiberError) do 84 f = Fiber.new{} 85 f.resume 86 assert_false f.alive? 87 f.resume 88 end 89end 90 91assert('Yield raises when called on root fiber') do 92 assert_raise(FiberError) { Fiber.yield } 93end 94 95assert('Double resume of Fiber') do 96 f1 = Fiber.new {} 97 f2 = Fiber.new { 98 f1.resume 99 assert_raise(FiberError) { f2.resume } 100 Fiber.yield 0 101 } 102 assert_equal 0, f2.resume 103 f2.resume 104 assert_false f1.alive? 105 assert_false f2.alive? 106end 107 108assert('Recursive resume of Fiber') do 109 f1, f2 = nil, nil 110 f1 = Fiber.new { assert_raise(FiberError) { f2.resume } } 111 f2 = Fiber.new { 112 f1.resume 113 Fiber.yield 0 114 } 115 f3 = Fiber.new { 116 f2.resume 117 } 118 assert_equal 0, f3.resume 119 f2.resume 120 assert_false f1.alive? 121 assert_false f2.alive? 122 assert_false f3.alive? 123end 124 125assert('Root fiber resume') do 126 root = Fiber.current 127 assert_raise(FiberError) { root.resume } 128 f = Fiber.new { 129 assert_raise(FiberError) { root.resume } 130 } 131 f.resume 132 assert_false f.alive? 133end 134 135assert('Fiber without block') do 136 assert_raise(ArgumentError) { Fiber.new } 137end 138 139 140assert('Transfer to self.') do 141 result = [] 142 f = Fiber.new { result << :start; f.transfer; result << :end } 143 f.transfer 144 assert_equal [:start, :end], result 145 146 result = [] 147 f = Fiber.new { result << :start; f.transfer; result << :end } 148 f.resume 149 assert_equal [:start, :end], result 150end 151 152assert('Resume transferred fiber') do 153 f = Fiber.new { 154 assert_raise(FiberError) { f.resume } 155 } 156 f.transfer 157end 158 159assert('Root fiber transfer.') do 160 result = nil 161 root = Fiber.current 162 f = Fiber.new { 163 result = :ok 164 root.transfer 165 } 166 f.resume 167 assert_true f.alive? 168 assert_equal :ok, result 169end 170 171assert('Break nested fiber with root fiber transfer') do 172 root = Fiber.current 173 174 result = nil 175 f2 = nil 176 f1 = Fiber.new { 177 Fiber.yield f2.resume 178 result = :f1 179 } 180 f2 = Fiber.new { 181 result = :to_root 182 root.transfer :from_f2 183 result = :f2 184 } 185 assert_equal :from_f2, f1.resume 186 assert_equal :to_root, result 187 assert_equal :f2, f2.transfer 188 assert_equal :f2, result 189 assert_false f2.alive? 190 assert_equal :f1, f1.resume 191 assert_equal :f1, result 192 assert_false f1.alive? 193end 194 195assert('CRuby Fiber#transfer test.') do 196 ary = [] 197 f2 = nil 198 f1 = Fiber.new{ 199 ary << f2.transfer(:foo) 200 :ok 201 } 202 f2 = Fiber.new{ 203 ary << f1.transfer(:baz) 204 :ng 205 } 206 assert_equal :ok, f1.transfer 207 assert_equal [:baz], ary 208end 209