typhoeus 0.4.2 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (120) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +8 -0
  3. data/.rspec +4 -0
  4. data/.travis.yml +26 -0
  5. data/CHANGELOG.md +341 -28
  6. data/CONTRIBUTING.md +20 -0
  7. data/Gemfile +31 -2
  8. data/Guardfile +9 -0
  9. data/LICENSE +1 -1
  10. data/README.md +486 -357
  11. data/Rakefile +21 -12
  12. data/UPGRADE.md +55 -0
  13. data/lib/rack/typhoeus/middleware/params_decoder/helper.rb +76 -0
  14. data/lib/rack/typhoeus/middleware/params_decoder.rb +57 -0
  15. data/lib/rack/typhoeus.rb +1 -0
  16. data/lib/typhoeus/adapters/faraday.rb +180 -0
  17. data/lib/typhoeus/cache/dalli.rb +28 -0
  18. data/lib/typhoeus/cache/rails.rb +28 -0
  19. data/lib/typhoeus/cache/redis.rb +35 -0
  20. data/lib/typhoeus/config.rb +69 -0
  21. data/lib/typhoeus/easy_factory.rb +180 -0
  22. data/lib/typhoeus/errors/no_stub.rb +12 -0
  23. data/lib/typhoeus/errors/typhoeus_error.rb +8 -0
  24. data/lib/typhoeus/errors.rb +9 -0
  25. data/lib/typhoeus/expectation.rb +217 -0
  26. data/lib/typhoeus/hydra/addable.rb +23 -0
  27. data/lib/typhoeus/hydra/before.rb +31 -0
  28. data/lib/typhoeus/hydra/block_connection.rb +35 -0
  29. data/lib/typhoeus/hydra/cacheable.rb +15 -0
  30. data/lib/typhoeus/hydra/memoizable.rb +56 -0
  31. data/lib/typhoeus/hydra/queueable.rb +83 -0
  32. data/lib/typhoeus/hydra/runnable.rb +19 -0
  33. data/lib/typhoeus/hydra/stubbable.rb +28 -0
  34. data/lib/typhoeus/hydra.rb +84 -236
  35. data/lib/typhoeus/pool.rb +70 -0
  36. data/lib/typhoeus/railtie.rb +12 -0
  37. data/lib/typhoeus/request/actions.rb +125 -0
  38. data/lib/typhoeus/request/before.rb +30 -0
  39. data/lib/typhoeus/request/block_connection.rb +52 -0
  40. data/lib/typhoeus/request/cacheable.rb +38 -0
  41. data/lib/typhoeus/request/callbacks.rb +151 -0
  42. data/lib/typhoeus/request/marshal.rb +22 -0
  43. data/lib/typhoeus/request/memoizable.rb +38 -0
  44. data/lib/typhoeus/request/operations.rb +40 -0
  45. data/lib/typhoeus/request/responseable.rb +29 -0
  46. data/lib/typhoeus/request/streamable.rb +34 -0
  47. data/lib/typhoeus/request/stubbable.rb +30 -0
  48. data/lib/typhoeus/request.rb +186 -231
  49. data/lib/typhoeus/response/cacheable.rb +14 -0
  50. data/lib/typhoeus/response/header.rb +105 -0
  51. data/lib/typhoeus/response/informations.rb +248 -0
  52. data/lib/typhoeus/response/status.rb +106 -0
  53. data/lib/typhoeus/response.rb +60 -115
  54. data/lib/typhoeus/version.rb +3 -1
  55. data/lib/typhoeus.rb +126 -39
  56. data/perf/profile.rb +14 -0
  57. data/perf/vs_nethttp.rb +64 -0
  58. data/spec/rack/typhoeus/middleware/params_decoder/helper_spec.rb +156 -0
  59. data/spec/rack/typhoeus/middleware/params_decoder_spec.rb +31 -0
  60. data/spec/spec_helper.rb +29 -0
  61. data/spec/support/localhost_server.rb +94 -0
  62. data/spec/support/memory_cache.rb +15 -0
  63. data/spec/support/server.rb +116 -0
  64. data/spec/typhoeus/adapters/faraday_spec.rb +339 -0
  65. data/spec/typhoeus/cache/dalli_spec.rb +41 -0
  66. data/spec/typhoeus/cache/redis_spec.rb +41 -0
  67. data/spec/typhoeus/config_spec.rb +15 -0
  68. data/spec/typhoeus/easy_factory_spec.rb +143 -0
  69. data/spec/typhoeus/errors/no_stub_spec.rb +13 -0
  70. data/spec/typhoeus/expectation_spec.rb +280 -0
  71. data/spec/typhoeus/hydra/addable_spec.rb +22 -0
  72. data/spec/typhoeus/hydra/before_spec.rb +98 -0
  73. data/spec/typhoeus/hydra/block_connection_spec.rb +18 -0
  74. data/spec/typhoeus/hydra/cacheable_spec.rb +88 -0
  75. data/spec/typhoeus/hydra/memoizable_spec.rb +53 -0
  76. data/spec/typhoeus/hydra/queueable_spec.rb +98 -0
  77. data/spec/typhoeus/hydra/runnable_spec.rb +137 -0
  78. data/spec/typhoeus/hydra/stubbable_spec.rb +48 -0
  79. data/spec/typhoeus/hydra_spec.rb +22 -0
  80. data/spec/typhoeus/pool_spec.rb +137 -0
  81. data/spec/typhoeus/request/actions_spec.rb +19 -0
  82. data/spec/typhoeus/request/before_spec.rb +93 -0
  83. data/spec/typhoeus/request/block_connection_spec.rb +75 -0
  84. data/spec/typhoeus/request/cacheable_spec.rb +94 -0
  85. data/spec/typhoeus/request/callbacks_spec.rb +91 -0
  86. data/spec/typhoeus/request/marshal_spec.rb +60 -0
  87. data/spec/typhoeus/request/memoizable_spec.rb +34 -0
  88. data/spec/typhoeus/request/operations_spec.rb +101 -0
  89. data/spec/typhoeus/request/responseable_spec.rb +13 -0
  90. data/spec/typhoeus/request/stubbable_spec.rb +45 -0
  91. data/spec/typhoeus/request_spec.rb +232 -0
  92. data/spec/typhoeus/response/header_spec.rb +147 -0
  93. data/spec/typhoeus/response/informations_spec.rb +283 -0
  94. data/spec/typhoeus/response/status_spec.rb +256 -0
  95. data/spec/typhoeus/response_spec.rb +100 -0
  96. data/spec/typhoeus_spec.rb +105 -0
  97. data/typhoeus.gemspec +25 -0
  98. metadata +146 -158
  99. data/lib/typhoeus/curl.rb +0 -453
  100. data/lib/typhoeus/easy/auth.rb +0 -14
  101. data/lib/typhoeus/easy/callbacks.rb +0 -33
  102. data/lib/typhoeus/easy/ffi_helper.rb +0 -61
  103. data/lib/typhoeus/easy/infos.rb +0 -90
  104. data/lib/typhoeus/easy/options.rb +0 -115
  105. data/lib/typhoeus/easy/proxy.rb +0 -20
  106. data/lib/typhoeus/easy/ssl.rb +0 -82
  107. data/lib/typhoeus/easy.rb +0 -115
  108. data/lib/typhoeus/filter.rb +0 -28
  109. data/lib/typhoeus/form.rb +0 -61
  110. data/lib/typhoeus/header.rb +0 -54
  111. data/lib/typhoeus/hydra/callbacks.rb +0 -24
  112. data/lib/typhoeus/hydra/connect_options.rb +0 -61
  113. data/lib/typhoeus/hydra/stubbing.rb +0 -68
  114. data/lib/typhoeus/hydra_mock.rb +0 -131
  115. data/lib/typhoeus/multi.rb +0 -146
  116. data/lib/typhoeus/param_processor.rb +0 -43
  117. data/lib/typhoeus/remote.rb +0 -306
  118. data/lib/typhoeus/remote_method.rb +0 -108
  119. data/lib/typhoeus/remote_proxy_object.rb +0 -50
  120. data/lib/typhoeus/utils.rb +0 -50
@@ -0,0 +1,147 @@
1
+ require 'spec_helper'
2
+
3
+ describe Typhoeus::Response::Header do
4
+ let(:raw) { nil }
5
+ let(:header) { Typhoeus::Response::Header.new(raw) }
6
+
7
+ describe ".new" do
8
+ context "when string" do
9
+ let(:raw) { 'Date: Fri, 29 Jun 2012 10:09:23 GMT' }
10
+
11
+ it "sets Date" do
12
+ expect(header['Date']).to eq('Fri, 29 Jun 2012 10:09:23 GMT')
13
+ end
14
+
15
+ it "provides case insensitive access" do
16
+ expect(header['DaTe']).to eq('Fri, 29 Jun 2012 10:09:23 GMT')
17
+ end
18
+
19
+ it "provides symbol access" do
20
+ expect(header[:date]).to eq('Fri, 29 Jun 2012 10:09:23 GMT')
21
+ end
22
+ end
23
+
24
+ context "when hash" do
25
+ let(:raw) { { 'Date' => 'Fri, 29 Jun 2012 10:09:23 GMT' } }
26
+
27
+ it "sets Date" do
28
+ expect(header['Date']).to eq(raw['Date'])
29
+ end
30
+
31
+ it "provides case insensitive access" do
32
+ expect(header['DaTe']).to eq(raw['Date'])
33
+ end
34
+ end
35
+ end
36
+
37
+ describe "#parse" do
38
+ context "when no header" do
39
+ it "returns nil" do
40
+ expect(header).to be_empty
41
+ end
42
+ end
43
+
44
+ context "when header" do
45
+ let(:raw) do
46
+ 'HTTP/1.1 200 OK
47
+ Set-Cookie: NID=61=LblqYgUOu; expires=Sat, 29-Dec-2012 10:09:23 GMT; path=/; domain=.google.de; HttpOnly
48
+ Date: Fri, 29 Jun 2012 10:09:23 GMT
49
+ Expires: -1
50
+ Cache-Control: private, max-age=0
51
+ Content-Type: text/html; charset=ISO-8859-1
52
+ Set-Cookie: PREF=ID=77e93yv0hPtejLou; expires=Sun, 29-Jun-2014 10:09:23 GMT; path=/; domain=.google.de
53
+ Set-Cookie: NID=61=LblqYgh5Ou; expires=Sat, 29-Dec-2012 10:09:23 GMT; path=/; domain=.google.de; HttpOnly
54
+ P3P: CP="This is not a P3P policy! See http://www.google.com/support/accounts/bin/answer.py?hl=en&answer=151657 for more info."
55
+ Server: gws
56
+ X-XSS-Protection: 1; mode=block
57
+ X-Frame-Options: SAMEORIGIN
58
+ Transfer-Encoding: chunked'.gsub(/^\s{8}/, '')
59
+ end
60
+
61
+ it "sets raw" do
62
+ expect(header.send(:raw)).to eq(raw)
63
+ end
64
+
65
+ it "sets Set-Cookie" do
66
+ expect(header['set-cookie'].size).to eq(3)
67
+ end
68
+
69
+ it "provides case insensitive access" do
70
+ expect(header['Set-CooKie'].size).to eq(3)
71
+ end
72
+
73
+ [
74
+ 'NID=61=LblqYgUOu; expires=Sat, 29-Dec-2012 10:09:23 GMT; path=/; domain=.google.de; HttpOnly',
75
+ 'PREF=ID=77e93yv0hPtejLou; expires=Sun, 29-Jun-2014 10:09:23 GMT; path=/; domain=.google.de',
76
+ 'NID=61=LblqYgh5Ou; expires=Sat, 29-Dec-2012 10:09:23 GMT; path=/; domain=.google.de; HttpOnly'
77
+ ].each_with_index do |cookie, i|
78
+ it "sets Cookie##{i}" do
79
+ expect(header['set-cookie']).to include(cookie)
80
+ end
81
+ end
82
+
83
+ {
84
+ 'Date' => 'Fri, 29 Jun 2012 10:09:23 GMT', 'Expires' => '-1',
85
+ 'Cache-Control' => 'private, max-age=0',
86
+ 'Content-Type' => 'text/html; charset=ISO-8859-1',
87
+ 'P3P' => 'CP="This is not a P3P policy! See http://www.google.com/support/accounts/bin/answer.py?hl=en&answer=151657 for more info."',
88
+ 'Server' => 'gws', 'X-XSS-Protection' => '1; mode=block',
89
+ 'X-Frame-Options' => 'SAMEORIGIN', 'Transfer-Encoding' => 'chunked'
90
+ }.each do |name, value|
91
+ it "sets #{name}" do
92
+ expect(header[name.downcase]).to eq(value)
93
+ end
94
+ end
95
+
96
+ context 'includes a multi-line header' do
97
+ let(:raw) do
98
+ 'HTTP/1.1 200 OK
99
+ Date: Fri, 29 Jun 2012 10:09:23 GMT
100
+ Content-Security-Policy: default-src "self";
101
+ img-src * data: "self";
102
+ upgrade-insecure-requests;'.gsub(/^\s{10}/, '')
103
+ end
104
+
105
+ it "joins header parts" do
106
+ expect(header).to eq({
107
+ 'Date' => 'Fri, 29 Jun 2012 10:09:23 GMT',
108
+ 'Content-Security-Policy' => 'default-src "self"; img-src * data: "self"; upgrade-insecure-requests;'
109
+ })
110
+ end
111
+ end
112
+
113
+ context 'includes line with only whitespace' do
114
+ let(:raw) do
115
+ 'HTTP/1.1 200 OK
116
+ Date: Fri, 29 Jun 2012 10:09:23 GMT
117
+
118
+ '.gsub(/^\s{10}/, '')
119
+ end
120
+
121
+ it 'ignores it' do
122
+ expect(header).to eq({ 'Date' => 'Fri, 29 Jun 2012 10:09:23 GMT' })
123
+ end
124
+ end
125
+
126
+ context 'with broken headers' do
127
+ let(:raw) do
128
+ 'HTTP/1.1 200 OK
129
+ Date:
130
+ Content-Type
131
+ '.gsub(/^\s{10}/, '')
132
+ end
133
+
134
+ it 'returns empty string for invalid headers' do
135
+ expect(header.to_hash).to include({ 'Date' => '', 'Content-Type' => '' })
136
+ end
137
+ end
138
+ end
139
+ end
140
+
141
+ it "can be Marshal'd" do
142
+ header = Typhoeus::Response::Header.new("Foo: Bar")
143
+ expect {
144
+ Marshal.dump(header)
145
+ }.not_to raise_error
146
+ end
147
+ end
@@ -0,0 +1,283 @@
1
+ require 'spec_helper'
2
+
3
+ describe Typhoeus::Response::Informations do
4
+ let(:options) { {} }
5
+ let(:response) { Typhoeus::Response.new(options) }
6
+
7
+ describe "#return_code" do
8
+ let(:options) { { :return_code => :ok } }
9
+
10
+ it "returns return_code from options" do
11
+ expect(response.return_code).to be(:ok)
12
+ end
13
+ end
14
+
15
+ describe "#debug_info" do
16
+ let(:options) { { :debug_info => Ethon::Easy::DebugInfo.new } }
17
+
18
+ it "returns debug_info from options" do
19
+ expect(response.debug_info).to be_a(Ethon::Easy::DebugInfo)
20
+ end
21
+ end
22
+
23
+ describe "#return_message" do
24
+ let(:options) { { :return_code => :couldnt_connect } }
25
+
26
+ it "returns a message" do
27
+ expect(response.return_message).to eq("Couldn't connect to server")
28
+ end
29
+
30
+ describe "with nil return_code" do
31
+ let(:options) { { :return_code => nil } }
32
+
33
+ it "returns nil" do
34
+ expect(response.return_message).to be_nil
35
+ end
36
+ end
37
+ end
38
+
39
+ describe "#response_body" do
40
+ context "when response_body" do
41
+ let(:options) { { :response_body => "body" } }
42
+
43
+ it "returns response_body from options" do
44
+ expect(response.response_body).to eq("body")
45
+ end
46
+ end
47
+
48
+ context "when body" do
49
+ let(:options) { { :body => "body" } }
50
+
51
+ it "returns body from options" do
52
+ expect(response.body).to eq("body")
53
+ end
54
+ end
55
+ end
56
+
57
+ describe "#response_headers" do
58
+ let(:options) { { :response_headers => "Length: 1" } }
59
+
60
+ context "when no mock" do
61
+ it "returns response_headers from options" do
62
+ expect(response.response_headers).to eq("Length: 1")
63
+ end
64
+ end
65
+
66
+ context "when mock" do
67
+ context "when no response_headers" do
68
+ context "when headers" do
69
+ let(:options) { { :mock => true, :headers => {"Length" => 1, "Content-Type" => "text/plain" } } }
70
+
71
+ it "constructs response_headers" do
72
+ expect(response.response_headers).to include("Length: 1")
73
+ expect(response.response_headers).to include("Content-Type: text/plain")
74
+ expect(response.response_headers).to include("\r\n")
75
+ end
76
+ end
77
+
78
+ context "when multiple values for a header" do
79
+ let(:options) { { :mock => true, :headers => {"Length" => 1, "Content-Type" => "text/plain", "set-cookie" => ["cookieone=one","cookietwo=two"] } } }
80
+
81
+ it "constructs response_headers" do
82
+ expect(response.response_headers).to include("Length: 1")
83
+ expect(response.response_headers).to include("Content-Type: text/plain")
84
+ expect(response.response_headers).to include("set-cookie: cookieone=one,cookietwo=two")
85
+ expect(response.response_headers).to include("\r\n")
86
+ end
87
+ end
88
+ end
89
+ end
90
+ end
91
+
92
+ describe "#response_code" do
93
+ context "when response_code" do
94
+ let(:options) { { :response_code => "200" } }
95
+
96
+ it "returns response_code from options" do
97
+ expect(response.response_code).to eq(200)
98
+ end
99
+ end
100
+
101
+ context "when code" do
102
+ let(:options) { { :code => "200" } }
103
+
104
+ it "returns code from options" do
105
+ expect(response.code).to eq(200)
106
+ end
107
+ end
108
+ end
109
+
110
+ describe "#httpauth_avail" do
111
+ let(:options) { { :httpauth_avail => "code" } }
112
+
113
+ it "returns httpauth_avail from options" do
114
+ expect(response.httpauth_avail).to eq("code")
115
+ end
116
+ end
117
+
118
+ describe "#total_time" do
119
+ let(:options) { { :total_time => 1 } }
120
+
121
+ it "returns total_time from options" do
122
+ expect(response.total_time).to eq(1)
123
+ end
124
+ end
125
+
126
+ describe "#starttransfer_time" do
127
+ let(:options) { { :starttransfer_time => 1 } }
128
+
129
+ it "returns starttransfer_time from options" do
130
+ expect(response.starttransfer_time).to eq(1)
131
+ end
132
+ end
133
+
134
+ describe "#appconnect_time" do
135
+ let(:options) { { :appconnect_time => 1 } }
136
+
137
+ it "returns appconnect_time from options" do
138
+ expect(response.appconnect_time).to eq(1)
139
+ end
140
+ end
141
+
142
+ describe "#pretransfer_time" do
143
+ let(:options) { { :pretransfer_time => 1 } }
144
+
145
+ it "returns pretransfer_time from options" do
146
+ expect(response.pretransfer_time).to eq(1)
147
+ end
148
+ end
149
+
150
+ describe "#connect_time" do
151
+ let(:options) { { :connect_time => 1 } }
152
+
153
+ it "returns connect_time from options" do
154
+ expect(response.connect_time).to eq(1)
155
+ end
156
+ end
157
+
158
+ describe "#namelookup_time" do
159
+ let(:options) { { :namelookup_time => 1 } }
160
+
161
+ it "returns namelookup_time from options" do
162
+ expect(response.namelookup_time).to eq(1)
163
+ end
164
+ end
165
+
166
+ describe "#redirect_time" do
167
+ let(:options) { { :redirect_time => 1 } }
168
+
169
+ it "returns redirect_time from options" do
170
+ expect(response.redirect_time).to eq(1)
171
+ end
172
+ end
173
+
174
+ describe "#effective_url" do
175
+ let(:options) { { :effective_url => "http://www.example.com" } }
176
+
177
+ it "returns effective_url from options" do
178
+ expect(response.effective_url).to eq("http://www.example.com")
179
+ end
180
+ end
181
+
182
+ describe "#primary_ip" do
183
+ let(:options) { { :primary_ip => "127.0.0.1" } }
184
+
185
+ it "returns primary_ip from options" do
186
+ expect(response.primary_ip).to eq("127.0.0.1")
187
+ end
188
+ end
189
+
190
+ describe "#redirect_count" do
191
+ let(:options) { { :redirect_count => 2 } }
192
+
193
+ it "returns redirect_count from options" do
194
+ expect(response.redirect_count).to eq(2)
195
+ end
196
+ end
197
+
198
+ describe "#request_size" do
199
+ let(:options) { { :request_size => 2 } }
200
+
201
+ it "returns request_size from options" do
202
+ expect(response.request_size).to eq(2)
203
+ end
204
+ end
205
+
206
+ describe "#headers" do
207
+ context "when no response_headers" do
208
+ it "returns nil" do
209
+ expect(response.headers).to be_nil
210
+ end
211
+ end
212
+
213
+ context "when response_headers" do
214
+ let(:options) { {:response_headers => "Expire: -1\nServer: gws"} }
215
+
216
+ it "returns nonempty headers" do
217
+ expect(response.headers).to_not be_empty
218
+ end
219
+
220
+ it "has Expire" do
221
+ expect(response.headers['expire']).to eq('-1')
222
+ end
223
+
224
+ it "has Server" do
225
+ expect(response.headers['server']).to eq('gws')
226
+ end
227
+ end
228
+
229
+ context "when multiple headers" do
230
+ let(:options) { {:response_headers => "Server: A\r\n\r\nServer: B"} }
231
+
232
+ it "returns the last" do
233
+ expect(response.headers['server']).to eq("B")
234
+ end
235
+ end
236
+
237
+ context "when mock" do
238
+ context "when headers" do
239
+ let(:options) { {:mock => true, :headers => {"Length" => "1"}} }
240
+
241
+ it "returns Typhoeus::Response::Header" do
242
+ expect(response.headers).to be_a(Typhoeus::Response::Header)
243
+ end
244
+
245
+ it "returns headers" do
246
+ expect(response.headers.to_hash).to include("Length" => "1")
247
+ end
248
+ end
249
+ end
250
+
251
+ context "when requesting" do
252
+ let(:response) { Typhoeus.get("localhost:3001") }
253
+
254
+ it "returns headers" do
255
+ expect(response.headers).to_not be_empty
256
+ end
257
+ end
258
+ end
259
+
260
+ describe "#redirections" do
261
+ context "when no response_headers" do
262
+ it "returns empty array" do
263
+ expect(response.redirections).to be_empty
264
+ end
265
+ end
266
+
267
+ context "when headers" do
268
+ let(:options) { {:response_headers => "Expire: -1\nServer: gws"} }
269
+
270
+ it "returns empty array" do
271
+ expect(response.redirections).to be_empty
272
+ end
273
+ end
274
+
275
+ context "when multiple headers" do
276
+ let(:options) { {:response_headers => "Server: A\r\n\r\nServer: B"} }
277
+
278
+ it "returns response from all but last headers" do
279
+ expect(response.redirections.size).to eq(1)
280
+ end
281
+ end
282
+ end
283
+ end
@@ -0,0 +1,256 @@
1
+ require 'spec_helper'
2
+
3
+ describe Typhoeus::Response::Status do
4
+ let(:response) { Typhoeus::Response.new(options) }
5
+ let(:options) { {} }
6
+
7
+ describe "timed_out?" do
8
+ context "when return code is operation_timedout" do
9
+ let(:options) { {:return_code => :operation_timedout} }
10
+
11
+ it "return true" do
12
+ expect(response).to be_timed_out
13
+ end
14
+ end
15
+ end
16
+
17
+ describe "#status_message" do
18
+ context "when no header" do
19
+ it "returns nil" do
20
+ expect(response.status_message).to be_nil
21
+ end
22
+ end
23
+
24
+ context "when header" do
25
+ context "when no message" do
26
+ let(:options) { {:response_headers => "HTTP/1.1 200\r\n"} }
27
+
28
+ it "returns nil" do
29
+ expect(response.status_message).to be_nil
30
+ end
31
+ end
32
+
33
+ context "when messsage" do
34
+ let(:options) { {:response_headers => "HTTP/1.1 200 message\r\n"} }
35
+
36
+ it "returns message" do
37
+ expect(response.status_message).to eq("message")
38
+ end
39
+ end
40
+ end
41
+ end
42
+
43
+ describe "#http_version" do
44
+ context "when no header" do
45
+ it "returns nil" do
46
+ expect(response.http_version).to be_nil
47
+ end
48
+ end
49
+
50
+ context "when header" do
51
+ context "when no http version" do
52
+ let(:options) { {:response_headers => "HTTP OK"} }
53
+
54
+ it "returns nil" do
55
+ expect(response.http_version).to be_nil
56
+ end
57
+ end
58
+
59
+ context "when invalid http_version" do
60
+ let(:options) { {:response_headers => "HTTP foo/bar OK"} }
61
+
62
+ it "returns nil" do
63
+ expect(response.http_version).to be_nil
64
+ end
65
+ end
66
+
67
+ context "when valid http_version" do
68
+ let(:options) { {:response_headers => "HTTP/1.1 OK"} }
69
+
70
+ it "returns http_version" do
71
+ expect(response.http_version).to eq("1.1")
72
+ end
73
+ end
74
+ end
75
+ end
76
+
77
+ describe "#success?" do
78
+ context "when response code 200-299" do
79
+ let(:options) { {:return_code => return_code, :response_code => 201} }
80
+
81
+ context "when mock" do
82
+ before { response.mock = true }
83
+
84
+ context "when return_code :ok" do
85
+ let(:return_code) { :ok }
86
+
87
+ it "returns true" do
88
+ expect(response.success?).to be_truthy
89
+ end
90
+ end
91
+
92
+ context "when return_code nil" do
93
+ let(:return_code) { nil }
94
+
95
+ it "returns true" do
96
+ expect(response.success?).to be_truthy
97
+ end
98
+ end
99
+ end
100
+
101
+ context "when no mock" do
102
+ before { response.mock = nil }
103
+
104
+ context "when return_code :ok" do
105
+ let(:return_code) { :ok }
106
+
107
+ it "returns true" do
108
+ expect(response.success?).to be_truthy
109
+ end
110
+ end
111
+
112
+ context "when return_code nil" do
113
+ let(:return_code) { nil }
114
+
115
+ it "returns false" do
116
+ expect(response.success?).to be_falsey
117
+ end
118
+ end
119
+ end
120
+ end
121
+
122
+ context "when response code is not 200-299" do
123
+ let(:options) { {:return_code => :ok, :response_code => 500} }
124
+
125
+ it "returns false" do
126
+ expect(response.success?).to be_falsey
127
+ end
128
+ end
129
+ end
130
+
131
+ describe "#failure?" do
132
+ context "when response code between 300-526 and 100-300" do
133
+ let(:options) { {:return_code => return_code, :response_code => 300} }
134
+
135
+ context "when mock" do
136
+ before { response.mock = true }
137
+
138
+ context "when return_code :internal_server_error" do
139
+ let(:return_code) { :internal_server_error }
140
+
141
+ it "returns true" do
142
+ expect(response.failure?).to be_truthy
143
+ end
144
+ end
145
+
146
+ context "when return_code nil" do
147
+ let(:return_code) { nil }
148
+
149
+ it "returns true" do
150
+ expect(response.failure?).to be_truthy
151
+ end
152
+ end
153
+ end
154
+
155
+ context "when no mock" do
156
+ before { response.mock = nil }
157
+
158
+ context "when return_code :internal_server_error" do
159
+ let(:return_code) { :internal_server_error }
160
+
161
+ it "returns true" do
162
+ expect(response.failure?).to be_truthy
163
+ end
164
+ end
165
+
166
+ context "when return_code nil" do
167
+ let(:return_code) { nil }
168
+
169
+ it "returns false" do
170
+ expect(response.failure?).to be_falsey
171
+ end
172
+ end
173
+ end
174
+ end
175
+
176
+ context "when response code is not 300-526" do
177
+ let(:options) { {:return_code => :ok, :response_code => 200} }
178
+
179
+ it "returns false" do
180
+ expect(response.failure?).to be_falsey
181
+ end
182
+ end
183
+ end
184
+
185
+ describe "#modified?" do
186
+ context "when response code 304" do
187
+ let(:options) { {:return_code => :ok, :response_code => 304} }
188
+
189
+ context "when mock" do
190
+ before { response.mock = true }
191
+
192
+ context "when return_code :ok" do
193
+ let(:return_code) { :ok }
194
+
195
+ it "returns false" do
196
+ expect(response.modified?).to be_falsey
197
+ end
198
+ end
199
+
200
+ context "when return_code nil" do
201
+ let(:return_code) { nil }
202
+
203
+ it "returns false" do
204
+ expect(response.modified?).to be_falsey
205
+ end
206
+ end
207
+ end
208
+
209
+ context "when no mock" do
210
+ before { response.mock = nil }
211
+
212
+ context "when return_code :ok" do
213
+ let(:return_code) { :ok }
214
+
215
+ it "returns false" do
216
+ expect(response.modified?).to be_falsey
217
+ end
218
+ end
219
+
220
+ context "when return_code nil" do
221
+ let(:return_code) { nil }
222
+
223
+ it "returns true" do
224
+ expect(response.modified?).to be_falsey
225
+ end
226
+ end
227
+ end
228
+ end
229
+
230
+ context "when response code is not 304" do
231
+ let(:options) { {:return_code => :ok, :response_code => 500} }
232
+
233
+ it "returns true" do
234
+ expect(response.modified?).to be_truthy
235
+ end
236
+ end
237
+ end
238
+
239
+ describe "#first_header_line" do
240
+ context "when multiple header" do
241
+ let(:options) { {:response_headers => "1\r\n\r\n2\r\nbla"} }
242
+
243
+ it "returns first line of last block" do
244
+ expect(response.method(:first_header_line).call).to eq("2")
245
+ end
246
+ end
247
+
248
+ context "when single header" do
249
+ let(:options) { {:response_headers => "1"} }
250
+
251
+ it "returns first line" do
252
+ expect(response.method(:first_header_line).call).to eq("1")
253
+ end
254
+ end
255
+ end
256
+ end