http 0.7.4 → 0.8.0.pre

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.
Files changed (73) hide show
  1. checksums.yaml +4 -4
  2. data/.rspec +0 -1
  3. data/.rubocop.yml +5 -2
  4. data/CHANGES.md +24 -7
  5. data/CONTRIBUTING.md +25 -0
  6. data/Gemfile +24 -22
  7. data/Guardfile +2 -2
  8. data/README.md +34 -4
  9. data/Rakefile +7 -7
  10. data/examples/parallel_requests_with_celluloid.rb +2 -2
  11. data/http.gemspec +12 -12
  12. data/lib/http.rb +11 -10
  13. data/lib/http/cache.rb +146 -0
  14. data/lib/http/cache/headers.rb +100 -0
  15. data/lib/http/cache/null_cache.rb +13 -0
  16. data/lib/http/chainable.rb +14 -3
  17. data/lib/http/client.rb +64 -80
  18. data/lib/http/connection.rb +139 -0
  19. data/lib/http/content_type.rb +2 -2
  20. data/lib/http/errors.rb +7 -1
  21. data/lib/http/headers.rb +21 -8
  22. data/lib/http/headers/mixin.rb +1 -1
  23. data/lib/http/mime_type.rb +2 -2
  24. data/lib/http/mime_type/adapter.rb +2 -2
  25. data/lib/http/mime_type/json.rb +4 -4
  26. data/lib/http/options.rb +65 -74
  27. data/lib/http/redirector.rb +3 -3
  28. data/lib/http/request.rb +20 -13
  29. data/lib/http/request/caching.rb +95 -0
  30. data/lib/http/request/writer.rb +5 -5
  31. data/lib/http/response.rb +15 -9
  32. data/lib/http/response/body.rb +21 -8
  33. data/lib/http/response/caching.rb +142 -0
  34. data/lib/http/response/io_body.rb +63 -0
  35. data/lib/http/response/parser.rb +1 -1
  36. data/lib/http/response/status.rb +4 -12
  37. data/lib/http/response/status/reasons.rb +53 -53
  38. data/lib/http/response/string_body.rb +53 -0
  39. data/lib/http/version.rb +1 -1
  40. data/spec/lib/http/cache/headers_spec.rb +77 -0
  41. data/spec/lib/http/cache_spec.rb +182 -0
  42. data/spec/lib/http/client_spec.rb +123 -95
  43. data/spec/lib/http/content_type_spec.rb +25 -25
  44. data/spec/lib/http/headers/mixin_spec.rb +8 -8
  45. data/spec/lib/http/headers_spec.rb +213 -173
  46. data/spec/lib/http/options/body_spec.rb +5 -5
  47. data/spec/lib/http/options/form_spec.rb +3 -3
  48. data/spec/lib/http/options/headers_spec.rb +7 -7
  49. data/spec/lib/http/options/json_spec.rb +3 -3
  50. data/spec/lib/http/options/merge_spec.rb +26 -22
  51. data/spec/lib/http/options/new_spec.rb +10 -10
  52. data/spec/lib/http/options/proxy_spec.rb +8 -8
  53. data/spec/lib/http/options_spec.rb +2 -2
  54. data/spec/lib/http/redirector_spec.rb +32 -32
  55. data/spec/lib/http/request/caching_spec.rb +133 -0
  56. data/spec/lib/http/request/writer_spec.rb +26 -26
  57. data/spec/lib/http/request_spec.rb +63 -58
  58. data/spec/lib/http/response/body_spec.rb +13 -13
  59. data/spec/lib/http/response/caching_spec.rb +201 -0
  60. data/spec/lib/http/response/io_body_spec.rb +35 -0
  61. data/spec/lib/http/response/status_spec.rb +25 -25
  62. data/spec/lib/http/response/string_body_spec.rb +35 -0
  63. data/spec/lib/http/response_spec.rb +64 -45
  64. data/spec/lib/http_spec.rb +103 -76
  65. data/spec/spec_helper.rb +10 -12
  66. data/spec/support/connection_reuse_shared.rb +100 -0
  67. data/spec/support/create_certs.rb +12 -12
  68. data/spec/support/dummy_server.rb +11 -11
  69. data/spec/support/dummy_server/servlet.rb +43 -31
  70. data/spec/support/proxy_server.rb +31 -25
  71. metadata +57 -8
  72. data/spec/support/example_server.rb +0 -30
  73. data/spec/support/example_server/servlet.rb +0 -102
@@ -1,45 +1,45 @@
1
1
  RSpec.describe HTTP::ContentType do
2
- describe '.parse' do
3
- context 'with text/plain' do
4
- subject { described_class.parse 'text/plain' }
5
- its(:mime_type) { is_expected.to eq 'text/plain' }
2
+ describe ".parse" do
3
+ context "with text/plain" do
4
+ subject { described_class.parse "text/plain" }
5
+ its(:mime_type) { is_expected.to eq "text/plain" }
6
6
  its(:charset) { is_expected.to be_nil }
7
7
  end
8
8
 
9
- context 'with tEXT/plaIN' do
10
- subject { described_class.parse 'tEXT/plaIN' }
11
- its(:mime_type) { is_expected.to eq 'text/plain' }
9
+ context "with tEXT/plaIN" do
10
+ subject { described_class.parse "tEXT/plaIN" }
11
+ its(:mime_type) { is_expected.to eq "text/plain" }
12
12
  its(:charset) { is_expected.to be_nil }
13
13
  end
14
14
 
15
- context 'with text/plain; charset=utf-8' do
16
- subject { described_class.parse 'text/plain; charset=utf-8' }
17
- its(:mime_type) { is_expected.to eq 'text/plain' }
18
- its(:charset) { is_expected.to eq 'utf-8' }
15
+ context "with text/plain; charset=utf-8" do
16
+ subject { described_class.parse "text/plain; charset=utf-8" }
17
+ its(:mime_type) { is_expected.to eq "text/plain" }
18
+ its(:charset) { is_expected.to eq "utf-8" }
19
19
  end
20
20
 
21
21
  context 'with text/plain; charset="utf-8"' do
22
22
  subject { described_class.parse 'text/plain; charset="utf-8"' }
23
- its(:mime_type) { is_expected.to eq 'text/plain' }
24
- its(:charset) { is_expected.to eq 'utf-8' }
23
+ its(:mime_type) { is_expected.to eq "text/plain" }
24
+ its(:charset) { is_expected.to eq "utf-8" }
25
25
  end
26
26
 
27
- context 'with text/plain; charSET=utf-8' do
28
- subject { described_class.parse 'text/plain; charSET=utf-8' }
29
- its(:mime_type) { is_expected.to eq 'text/plain' }
30
- its(:charset) { is_expected.to eq 'utf-8' }
27
+ context "with text/plain; charSET=utf-8" do
28
+ subject { described_class.parse "text/plain; charSET=utf-8" }
29
+ its(:mime_type) { is_expected.to eq "text/plain" }
30
+ its(:charset) { is_expected.to eq "utf-8" }
31
31
  end
32
32
 
33
- context 'with text/plain; foo=bar; charset=utf-8' do
34
- subject { described_class.parse 'text/plain; foo=bar; charset=utf-8' }
35
- its(:mime_type) { is_expected.to eq 'text/plain' }
36
- its(:charset) { is_expected.to eq 'utf-8' }
33
+ context "with text/plain; foo=bar; charset=utf-8" do
34
+ subject { described_class.parse "text/plain; foo=bar; charset=utf-8" }
35
+ its(:mime_type) { is_expected.to eq "text/plain" }
36
+ its(:charset) { is_expected.to eq "utf-8" }
37
37
  end
38
38
 
39
- context 'with text/plain;charset=utf-8;foo=bar' do
40
- subject { described_class.parse 'text/plain;charset=utf-8;foo=bar' }
41
- its(:mime_type) { is_expected.to eq 'text/plain' }
42
- its(:charset) { is_expected.to eq 'utf-8' }
39
+ context "with text/plain;charset=utf-8;foo=bar" do
40
+ subject { described_class.parse "text/plain;charset=utf-8;foo=bar" }
41
+ its(:mime_type) { is_expected.to eq "text/plain" }
42
+ its(:charset) { is_expected.to eq "utf-8" }
43
43
  end
44
44
  end
45
45
  end
@@ -12,23 +12,23 @@ RSpec.describe HTTP::Headers::Mixin do
12
12
  let(:headers) { HTTP::Headers.new }
13
13
  let(:dummy) { dummy_class.new headers }
14
14
 
15
- describe '#headers' do
16
- it 'returns @headers instance variable' do
15
+ describe "#headers" do
16
+ it "returns @headers instance variable" do
17
17
  expect(dummy.headers).to be headers
18
18
  end
19
19
  end
20
20
 
21
- describe '#[]' do
22
- it 'proxies to headers#[]' do
21
+ describe "#[]" do
22
+ it "proxies to headers#[]" do
23
23
  expect(headers).to receive(:[]).with(:accept)
24
24
  dummy[:accept]
25
25
  end
26
26
  end
27
27
 
28
- describe '#[]=' do
29
- it 'proxies to headers#[]' do
30
- expect(headers).to receive(:[]=).with(:accept, 'text/plain')
31
- dummy[:accept] = 'text/plain'
28
+ describe "#[]=" do
29
+ it "proxies to headers#[]" do
30
+ expect(headers).to receive(:[]=).with(:accept, "text/plain")
31
+ dummy[:accept] = "text/plain"
32
32
  end
33
33
  end
34
34
  end
@@ -1,189 +1,229 @@
1
1
  RSpec.describe HTTP::Headers do
2
2
  subject(:headers) { described_class.new }
3
3
 
4
- it 'is Enumerable' do
4
+ it "is Enumerable" do
5
5
  expect(headers).to be_an Enumerable
6
6
  end
7
7
 
8
- describe '#set' do
9
- it 'sets header value' do
10
- headers.set 'Accept', 'application/json'
11
- expect(headers['Accept']).to eq 'application/json'
8
+ describe "#set" do
9
+ it "sets header value" do
10
+ headers.set "Accept", "application/json"
11
+ expect(headers["Accept"]).to eq "application/json"
12
12
  end
13
13
 
14
- it 'normalizes header name' do
15
- headers.set :content_type, 'application/json'
16
- expect(headers['Content-Type']).to eq 'application/json'
14
+ it "normalizes header name" do
15
+ headers.set :content_type, "application/json"
16
+ expect(headers["Content-Type"]).to eq "application/json"
17
17
  end
18
18
 
19
- it 'overwrites previous value' do
20
- headers.set :set_cookie, 'hoo=ray'
21
- headers.set :set_cookie, 'woo=hoo'
22
- expect(headers['Set-Cookie']).to eq 'woo=hoo'
19
+ it "overwrites previous value" do
20
+ headers.set :set_cookie, "hoo=ray"
21
+ headers.set :set_cookie, "woo=hoo"
22
+ expect(headers["Set-Cookie"]).to eq "woo=hoo"
23
23
  end
24
24
 
25
- it 'allows set multiple values' do
26
- headers.set :set_cookie, 'hoo=ray'
25
+ it "allows set multiple values" do
26
+ headers.set :set_cookie, "hoo=ray"
27
27
  headers.set :set_cookie, %w(hoo=ray woo=hoo)
28
- expect(headers['Set-Cookie']).to eq %w(hoo=ray woo=hoo)
28
+ expect(headers["Set-Cookie"]).to eq %w(hoo=ray woo=hoo)
29
+ end
30
+
31
+ it "fails with empty header name" do
32
+ expect { headers.set "", "foo bar" }
33
+ .to raise_error HTTP::InvalidHeaderNameError
34
+ end
35
+
36
+ it "fails with invalid header name" do
37
+ expect { headers.set "foo bar", "baz" }
38
+ .to raise_error HTTP::InvalidHeaderNameError
29
39
  end
30
40
  end
31
41
 
32
- describe '#[]=' do
33
- it 'sets header value' do
34
- headers['Accept'] = 'application/json'
35
- expect(headers['Accept']).to eq 'application/json'
42
+ describe "#[]=" do
43
+ it "sets header value" do
44
+ headers["Accept"] = "application/json"
45
+ expect(headers["Accept"]).to eq "application/json"
36
46
  end
37
47
 
38
- it 'normalizes header name' do
39
- headers[:content_type] = 'application/json'
40
- expect(headers['Content-Type']).to eq 'application/json'
48
+ it "normalizes header name" do
49
+ headers[:content_type] = "application/json"
50
+ expect(headers["Content-Type"]).to eq "application/json"
41
51
  end
42
52
 
43
- it 'overwrites previous value' do
44
- headers[:set_cookie] = 'hoo=ray'
45
- headers[:set_cookie] = 'woo=hoo'
46
- expect(headers['Set-Cookie']).to eq 'woo=hoo'
53
+ it "overwrites previous value" do
54
+ headers[:set_cookie] = "hoo=ray"
55
+ headers[:set_cookie] = "woo=hoo"
56
+ expect(headers["Set-Cookie"]).to eq "woo=hoo"
47
57
  end
48
58
 
49
- it 'allows set multiple values' do
50
- headers[:set_cookie] = 'hoo=ray'
59
+ it "allows set multiple values" do
60
+ headers[:set_cookie] = "hoo=ray"
51
61
  headers[:set_cookie] = %w(hoo=ray woo=hoo)
52
- expect(headers['Set-Cookie']).to eq %w(hoo=ray woo=hoo)
62
+ expect(headers["Set-Cookie"]).to eq %w(hoo=ray woo=hoo)
53
63
  end
54
64
  end
55
65
 
56
- describe '#delete' do
57
- before { headers.set 'Content-Type', 'application/json' }
66
+ describe "#delete" do
67
+ before { headers.set "Content-Type", "application/json" }
58
68
 
59
- it 'removes given header' do
60
- headers.delete 'Content-Type'
61
- expect(headers['Content-Type']).to be_nil
69
+ it "removes given header" do
70
+ headers.delete "Content-Type"
71
+ expect(headers["Content-Type"]).to be_nil
62
72
  end
63
73
 
64
- it 'normalizes header name' do
74
+ it "normalizes header name" do
65
75
  headers.delete :content_type
66
- expect(headers['Content-Type']).to be_nil
76
+ expect(headers["Content-Type"]).to be_nil
77
+ end
78
+
79
+ it "fails with empty header name" do
80
+ expect { headers.delete "" }
81
+ .to raise_error HTTP::InvalidHeaderNameError
82
+ end
83
+
84
+ it "fails with invalid header name" do
85
+ expect { headers.delete "foo bar" }
86
+ .to raise_error HTTP::InvalidHeaderNameError
67
87
  end
68
88
  end
69
89
 
70
- describe '#add' do
71
- it 'sets header value' do
72
- headers.add 'Accept', 'application/json'
73
- expect(headers['Accept']).to eq 'application/json'
90
+ describe "#add" do
91
+ it "sets header value" do
92
+ headers.add "Accept", "application/json"
93
+ expect(headers["Accept"]).to eq "application/json"
74
94
  end
75
95
 
76
- it 'normalizes header name' do
77
- headers.add :content_type, 'application/json'
78
- expect(headers['Content-Type']).to eq 'application/json'
96
+ it "normalizes header name" do
97
+ headers.add :content_type, "application/json"
98
+ expect(headers["Content-Type"]).to eq "application/json"
79
99
  end
80
100
 
81
- it 'appends new value if header exists' do
82
- headers.add :set_cookie, 'hoo=ray'
83
- headers.add :set_cookie, 'woo=hoo'
84
- expect(headers['Set-Cookie']).to eq %w(hoo=ray woo=hoo)
101
+ it "appends new value if header exists" do
102
+ headers.add :set_cookie, "hoo=ray"
103
+ headers.add :set_cookie, "woo=hoo"
104
+ expect(headers["Set-Cookie"]).to eq %w(hoo=ray woo=hoo)
85
105
  end
86
106
 
87
- it 'allows append multiple values' do
88
- headers.add :set_cookie, 'hoo=ray'
107
+ it "allows append multiple values" do
108
+ headers.add :set_cookie, "hoo=ray"
89
109
  headers.add :set_cookie, %w(woo=hoo yup=pie)
90
- expect(headers['Set-Cookie']).to eq %w(hoo=ray woo=hoo yup=pie)
110
+ expect(headers["Set-Cookie"]).to eq %w(hoo=ray woo=hoo yup=pie)
111
+ end
112
+
113
+ it "fails with empty header name" do
114
+ expect { headers.add "", "foobar" }
115
+ .to raise_error HTTP::InvalidHeaderNameError
116
+ end
117
+
118
+ it "fails with invalid header name" do
119
+ expect { headers.add "foo bar", "baz" }
120
+ .to raise_error HTTP::InvalidHeaderNameError
91
121
  end
92
122
  end
93
123
 
94
- describe '#get' do
95
- before { headers.set 'Content-Type', 'application/json' }
124
+ describe "#get" do
125
+ before { headers.set "Content-Type", "application/json" }
96
126
 
97
- it 'returns array of associated values' do
98
- expect(headers.get 'Content-Type').to eq %w(application/json)
127
+ it "returns array of associated values" do
128
+ expect(headers.get "Content-Type").to eq %w(application/json)
99
129
  end
100
130
 
101
- it 'normalizes header name' do
131
+ it "normalizes header name" do
102
132
  expect(headers.get :content_type).to eq %w(application/json)
103
133
  end
104
134
 
105
- context 'when header does not exists' do
106
- it 'returns empty array' do
135
+ context "when header does not exists" do
136
+ it "returns empty array" do
107
137
  expect(headers.get :accept).to eq []
108
138
  end
109
139
  end
140
+
141
+ it "fails with empty header name" do
142
+ expect { headers.get "" }
143
+ .to raise_error HTTP::InvalidHeaderNameError
144
+ end
145
+
146
+ it "fails with invalid header name" do
147
+ expect { headers.get "foo bar" }
148
+ .to raise_error HTTP::InvalidHeaderNameError
149
+ end
110
150
  end
111
151
 
112
- describe '#[]' do
113
- context 'when header does not exists' do
114
- it 'returns nil' do
152
+ describe "#[]" do
153
+ context "when header does not exists" do
154
+ it "returns nil" do
115
155
  expect(headers[:accept]).to be_nil
116
156
  end
117
157
  end
118
158
 
119
- context 'when header has a single value' do
120
- before { headers.set 'Content-Type', 'application/json' }
159
+ context "when header has a single value" do
160
+ before { headers.set "Content-Type", "application/json" }
121
161
 
122
- it 'normalizes header name' do
162
+ it "normalizes header name" do
123
163
  expect(headers[:content_type]).to_not be_nil
124
164
  end
125
165
 
126
- it 'returns it returns a single value' do
127
- expect(headers[:content_type]).to eq 'application/json'
166
+ it "returns it returns a single value" do
167
+ expect(headers[:content_type]).to eq "application/json"
128
168
  end
129
169
  end
130
170
 
131
- context 'when header has a multiple values' do
171
+ context "when header has a multiple values" do
132
172
  before do
133
- headers.add :set_cookie, 'hoo=ray'
134
- headers.add :set_cookie, 'woo=hoo'
173
+ headers.add :set_cookie, "hoo=ray"
174
+ headers.add :set_cookie, "woo=hoo"
135
175
  end
136
176
 
137
- it 'normalizes header name' do
177
+ it "normalizes header name" do
138
178
  expect(headers[:set_cookie]).to_not be_nil
139
179
  end
140
180
 
141
- it 'returns array of associated values' do
181
+ it "returns array of associated values" do
142
182
  expect(headers[:set_cookie]).to eq %w(hoo=ray woo=hoo)
143
183
  end
144
184
  end
145
185
  end
146
186
 
147
- describe '#to_h' do
187
+ describe "#to_h" do
148
188
  before do
149
- headers.add :content_type, 'application/json'
150
- headers.add :set_cookie, 'hoo=ray'
151
- headers.add :set_cookie, 'woo=hoo'
189
+ headers.add :content_type, "application/json"
190
+ headers.add :set_cookie, "hoo=ray"
191
+ headers.add :set_cookie, "woo=hoo"
152
192
  end
153
193
 
154
- it 'returns a Hash' do
194
+ it "returns a Hash" do
155
195
  expect(headers.to_h).to be_a ::Hash
156
196
  end
157
197
 
158
- it 'returns Hash with normalized keys' do
198
+ it "returns Hash with normalized keys" do
159
199
  expect(headers.to_h.keys).to match_array %w(Content-Type Set-Cookie)
160
200
  end
161
201
 
162
- context 'for a header with single value' do
163
- it 'provides a value as is' do
164
- expect(headers.to_h['Content-Type']).to eq 'application/json'
202
+ context "for a header with single value" do
203
+ it "provides a value as is" do
204
+ expect(headers.to_h["Content-Type"]).to eq "application/json"
165
205
  end
166
206
  end
167
207
 
168
- context 'for a header with multiple values' do
169
- it 'provides an array of values' do
170
- expect(headers.to_h['Set-Cookie']).to eq %w(hoo=ray woo=hoo)
208
+ context "for a header with multiple values" do
209
+ it "provides an array of values" do
210
+ expect(headers.to_h["Set-Cookie"]).to eq %w(hoo=ray woo=hoo)
171
211
  end
172
212
  end
173
213
  end
174
214
 
175
- describe '#to_a' do
215
+ describe "#to_a" do
176
216
  before do
177
- headers.add :content_type, 'application/json'
178
- headers.add :set_cookie, 'hoo=ray'
179
- headers.add :set_cookie, 'woo=hoo'
217
+ headers.add :content_type, "application/json"
218
+ headers.add :set_cookie, "hoo=ray"
219
+ headers.add :set_cookie, "woo=hoo"
180
220
  end
181
221
 
182
- it 'returns an Array' do
222
+ it "returns an Array" do
183
223
  expect(headers.to_a).to be_a Array
184
224
  end
185
225
 
186
- it 'returns Array of key/value pairs with normalized keys' do
226
+ it "returns Array of key/value pairs with normalized keys" do
187
227
  expect(headers.to_a).to eq [
188
228
  %w(Content-Type application/json),
189
229
  %w(Set-Cookie hoo=ray),
@@ -192,41 +232,41 @@ RSpec.describe HTTP::Headers do
192
232
  end
193
233
  end
194
234
 
195
- describe '#inspect' do
235
+ describe "#inspect" do
196
236
  before { headers.set :set_cookie, %w(hoo=ray woo=hoo) }
197
237
  subject { headers.inspect }
198
238
 
199
239
  it { is_expected.to eq '#<HTTP::Headers {"Set-Cookie"=>["hoo=ray", "woo=hoo"]}>' }
200
240
  end
201
241
 
202
- describe '#keys' do
242
+ describe "#keys" do
203
243
  before do
204
- headers.add :content_type, 'application/json'
205
- headers.add :set_cookie, 'hoo=ray'
206
- headers.add :set_cookie, 'woo=hoo'
244
+ headers.add :content_type, "application/json"
245
+ headers.add :set_cookie, "hoo=ray"
246
+ headers.add :set_cookie, "woo=hoo"
207
247
  end
208
248
 
209
- it 'returns uniq keys only' do
249
+ it "returns uniq keys only" do
210
250
  expect(headers.keys.size).to eq 2
211
251
  end
212
252
 
213
- it 'normalizes keys' do
214
- expect(headers.keys).to include('Content-Type', 'Set-Cookie')
253
+ it "normalizes keys" do
254
+ expect(headers.keys).to include("Content-Type", "Set-Cookie")
215
255
  end
216
256
  end
217
257
 
218
- describe '#each' do
258
+ describe "#each" do
219
259
  before do
220
- headers.add :set_cookie, 'hoo=ray'
221
- headers.add :content_type, 'application/json'
222
- headers.add :set_cookie, 'woo=hoo'
260
+ headers.add :set_cookie, "hoo=ray"
261
+ headers.add :content_type, "application/json"
262
+ headers.add :set_cookie, "woo=hoo"
223
263
  end
224
264
 
225
- it 'yields each key/value pair separatedly' do
265
+ it "yields each key/value pair separatedly" do
226
266
  expect { |b| headers.each(&b) }.to yield_control.exactly(3).times
227
267
  end
228
268
 
229
- it 'yields headers in the same order they were added' do
269
+ it "yields headers in the same order they were added" do
230
270
  expect { |b| headers.each(&b) }.to yield_successive_args(
231
271
  %w(Set-Cookie hoo=ray),
232
272
  %w(Content-Type application/json),
@@ -234,30 +274,30 @@ RSpec.describe HTTP::Headers do
234
274
  )
235
275
  end
236
276
 
237
- it 'returns self instance if block given' do
277
+ it "returns self instance if block given" do
238
278
  expect(headers.each { |*| }).to be headers
239
279
  end
240
280
 
241
- it 'returns Enumerator if no block given' do
281
+ it "returns Enumerator if no block given" do
242
282
  expect(headers.each).to be_a Enumerator
243
283
  end
244
284
  end
245
285
 
246
- describe '.empty?' do
286
+ describe ".empty?" do
247
287
  subject { headers.empty? }
248
288
 
249
- context 'initially' do
289
+ context "initially" do
250
290
  it { is_expected.to be true }
251
291
  end
252
292
 
253
- context 'when header exists' do
254
- before { headers.add :accept, 'text/plain' }
293
+ context "when header exists" do
294
+ before { headers.add :accept, "text/plain" }
255
295
  it { is_expected.to be false }
256
296
  end
257
297
 
258
- context 'when last header was removed' do
298
+ context "when last header was removed" do
259
299
  before do
260
- headers.add :accept, 'text/plain'
300
+ headers.add :accept, "text/plain"
261
301
  headers.delete :accept
262
302
  end
263
303
 
@@ -265,154 +305,154 @@ RSpec.describe HTTP::Headers do
265
305
  end
266
306
  end
267
307
 
268
- describe '#hash' do
308
+ describe "#hash" do
269
309
  let(:left) { described_class.new }
270
310
  let(:right) { described_class.new }
271
311
 
272
- it 'equals if two headers equals' do
273
- left.add :accept, 'text/plain'
274
- right.add :accept, 'text/plain'
312
+ it "equals if two headers equals" do
313
+ left.add :accept, "text/plain"
314
+ right.add :accept, "text/plain"
275
315
 
276
316
  expect(left.hash).to eq right.hash
277
317
  end
278
318
  end
279
319
 
280
- describe '#==' do
320
+ describe "#==" do
281
321
  let(:left) { described_class.new }
282
322
  let(:right) { described_class.new }
283
323
 
284
- it 'compares header keys and values' do
285
- left.add :accept, 'text/plain'
286
- right.add :accept, 'text/plain'
324
+ it "compares header keys and values" do
325
+ left.add :accept, "text/plain"
326
+ right.add :accept, "text/plain"
287
327
 
288
328
  expect(left).to eq right
289
329
  end
290
330
 
291
- it 'allows comparison with Array of key/value pairs' do
292
- left.add :accept, 'text/plain'
331
+ it "allows comparison with Array of key/value pairs" do
332
+ left.add :accept, "text/plain"
293
333
  expect(left).to eq [%w(Accept text/plain)]
294
334
  end
295
335
 
296
- it 'sensitive to headers order' do
297
- left.add :accept, 'text/plain'
298
- left.add :cookie, 'woo=hoo'
299
- right.add :cookie, 'woo=hoo'
300
- right.add :accept, 'text/plain'
336
+ it "sensitive to headers order" do
337
+ left.add :accept, "text/plain"
338
+ left.add :cookie, "woo=hoo"
339
+ right.add :cookie, "woo=hoo"
340
+ right.add :accept, "text/plain"
301
341
 
302
342
  expect(left).to_not eq right
303
343
  end
304
344
 
305
- it 'sensitive to header values order' do
306
- left.add :cookie, 'hoo=ray'
307
- left.add :cookie, 'woo=hoo'
308
- right.add :cookie, 'woo=hoo'
309
- right.add :cookie, 'hoo=ray'
345
+ it "sensitive to header values order" do
346
+ left.add :cookie, "hoo=ray"
347
+ left.add :cookie, "woo=hoo"
348
+ right.add :cookie, "woo=hoo"
349
+ right.add :cookie, "hoo=ray"
310
350
 
311
351
  expect(left).to_not eq right
312
352
  end
313
353
  end
314
354
 
315
- describe '#dup' do
316
- before { headers.set :content_type, 'application/json' }
355
+ describe "#dup" do
356
+ before { headers.set :content_type, "application/json" }
317
357
 
318
358
  subject(:dupped) { headers.dup }
319
359
 
320
360
  it { is_expected.to be_a described_class }
321
361
  it { is_expected.not_to be headers }
322
362
 
323
- it 'has headers copied' do
324
- expect(dupped[:content_type]).to eq 'application/json'
363
+ it "has headers copied" do
364
+ expect(dupped[:content_type]).to eq "application/json"
325
365
  end
326
366
 
327
- context 'modifying a copy' do
328
- before { dupped.set :content_type, 'text/plain' }
367
+ context "modifying a copy" do
368
+ before { dupped.set :content_type, "text/plain" }
329
369
 
330
- it 'modifies dupped copy' do
331
- expect(dupped[:content_type]).to eq 'text/plain'
370
+ it "modifies dupped copy" do
371
+ expect(dupped[:content_type]).to eq "text/plain"
332
372
  end
333
373
 
334
- it 'does not affects original headers' do
335
- expect(headers[:content_type]).to eq 'application/json'
374
+ it "does not affects original headers" do
375
+ expect(headers[:content_type]).to eq "application/json"
336
376
  end
337
377
  end
338
378
  end
339
379
 
340
- describe '#merge!' do
380
+ describe "#merge!" do
341
381
  before do
342
- headers.set :host, 'example.com'
343
- headers.set :accept, 'application/json'
344
- headers.merge! :accept => 'plain/text', :cookie => %w(hoo=ray woo=hoo)
382
+ headers.set :host, "example.com"
383
+ headers.set :accept, "application/json"
384
+ headers.merge! :accept => "plain/text", :cookie => %w(hoo=ray woo=hoo)
345
385
  end
346
386
 
347
- it 'leaves headers not presented in other as is' do
348
- expect(headers[:host]).to eq 'example.com'
387
+ it "leaves headers not presented in other as is" do
388
+ expect(headers[:host]).to eq "example.com"
349
389
  end
350
390
 
351
- it 'overwrites existing values' do
352
- expect(headers[:accept]).to eq 'plain/text'
391
+ it "overwrites existing values" do
392
+ expect(headers[:accept]).to eq "plain/text"
353
393
  end
354
394
 
355
- it 'appends other headers, not presented in base' do
395
+ it "appends other headers, not presented in base" do
356
396
  expect(headers[:cookie]).to eq %w(hoo=ray woo=hoo)
357
397
  end
358
398
  end
359
399
 
360
- describe '#merge' do
400
+ describe "#merge" do
361
401
  before do
362
- headers.set :host, 'example.com'
363
- headers.set :accept, 'application/json'
402
+ headers.set :host, "example.com"
403
+ headers.set :accept, "application/json"
364
404
  end
365
405
 
366
406
  subject(:merged) do
367
- headers.merge :accept => 'plain/text', :cookie => %w(hoo=ray woo=hoo)
407
+ headers.merge :accept => "plain/text", :cookie => %w(hoo=ray woo=hoo)
368
408
  end
369
409
 
370
410
  it { is_expected.to be_a described_class }
371
411
  it { is_expected.not_to be headers }
372
412
 
373
- it 'does not affects original headers' do
413
+ it "does not affects original headers" do
374
414
  expect(merged.to_h).to_not eq headers.to_h
375
415
  end
376
416
 
377
- it 'leaves headers not presented in other as is' do
378
- expect(merged[:host]).to eq 'example.com'
417
+ it "leaves headers not presented in other as is" do
418
+ expect(merged[:host]).to eq "example.com"
379
419
  end
380
420
 
381
- it 'overwrites existing values' do
382
- expect(merged[:accept]).to eq 'plain/text'
421
+ it "overwrites existing values" do
422
+ expect(merged[:accept]).to eq "plain/text"
383
423
  end
384
424
 
385
- it 'appends other headers, not presented in base' do
425
+ it "appends other headers, not presented in base" do
386
426
  expect(merged[:cookie]).to eq %w(hoo=ray woo=hoo)
387
427
  end
388
428
  end
389
429
 
390
- describe '.coerce' do
430
+ describe ".coerce" do
391
431
  let(:dummyClass) { Class.new { def respond_to?(*); end } }
392
432
 
393
- it 'accepts any object that respond to #to_hash' do
394
- hashie = double :to_hash => {'accept' => 'json'}
395
- expect(described_class.coerce(hashie)['accept']).to eq 'json'
433
+ it "accepts any object that respond to #to_hash" do
434
+ hashie = double :to_hash => {"accept" => "json"}
435
+ expect(described_class.coerce(hashie)["accept"]).to eq "json"
396
436
  end
397
437
 
398
- it 'accepts any object that respond to #to_h' do
399
- hashie = double :to_h => {'accept' => 'json'}
400
- expect(described_class.coerce(hashie)['accept']).to eq 'json'
438
+ it "accepts any object that respond to #to_h" do
439
+ hashie = double :to_h => {"accept" => "json"}
440
+ expect(described_class.coerce(hashie)["accept"]).to eq "json"
401
441
  end
402
442
 
403
- it 'accepts any object that respond to #to_a' do
443
+ it "accepts any object that respond to #to_a" do
404
444
  hashie = double :to_a => [%w(accept json)]
405
- expect(described_class.coerce(hashie)['accept']).to eq 'json'
445
+ expect(described_class.coerce(hashie)["accept"]).to eq "json"
406
446
  end
407
447
 
408
- it 'fails if given object cannot be coerced' do
448
+ it "fails if given object cannot be coerced" do
409
449
  expect { described_class.coerce dummyClass.new }.to raise_error HTTP::Error
410
450
  end
411
451
 
412
- context 'with duplicate header keys (mixed case)' do
413
- let(:headers) { {'Set-Cookie' => 'hoo=ray', 'set-cookie' => 'woo=hoo'} }
452
+ context "with duplicate header keys (mixed case)" do
453
+ let(:headers) { {"Set-Cookie" => "hoo=ray", "set-cookie" => "woo=hoo"} }
414
454
 
415
- it 'adds all headers' do
455
+ it "adds all headers" do
416
456
  expect(described_class.coerce(headers).to_a).to match_array([
417
457
  %w(Set-Cookie hoo=ray),
418
458
  %w(Set-Cookie woo=hoo)
@@ -420,7 +460,7 @@ RSpec.describe HTTP::Headers do
420
460
  end
421
461
  end
422
462
 
423
- it 'is aliased as .[]' do
463
+ it "is aliased as .[]" do
424
464
  expect(described_class.method :coerce).to eq described_class.method(:[])
425
465
  end
426
466
  end