http-2 0.7.0 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,22 +1,11 @@
1
- begin
2
- if RSpec::Core::Version::STRING.to_i >= 3
3
- # Disable deprecation warnings for newer RSpec
4
- RSpec.configure do |config|
5
- config.expect_with :rspec do |c|
6
- c.syntax = [:should, :expect]
7
- end
8
- config.mock_with :rspec do |c|
9
- c.syntax = [:should, :expect]
10
- end
11
- end
12
- end
13
- rescue Exception
14
- end
1
+ require 'active_support/core_ext/object/deep_dup'
2
+
3
+ RSpec.configure(&:disable_monkey_patching!)
15
4
 
16
5
  require 'json'
17
6
  require 'coveralls'
18
7
 
19
- Coveralls.wear! if ENV["CI"]
8
+ Coveralls.wear! if ENV['CI']
20
9
 
21
10
  require 'http/2'
22
11
 
@@ -26,24 +15,24 @@ include HTTP2::Error
26
15
 
27
16
  DATA = {
28
17
  type: :data,
29
- flags: [:end_stream],
18
+ flags: [:end_stream].freeze,
30
19
  stream: 1,
31
- payload: 'text'
32
- }
20
+ payload: 'text'.freeze,
21
+ }.freeze
33
22
 
34
23
  HEADERS = {
35
24
  type: :headers,
36
- flags: [:end_headers],
25
+ flags: [:end_headers].freeze,
37
26
  stream: 1,
38
- payload: Compressor.new.encode([['a','b']])
39
- }
27
+ payload: Compressor.new.encode([%w(a b)]).freeze,
28
+ }.freeze
40
29
 
41
30
  HEADERS_END_STREAM = {
42
31
  type: :headers,
43
- flags: [:end_headers, :end_stream],
32
+ flags: [:end_headers, :end_stream].freeze,
44
33
  stream: 1,
45
- payload: Compressor.new.encode([['a','b']])
46
- }
34
+ payload: Compressor.new.encode([%w(a b)]).freeze,
35
+ }.freeze
47
36
 
48
37
  PRIORITY = {
49
38
  type: :priority,
@@ -51,79 +40,89 @@ PRIORITY = {
51
40
  exclusive: false,
52
41
  stream_dependency: 0,
53
42
  weight: 20,
54
- }
43
+ }.freeze
55
44
 
56
45
  RST_STREAM = {
57
46
  type: :rst_stream,
58
47
  stream: 1,
59
- error: :stream_closed
60
- }
48
+ error: :stream_closed,
49
+ }.freeze
61
50
 
62
51
  SETTINGS = {
63
52
  type: :settings,
64
53
  stream: 0,
65
54
  payload: [
66
- [:settings_max_concurrent_streams, 10],
67
- [:settings_initial_window_size, 0x7fffffff],
68
- ]
69
- }
55
+ [:settings_max_concurrent_streams, 10].freeze,
56
+ [:settings_initial_window_size, 0x7fffffff].freeze,
57
+ ].freeze,
58
+ }.freeze
70
59
 
71
60
  PUSH_PROMISE = {
72
61
  type: :push_promise,
73
- flags: [:end_headers],
62
+ flags: [:end_headers].freeze,
74
63
  stream: 1,
75
64
  promise_stream: 2,
76
- payload: Compressor.new.encode([['a','b']])
77
- }
65
+ payload: Compressor.new.encode([%w(a b)]).freeze,
66
+ }.freeze
78
67
 
79
68
  PING = {
80
69
  stream: 0,
81
70
  type: :ping,
82
- payload: '12345678'
83
- }
71
+ payload: '12345678'.freeze,
72
+ }.freeze
84
73
 
85
74
  PONG = {
86
75
  stream: 0,
87
76
  type: :ping,
88
- flags: [:ack],
89
- payload: '12345678'
90
- }
77
+ flags: [:ack].freeze,
78
+ payload: '12345678'.freeze,
79
+ }.freeze
91
80
 
92
81
  GOAWAY = {
93
82
  type: :goaway,
94
83
  last_stream: 2,
95
84
  error: :no_error,
96
- payload: 'debug'
97
- }
85
+ payload: 'debug'.freeze,
86
+ }.freeze
98
87
 
99
88
  WINDOW_UPDATE = {
100
89
  type: :window_update,
101
- increment: 10
102
- }
90
+ increment: 10,
91
+ }.freeze
103
92
 
104
93
  CONTINUATION = {
105
94
  type: :continuation,
106
- flags: [:end_headers],
107
- payload: '-second-block'
108
- }
95
+ flags: [:end_headers].freeze,
96
+ payload: '-second-block'.freeze,
97
+ }.freeze
109
98
 
110
99
  ALTSVC = {
111
100
  type: :altsvc,
112
- max_age: 1402290402, # 4
113
- port: 8080, # 2 reserved 1
114
- proto: 'h2-12', # 1 + 5
115
- host: 'www.example.com', # 1 + 15
116
- origin: 'www.example.com', # 15
117
- }
101
+ max_age: 1_402_290_402, # 4
102
+ port: 8080, # 2 reserved 1
103
+ proto: 'h2-12'.freeze, # 1 + 5
104
+ host: 'www.example.com'.freeze, # 1 + 15
105
+ origin: 'www.example.com'.freeze, # 15
106
+ }.freeze
118
107
 
119
108
  FRAME_TYPES = [
120
- DATA, HEADERS, PRIORITY, RST_STREAM, SETTINGS, PUSH_PROMISE,
121
- PING, GOAWAY, WINDOW_UPDATE, CONTINUATION, ALTSVC
122
- ]
109
+ DATA,
110
+ HEADERS,
111
+ PRIORITY,
112
+ RST_STREAM,
113
+ SETTINGS,
114
+ PUSH_PROMISE,
115
+ PING,
116
+ GOAWAY,
117
+ WINDOW_UPDATE,
118
+ CONTINUATION,
119
+ ALTSVC,
120
+ ].freeze
123
121
 
124
122
  def set_stream_id(bytes, id)
125
- head = bytes.slice!(0,9).unpack('CnCCN')
123
+ scheme = 'CnCCN'.freeze
124
+ head = bytes.slice!(0, 9).unpack(scheme)
126
125
  head[4] = id
127
126
 
128
- head.pack('CnCCN') + bytes
127
+ head.pack(scheme) + bytes
129
128
  end
@@ -1,67 +1,67 @@
1
- require "helper"
1
+ require 'helper'
2
2
 
3
- describe HTTP2::Header::Huffman do
4
- huffman_examples = [# plain, encoded
5
- ["www.example.com", "f1e3c2e5f23a6ba0ab90f4ff"],
6
- ["no-cache", "a8eb10649cbf"],
7
- ["Mon, 21 Oct 2013 20:13:21 GMT", "d07abe941054d444a8200595040b8166e082a62d1bff"],
3
+ RSpec.describe HTTP2::Header::Huffman do
4
+ huffman_examples = [ # plain, encoded
5
+ ['www.example.com', 'f1e3c2e5f23a6ba0ab90f4ff'],
6
+ ['no-cache', 'a8eb10649cbf'],
7
+ ['Mon, 21 Oct 2013 20:13:21 GMT', 'd07abe941054d444a8200595040b8166e082a62d1bff'],
8
8
  ]
9
- context "encode" do
9
+ context 'encode' do
10
10
  before(:all) { @encoder = HTTP2::Header::Huffman.new }
11
11
  huffman_examples.each do |plain, encoded|
12
12
  it "should encode #{plain} into #{encoded}" do
13
- @encoder.encode(plain).unpack("H*").first.should eq encoded
13
+ expect(@encoder.encode(plain).unpack('H*').first).to eq encoded
14
14
  end
15
15
  end
16
16
  end
17
- context "decode" do
17
+ context 'decode' do
18
18
  before(:all) { @encoder = HTTP2::Header::Huffman.new }
19
19
  huffman_examples.each do |plain, encoded|
20
20
  it "should decode #{encoded} into #{plain}" do
21
- @encoder.decode(HTTP2::Buffer.new([encoded].pack("H*"))).should eq plain
21
+ expect(@encoder.decode(HTTP2::Buffer.new([encoded].pack('H*')))).to eq plain
22
22
  end
23
23
  end
24
24
 
25
25
  [
26
- "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:16.0) Gecko/20100101 Firefox/16.0",
27
- "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
28
- "http://www.craigslist.org/about/sites/",
29
- "cl_b=AB2BKbsl4hGM7M4nH5PYWghTM5A; cl_def_lang=en; cl_def_hp=shoals",
30
- "image/png,image/*;q=0.8,*/*;q=0.5",
31
- "BX=c99r6jp89a7no&b=3&s=q4; localization=en-us%3Bus%3Bus",
32
- "UTF-8でエンコードした日本語文字列",
26
+ 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:16.0) Gecko/20100101 Firefox/16.0',
27
+ 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
28
+ 'http://www.craigslist.org/about/sites/',
29
+ 'cl_b=AB2BKbsl4hGM7M4nH5PYWghTM5A; cl_def_lang=en; cl_def_hp=shoals',
30
+ 'image/png,image/*;q=0.8,*/*;q=0.5',
31
+ 'BX=c99r6jp89a7no&b=3&s=q4; localization=en-us%3Bus%3Bus',
32
+ 'UTF-8でエンコードした日本語文字列',
33
33
  ].each do |string|
34
34
  it "should encode then decode '#{string}' into the same" do
35
- s = string.dup.force_encoding('binary')
35
+ s = string.dup.force_encoding(Encoding::BINARY)
36
36
  encoded = @encoder.encode(s)
37
- @encoder.decode(HTTP2::Buffer.new(encoded)).should eq s
37
+ expect(@encoder.decode(HTTP2::Buffer.new(encoded))).to eq s
38
38
  end
39
39
  end
40
40
 
41
- it "should encode/decode all_possible 2-byte sequences" do
41
+ it 'should encode/decode all_possible 2-byte sequences' do
42
42
  (2**16).times do |n|
43
- str = [n].pack("V")[0,2].force_encoding('binary')
44
- @encoder.decode(HTTP2::Buffer.new(@encoder.encode(str))).should eq str
43
+ str = [n].pack('V')[0, 2].force_encoding(Encoding::BINARY)
44
+ expect(@encoder.decode(HTTP2::Buffer.new(@encoder.encode(str)))).to eq str
45
45
  end
46
46
  end
47
47
 
48
- it "should raise when input is shorter than expected" do
49
- plain, encoded = huffman_examples[0]
50
- encoded = [encoded].pack("H*")
48
+ it 'should raise when input is shorter than expected' do
49
+ encoded = huffman_examples.first.last
50
+ encoded = [encoded].pack('H*')
51
51
  expect { @encoder.decode(HTTP2::Buffer.new(encoded[0...-1])) }.to raise_error(/EOS invalid/)
52
52
  end
53
- it "should raise when input is not padded by 1s" do
54
- plain, encoded = ["www.example.com", "f1e3c2e5f23a6ba0ab90f4fe"] # note the fe at end
55
- encoded = [encoded].pack("H*")
53
+ it 'should raise when input is not padded by 1s' do
54
+ encoded = 'f1e3c2e5f23a6ba0ab90f4fe' # note the fe at end
55
+ encoded = [encoded].pack('H*')
56
56
  expect { @encoder.decode(HTTP2::Buffer.new(encoded)) }.to raise_error(/EOS invalid/)
57
57
  end
58
- it "should raise when exceedingly padded" do
59
- plain, encoded = ["www.example.com", "e7cf9bebe89b6fb16fa9b6ffff"] # note the extra ff
60
- encoded = [encoded].pack("H*")
58
+ it 'should raise when exceedingly padded' do
59
+ encoded = 'e7cf9bebe89b6fb16fa9b6ffff' # note the extra ff
60
+ encoded = [encoded].pack('H*')
61
61
  expect { @encoder.decode(HTTP2::Buffer.new(encoded)) }.to raise_error(/EOS invalid/)
62
62
  end
63
- it "should raise when EOS is explicitly encoded" do
64
- encoded = ["1c7fffffffff"].pack("H*") # a b EOS
63
+ it 'should raise when EOS is explicitly encoded' do
64
+ encoded = ['1c7fffffffff'].pack('H*') # a b EOS
65
65
  expect { @encoder.decode(HTTP2::Buffer.new(encoded)) }.to raise_error(/EOS found/)
66
66
  end
67
67
  end
@@ -1,26 +1,26 @@
1
- require "helper"
1
+ require 'helper'
2
2
 
3
- describe HTTP2::Server do
3
+ RSpec.describe HTTP2::Server do
4
4
  before(:each) do
5
5
  @srv = Server.new
6
6
  end
7
7
 
8
8
  let(:f) { Framer.new }
9
9
 
10
- context "initialization and settings" do
11
- it "should return even stream IDs" do
12
- @srv.new_stream.id.should be_even
10
+ context 'initialization and settings' do
11
+ it 'should return even stream IDs' do
12
+ expect(@srv.new_stream.id).to be_even
13
13
  end
14
14
 
15
- it "should emit SETTINGS on new connection" do
15
+ it 'should emit SETTINGS on new connection' do
16
16
  frames = []
17
17
  @srv.on(:frame) { |recv| frames << recv }
18
18
  @srv << CONNECTION_PREFACE_MAGIC
19
19
 
20
- f.parse(frames[0])[:type].should eq :settings
20
+ expect(f.parse(frames[0])[:type]).to eq :settings
21
21
  end
22
22
 
23
- it "should initialize client with custom connection settings" do
23
+ it 'should initialize client with custom connection settings' do
24
24
  frames = []
25
25
 
26
26
  @srv = Server.new(settings_max_concurrent_streams: 200,
@@ -29,23 +29,23 @@ describe HTTP2::Server do
29
29
  @srv << CONNECTION_PREFACE_MAGIC
30
30
 
31
31
  frame = f.parse(frames[0])
32
- frame[:type].should eq :settings
33
- frame[:payload].should include([:settings_max_concurrent_streams, 200])
34
- frame[:payload].should include([:settings_initial_window_size, 2**10])
32
+ expect(frame[:type]).to eq :settings
33
+ expect(frame[:payload]).to include([:settings_max_concurrent_streams, 200])
34
+ expect(frame[:payload]).to include([:settings_initial_window_size, 2**10])
35
35
  end
36
36
  end
37
37
 
38
- it "should allow server push" do
38
+ it 'should allow server push' do
39
39
  client = Client.new
40
40
  client.on(:frame) { |bytes| @srv << bytes }
41
41
 
42
42
  @srv.on(:stream) do |stream|
43
- expect {
43
+ expect do
44
44
  stream.promise(':method' => 'GET') {}
45
- }.to_not raise_error
45
+ end.to_not raise_error
46
46
  end
47
47
 
48
48
  client.new_stream
49
- client.send HEADERS
49
+ client.send HEADERS.deep_dup
50
50
  end
51
51
  end
@@ -1,169 +1,207 @@
1
- require "helper"
1
+ require 'helper'
2
2
 
3
- describe HTTP2::Stream do
3
+ RSpec.describe HTTP2::Stream do
4
4
  before(:each) do
5
5
  @client = Client.new
6
6
  @stream = @client.new_stream
7
7
  end
8
8
 
9
- context "stream states" do
10
- it "should initiliaze all streams to IDLE" do
11
- @stream.state.should eq :idle
9
+ context 'stream states' do
10
+ it 'should initiliaze all streams to IDLE' do
11
+ expect(@stream.state).to eq :idle
12
12
  end
13
13
 
14
- it "should set custom stream priority" do
14
+ it 'should set custom stream priority' do
15
15
  stream = @client.new_stream(weight: 3, dependency: 2, exclusive: true)
16
- stream.weight.should eq 3
16
+ expect(stream.weight).to eq 3
17
17
  end
18
18
 
19
- context "reserved (local)" do
20
- before(:each) { @stream.send PUSH_PROMISE }
19
+ context 'idle' do
20
+ it 'should transition to open on sent HEADERS' do
21
+ @stream.send HEADERS.deep_dup
22
+ expect(@stream.state).to eq :open
23
+ end
24
+ it 'should transition to open on received HEADERS' do
25
+ @stream.receive HEADERS
26
+ expect(@stream.state).to eq :open
27
+ end
28
+ it 'should transition to reserved (local) on sent PUSH_PROMISE' do
29
+ @stream.send PUSH_PROMISE.deep_dup
30
+ expect(@stream.state).to eq :reserved_local
31
+ end
32
+ it 'should transition to reserved (remote) on received PUSH_PROMISE' do
33
+ @stream.receive PUSH_PROMISE
34
+ expect(@stream.state).to eq :reserved_remote
35
+ end
36
+ it 'should reprioritize stream on sent PRIORITY' do
37
+ expect { @stream.send PRIORITY.dup }.to_not raise_error
38
+ expect(@stream.weight).to eq 20
39
+ end
40
+ it 'should reprioritize stream on received PRIORITY' do
41
+ expect { @stream.send PRIORITY.dup }.to_not raise_error
42
+ expect(@stream.weight).to eq 20
43
+ end
44
+ end
45
+
46
+ context 'reserved (local)' do
47
+ before(:each) { @stream.send PUSH_PROMISE.deep_dup }
21
48
 
22
- it "should transition on sent PUSH_PROMISE" do
23
- @stream.state.should eq :reserved_local
49
+ it 'should transition on sent PUSH_PROMISE' do
50
+ expect(@stream.state).to eq :reserved_local
24
51
  end
25
52
 
26
- it "should allow HEADERS to be sent" do
27
- expect { @stream.send HEADERS }.to_not raise_error
53
+ it 'should allow HEADERS to be sent' do
54
+ expect { @stream.send HEADERS.deep_dup }.to_not raise_error
28
55
  end
29
56
 
30
- it "should raise error if sending invalid frames" do
57
+ it 'should raise error if sending invalid frames' do
31
58
  (FRAME_TYPES - [HEADERS, RST_STREAM]).each do |type|
32
- expect { @stream.dup.send type }.to raise_error StreamError
59
+ expect { @stream.dup.send type }.to raise_error InternalError
33
60
  end
34
61
  end
35
62
 
36
- it "should raise error on receipt of invalid frames" do
37
- (FRAME_TYPES - [PRIORITY, RST_STREAM]).each do |type|
38
- expect { @stream.dup.receive type }.to raise_error StreamError
63
+ it 'should raise error on receipt of invalid frames' do
64
+ what_types = (FRAME_TYPES - [PRIORITY, RST_STREAM, WINDOW_UPDATE])
65
+ what_types.each do |type|
66
+ expect { @stream.dup.receive type }.to raise_error InternalError
39
67
  end
40
68
  end
41
69
 
42
- it "should transition to half closed (remote) on sent HEADERS" do
43
- @stream.send HEADERS
44
- @stream.state.should eq :half_closed_remote
70
+ it 'should transition to half closed (remote) on sent HEADERS' do
71
+ @stream.send HEADERS.deep_dup
72
+ expect(@stream.state).to eq :half_closed_remote
45
73
  end
46
74
 
47
- it "should transition to closed on sent RST_STREAM" do
75
+ it 'should transition to closed on sent RST_STREAM' do
48
76
  @stream.close
49
- @stream.state.should eq :closed
77
+ expect(@stream.state).to eq :closed
50
78
  end
51
79
 
52
- it "should transition to closed on received RST_STREAM" do
80
+ it 'should transition to closed on received RST_STREAM' do
53
81
  @stream.receive RST_STREAM
54
- @stream.state.should eq :closed
82
+ expect(@stream.state).to eq :closed
55
83
  end
56
84
 
57
- it "should reprioritize stream on PRIORITY" do
85
+ it 'should reprioritize stream on PRIORITY' do
58
86
  expect { @stream.receive PRIORITY }.to_not raise_error
59
- @stream.weight.should eq 20
87
+ expect(@stream.weight).to eq 20
88
+ end
89
+
90
+ it 'should increment remote_window on received WINDOW_UPDATE' do
91
+ expect { @stream.receive WINDOW_UPDATE }.to_not raise_error
92
+ expect(@stream.remote_window).to eq DEFAULT_FLOW_WINDOW + WINDOW_UPDATE[:increment]
60
93
  end
61
94
  end
62
95
 
63
- context "reserved (remote)" do
96
+ context 'reserved (remote)' do
64
97
  before(:each) { @stream.receive PUSH_PROMISE }
65
98
 
66
- it "should transition on received PUSH_PROMISE" do
67
- @stream.state.should eq :reserved_remote
99
+ it 'should transition on received PUSH_PROMISE' do
100
+ expect(@stream.state).to eq :reserved_remote
68
101
  end
69
102
 
70
- it "should raise error if sending invalid frames" do
71
- (FRAME_TYPES - [PRIORITY, RST_STREAM]).each do |type|
72
- expect { @stream.dup.send type }.to raise_error StreamError
103
+ it 'should raise error if sending invalid frames' do
104
+ (FRAME_TYPES - [PRIORITY, RST_STREAM, WINDOW_UPDATE]).each do |type|
105
+ expect { @stream.dup.send type }.to raise_error InternalError
73
106
  end
74
107
  end
75
108
 
76
- it "should raise error on receipt of invalid frames" do
109
+ it 'should raise error on receipt of invalid frames' do
77
110
  (FRAME_TYPES - [HEADERS, RST_STREAM]).each do |type|
78
- expect { @stream.dup.receive type }.to raise_error StreamError
111
+ expect { @stream.dup.receive type }.to raise_error InternalError
79
112
  end
80
113
  end
81
114
 
82
- it "should transition to half closed (local) on received HEADERS" do
115
+ it 'should transition to half closed (local) on received HEADERS' do
83
116
  @stream.receive HEADERS
84
- @stream.state.should eq :half_closed_local
117
+ expect(@stream.state).to eq :half_closed_local
85
118
  end
86
119
 
87
- it "should transition to closed on sent RST_STREAM" do
120
+ it 'should transition to closed on sent RST_STREAM' do
88
121
  @stream.close
89
- @stream.state.should eq :closed
122
+ expect(@stream.state).to eq :closed
90
123
  end
91
124
 
92
- it "should transition to closed on received RST_STREAM" do
125
+ it 'should transition to closed on received RST_STREAM' do
93
126
  @stream.receive RST_STREAM
94
- @stream.state.should eq :closed
127
+ expect(@stream.state).to eq :closed
95
128
  end
96
129
 
97
- it "should reprioritize stream on PRIORITY" do
98
- expect { @stream.send PRIORITY }.to_not raise_error
99
- @stream.weight.should eq 20
130
+ it 'should reprioritize stream on PRIORITY' do
131
+ expect { @stream.send PRIORITY.dup }.to_not raise_error
132
+ expect(@stream.weight).to eq 20
133
+ end
134
+
135
+ it 'should increment local_window on sent WINDOW_UPDATE' do
136
+ expect { @stream.send WINDOW_UPDATE.dup }.to_not raise_error
137
+ expect(@stream.local_window).to eq DEFAULT_FLOW_WINDOW + WINDOW_UPDATE[:increment]
100
138
  end
101
139
  end
102
140
 
103
- context "open" do
141
+ context 'open' do
104
142
  before(:each) { @stream.receive HEADERS }
105
143
 
106
- it "should allow any valid frames types to be sent" do
144
+ it 'should allow any valid frames types to be sent' do
107
145
  (FRAME_TYPES - [PING, GOAWAY, SETTINGS]).each do |type|
108
- expect { @stream.dup.send type }.to_not raise_error
146
+ expect { @stream.dup.send type.deep_dup }.to_not raise_error
109
147
  end
110
148
  end
111
149
 
112
- it "should allow frames of any type to be received" do
150
+ it 'should allow frames of any type to be received' do
113
151
  FRAME_TYPES.each do |type|
114
152
  expect { @stream.dup.receive type }.to_not raise_error
115
153
  end
116
154
  end
117
155
 
118
- it "should transition to half closed (local) if sending END_STREAM" do
156
+ it 'should transition to half closed (local) if sending END_STREAM' do
119
157
  [DATA, HEADERS].each do |frame|
120
- s, f = @stream.dup, frame.dup
158
+ s, f = @stream.dup, frame.deep_dup
121
159
  f[:flags] = [:end_stream]
122
160
 
123
161
  s.send f
124
- s.state.should eq :half_closed_local
162
+ expect(s.state).to eq :half_closed_local
125
163
  end
126
164
  end
127
165
 
128
- it "should transition to half closed (remote) if receiving END_STREAM" do
166
+ it 'should transition to half closed (remote) if receiving END_STREAM' do
129
167
  [DATA, HEADERS].each do |frame|
130
168
  s, f = @stream.dup, frame.dup
131
169
  f[:flags] = [:end_stream]
132
170
 
133
171
  s.receive f
134
- s.state.should eq :half_closed_remote
172
+ expect(s.state).to eq :half_closed_remote
135
173
  end
136
174
  end
137
175
 
138
- it "should transition to half closed if remote opened with END_STREAM" do
176
+ it 'should transition to half closed if remote opened with END_STREAM' do
139
177
  s = @client.new_stream
140
178
  hclose = HEADERS.dup
141
179
  hclose[:flags] = [:end_stream]
142
180
 
143
181
  s.receive hclose
144
- s.state.should eq :half_closed_remote
182
+ expect(s.state).to eq :half_closed_remote
145
183
  end
146
184
 
147
- it "should transition to half closed if local opened with END_STREAM" do
185
+ it 'should transition to half closed if local opened with END_STREAM' do
148
186
  s = @client.new_stream
149
- hclose = HEADERS.dup
187
+ hclose = HEADERS.deep_dup
150
188
  hclose[:flags] = [:end_stream]
151
189
 
152
190
  s.send hclose
153
- s.state.should eq :half_closed_local
191
+ expect(s.state).to eq :half_closed_local
154
192
  end
155
193
 
156
- it "should transition to closed if sending RST_STREAM" do
194
+ it 'should transition to closed if sending RST_STREAM' do
157
195
  @stream.close
158
- @stream.state.should eq :closed
196
+ expect(@stream.state).to eq :closed
159
197
  end
160
198
 
161
- it "should transition to closed if receiving RST_STREAM" do
199
+ it 'should transition to closed if receiving RST_STREAM' do
162
200
  @stream.receive RST_STREAM
163
- @stream.state.should eq :closed
201
+ expect(@stream.state).to eq :closed
164
202
  end
165
203
 
166
- it "should emit :active on open transition" do
204
+ it 'should emit :active on open transition' do
167
205
  openp, openr = false, false
168
206
  sp = @client.new_stream
169
207
  sr = @client.new_stream
@@ -171,28 +209,28 @@ describe HTTP2::Stream do
171
209
  sr.on(:active) { openr = true }
172
210
 
173
211
  sp.receive HEADERS
174
- sr.send HEADERS
212
+ sr.send HEADERS.deep_dup
175
213
 
176
- openp.should be_truthy
177
- openr.should be_truthy
214
+ expect(openp).to be_truthy
215
+ expect(openr).to be_truthy
178
216
  end
179
217
 
180
- it "should not emit :active on transition from open" do
218
+ it 'should not emit :active on transition from open' do
181
219
  order, stream = [], @client.new_stream
182
220
 
183
221
  stream.on(:active) { order << :active }
184
222
  stream.on(:half_close) { order << :half_close }
185
223
  stream.on(:close) { order << :close }
186
224
 
187
- req = HEADERS.dup
225
+ req = HEADERS.deep_dup
188
226
  req[:flags] = [:end_headers]
189
227
 
190
228
  stream.send req
191
- stream.send DATA
192
- order.should eq [:active, :half_close]
229
+ stream.send DATA.dup
230
+ expect(order).to eq [:active, :half_close]
193
231
  end
194
232
 
195
- it "should emit :close on close transition" do
233
+ it 'should emit :close on close transition' do
196
234
  closep, closer = false, false
197
235
  sp, sr = @stream.dup, @stream.dup
198
236
 
@@ -202,11 +240,11 @@ describe HTTP2::Stream do
202
240
  sp.receive RST_STREAM
203
241
  sr.close
204
242
 
205
- closep.should be_truthy
206
- closer.should be_truthy
243
+ expect(closep).to be_truthy
244
+ expect(closer).to be_truthy
207
245
  end
208
246
 
209
- it "should emit :close after frame is processed" do
247
+ it 'should emit :close after frame is processed' do
210
248
  order, stream = [], @client.new_stream
211
249
 
212
250
  stream.on(:active) { order << :active }
@@ -214,130 +252,162 @@ describe HTTP2::Stream do
214
252
  stream.on(:half_close) { order << :half_close }
215
253
  stream.on(:close) { order << :close }
216
254
 
217
- req = HEADERS.dup
255
+ req = HEADERS.deep_dup
218
256
  req[:flags] = [:end_stream, :end_headers]
219
257
 
220
258
  stream.send req
221
259
  stream.receive HEADERS
222
260
  stream.receive DATA
223
261
 
224
- order.should eq [:active, :half_close, :data, :close]
262
+ expect(order).to eq [:active, :half_close, :data, :close]
225
263
  end
226
264
 
227
- it "should emit :close with reason" do
265
+ it 'should emit :close with reason' do
228
266
  reason = nil
229
- @stream.on(:close) {|r| reason = r }
267
+ @stream.on(:close) { |r| reason = r }
230
268
  @stream.receive RST_STREAM
231
- reason.should_not be_nil
269
+ expect(reason).not_to be_nil
270
+ end
271
+
272
+ it 'should reprioritize stream on sent PRIORITY' do
273
+ expect { @stream.send PRIORITY.dup }.to_not raise_error
274
+ expect(@stream.weight).to eq 20
275
+ end
276
+ it 'should reprioritize stream on received PRIORITY' do
277
+ expect { @stream.receive PRIORITY }.to_not raise_error
278
+ expect(@stream.weight).to eq 20
232
279
  end
233
280
  end
234
281
 
235
- context "half closed (local)" do
236
- before(:each) { @stream.send HEADERS_END_STREAM }
282
+ context 'half closed (local)' do
283
+ before(:each) { @stream.send HEADERS_END_STREAM.deep_dup }
237
284
 
238
- it "should raise error on attempt to send frames" do
239
- (FRAME_TYPES - [PRIORITY, RST_STREAM]).each do |frame|
240
- expect { @stream.dup.send frame }.to raise_error StreamError
285
+ it 'should raise error on attempt to send invalid frames' do
286
+ (FRAME_TYPES - [PRIORITY, RST_STREAM, WINDOW_UPDATE]).each do |frame|
287
+ expect { @stream.dup.send frame }.to raise_error InternalError
241
288
  end
242
289
  end
243
290
 
244
- it "should transition to closed on receipt of END_STREAM flag" do
291
+ it 'should transition to closed on receipt of END_STREAM flag' do
245
292
  [DATA, HEADERS, CONTINUATION].each do |frame|
246
293
  s, f = @stream.dup, frame.dup
247
294
  f[:flags] = [:end_stream]
248
295
 
249
296
  s.receive f
250
- s.state.should eq :closed
297
+ expect(s.state).to eq :closed
251
298
  end
252
299
  end
253
300
 
254
- it "should transition to closed on receipt of RST_STREAM frame" do
301
+ it 'should transition to closed on receipt of RST_STREAM frame' do
255
302
  @stream.receive RST_STREAM
256
- @stream.state.should eq :closed
303
+ expect(@stream.state).to eq :closed
257
304
  end
258
305
 
259
- it "should transition to closed if RST_STREAM frame is sent" do
260
- @stream.send RST_STREAM
261
- @stream.state.should eq :closed
306
+ it 'should transition to closed if RST_STREAM frame is sent' do
307
+ @stream.send RST_STREAM.deep_dup
308
+ expect(@stream.state).to eq :closed
262
309
  end
263
310
 
264
- it "should ignore received WINDOW_UPDATE, PRIORITY frames" do
311
+ it 'should ignore received WINDOW_UPDATE frames' do
265
312
  expect { @stream.receive WINDOW_UPDATE }.to_not raise_error
313
+ expect(@stream.state).to eq :half_closed_local
314
+ end
315
+
316
+ it 'should ignore received PRIORITY frames' do
266
317
  expect { @stream.receive PRIORITY }.to_not raise_error
267
- @stream.state.should eq :half_closed_local
318
+ expect(@stream.state).to eq :half_closed_local
319
+ end
320
+
321
+ it 'should reprioritize stream on sent PRIORITY' do
322
+ expect { @stream.send PRIORITY.dup }.to_not raise_error
323
+ expect(@stream.weight).to eq 20
268
324
  end
269
325
 
270
- it "should reprioritize stream on PRIORITY" do
271
- expect { @stream.send PRIORITY }.to_not raise_error
272
- @stream.weight.should eq 20
326
+ it 'should reprioritize stream (and decendants) on received PRIORITY' do
327
+ expect { @stream.receive PRIORITY }.to_not raise_error
328
+ expect(@stream.weight).to eq 20
273
329
  end
274
330
 
275
- it "should emit :half_close event on transition" do
331
+ it 'should increment local_window on sent WINDOW_UPDATE' do
332
+ expect { @stream.send WINDOW_UPDATE.dup }.to_not raise_error
333
+ expect(@stream.local_window).to eq DEFAULT_FLOW_WINDOW + WINDOW_UPDATE[:increment]
334
+ end
335
+
336
+ it 'should emit :half_close event on transition' do
276
337
  order = []
277
338
  stream = @client.new_stream
278
339
  stream.on(:active) { order << :active }
279
340
  stream.on(:half_close) { order << :half_close }
280
341
 
281
- req = HEADERS.dup
342
+ req = HEADERS.deep_dup
282
343
  req[:flags] = [:end_stream, :end_headers]
283
344
 
284
345
  stream.send req
285
- order.should eq [:active, :half_close]
346
+ expect(order).to eq [:active, :half_close]
286
347
  end
287
348
 
288
- it "should emit :close event on transition to closed" do
349
+ it 'should emit :close event on transition to closed' do
289
350
  closed = false
290
351
  @stream.on(:close) { closed = true }
291
352
  @stream.receive RST_STREAM
292
353
 
293
- @stream.state.should eq :closed
294
- closed.should be_truthy
354
+ expect(@stream.state).to eq :closed
355
+ expect(closed).to be_truthy
295
356
  end
296
357
  end
297
358
 
298
- context "half closed (remote)" do
359
+ context 'half closed (remote)' do
299
360
  before(:each) { @stream.receive HEADERS_END_STREAM }
300
361
 
301
- it "should raise STREAM_CLOSED error on reciept of frames" do
362
+ it 'should raise STREAM_CLOSED error on reciept of frames' do
302
363
  (FRAME_TYPES - [PRIORITY, RST_STREAM, WINDOW_UPDATE]).each do |frame|
303
- expect {
364
+ expect do
304
365
  @stream.dup.receive frame
305
- }.to raise_error(StreamClosed)
366
+ end.to raise_error(StreamClosed)
306
367
  end
307
368
  end
308
369
 
309
- it "should transition to closed if END_STREAM flag is sent" do
370
+ it 'should transition to closed if END_STREAM flag is sent' do
310
371
  [DATA, HEADERS].each do |frame|
311
- s, f = @stream.dup, frame.dup
372
+ s, f = @stream.dup, frame.deep_dup
312
373
  f[:flags] = [:end_stream]
313
374
 
314
- s.on(:close) { s.state.should eq :closed }
375
+ s.on(:close) { expect(s.state).to eq :closed }
315
376
  s.send f
316
- s.state.should eq :closed
377
+ expect(s.state).to eq :closed
317
378
  end
318
379
  end
319
380
 
320
- it "should transition to closed if RST_STREAM is sent" do
381
+ it 'should transition to closed if RST_STREAM is sent' do
321
382
  @stream.close
322
- @stream.state.should eq :closed
383
+ expect(@stream.state).to eq :closed
323
384
  end
324
385
 
325
- it "should transition to closed on reciept of RST_STREAM frame" do
386
+ it 'should transition to closed on reciept of RST_STREAM frame' do
326
387
  @stream.receive RST_STREAM
327
- @stream.state.should eq :closed
388
+ expect(@stream.state).to eq :closed
389
+ end
390
+
391
+ it 'should ignore sent WINDOW_UPDATE frames' do
392
+ expect { @stream.send WINDOW_UPDATE.dup }.to_not raise_error
393
+ expect(@stream.state).to eq :half_closed_remote
328
394
  end
329
395
 
330
- it "should ignore received WINDOW_UPDATE frames" do
396
+ it 'should increment remote_window on received WINDOW_UPDATE' do
331
397
  expect { @stream.receive WINDOW_UPDATE }.to_not raise_error
332
- @stream.state.should eq :half_closed_remote
398
+ expect(@stream.remote_window).to eq DEFAULT_FLOW_WINDOW + WINDOW_UPDATE[:increment]
333
399
  end
334
400
 
335
- it "should reprioritize stream on PRIORITY" do
401
+ it 'should reprioritize stream on sent PRIORITY' do
402
+ expect { @stream.send PRIORITY.dup }.to_not raise_error
403
+ expect(@stream.weight).to eq 20
404
+ end
405
+ it 'should reprioritize stream on received PRIORITY' do
336
406
  expect { @stream.receive PRIORITY }.to_not raise_error
337
- @stream.weight.should eq 20
407
+ expect(@stream.weight).to eq 20
338
408
  end
339
409
 
340
- it "should emit :half_close event on transition" do
410
+ it 'should emit :half_close event on transition' do
341
411
  order = []
342
412
  stream = @client.new_stream
343
413
  stream.on(:active) { order << :active }
@@ -347,85 +417,92 @@ describe HTTP2::Stream do
347
417
  req[:flags] = [:end_stream, :end_headers]
348
418
 
349
419
  stream.receive req
350
- order.should eq [:active, :half_close]
420
+ expect(order).to eq [:active, :half_close]
351
421
  end
352
422
 
353
- it "should emit :close event on close transition" do
423
+ it 'should emit :close event on close transition' do
354
424
  closed = false
355
425
  @stream.on(:close) { closed = true }
356
426
  @stream.close
357
427
 
358
- @stream.state.should eq :closed
359
- closed.should be_truthy
428
+ expect(@stream.state).to eq :closed
429
+ expect(closed).to be_truthy
360
430
  end
361
431
  end
362
432
 
363
- context "closed" do
364
- context "remote closed stream" do
433
+ context 'closed' do
434
+ context 'remote closed stream' do
365
435
  before(:each) do
366
- @stream.send HEADERS_END_STREAM # half closed local
436
+ @stream.send HEADERS_END_STREAM.deep_dup # half closed local
367
437
  @stream.receive HEADERS_END_STREAM # closed by remote
368
438
  end
369
439
 
370
- it "should raise STREAM_CLOSED on attempt to send frames" do
440
+ it 'should raise STREAM_CLOSED on attempt to send frames' do
371
441
  (FRAME_TYPES - [PRIORITY, RST_STREAM]).each do |frame|
372
- expect {
442
+ expect do
373
443
  @stream.dup.send frame
374
- }.to raise_error(StreamClosed)
444
+ end.to raise_error(StreamClosed)
375
445
  end
376
446
  end
377
447
 
378
- it "should raise STREAM_CLOSED on receipt of frame" do
448
+ it 'should raise STREAM_CLOSED on receipt of frame' do
379
449
  (FRAME_TYPES - [PRIORITY, RST_STREAM, WINDOW_UPDATE]).each do |frame|
380
- expect {
450
+ expect do
381
451
  @stream.dup.receive frame
382
- }.to raise_error(StreamClosed)
452
+ end.to raise_error(StreamClosed)
383
453
  end
384
454
  end
385
455
 
386
- it "should allow PRIORITY, RST_STREAM to be sent" do
387
- expect { @stream.send PRIORITY }.to_not raise_error
388
- expect { @stream.send RST_STREAM }.to_not raise_error
456
+ it 'should allow PRIORITY, RST_STREAM to be sent' do
457
+ expect { @stream.send PRIORITY.dup }.to_not raise_error
458
+ expect { @stream.send RST_STREAM.dup }.to_not raise_error
389
459
  end
390
460
 
391
- it "should allow PRIORITY, RST_STREAM to be received" do
461
+ it 'should allow PRIORITY, RST_STREAM to be received' do
392
462
  expect { @stream.receive PRIORITY }.to_not raise_error
393
463
  expect { @stream.receive RST_STREAM }.to_not raise_error
394
464
  end
395
465
 
396
- it "should reprioritize stream on PRIORITY" do
466
+ it 'should reprioritize stream on sent PRIORITY' do
467
+ expect { @stream.send PRIORITY.dup }.to_not raise_error
468
+ expect(@stream.weight).to eq 20
469
+ end
470
+ it 'should reprioritize stream on received PRIORITY' do
397
471
  expect { @stream.receive PRIORITY }.to_not raise_error
398
- @stream.weight.should eq 20
472
+ expect(@stream.weight).to eq 20
399
473
  end
400
474
 
475
+ it 'should ignore received WINDOW_UPDATE frames' do
476
+ expect { @stream.receive WINDOW_UPDATE }.to_not raise_error
477
+ expect(@stream.state).to eq :closed
478
+ end
401
479
  end
402
480
 
403
- context "local closed via RST_STREAM frame" do
481
+ context 'local closed via RST_STREAM frame' do
404
482
  before(:each) do
405
- @stream.send HEADERS # open
406
- @stream.send RST_STREAM # closed by local
483
+ @stream.send HEADERS.deep_dup # open
484
+ @stream.send RST_STREAM.deep_dup # closed by local
407
485
  end
408
486
 
409
- it "should ignore received frames" do
487
+ it 'should ignore received frames' do
410
488
  (FRAME_TYPES - [PUSH_PROMISE]).each do |frame|
411
- expect {
489
+ expect do
412
490
  cb = []
413
491
  @stream.on(:data) { cb << :data }
414
- @stream.on(:headers) { cb << :headers}
415
- @stream.dup.receive frame
416
- cb.should be_empty
417
- }.to_not raise_error
492
+ @stream.on(:headers) { cb << :headers }
493
+ @stream.dup.receive frame.dup
494
+ expect(cb).to be_empty
495
+ end.to_not raise_error
418
496
  end
419
497
  end
420
498
 
421
- #it "should transition to reserved remote on PUSH_PROMISE" do
422
- # An endpoint might receive a PUSH_PROMISE frame after it sends
423
- # RST_STREAM. PUSH_PROMISE causes a stream to become "reserved".
424
- # ...
425
- # We're auto RST'ing PUSH streams in connection class, hence
426
- # skipping this transition for now.
427
- #end
428
-
499
+ # it "should transition to reserved remote on PUSH_PROMISE" do
500
+ # An endpoint might receive a PUSH_PROMISE frame after it sends
501
+ # RST_STREAM. PUSH_PROMISE causes a stream to become "reserved".
502
+ # ...
503
+ # We're auto RST'ing PUSH streams in connection class, hence
504
+ # skipping this transition for now.
505
+ # end
429
506
  end
430
507
 
431
508
  # FIXME: Isn't this test same as "half closed (local)"?
@@ -441,42 +518,41 @@ describe HTTP2::Stream do
441
518
  # end
442
519
  # end
443
520
  # end
444
-
445
521
  end
446
522
  end # end stream states
447
523
 
448
524
  # TODO: add test cases to ensure on(:priority) emitted after close
449
525
 
450
- context "flow control" do
451
- it "should initialize to default flow control window" do
452
- @stream.remote_window.should eq DEFAULT_FLOW_WINDOW
526
+ context 'flow control' do
527
+ it 'should initialize to default flow control window' do
528
+ expect(@stream.remote_window).to eq DEFAULT_FLOW_WINDOW
453
529
  end
454
530
 
455
- it "should update window size on DATA frames only" do
456
- @stream.send HEADERS # go to open
457
- @stream.remote_window.should eq DEFAULT_FLOW_WINDOW
531
+ it 'should update window size on DATA frames only' do
532
+ @stream.send HEADERS.deep_dup # go to open
533
+ expect(@stream.remote_window).to eq DEFAULT_FLOW_WINDOW
458
534
 
459
- (FRAME_TYPES - [DATA,PING,GOAWAY,SETTINGS]).each do |frame|
535
+ (FRAME_TYPES - [DATA, PING, GOAWAY, SETTINGS]).each do |frame|
460
536
  s = @stream.dup
461
- s.send frame
462
- s.remote_window.should eq DEFAULT_FLOW_WINDOW
537
+ s.send frame.deep_dup
538
+ expect(s.remote_window).to eq DEFAULT_FLOW_WINDOW
463
539
  end
464
540
 
465
- @stream.send DATA
466
- @stream.remote_window.should eq DEFAULT_FLOW_WINDOW - DATA[:payload].bytesize
541
+ @stream.send DATA.dup
542
+ expect(@stream.remote_window).to eq DEFAULT_FLOW_WINDOW - DATA[:payload].bytesize
467
543
  end
468
544
 
469
- it "should update window size on receipt of WINDOW_UPDATE" do
470
- @stream.send HEADERS
471
- @stream.send DATA
545
+ it 'should update window size on receipt of WINDOW_UPDATE' do
546
+ @stream.send HEADERS.deep_dup
547
+ @stream.send DATA.dup
472
548
  @stream.receive WINDOW_UPDATE
473
549
 
474
- @stream.remote_window.should eq (
475
- DEFAULT_FLOW_WINDOW - DATA[:payload].bytesize + WINDOW_UPDATE[:increment]
550
+ expect(@stream.remote_window).to eq(
551
+ DEFAULT_FLOW_WINDOW - DATA[:payload].bytesize + WINDOW_UPDATE[:increment],
476
552
  )
477
553
  end
478
554
 
479
- it "should observe session flow control" do
555
+ it 'should observe session flow control' do
480
556
  settings, data = SETTINGS.dup, DATA.dup
481
557
  settings[:payload] = [[:settings_initial_window_size, 1000]]
482
558
  settings[:stream] = 0
@@ -485,198 +561,207 @@ describe HTTP2::Stream do
485
561
  @client << framer.generate(settings)
486
562
 
487
563
  s1 = @client.new_stream
488
- s1.send HEADERS
489
- s1.send data.merge({payload: "x" * 900, flags: []})
490
- s1.remote_window.should eq 100
491
-
492
- s1.send data.merge({payload: "x" * 200})
493
- s1.remote_window.should eq 0
494
- s1.buffered_amount.should eq 100
495
-
496
- @client << framer.generate(WINDOW_UPDATE.merge({
497
- stream: s1.id, increment: 1000
498
- }))
499
- s1.buffered_amount.should eq 0
500
- s1.remote_window.should eq 900
564
+ s1.send HEADERS.deep_dup
565
+ s1.send data.merge(payload: 'x' * 900, flags: [])
566
+ expect(s1.remote_window).to eq 100
567
+
568
+ s1.send data.merge(payload: 'x' * 200)
569
+ expect(s1.remote_window).to eq 0
570
+ expect(s1.buffered_amount).to eq 100
571
+
572
+ @client << framer.generate(WINDOW_UPDATE.merge(stream: s1.id, increment: 1000))
573
+ expect(s1.buffered_amount).to eq 0
574
+ expect(s1.remote_window).to eq 900
501
575
  end
502
576
  end
503
577
 
504
- context "client API" do
505
- it ".reprioritize should emit PRIORITY frame" do
506
- @stream.should_receive(:send) do |frame|
507
- frame[:type].should eq :priority
508
- frame[:weight].should eq 30
578
+ context 'client API' do
579
+ it '.reprioritize should emit PRIORITY frame' do
580
+ expect(@stream).to receive(:send) do |frame|
581
+ expect(frame[:type]).to eq :priority
582
+ expect(frame[:weight]).to eq 30
509
583
  end
510
584
 
511
585
  @stream.reprioritize weight: 30
512
586
  end
513
587
 
514
- it ".reprioritize should raise error if invoked by server" do
588
+ it '.reprioritize should raise error if invoked by server' do
515
589
  srv = Server.new
516
590
  stream = srv.new_stream
517
591
 
518
- expect { stream.reprioritize(weight: 10) }.to raise_error(StreamError)
592
+ expect { stream.reprioritize(weight: 10) }.to raise_error(InternalError)
519
593
  end
520
594
 
521
- it ".headers should emit HEADERS frames" do
595
+ it '.headers should emit HEADERS frames' do
522
596
  payload = {
523
597
  ':method' => 'GET',
524
598
  ':scheme' => 'http',
525
599
  ':host' => 'www.example.org',
526
600
  ':path' => '/resource',
527
- 'custom' => 'value'
601
+ 'custom' => 'value',
528
602
  }
529
603
 
530
- @stream.should_receive(:send) do |frame|
531
- frame[:type].should eq :headers
532
- frame[:payload].should eq payload.to_a
533
- frame[:flags].should eq [:end_headers]
604
+ expect(@stream).to receive(:send) do |frame|
605
+ expect(frame[:type]).to eq :headers
606
+ expect(frame[:payload]).to eq payload.to_a
607
+ expect(frame[:flags]).to eq [:end_headers]
534
608
  end
535
609
 
536
610
  @stream.headers(payload, end_stream: false, end_headers: true)
537
611
  end
538
612
 
539
- it ".data should emit DATA frames" do
540
- @stream.should_receive(:send) do |frame|
541
- frame[:type].should eq :data
542
- frame[:payload].should eq "text"
543
- frame[:flags].should be_empty
613
+ it '.data should emit DATA frames' do
614
+ expect(@stream).to receive(:send) do |frame|
615
+ expect(frame[:type]).to eq :data
616
+ expect(frame[:payload]).to eq 'text'
617
+ expect(frame[:flags]).to be_empty
544
618
  end
545
- @stream.data("text", end_stream: false)
619
+ @stream.data('text', end_stream: false)
546
620
 
547
- @stream.should_receive(:send) do |frame|
548
- frame[:flags].should eq [:end_stream]
621
+ expect(@stream).to receive(:send) do |frame|
622
+ expect(frame[:flags]).to eq [:end_stream]
549
623
  end
550
- @stream.data("text")
624
+ @stream.data('text')
551
625
  end
552
626
 
553
- it ".data should split large DATA frames" do
554
- data = "x" * 16384 * 2
627
+ it '.data should split large DATA frames' do
628
+ data = 'x' * 16_384 * 2
629
+
630
+ want = [
631
+ { type: :data, flags: [], length: 16_384 },
632
+ { type: :data, flags: [], length: 16_384 },
633
+ { type: :data, flags: [:end_stream], length: 1 },
634
+ ]
635
+ want.each do |w|
636
+ expect(@stream).to receive(:send) do |frame|
637
+ expect(frame[:type]).to eq w[:type]
638
+ expect(frame[:flags]).to eq w[:flags]
639
+ expect(frame[:payload].length).to eq w[:length]
640
+ end
641
+ end
555
642
 
556
- @stream.stub(:send)
557
- @stream.should_receive(:send).exactly(3).times
558
- @stream.data(data + "x")
643
+ @stream.data(data + 'x')
559
644
  end
560
645
 
561
- it ".cancel should reset stream with cancel error code" do
562
- @stream.should_receive(:send) do |frame|
563
- frame[:type].should eq :rst_stream
564
- frame[:error].should eq :cancel
646
+ it '.cancel should reset stream with cancel error code' do
647
+ expect(@stream).to receive(:send) do |frame|
648
+ expect(frame[:type]).to eq :rst_stream
649
+ expect(frame[:error]).to eq :cancel
565
650
  end
566
651
 
567
652
  @stream.cancel
568
653
  end
569
654
 
570
- it ".refuse should reset stream with refused stream error code" do
571
- @stream.should_receive(:send) do |frame|
572
- frame[:type].should eq :rst_stream
573
- frame[:error].should eq :refused_stream
655
+ it '.refuse should reset stream with refused stream error code' do
656
+ expect(@stream).to receive(:send) do |frame|
657
+ expect(frame[:type]).to eq :rst_stream
658
+ expect(frame[:error]).to eq :refused_stream
574
659
  end
575
660
 
576
661
  @stream.refuse
577
662
  end
578
663
  end
579
664
 
580
- context "server API" do
665
+ context 'server API' do
581
666
  before(:each) do
582
667
  @srv = Server.new
583
668
  @frm = Framer.new
584
669
 
585
- @client.on(:frame) {|bytes| @srv << bytes }
670
+ @client.on(:frame) { |bytes| @srv << bytes }
586
671
  @client_stream = @client.new_stream
587
672
  end
588
673
 
589
- it "should emit received headers via on(:headers)" do
590
- headers, recv = [["header", "value"]], nil
674
+ it 'should emit received headers via on(:headers)' do
675
+ headers, recv = [%w(header value)], nil
591
676
  @srv.on(:stream) do |stream|
592
- stream.on(:headers) {|h| recv = h}
677
+ stream.on(:headers) { |h| recv = h }
593
678
  end
594
679
 
595
680
  @client_stream.headers(headers)
596
- recv.should eq headers
681
+ expect(recv).to eq headers
597
682
  end
598
683
 
599
- it "should emit received payload via on(:data)" do
600
- payload, recv = "some-payload", nil
684
+ it 'should emit received payload via on(:data)' do
685
+ payload = 'some-payload'
601
686
  @srv.on(:stream) do |stream|
602
687
  stream.on(:data) do |recv|
603
- recv.should eq payload
688
+ expect(recv).to eq payload
604
689
  end
605
690
  end
606
691
 
607
- @client_stream.headers({"key" => "value"})
692
+ @client_stream.headers('key' => 'value')
608
693
  @client_stream.data(payload)
609
694
  end
610
695
 
611
- it "should emit received priority parameters via on(:priority)" do
696
+ it 'should emit received priority parameters via on(:priority)' do
612
697
  new_weight, new_dependency = 15, @client_stream.id + 2
613
698
  callback_called = false
614
699
  @srv.on(:stream) do |stream|
615
700
  stream.on(:priority) do |pri|
616
701
  callback_called = true
617
- pri.is_a?(Hash).should be
618
- pri[:weight].should eq new_weight
619
- pri[:dependency].should eq new_dependency
702
+ expect(pri.is_a?(Hash)).to be
703
+ expect(pri[:weight]).to eq new_weight
704
+ expect(pri[:dependency]).to eq new_dependency
620
705
  end
621
706
  end
622
707
 
623
- @client_stream.headers({"key" => "value"})
708
+ @client_stream.headers('key' => 'value')
624
709
  @client_stream.reprioritize(weight: new_weight, dependency: new_dependency)
625
- callback_called.should be
710
+ expect(callback_called).to be
626
711
  end
627
712
 
628
- context "push" do
713
+ context 'push' do
629
714
  before(:each) do
630
- @srv.on(:frame) {|bytes| @client << bytes }
715
+ @srv.on(:frame) { |bytes| @client << bytes }
631
716
  @srv.on(:stream) do |stream|
632
717
  @server_stream = stream
633
718
  end
634
719
 
635
- @client_stream.headers({"key" => "value"})
720
+ @client_stream.headers('key' => 'value')
636
721
  end
637
722
 
638
- it ".promise should emit server initiated stream" do
723
+ it '.promise should emit server initiated stream' do
639
724
  push = nil
640
- @server_stream.promise({"key" => "val"}) { |pstream| push = pstream }
641
- push.id.should eq 2
725
+ @server_stream.promise('key' => 'val') { |pstream| push = pstream }
726
+ expect(push.id).to eq 2
642
727
  end
643
728
 
644
- it ".promise push stream should have parent stream" do
729
+ it '.promise push stream should have parent stream' do
645
730
  push = nil
646
- @server_stream.promise({"key" => "val"}) { |pstream| push = pstream }
731
+ @server_stream.promise('key' => 'val') { |pstream| push = pstream }
647
732
 
648
- push.state.should eq :reserved_local
649
- push.parent.id.should eq @server_stream.id
733
+ expect(push.state).to eq :reserved_local
734
+ expect(push.parent.id).to eq @server_stream.id
650
735
  end
651
736
 
652
- context "stream states" do
653
- it "server: active > half close > close" do
737
+ context 'stream states' do
738
+ it 'server: active > half close > close' do
654
739
  order = []
655
- @server_stream.promise({"key" => "val"}) do |push|
740
+ @server_stream.promise('key' => 'val') do |push|
656
741
  stream = push
657
742
 
658
- push.state.should eq :reserved_local
743
+ expect(push.state).to eq :reserved_local
659
744
  order << :reserved
660
745
 
661
746
  push.on(:active) { order << :active }
662
- push.on(:half_close){ order << :half_close }
747
+ push.on(:half_close) { order << :half_close }
663
748
  push.on(:close) { order << :close }
664
749
 
665
- push.headers({"key2" => "val2"})
666
- push.send DATA.merge({stream: stream.id})
750
+ push.headers('key2' => 'val2')
751
+ push.send DATA.merge(stream: stream.id)
667
752
  end
668
753
 
669
- order.should eq [:reserved, :active, :half_close, :close]
754
+ expect(order).to eq [:reserved, :active, :half_close, :close]
670
755
  end
671
756
 
672
- it "client: headers > active > headers > .. > data > close" do
757
+ it 'client: headers > active > headers > .. > data > close' do
673
758
  order, headers = [], []
674
759
  @client.on(:promise) do |push|
675
760
  order << :reserved
676
761
 
677
762
  push.on(:active) { order << :active }
678
763
  push.on(:data) { order << :data }
679
- push.on(:half_close){ order << :half_close }
764
+ push.on(:half_close) { order << :half_close }
680
765
  push.on(:close) { order << :close }
681
766
 
682
767
  push.on(:headers) do |h|
@@ -684,20 +769,26 @@ describe HTTP2::Stream do
684
769
  headers += h
685
770
  end
686
771
 
687
- push.id.should be_even
772
+ expect(push.id).to be_even
688
773
  end
689
774
 
690
- @server_stream.promise({"key" => "val"}) do |push|
691
- push.headers("key2" => "val2")
692
- push.data("somedata")
775
+ @server_stream.promise('key' => 'val') do |push|
776
+ push.headers('key2' => 'val2')
777
+ push.data('somedata')
693
778
  end
694
779
 
695
- headers.should eq([["key", "val"], ["key2", "val2"]])
696
- order.should eq [:reserved, :headers, :active, :headers,
697
- :half_close, :data, :close]
780
+ expect(headers).to eq([%w(key val), %w(key2 val2)])
781
+ expect(order).to eq [
782
+ :reserved,
783
+ :headers,
784
+ :active,
785
+ :headers,
786
+ :half_close,
787
+ :data,
788
+ :close,
789
+ ]
698
790
  end
699
791
  end
700
-
701
792
  end
702
793
  end
703
794
  end