require "awesome_print" require "kontext" describe Kontext do describe Kontext::RootFiber do it "is a reference to the root fiber" do Kontext::RootFiber.should equal(Fiber.current) end end let :kontext do Kontext.new end describe "#thread?" do it "returns true if the current thread is not the main thread" do result = nil Thread.new { result = kontext.thread? } sleep 0.01 result.should be_true end it "returns false if we're in the main thread" do kontext.thread?.should be_false end end describe "#fiber?" do it "returns true if the current fiber is not the root fiber" do result = nil Fiber.new { result = kontext.fiber? }.resume result.should be_true end it "returns false if we're in the root fiber" do kontext.fiber?.should be_false end end describe "#store" do describe "when in a fiber" do before do kontext.stub :fiber? => true, :thread? => false end it "returns a fiber specific store" do key = Fiber.current.object_id.to_s kontext.store.should equal(Thread.current[key]) end end describe "when in a thread" do before do kontext.stub :fiber? => false, :thread? => true end it "returns a thread specific hash store" do kontext.store.should equal(Thread.current) end end describe "when neither in thread nor in fiber" do before do kontext.stub :fiber? => false, :thread? => false end it "returns a hash" do kontext.store.should be_a(Hash) kontext.store.should be_empty end end end describe "#stack" do it "returns the instance's stack" do kontext.stack.should be_an(Array) kontext.stack.should be_empty kontext.stack.should equal(kontext.store[kontext]) end end describe "#with(obj)" do let(:obj) { stub "obj" } it "pushes the object to the stack" do kontext.with obj do kontext.last.should equal(obj) kontext.with obj do kontext.stack.should == [obj, obj] end end end it "yields the object" do kontext.with obj do |o| o.should equal(obj) end end it "correctly updates the stack when the block raises" do begin kontext.with obj do begin kontext.with(obj) { raise } ensure kontext.stack.should == [obj] end end rescue kontext.stack.should be_empty end end it "expects a block" do proc { kontext.with obj }.should raise_error(LocalJumpError) end end describe "#push(obj)" do it "adds an object to the stack" do kontext.push :foo kontext.push :bar kontext.last.should equal(:bar) end end describe "#pop" do it "removes an object from the top of the stack" do kontext.pop.should be_nil kontext.push :foo kontext.pop.should equal(:foo) kontext.size.should be_zero end end describe "#last" do it "returns the object at the top of the stack" do kontext.last.should be_nil kontext.push :foo kontext.last.should equal(:foo) end end describe "#size" do it "is zero initially" do kontext.size.should be_zero end it "increases by 1 for each nesting level" do kontext.with :foo do kontext.size.should equal(1) end end end describe "#truncate(new_size)" do it "pops objects until there are $new_size object left" do [:foo, :bar, :baz].each &kontext.method(:push) kontext.truncate 1 kontext.last.should equal(:foo) end end end