http-2 0.7.0 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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