spec/stream_spec.rb in http-2-0.7.0 vs spec/stream_spec.rb in http-2-0.8.0
- old
+ new
@@ -1,433 +1,510 @@
-require "helper"
+require 'helper'
-describe HTTP2::Stream do
+RSpec.describe HTTP2::Stream do
before(:each) do
@client = Client.new
@stream = @client.new_stream
end
- context "stream states" do
- it "should initiliaze all streams to IDLE" do
- @stream.state.should eq :idle
+ context 'stream states' do
+ it 'should initiliaze all streams to IDLE' do
+ expect(@stream.state).to eq :idle
end
- it "should set custom stream priority" do
+ it 'should set custom stream priority' do
stream = @client.new_stream(weight: 3, dependency: 2, exclusive: true)
- stream.weight.should eq 3
+ expect(stream.weight).to eq 3
end
- context "reserved (local)" do
- before(:each) { @stream.send PUSH_PROMISE }
+ context 'idle' do
+ it 'should transition to open on sent HEADERS' do
+ @stream.send HEADERS.deep_dup
+ expect(@stream.state).to eq :open
+ end
+ it 'should transition to open on received HEADERS' do
+ @stream.receive HEADERS
+ expect(@stream.state).to eq :open
+ end
+ it 'should transition to reserved (local) on sent PUSH_PROMISE' do
+ @stream.send PUSH_PROMISE.deep_dup
+ expect(@stream.state).to eq :reserved_local
+ end
+ it 'should transition to reserved (remote) on received PUSH_PROMISE' do
+ @stream.receive PUSH_PROMISE
+ expect(@stream.state).to eq :reserved_remote
+ end
+ it 'should reprioritize stream on sent PRIORITY' do
+ expect { @stream.send PRIORITY.dup }.to_not raise_error
+ expect(@stream.weight).to eq 20
+ end
+ it 'should reprioritize stream on received PRIORITY' do
+ expect { @stream.send PRIORITY.dup }.to_not raise_error
+ expect(@stream.weight).to eq 20
+ end
+ end
- it "should transition on sent PUSH_PROMISE" do
- @stream.state.should eq :reserved_local
+ context 'reserved (local)' do
+ before(:each) { @stream.send PUSH_PROMISE.deep_dup }
+
+ it 'should transition on sent PUSH_PROMISE' do
+ expect(@stream.state).to eq :reserved_local
end
- it "should allow HEADERS to be sent" do
- expect { @stream.send HEADERS }.to_not raise_error
+ it 'should allow HEADERS to be sent' do
+ expect { @stream.send HEADERS.deep_dup }.to_not raise_error
end
- it "should raise error if sending invalid frames" do
+ it 'should raise error if sending invalid frames' do
(FRAME_TYPES - [HEADERS, RST_STREAM]).each do |type|
- expect { @stream.dup.send type }.to raise_error StreamError
+ expect { @stream.dup.send type }.to raise_error InternalError
end
end
- it "should raise error on receipt of invalid frames" do
- (FRAME_TYPES - [PRIORITY, RST_STREAM]).each do |type|
- expect { @stream.dup.receive type }.to raise_error StreamError
+ it 'should raise error on receipt of invalid frames' do
+ what_types = (FRAME_TYPES - [PRIORITY, RST_STREAM, WINDOW_UPDATE])
+ what_types.each do |type|
+ expect { @stream.dup.receive type }.to raise_error InternalError
end
end
- it "should transition to half closed (remote) on sent HEADERS" do
- @stream.send HEADERS
- @stream.state.should eq :half_closed_remote
+ it 'should transition to half closed (remote) on sent HEADERS' do
+ @stream.send HEADERS.deep_dup
+ expect(@stream.state).to eq :half_closed_remote
end
- it "should transition to closed on sent RST_STREAM" do
+ it 'should transition to closed on sent RST_STREAM' do
@stream.close
- @stream.state.should eq :closed
+ expect(@stream.state).to eq :closed
end
- it "should transition to closed on received RST_STREAM" do
+ it 'should transition to closed on received RST_STREAM' do
@stream.receive RST_STREAM
- @stream.state.should eq :closed
+ expect(@stream.state).to eq :closed
end
- it "should reprioritize stream on PRIORITY" do
+ it 'should reprioritize stream on PRIORITY' do
expect { @stream.receive PRIORITY }.to_not raise_error
- @stream.weight.should eq 20
+ expect(@stream.weight).to eq 20
end
+
+ it 'should increment remote_window on received WINDOW_UPDATE' do
+ expect { @stream.receive WINDOW_UPDATE }.to_not raise_error
+ expect(@stream.remote_window).to eq DEFAULT_FLOW_WINDOW + WINDOW_UPDATE[:increment]
+ end
end
- context "reserved (remote)" do
+ context 'reserved (remote)' do
before(:each) { @stream.receive PUSH_PROMISE }
- it "should transition on received PUSH_PROMISE" do
- @stream.state.should eq :reserved_remote
+ it 'should transition on received PUSH_PROMISE' do
+ expect(@stream.state).to eq :reserved_remote
end
- it "should raise error if sending invalid frames" do
- (FRAME_TYPES - [PRIORITY, RST_STREAM]).each do |type|
- expect { @stream.dup.send type }.to raise_error StreamError
+ it 'should raise error if sending invalid frames' do
+ (FRAME_TYPES - [PRIORITY, RST_STREAM, WINDOW_UPDATE]).each do |type|
+ expect { @stream.dup.send type }.to raise_error InternalError
end
end
- it "should raise error on receipt of invalid frames" do
+ it 'should raise error on receipt of invalid frames' do
(FRAME_TYPES - [HEADERS, RST_STREAM]).each do |type|
- expect { @stream.dup.receive type }.to raise_error StreamError
+ expect { @stream.dup.receive type }.to raise_error InternalError
end
end
- it "should transition to half closed (local) on received HEADERS" do
+ it 'should transition to half closed (local) on received HEADERS' do
@stream.receive HEADERS
- @stream.state.should eq :half_closed_local
+ expect(@stream.state).to eq :half_closed_local
end
- it "should transition to closed on sent RST_STREAM" do
+ it 'should transition to closed on sent RST_STREAM' do
@stream.close
- @stream.state.should eq :closed
+ expect(@stream.state).to eq :closed
end
- it "should transition to closed on received RST_STREAM" do
+ it 'should transition to closed on received RST_STREAM' do
@stream.receive RST_STREAM
- @stream.state.should eq :closed
+ expect(@stream.state).to eq :closed
end
- it "should reprioritize stream on PRIORITY" do
- expect { @stream.send PRIORITY }.to_not raise_error
- @stream.weight.should eq 20
+ it 'should reprioritize stream on PRIORITY' do
+ expect { @stream.send PRIORITY.dup }.to_not raise_error
+ expect(@stream.weight).to eq 20
end
+
+ it 'should increment local_window on sent WINDOW_UPDATE' do
+ expect { @stream.send WINDOW_UPDATE.dup }.to_not raise_error
+ expect(@stream.local_window).to eq DEFAULT_FLOW_WINDOW + WINDOW_UPDATE[:increment]
+ end
end
- context "open" do
+ context 'open' do
before(:each) { @stream.receive HEADERS }
- it "should allow any valid frames types to be sent" do
+ it 'should allow any valid frames types to be sent' do
(FRAME_TYPES - [PING, GOAWAY, SETTINGS]).each do |type|
- expect { @stream.dup.send type }.to_not raise_error
+ expect { @stream.dup.send type.deep_dup }.to_not raise_error
end
end
- it "should allow frames of any type to be received" do
+ it 'should allow frames of any type to be received' do
FRAME_TYPES.each do |type|
expect { @stream.dup.receive type }.to_not raise_error
end
end
- it "should transition to half closed (local) if sending END_STREAM" do
+ it 'should transition to half closed (local) if sending END_STREAM' do
[DATA, HEADERS].each do |frame|
- s, f = @stream.dup, frame.dup
+ s, f = @stream.dup, frame.deep_dup
f[:flags] = [:end_stream]
s.send f
- s.state.should eq :half_closed_local
+ expect(s.state).to eq :half_closed_local
end
end
- it "should transition to half closed (remote) if receiving END_STREAM" do
+ it 'should transition to half closed (remote) if receiving END_STREAM' do
[DATA, HEADERS].each do |frame|
s, f = @stream.dup, frame.dup
f[:flags] = [:end_stream]
s.receive f
- s.state.should eq :half_closed_remote
+ expect(s.state).to eq :half_closed_remote
end
end
- it "should transition to half closed if remote opened with END_STREAM" do
+ it 'should transition to half closed if remote opened with END_STREAM' do
s = @client.new_stream
hclose = HEADERS.dup
hclose[:flags] = [:end_stream]
s.receive hclose
- s.state.should eq :half_closed_remote
+ expect(s.state).to eq :half_closed_remote
end
- it "should transition to half closed if local opened with END_STREAM" do
+ it 'should transition to half closed if local opened with END_STREAM' do
s = @client.new_stream
- hclose = HEADERS.dup
+ hclose = HEADERS.deep_dup
hclose[:flags] = [:end_stream]
s.send hclose
- s.state.should eq :half_closed_local
+ expect(s.state).to eq :half_closed_local
end
- it "should transition to closed if sending RST_STREAM" do
+ it 'should transition to closed if sending RST_STREAM' do
@stream.close
- @stream.state.should eq :closed
+ expect(@stream.state).to eq :closed
end
- it "should transition to closed if receiving RST_STREAM" do
+ it 'should transition to closed if receiving RST_STREAM' do
@stream.receive RST_STREAM
- @stream.state.should eq :closed
+ expect(@stream.state).to eq :closed
end
- it "should emit :active on open transition" do
+ it 'should emit :active on open transition' do
openp, openr = false, false
sp = @client.new_stream
sr = @client.new_stream
sp.on(:active) { openp = true }
sr.on(:active) { openr = true }
sp.receive HEADERS
- sr.send HEADERS
+ sr.send HEADERS.deep_dup
- openp.should be_truthy
- openr.should be_truthy
+ expect(openp).to be_truthy
+ expect(openr).to be_truthy
end
- it "should not emit :active on transition from open" do
+ it 'should not emit :active on transition from open' do
order, stream = [], @client.new_stream
stream.on(:active) { order << :active }
stream.on(:half_close) { order << :half_close }
stream.on(:close) { order << :close }
- req = HEADERS.dup
+ req = HEADERS.deep_dup
req[:flags] = [:end_headers]
stream.send req
- stream.send DATA
- order.should eq [:active, :half_close]
+ stream.send DATA.dup
+ expect(order).to eq [:active, :half_close]
end
- it "should emit :close on close transition" do
+ it 'should emit :close on close transition' do
closep, closer = false, false
sp, sr = @stream.dup, @stream.dup
sp.on(:close) { closep = true }
sr.on(:close) { closer = true }
sp.receive RST_STREAM
sr.close
- closep.should be_truthy
- closer.should be_truthy
+ expect(closep).to be_truthy
+ expect(closer).to be_truthy
end
- it "should emit :close after frame is processed" do
+ it 'should emit :close after frame is processed' do
order, stream = [], @client.new_stream
stream.on(:active) { order << :active }
stream.on(:data) { order << :data }
stream.on(:half_close) { order << :half_close }
stream.on(:close) { order << :close }
- req = HEADERS.dup
+ req = HEADERS.deep_dup
req[:flags] = [:end_stream, :end_headers]
stream.send req
stream.receive HEADERS
stream.receive DATA
- order.should eq [:active, :half_close, :data, :close]
+ expect(order).to eq [:active, :half_close, :data, :close]
end
- it "should emit :close with reason" do
+ it 'should emit :close with reason' do
reason = nil
- @stream.on(:close) {|r| reason = r }
+ @stream.on(:close) { |r| reason = r }
@stream.receive RST_STREAM
- reason.should_not be_nil
+ expect(reason).not_to be_nil
end
+
+ it 'should reprioritize stream on sent PRIORITY' do
+ expect { @stream.send PRIORITY.dup }.to_not raise_error
+ expect(@stream.weight).to eq 20
+ end
+ it 'should reprioritize stream on received PRIORITY' do
+ expect { @stream.receive PRIORITY }.to_not raise_error
+ expect(@stream.weight).to eq 20
+ end
end
- context "half closed (local)" do
- before(:each) { @stream.send HEADERS_END_STREAM }
+ context 'half closed (local)' do
+ before(:each) { @stream.send HEADERS_END_STREAM.deep_dup }
- it "should raise error on attempt to send frames" do
- (FRAME_TYPES - [PRIORITY, RST_STREAM]).each do |frame|
- expect { @stream.dup.send frame }.to raise_error StreamError
+ it 'should raise error on attempt to send invalid frames' do
+ (FRAME_TYPES - [PRIORITY, RST_STREAM, WINDOW_UPDATE]).each do |frame|
+ expect { @stream.dup.send frame }.to raise_error InternalError
end
end
- it "should transition to closed on receipt of END_STREAM flag" do
+ it 'should transition to closed on receipt of END_STREAM flag' do
[DATA, HEADERS, CONTINUATION].each do |frame|
s, f = @stream.dup, frame.dup
f[:flags] = [:end_stream]
s.receive f
- s.state.should eq :closed
+ expect(s.state).to eq :closed
end
end
- it "should transition to closed on receipt of RST_STREAM frame" do
+ it 'should transition to closed on receipt of RST_STREAM frame' do
@stream.receive RST_STREAM
- @stream.state.should eq :closed
+ expect(@stream.state).to eq :closed
end
- it "should transition to closed if RST_STREAM frame is sent" do
- @stream.send RST_STREAM
- @stream.state.should eq :closed
+ it 'should transition to closed if RST_STREAM frame is sent' do
+ @stream.send RST_STREAM.deep_dup
+ expect(@stream.state).to eq :closed
end
- it "should ignore received WINDOW_UPDATE, PRIORITY frames" do
+ it 'should ignore received WINDOW_UPDATE frames' do
expect { @stream.receive WINDOW_UPDATE }.to_not raise_error
+ expect(@stream.state).to eq :half_closed_local
+ end
+
+ it 'should ignore received PRIORITY frames' do
expect { @stream.receive PRIORITY }.to_not raise_error
- @stream.state.should eq :half_closed_local
+ expect(@stream.state).to eq :half_closed_local
end
- it "should reprioritize stream on PRIORITY" do
- expect { @stream.send PRIORITY }.to_not raise_error
- @stream.weight.should eq 20
+ it 'should reprioritize stream on sent PRIORITY' do
+ expect { @stream.send PRIORITY.dup }.to_not raise_error
+ expect(@stream.weight).to eq 20
end
- it "should emit :half_close event on transition" do
+ it 'should reprioritize stream (and decendants) on received PRIORITY' do
+ expect { @stream.receive PRIORITY }.to_not raise_error
+ expect(@stream.weight).to eq 20
+ end
+
+ it 'should increment local_window on sent WINDOW_UPDATE' do
+ expect { @stream.send WINDOW_UPDATE.dup }.to_not raise_error
+ expect(@stream.local_window).to eq DEFAULT_FLOW_WINDOW + WINDOW_UPDATE[:increment]
+ end
+
+ it 'should emit :half_close event on transition' do
order = []
stream = @client.new_stream
stream.on(:active) { order << :active }
stream.on(:half_close) { order << :half_close }
- req = HEADERS.dup
+ req = HEADERS.deep_dup
req[:flags] = [:end_stream, :end_headers]
stream.send req
- order.should eq [:active, :half_close]
+ expect(order).to eq [:active, :half_close]
end
- it "should emit :close event on transition to closed" do
+ it 'should emit :close event on transition to closed' do
closed = false
@stream.on(:close) { closed = true }
@stream.receive RST_STREAM
- @stream.state.should eq :closed
- closed.should be_truthy
+ expect(@stream.state).to eq :closed
+ expect(closed).to be_truthy
end
end
- context "half closed (remote)" do
+ context 'half closed (remote)' do
before(:each) { @stream.receive HEADERS_END_STREAM }
- it "should raise STREAM_CLOSED error on reciept of frames" do
+ it 'should raise STREAM_CLOSED error on reciept of frames' do
(FRAME_TYPES - [PRIORITY, RST_STREAM, WINDOW_UPDATE]).each do |frame|
- expect {
+ expect do
@stream.dup.receive frame
- }.to raise_error(StreamClosed)
+ end.to raise_error(StreamClosed)
end
end
- it "should transition to closed if END_STREAM flag is sent" do
+ it 'should transition to closed if END_STREAM flag is sent' do
[DATA, HEADERS].each do |frame|
- s, f = @stream.dup, frame.dup
+ s, f = @stream.dup, frame.deep_dup
f[:flags] = [:end_stream]
- s.on(:close) { s.state.should eq :closed }
+ s.on(:close) { expect(s.state).to eq :closed }
s.send f
- s.state.should eq :closed
+ expect(s.state).to eq :closed
end
end
- it "should transition to closed if RST_STREAM is sent" do
+ it 'should transition to closed if RST_STREAM is sent' do
@stream.close
- @stream.state.should eq :closed
+ expect(@stream.state).to eq :closed
end
- it "should transition to closed on reciept of RST_STREAM frame" do
+ it 'should transition to closed on reciept of RST_STREAM frame' do
@stream.receive RST_STREAM
- @stream.state.should eq :closed
+ expect(@stream.state).to eq :closed
end
- it "should ignore received WINDOW_UPDATE frames" do
+ it 'should ignore sent WINDOW_UPDATE frames' do
+ expect { @stream.send WINDOW_UPDATE.dup }.to_not raise_error
+ expect(@stream.state).to eq :half_closed_remote
+ end
+
+ it 'should increment remote_window on received WINDOW_UPDATE' do
expect { @stream.receive WINDOW_UPDATE }.to_not raise_error
- @stream.state.should eq :half_closed_remote
+ expect(@stream.remote_window).to eq DEFAULT_FLOW_WINDOW + WINDOW_UPDATE[:increment]
end
- it "should reprioritize stream on PRIORITY" do
+ it 'should reprioritize stream on sent PRIORITY' do
+ expect { @stream.send PRIORITY.dup }.to_not raise_error
+ expect(@stream.weight).to eq 20
+ end
+ it 'should reprioritize stream on received PRIORITY' do
expect { @stream.receive PRIORITY }.to_not raise_error
- @stream.weight.should eq 20
+ expect(@stream.weight).to eq 20
end
- it "should emit :half_close event on transition" do
+ it 'should emit :half_close event on transition' do
order = []
stream = @client.new_stream
stream.on(:active) { order << :active }
stream.on(:half_close) { order << :half_close }
req = HEADERS.dup
req[:flags] = [:end_stream, :end_headers]
stream.receive req
- order.should eq [:active, :half_close]
+ expect(order).to eq [:active, :half_close]
end
- it "should emit :close event on close transition" do
+ it 'should emit :close event on close transition' do
closed = false
@stream.on(:close) { closed = true }
@stream.close
- @stream.state.should eq :closed
- closed.should be_truthy
+ expect(@stream.state).to eq :closed
+ expect(closed).to be_truthy
end
end
- context "closed" do
- context "remote closed stream" do
+ context 'closed' do
+ context 'remote closed stream' do
before(:each) do
- @stream.send HEADERS_END_STREAM # half closed local
+ @stream.send HEADERS_END_STREAM.deep_dup # half closed local
@stream.receive HEADERS_END_STREAM # closed by remote
end
- it "should raise STREAM_CLOSED on attempt to send frames" do
+ it 'should raise STREAM_CLOSED on attempt to send frames' do
(FRAME_TYPES - [PRIORITY, RST_STREAM]).each do |frame|
- expect {
+ expect do
@stream.dup.send frame
- }.to raise_error(StreamClosed)
+ end.to raise_error(StreamClosed)
end
end
- it "should raise STREAM_CLOSED on receipt of frame" do
+ it 'should raise STREAM_CLOSED on receipt of frame' do
(FRAME_TYPES - [PRIORITY, RST_STREAM, WINDOW_UPDATE]).each do |frame|
- expect {
+ expect do
@stream.dup.receive frame
- }.to raise_error(StreamClosed)
+ end.to raise_error(StreamClosed)
end
end
- it "should allow PRIORITY, RST_STREAM to be sent" do
- expect { @stream.send PRIORITY }.to_not raise_error
- expect { @stream.send RST_STREAM }.to_not raise_error
+ it 'should allow PRIORITY, RST_STREAM to be sent' do
+ expect { @stream.send PRIORITY.dup }.to_not raise_error
+ expect { @stream.send RST_STREAM.dup }.to_not raise_error
end
- it "should allow PRIORITY, RST_STREAM to be received" do
+ it 'should allow PRIORITY, RST_STREAM to be received' do
expect { @stream.receive PRIORITY }.to_not raise_error
expect { @stream.receive RST_STREAM }.to_not raise_error
end
- it "should reprioritize stream on PRIORITY" do
+ it 'should reprioritize stream on sent PRIORITY' do
+ expect { @stream.send PRIORITY.dup }.to_not raise_error
+ expect(@stream.weight).to eq 20
+ end
+ it 'should reprioritize stream on received PRIORITY' do
expect { @stream.receive PRIORITY }.to_not raise_error
- @stream.weight.should eq 20
+ expect(@stream.weight).to eq 20
end
+ it 'should ignore received WINDOW_UPDATE frames' do
+ expect { @stream.receive WINDOW_UPDATE }.to_not raise_error
+ expect(@stream.state).to eq :closed
+ end
end
- context "local closed via RST_STREAM frame" do
+ context 'local closed via RST_STREAM frame' do
before(:each) do
- @stream.send HEADERS # open
- @stream.send RST_STREAM # closed by local
+ @stream.send HEADERS.deep_dup # open
+ @stream.send RST_STREAM.deep_dup # closed by local
end
- it "should ignore received frames" do
+ it 'should ignore received frames' do
(FRAME_TYPES - [PUSH_PROMISE]).each do |frame|
- expect {
+ expect do
cb = []
@stream.on(:data) { cb << :data }
- @stream.on(:headers) { cb << :headers}
- @stream.dup.receive frame
- cb.should be_empty
- }.to_not raise_error
+ @stream.on(:headers) { cb << :headers }
+ @stream.dup.receive frame.dup
+ expect(cb).to be_empty
+ end.to_not raise_error
end
end
- #it "should transition to reserved remote on PUSH_PROMISE" do
- # An endpoint might receive a PUSH_PROMISE frame after it sends
- # RST_STREAM. PUSH_PROMISE causes a stream to become "reserved".
- # ...
- # We're auto RST'ing PUSH streams in connection class, hence
- # skipping this transition for now.
- #end
-
+ # it "should transition to reserved remote on PUSH_PROMISE" do
+ # An endpoint might receive a PUSH_PROMISE frame after it sends
+ # RST_STREAM. PUSH_PROMISE causes a stream to become "reserved".
+ # ...
+ # We're auto RST'ing PUSH streams in connection class, hence
+ # skipping this transition for now.
+ # end
end
# FIXME: Isn't this test same as "half closed (local)"?
# context "local closed via END_STREAM flag" do
# before(:each) do
@@ -439,265 +516,279 @@
# FRAME_TYPES.each do |frame|
# expect { @stream.dup.receive frame }.to_not raise_error
# end
# end
# end
-
end
end # end stream states
# TODO: add test cases to ensure on(:priority) emitted after close
- context "flow control" do
- it "should initialize to default flow control window" do
- @stream.remote_window.should eq DEFAULT_FLOW_WINDOW
+ context 'flow control' do
+ it 'should initialize to default flow control window' do
+ expect(@stream.remote_window).to eq DEFAULT_FLOW_WINDOW
end
- it "should update window size on DATA frames only" do
- @stream.send HEADERS # go to open
- @stream.remote_window.should eq DEFAULT_FLOW_WINDOW
+ it 'should update window size on DATA frames only' do
+ @stream.send HEADERS.deep_dup # go to open
+ expect(@stream.remote_window).to eq DEFAULT_FLOW_WINDOW
- (FRAME_TYPES - [DATA,PING,GOAWAY,SETTINGS]).each do |frame|
+ (FRAME_TYPES - [DATA, PING, GOAWAY, SETTINGS]).each do |frame|
s = @stream.dup
- s.send frame
- s.remote_window.should eq DEFAULT_FLOW_WINDOW
+ s.send frame.deep_dup
+ expect(s.remote_window).to eq DEFAULT_FLOW_WINDOW
end
- @stream.send DATA
- @stream.remote_window.should eq DEFAULT_FLOW_WINDOW - DATA[:payload].bytesize
+ @stream.send DATA.dup
+ expect(@stream.remote_window).to eq DEFAULT_FLOW_WINDOW - DATA[:payload].bytesize
end
- it "should update window size on receipt of WINDOW_UPDATE" do
- @stream.send HEADERS
- @stream.send DATA
+ it 'should update window size on receipt of WINDOW_UPDATE' do
+ @stream.send HEADERS.deep_dup
+ @stream.send DATA.dup
@stream.receive WINDOW_UPDATE
- @stream.remote_window.should eq (
- DEFAULT_FLOW_WINDOW - DATA[:payload].bytesize + WINDOW_UPDATE[:increment]
+ expect(@stream.remote_window).to eq(
+ DEFAULT_FLOW_WINDOW - DATA[:payload].bytesize + WINDOW_UPDATE[:increment],
)
end
- it "should observe session flow control" do
+ it 'should observe session flow control' do
settings, data = SETTINGS.dup, DATA.dup
settings[:payload] = [[:settings_initial_window_size, 1000]]
settings[:stream] = 0
framer = Framer.new
@client << framer.generate(settings)
s1 = @client.new_stream
- s1.send HEADERS
- s1.send data.merge({payload: "x" * 900, flags: []})
- s1.remote_window.should eq 100
+ s1.send HEADERS.deep_dup
+ s1.send data.merge(payload: 'x' * 900, flags: [])
+ expect(s1.remote_window).to eq 100
- s1.send data.merge({payload: "x" * 200})
- s1.remote_window.should eq 0
- s1.buffered_amount.should eq 100
+ s1.send data.merge(payload: 'x' * 200)
+ expect(s1.remote_window).to eq 0
+ expect(s1.buffered_amount).to eq 100
- @client << framer.generate(WINDOW_UPDATE.merge({
- stream: s1.id, increment: 1000
- }))
- s1.buffered_amount.should eq 0
- s1.remote_window.should eq 900
+ @client << framer.generate(WINDOW_UPDATE.merge(stream: s1.id, increment: 1000))
+ expect(s1.buffered_amount).to eq 0
+ expect(s1.remote_window).to eq 900
end
end
- context "client API" do
- it ".reprioritize should emit PRIORITY frame" do
- @stream.should_receive(:send) do |frame|
- frame[:type].should eq :priority
- frame[:weight].should eq 30
+ context 'client API' do
+ it '.reprioritize should emit PRIORITY frame' do
+ expect(@stream).to receive(:send) do |frame|
+ expect(frame[:type]).to eq :priority
+ expect(frame[:weight]).to eq 30
end
@stream.reprioritize weight: 30
end
- it ".reprioritize should raise error if invoked by server" do
+ it '.reprioritize should raise error if invoked by server' do
srv = Server.new
stream = srv.new_stream
- expect { stream.reprioritize(weight: 10) }.to raise_error(StreamError)
+ expect { stream.reprioritize(weight: 10) }.to raise_error(InternalError)
end
- it ".headers should emit HEADERS frames" do
+ it '.headers should emit HEADERS frames' do
payload = {
':method' => 'GET',
':scheme' => 'http',
':host' => 'www.example.org',
':path' => '/resource',
- 'custom' => 'value'
+ 'custom' => 'value',
}
- @stream.should_receive(:send) do |frame|
- frame[:type].should eq :headers
- frame[:payload].should eq payload.to_a
- frame[:flags].should eq [:end_headers]
+ expect(@stream).to receive(:send) do |frame|
+ expect(frame[:type]).to eq :headers
+ expect(frame[:payload]).to eq payload.to_a
+ expect(frame[:flags]).to eq [:end_headers]
end
@stream.headers(payload, end_stream: false, end_headers: true)
end
- it ".data should emit DATA frames" do
- @stream.should_receive(:send) do |frame|
- frame[:type].should eq :data
- frame[:payload].should eq "text"
- frame[:flags].should be_empty
+ it '.data should emit DATA frames' do
+ expect(@stream).to receive(:send) do |frame|
+ expect(frame[:type]).to eq :data
+ expect(frame[:payload]).to eq 'text'
+ expect(frame[:flags]).to be_empty
end
- @stream.data("text", end_stream: false)
+ @stream.data('text', end_stream: false)
- @stream.should_receive(:send) do |frame|
- frame[:flags].should eq [:end_stream]
+ expect(@stream).to receive(:send) do |frame|
+ expect(frame[:flags]).to eq [:end_stream]
end
- @stream.data("text")
+ @stream.data('text')
end
- it ".data should split large DATA frames" do
- data = "x" * 16384 * 2
+ it '.data should split large DATA frames' do
+ data = 'x' * 16_384 * 2
- @stream.stub(:send)
- @stream.should_receive(:send).exactly(3).times
- @stream.data(data + "x")
+ want = [
+ { type: :data, flags: [], length: 16_384 },
+ { type: :data, flags: [], length: 16_384 },
+ { type: :data, flags: [:end_stream], length: 1 },
+ ]
+ want.each do |w|
+ expect(@stream).to receive(:send) do |frame|
+ expect(frame[:type]).to eq w[:type]
+ expect(frame[:flags]).to eq w[:flags]
+ expect(frame[:payload].length).to eq w[:length]
+ end
+ end
+
+ @stream.data(data + 'x')
end
- it ".cancel should reset stream with cancel error code" do
- @stream.should_receive(:send) do |frame|
- frame[:type].should eq :rst_stream
- frame[:error].should eq :cancel
+ it '.cancel should reset stream with cancel error code' do
+ expect(@stream).to receive(:send) do |frame|
+ expect(frame[:type]).to eq :rst_stream
+ expect(frame[:error]).to eq :cancel
end
@stream.cancel
end
- it ".refuse should reset stream with refused stream error code" do
- @stream.should_receive(:send) do |frame|
- frame[:type].should eq :rst_stream
- frame[:error].should eq :refused_stream
+ it '.refuse should reset stream with refused stream error code' do
+ expect(@stream).to receive(:send) do |frame|
+ expect(frame[:type]).to eq :rst_stream
+ expect(frame[:error]).to eq :refused_stream
end
@stream.refuse
end
end
- context "server API" do
+ context 'server API' do
before(:each) do
@srv = Server.new
@frm = Framer.new
- @client.on(:frame) {|bytes| @srv << bytes }
+ @client.on(:frame) { |bytes| @srv << bytes }
@client_stream = @client.new_stream
end
- it "should emit received headers via on(:headers)" do
- headers, recv = [["header", "value"]], nil
+ it 'should emit received headers via on(:headers)' do
+ headers, recv = [%w(header value)], nil
@srv.on(:stream) do |stream|
- stream.on(:headers) {|h| recv = h}
+ stream.on(:headers) { |h| recv = h }
end
@client_stream.headers(headers)
- recv.should eq headers
+ expect(recv).to eq headers
end
- it "should emit received payload via on(:data)" do
- payload, recv = "some-payload", nil
+ it 'should emit received payload via on(:data)' do
+ payload = 'some-payload'
@srv.on(:stream) do |stream|
stream.on(:data) do |recv|
- recv.should eq payload
+ expect(recv).to eq payload
end
end
- @client_stream.headers({"key" => "value"})
+ @client_stream.headers('key' => 'value')
@client_stream.data(payload)
end
- it "should emit received priority parameters via on(:priority)" do
+ it 'should emit received priority parameters via on(:priority)' do
new_weight, new_dependency = 15, @client_stream.id + 2
callback_called = false
@srv.on(:stream) do |stream|
stream.on(:priority) do |pri|
callback_called = true
- pri.is_a?(Hash).should be
- pri[:weight].should eq new_weight
- pri[:dependency].should eq new_dependency
+ expect(pri.is_a?(Hash)).to be
+ expect(pri[:weight]).to eq new_weight
+ expect(pri[:dependency]).to eq new_dependency
end
end
- @client_stream.headers({"key" => "value"})
+ @client_stream.headers('key' => 'value')
@client_stream.reprioritize(weight: new_weight, dependency: new_dependency)
- callback_called.should be
+ expect(callback_called).to be
end
- context "push" do
+ context 'push' do
before(:each) do
- @srv.on(:frame) {|bytes| @client << bytes }
+ @srv.on(:frame) { |bytes| @client << bytes }
@srv.on(:stream) do |stream|
@server_stream = stream
end
- @client_stream.headers({"key" => "value"})
+ @client_stream.headers('key' => 'value')
end
- it ".promise should emit server initiated stream" do
+ it '.promise should emit server initiated stream' do
push = nil
- @server_stream.promise({"key" => "val"}) { |pstream| push = pstream }
- push.id.should eq 2
+ @server_stream.promise('key' => 'val') { |pstream| push = pstream }
+ expect(push.id).to eq 2
end
- it ".promise push stream should have parent stream" do
+ it '.promise push stream should have parent stream' do
push = nil
- @server_stream.promise({"key" => "val"}) { |pstream| push = pstream }
+ @server_stream.promise('key' => 'val') { |pstream| push = pstream }
- push.state.should eq :reserved_local
- push.parent.id.should eq @server_stream.id
+ expect(push.state).to eq :reserved_local
+ expect(push.parent.id).to eq @server_stream.id
end
- context "stream states" do
- it "server: active > half close > close" do
+ context 'stream states' do
+ it 'server: active > half close > close' do
order = []
- @server_stream.promise({"key" => "val"}) do |push|
+ @server_stream.promise('key' => 'val') do |push|
stream = push
- push.state.should eq :reserved_local
+ expect(push.state).to eq :reserved_local
order << :reserved
push.on(:active) { order << :active }
- push.on(:half_close){ order << :half_close }
+ push.on(:half_close) { order << :half_close }
push.on(:close) { order << :close }
- push.headers({"key2" => "val2"})
- push.send DATA.merge({stream: stream.id})
+ push.headers('key2' => 'val2')
+ push.send DATA.merge(stream: stream.id)
end
- order.should eq [:reserved, :active, :half_close, :close]
+ expect(order).to eq [:reserved, :active, :half_close, :close]
end
- it "client: headers > active > headers > .. > data > close" do
+ it 'client: headers > active > headers > .. > data > close' do
order, headers = [], []
@client.on(:promise) do |push|
order << :reserved
push.on(:active) { order << :active }
push.on(:data) { order << :data }
- push.on(:half_close){ order << :half_close }
+ push.on(:half_close) { order << :half_close }
push.on(:close) { order << :close }
push.on(:headers) do |h|
order << :headers
headers += h
end
- push.id.should be_even
+ expect(push.id).to be_even
end
- @server_stream.promise({"key" => "val"}) do |push|
- push.headers("key2" => "val2")
- push.data("somedata")
+ @server_stream.promise('key' => 'val') do |push|
+ push.headers('key2' => 'val2')
+ push.data('somedata')
end
- headers.should eq([["key", "val"], ["key2", "val2"]])
- order.should eq [:reserved, :headers, :active, :headers,
- :half_close, :data, :close]
+ expect(headers).to eq([%w(key val), %w(key2 val2)])
+ expect(order).to eq [
+ :reserved,
+ :headers,
+ :active,
+ :headers,
+ :half_close,
+ :data,
+ :close,
+ ]
end
end
-
end
end
end