spec/selector_spec.rb in agent-0.10.0 vs spec/selector_spec.rb in agent-0.11.0

- old
+ new

@@ -5,45 +5,45 @@ # proceed. It looks similar to a "switch" statement but with the cases all # referring to communication operations. # - http://golang.org/doc/go_spec.html#Select_statements it "should yield Selector on select call" do - select! {|s| s.should be_kind_of Agent::Selector} + select! {|s| expect(s).to be_kind_of Agent::Selector} end it "should return immediately on empty select block" do s = Time.now.to_f select! {} - (Time.now.to_f - s).should be_within(0.05).of(0) + expect(Time.now.to_f - s).to be_within(0.05).of(0) end it "should timeout select statement" do r, now = [], Time.now.to_f select! do |s| s.timeout(0.1) { r.push :timeout } end - r.first.should == :timeout - (Time.now.to_f - now).should be_within(0.05).of(0.1) + expect(r.first).to eq(:timeout) + expect(Time.now.to_f - now).to be_within(0.05).of(0.1) end it "should not raise an error when a block is missing on default" do - lambda { + expect { select! do |s| s.default end - }.should_not raise_error(Agent::Errors::BlockMissing) + }.not_to raise_error end it "should not raise an error when a block is missing on timeout" do - lambda { + expect { select! do |s| s.timeout(1) s.default end - }.should_not raise_error(Agent::Errors::BlockMissing) + }.not_to raise_error end context "with unbuffered channels" do before do @c = channel!(Integer) @@ -56,30 +56,30 @@ it "should evaluate select statements top to bottom" do select! do |s| s.case(@c, :send, 1) s.case(@c, :receive) s.default - s.cases.size.should == 3 + expect(s.cases.size).to eq(3) end end it "should not raise an error when a block is missing on receive" do - lambda { + expect { select! do |s| s.case(@c, :receive) s.default end - }.should_not raise_error(Agent::Errors::BlockMissing) + }.not_to raise_error end it "should not raise an error when a block is missing on send" do - lambda { + expect { select! do |s| s.case(@c, :send, 1) s.default end - }.should_not raise_error(Agent::Errors::BlockMissing) + }.not_to raise_error end it "should scan all cases to identify available actions and execute first available one" do r = [] go!{ @c.send 1 } @@ -90,44 +90,73 @@ s.case(@c, :send, 1) { r.push 1 } s.case(@c, :receive) { r.push 2 } s.case(@c, :receive) { r.push 3 } end - r.size.should == 1 - r.first.should == 2 + expect(r.size).to eq(1) + expect(r.first).to eq(2) end it "should evaluate default case immediately if no other cases match" do r = [] select! do |s| s.case(@c, :send, 1) { r.push 1 } s.default { r.push :default } end - r.size.should == 1 - r.first.should == :default + expect(r.size).to eq(1) + expect(r.first).to eq(:default) end + it "should evaluate a matching prior closed channel in preference to the default case" do + r = [] + + @c.close + select! do |s| + s.case(@c, :receive) { r.push :from_closed } + s.default { r.push :default } + end + + expect(r.size).to eq(1) + expect(r.first).to eq(:from_closed) + end + + it "should receive from channels that are closed while selecting on said channels" do + r = [] + + Thread.new do + sleep 0.2 + @c.close + end + + select! do |s| + s.case(@c, :receive) { r.push :from_closed } + end + + expect(r.size).to eq(1) + expect(r.first).to eq(:from_closed) + end + it "should raise an error if the channel is closed out from under it and you are sending to it" do go!{ sleep 0.25; @c.close } - lambda { + expect { select! do |s| s.case(@c, :send, 1) end - }.should raise_error(Agent::Errors::ChannelClosed) + }.to raise_error(Agent::Errors::ChannelClosed) end it "should not raise an error if the channel is closed out from under it and you are receiving from it" do go!{ sleep 0.25; @c.close } - lambda { + expect { select! do |s| s.case(@c, :receive){} end - }.should_not raise_error + }.not_to raise_error end context "select immediately available channel" do it "should select read channel" do c = channel!(Integer) @@ -140,12 +169,12 @@ s.case(c, :send, 1) { r.push :send } s.case(c, :receive) { r.push :receive } s.default { r.push :empty } end - r.size.should == 1 - r.first.should == :receive + expect(r.size).to eq(1) + expect(r.first).to eq(:receive) c.close end it "should select write channel" do c = channel!(Integer) @@ -159,12 +188,12 @@ s.case(c, :send, 1) { r.push :send } s.case(c, :receive) { r.push :receive } s.default { r.push :empty } end - r.size.should == 1 - r.first.should == :send + expect(r.size).to eq(1) + expect(r.first).to eq(:send) c.close end end context "select busy channel" do @@ -178,27 +207,27 @@ select! do |s| s.case(c, :receive) {|value| r.push value } end - r.size.should == 1 - (Time.now.to_f - now).should be_within(0.1).of(0.2) + expect(r.size).to eq(1) + expect(Time.now.to_f - now).to be_within(0.1).of(0.2) c.close end it "should select busy write channel" do c = channel!(Integer) # brittle.. counting on select to execute within 0.5s now = Time.now.to_f - go!{sleep(0.2); c.receive[0].should == 2 } + go!{sleep(0.2); expect(c.receive[0]).to eq(2 )} select! do |s| s.case(c, :send, 2) end - (Time.now.to_f - now).should be_within(0.1).of(0.2) + expect(Time.now.to_f - now).to be_within(0.1).of(0.2) c.close end it "should select first available channel" do # create a write channel and a read channel @@ -222,17 +251,17 @@ s.case(cw, :send, 3) end ack.receive - res.size.should == 1 - res.first.should == 3 + expect(res.size).to eq(1) + expect(res.first).to eq(3) # 0.3s goroutine should eventually fire - cr.receive[0].should == 2 + expect(cr.receive[0]).to eq(2) - (Time.now.to_f - now).should be_within(0.05).of(0.3) + expect(Time.now.to_f - now).to be_within(0.05).of(0.3) cw.close cr.close end end end @@ -248,30 +277,30 @@ it "should evaluate select statements top to bottom" do select! do |s| s.case(@c, :send, 1) s.case(@c, :receive) - s.cases.size.should == 2 + expect(s.cases.size).to eq(2) end end it "should not raise an error when a block is missing on receive" do - lambda { + expect { select! do |s| s.case(@c, :receive) s.default end - }.should_not raise_error(Agent::Errors::BlockMissing) + }.not_to raise_error end it "should not raise an error when a block is missing on send" do - lambda { + expect { select! do |s| s.case(@c, :send, 1) s.default end - }.should_not raise_error(Agent::Errors::BlockMissing) + }.not_to raise_error end it "should scan all cases to identify available actions and execute first available one" do r = [] @c.send 1 @@ -280,12 +309,12 @@ s.case(@c, :send, 1) { r.push 1 } s.case(@c, :receive) { r.push 2 } s.case(@c, :receive) { r.push 3 } end - r.size.should == 1 - r.first.should == 2 + expect(r.size).to eq(1) + expect(r.first).to eq(2) end it "should evaluate default case immediately if no other cases match" do r = [] @@ -294,34 +323,64 @@ select! do |s| s.case(@c, :send, 1) { r.push 1 } s.default { r.push :default } end - r.size.should == 1 - r.first.should == :default + expect(r.size).to eq(1) + expect(r.first).to eq(:default) end + it "should evaluate a matching prior closed channel in preference to the default case" do + r = [] + + @c.close + + select! do |s| + s.case(@c, :receive) { r.push :from_closed } + s.default { r.push :default } + end + + expect(r.size).to eq(1) + expect(r.first).to eq(:from_closed) + end + + it "should receive from channels that are closed while selecting on said channels" do + r = [] + + Thread.new do + sleep 0.2 + @c.close + end + + select! do |s| + s.case(@c, :receive) { r.push :from_closed } + end + + expect(r.size).to eq(1) + expect(r.first).to eq(:from_closed) + end + it "should raise an error if the channel is closed out from under it and you are sending to it" do @c.send(1) go!{ sleep 0.25; @c.close } - lambda { + expect { select! do |s| s.case(@c, :send, 1) end - }.should raise_error(Agent::Errors::ChannelClosed) + }.to raise_error(Agent::Errors::ChannelClosed) end it "should not raise an error if the channel is closed out from under it and you are receiving from it" do go!{ sleep 0.25; @c.close } - lambda { + expect { select! do |s| s.case(@c, :receive){} end - }.should_not raise_error + }.not_to raise_error end context "select immediately available channel" do it "should select read channel" do c = channel!(Integer, 1) @@ -332,12 +391,12 @@ s.case(c, :send, 1) { r.push :send } s.case(c, :receive) { r.push :receive } s.default { r.push :empty } end - r.size.should == 1 - r.first.should == :receive + expect(r.size).to eq(1) + expect(r.first).to eq(:receive) c.close end it "should select write channel" do c = channel!(Integer, 1) @@ -347,12 +406,12 @@ s.case(c, :send, 1) { r.push :send } s.case(c, :receive) { r.push :receive } s.default { r.push :empty } end - r.size.should == 1 - r.first.should == :send + expect(r.size).to eq(1) + expect(r.first).to eq(:send) c.close end end context "select busy channel" do @@ -366,12 +425,12 @@ select! do |s| s.case(c, :receive) {|value| r.push value } end - r.size.should == 1 - (Time.now.to_f - now).should be_within(0.1).of(0.2) + expect(r.size).to eq(1) + expect(Time.now.to_f - now).to be_within(0.1).of(0.2) c.close end it "should select busy write channel" do c = channel!(Integer, 1) @@ -383,12 +442,12 @@ select! do |s| s.case(c, :send, 2) end - c.receive[0].should == 2 - (Time.now.to_f - now).should be_within(0.1).of(0.2) + expect(c.receive[0]).to eq(2) + expect(Time.now.to_f - now).to be_within(0.1).of(0.2) c.close end it "should select first available channel" do # create a "full" write channel, and "empty" read channel @@ -414,16 +473,16 @@ end ack.receive # 0.8s goroutine should have consumed the message first - res.size.should == 1 - res.first.should == 1 + expect(res.size).to eq(1) + expect(res.first).to eq(1) # send case should have fired, and we should have a message - cw.receive[0].should == 3 + expect(cw.receive[0]).to eq(3) - (Time.now.to_f - now).should be_within(0.1).of(0.2) + expect(Time.now.to_f - now).to be_within(0.1).of(0.2) cw.close cr.close end end end