diff options
Diffstat (limited to 'spec/ruby/core/fiber')
-rw-r--r-- | spec/ruby/core/fiber/blocking_spec.rb | 68 | ||||
-rw-r--r-- | spec/ruby/core/fiber/inspect_spec.rb | 8 | ||||
-rw-r--r-- | spec/ruby/core/fiber/raise_spec.rb | 56 | ||||
-rw-r--r-- | spec/ruby/core/fiber/resume_spec.rb | 15 | ||||
-rw-r--r-- | spec/ruby/core/fiber/storage_spec.rb | 88 |
5 files changed, 145 insertions, 90 deletions
diff --git a/spec/ruby/core/fiber/blocking_spec.rb b/spec/ruby/core/fiber/blocking_spec.rb index eeee5a71c1..ebefa116af 100644 --- a/spec/ruby/core/fiber/blocking_spec.rb +++ b/spec/ruby/core/fiber/blocking_spec.rb @@ -1,61 +1,59 @@ require_relative '../../spec_helper' require_relative 'shared/blocking' -ruby_version_is "3.0" do - require "fiber" +require "fiber" - describe "Fiber.blocking?" do - it_behaves_like :non_blocking_fiber, -> { Fiber.blocking? } +describe "Fiber.blocking?" do + it_behaves_like :non_blocking_fiber, -> { Fiber.blocking? } - context "when fiber is blocking" do - context "root Fiber of the main thread" do - it "returns 1 for blocking: true" do + context "when fiber is blocking" do + context "root Fiber of the main thread" do + it "returns 1 for blocking: true" do + fiber = Fiber.new(blocking: true) { Fiber.blocking? } + blocking = fiber.resume + + blocking.should == 1 + end + end + + context "root Fiber of a new thread" do + it "returns 1 for blocking: true" do + thread = Thread.new do fiber = Fiber.new(blocking: true) { Fiber.blocking? } blocking = fiber.resume blocking.should == 1 end + + thread.join end + end + end +end - context "root Fiber of a new thread" do - it "returns 1 for blocking: true" do - thread = Thread.new do - fiber = Fiber.new(blocking: true) { Fiber.blocking? } - blocking = fiber.resume +describe "Fiber#blocking?" do + it_behaves_like :non_blocking_fiber, -> { Fiber.current.blocking? } - blocking.should == 1 - end + context "when fiber is blocking" do + context "root Fiber of the main thread" do + it "returns true for blocking: true" do + fiber = Fiber.new(blocking: true) { Fiber.current.blocking? } + blocking = fiber.resume - thread.join - end + blocking.should == true end end - end - describe "Fiber#blocking?" do - it_behaves_like :non_blocking_fiber, -> { Fiber.current.blocking? } - - context "when fiber is blocking" do - context "root Fiber of the main thread" do - it "returns true for blocking: true" do + context "root Fiber of a new thread" do + it "returns true for blocking: true" do + thread = Thread.new do fiber = Fiber.new(blocking: true) { Fiber.current.blocking? } blocking = fiber.resume blocking.should == true end - end - context "root Fiber of a new thread" do - it "returns true for blocking: true" do - thread = Thread.new do - fiber = Fiber.new(blocking: true) { Fiber.current.blocking? } - blocking = fiber.resume - - blocking.should == true - end - - thread.join - end + thread.join end end end diff --git a/spec/ruby/core/fiber/inspect_spec.rb b/spec/ruby/core/fiber/inspect_spec.rb index ee53af3a39..f20a153fc2 100644 --- a/spec/ruby/core/fiber/inspect_spec.rb +++ b/spec/ruby/core/fiber/inspect_spec.rb @@ -18,11 +18,9 @@ describe "Fiber#inspect" do inspected.should =~ /\A#<Fiber:0x\h+ .+ \(resumed\)>\z/ end - ruby_version_is "3.0" do - it "is resumed for a Fiber which was transferred" do - inspected = Fiber.new { Fiber.current.inspect }.transfer - inspected.should =~ /\A#<Fiber:0x\h+ .+ \(resumed\)>\z/ - end + it "is resumed for a Fiber which was transferred" do + inspected = Fiber.new { Fiber.current.inspect }.transfer + inspected.should =~ /\A#<Fiber:0x\h+ .+ \(resumed\)>\z/ end it "is suspended for a Fiber which was resumed and yielded" do diff --git a/spec/ruby/core/fiber/raise_spec.rb b/spec/ruby/core/fiber/raise_spec.rb index 09c4c1b524..b3e021e636 100644 --- a/spec/ruby/core/fiber/raise_spec.rb +++ b/spec/ruby/core/fiber/raise_spec.rb @@ -91,29 +91,49 @@ describe "Fiber#raise" do fiber_two.resume.should == [:yield_one, :rescued] end -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 -ruby_version_is ""..."3.0" do - describe "Fiber#raise" do - it "raises a FiberError if invoked on a transferring Fiber" do - require "fiber" - root = Fiber.current - fiber = Fiber.new { root.transfer } - fiber.transfer - -> { fiber.raise }.should raise_error(FiberError, "cannot resume transferred Fiber") + 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 -ruby_version_is "3.0" do - describe "Fiber#raise" do - it "transfers and raises on a transferring fiber" do - require "fiber" - root = Fiber.current - fiber = Fiber.new { root.transfer } - fiber.transfer - -> { fiber.raise "msg" }.should raise_error(RuntimeError, "msg") - end + +describe "Fiber#raise" do + it "transfers and raises on a transferring fiber" do + require "fiber" + root = Fiber.current + fiber = Fiber.new { root.transfer } + fiber.transfer + -> { fiber.raise "msg" }.should raise_error(RuntimeError, "msg") end end diff --git a/spec/ruby/core/fiber/resume_spec.rb b/spec/ruby/core/fiber/resume_spec.rb index 273bc866af..ab9a6799ab 100644 --- a/spec/ruby/core/fiber/resume_spec.rb +++ b/spec/ruby/core/fiber/resume_spec.rb @@ -28,18 +28,9 @@ describe "Fiber#resume" do fiber.resume :second end - ruby_version_is '3.0' do - it "raises a FiberError if the Fiber tries to resume itself" do - fiber = Fiber.new { fiber.resume } - -> { fiber.resume }.should raise_error(FiberError, /current fiber/) - end - end - - ruby_version_is '' ... '3.0' do - it "raises a FiberError if the Fiber tries to resume itself" do - fiber = Fiber.new { fiber.resume } - -> { fiber.resume }.should raise_error(FiberError, /double resume/) - end + it "raises a FiberError if the Fiber tries to resume itself" do + fiber = Fiber.new { fiber.resume } + -> { fiber.resume }.should raise_error(FiberError, /current fiber/) end it "returns control to the calling Fiber if called from one" do diff --git a/spec/ruby/core/fiber/storage_spec.rb b/spec/ruby/core/fiber/storage_spec.rb index e99fe6e4df..5c87ed5d41 100644 --- a/spec/ruby/core/fiber/storage_spec.rb +++ b/spec/ruby/core/fiber/storage_spec.rb @@ -1,9 +1,7 @@ require_relative '../../spec_helper' -require 'fiber' - -describe "Fiber.new(storage:)" do - ruby_version_is "3.2" do +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 } @@ -24,11 +22,26 @@ describe "Fiber.new(storage:)" do 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 -end -describe "Fiber#storage=" do - ruby_version_is "3.2" do + 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 @@ -58,10 +71,8 @@ describe "Fiber#storage=" do -> { Fiber.current.storage = {life: 43, Object.new => 44} }.should raise_error(TypeError) end end -end -describe "Fiber.[]" do - ruby_version_is "3.2" do + 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 @@ -73,11 +84,34 @@ describe "Fiber.[]" do 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 -end -describe "Fiber.[]=" do - ruby_version_is "3.2" do + 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 @@ -89,17 +123,31 @@ describe "Fiber.[]=" do 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 - 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 == {} + 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 -end -describe "Thread.new" do - ruby_version_is "3.2" do + 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 |