httsoiree 0.13.1

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 (94) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +10 -0
  3. data/.travis.yml +7 -0
  4. data/Gemfile +14 -0
  5. data/Guardfile +16 -0
  6. data/History +303 -0
  7. data/MIT-LICENSE +20 -0
  8. data/README.md +77 -0
  9. data/Rakefile +12 -0
  10. data/bin/httparty +117 -0
  11. data/cucumber.yml +1 -0
  12. data/examples/aaws.rb +32 -0
  13. data/examples/basic.rb +28 -0
  14. data/examples/crack.rb +19 -0
  15. data/examples/custom_parsers.rb +67 -0
  16. data/examples/delicious.rb +37 -0
  17. data/examples/google.rb +16 -0
  18. data/examples/headers_and_user_agents.rb +6 -0
  19. data/examples/logging.rb +38 -0
  20. data/examples/nokogiri_html_parser.rb +22 -0
  21. data/examples/rubyurl.rb +14 -0
  22. data/examples/stackexchange.rb +24 -0
  23. data/examples/tripit_sign_in.rb +33 -0
  24. data/examples/twitter.rb +31 -0
  25. data/examples/whoismyrep.rb +10 -0
  26. data/features/basic_authentication.feature +20 -0
  27. data/features/command_line.feature +7 -0
  28. data/features/deals_with_http_error_codes.feature +26 -0
  29. data/features/digest_authentication.feature +20 -0
  30. data/features/handles_compressed_responses.feature +27 -0
  31. data/features/handles_multiple_formats.feature +57 -0
  32. data/features/steps/env.rb +22 -0
  33. data/features/steps/httparty_response_steps.rb +52 -0
  34. data/features/steps/httparty_steps.rb +43 -0
  35. data/features/steps/mongrel_helper.rb +94 -0
  36. data/features/steps/remote_service_steps.rb +74 -0
  37. data/features/supports_read_timeout_option.feature +13 -0
  38. data/features/supports_redirection.feature +22 -0
  39. data/features/supports_timeout_option.feature +13 -0
  40. data/httparty.gemspec +25 -0
  41. data/lib/httparty/connection_adapter.rb +188 -0
  42. data/lib/httparty/cookie_hash.rb +22 -0
  43. data/lib/httparty/core_extensions.rb +32 -0
  44. data/lib/httparty/exceptions.rb +29 -0
  45. data/lib/httparty/hash_conversions.rb +51 -0
  46. data/lib/httparty/logger/apache_logger.rb +22 -0
  47. data/lib/httparty/logger/curl_logger.rb +48 -0
  48. data/lib/httparty/logger/logger.rb +18 -0
  49. data/lib/httparty/module_inheritable_attributes.rb +56 -0
  50. data/lib/httparty/net_digest_auth.rb +84 -0
  51. data/lib/httparty/parser.rb +141 -0
  52. data/lib/httparty/request.rb +339 -0
  53. data/lib/httparty/response/headers.rb +31 -0
  54. data/lib/httparty/response.rb +72 -0
  55. data/lib/httparty/version.rb +3 -0
  56. data/lib/httparty.rb +618 -0
  57. data/lib/httsoiree.rb +3 -0
  58. data/script/release +42 -0
  59. data/spec/fixtures/delicious.xml +23 -0
  60. data/spec/fixtures/empty.xml +0 -0
  61. data/spec/fixtures/google.html +3 -0
  62. data/spec/fixtures/ssl/generate.sh +29 -0
  63. data/spec/fixtures/ssl/generated/1fe462c2.0 +16 -0
  64. data/spec/fixtures/ssl/generated/bogushost.crt +13 -0
  65. data/spec/fixtures/ssl/generated/ca.crt +16 -0
  66. data/spec/fixtures/ssl/generated/ca.key +15 -0
  67. data/spec/fixtures/ssl/generated/selfsigned.crt +14 -0
  68. data/spec/fixtures/ssl/generated/server.crt +13 -0
  69. data/spec/fixtures/ssl/generated/server.key +15 -0
  70. data/spec/fixtures/ssl/openssl-exts.cnf +9 -0
  71. data/spec/fixtures/twitter.csv +2 -0
  72. data/spec/fixtures/twitter.json +1 -0
  73. data/spec/fixtures/twitter.xml +403 -0
  74. data/spec/fixtures/undefined_method_add_node_for_nil.xml +2 -0
  75. data/spec/httparty/connection_adapter_spec.rb +370 -0
  76. data/spec/httparty/cookie_hash_spec.rb +83 -0
  77. data/spec/httparty/exception_spec.rb +23 -0
  78. data/spec/httparty/logger/apache_logger_spec.rb +41 -0
  79. data/spec/httparty/logger/curl_logger_spec.rb +18 -0
  80. data/spec/httparty/logger/logger_spec.rb +22 -0
  81. data/spec/httparty/net_digest_auth_spec.rb +152 -0
  82. data/spec/httparty/parser_spec.rb +165 -0
  83. data/spec/httparty/request_spec.rb +774 -0
  84. data/spec/httparty/response_spec.rb +221 -0
  85. data/spec/httparty/ssl_spec.rb +74 -0
  86. data/spec/httparty_spec.rb +783 -0
  87. data/spec/spec.opts +2 -0
  88. data/spec/spec_helper.rb +37 -0
  89. data/spec/support/ssl_test_helper.rb +47 -0
  90. data/spec/support/ssl_test_server.rb +80 -0
  91. data/spec/support/stub_response.rb +43 -0
  92. data/website/css/common.css +47 -0
  93. data/website/index.html +73 -0
  94. metadata +215 -0
@@ -0,0 +1,370 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
2
+
3
+ describe HTTParty::ConnectionAdapter do
4
+
5
+ describe "initialization" do
6
+ let(:uri) { URI 'http://www.google.com' }
7
+ it "takes a URI as input" do
8
+ HTTParty::ConnectionAdapter.new(uri)
9
+ end
10
+
11
+ it "raises an ArgumentError if the uri is nil" do
12
+ expect { HTTParty::ConnectionAdapter.new(nil) }.to raise_error ArgumentError
13
+ end
14
+
15
+ it "raises an ArgumentError if the uri is a String" do
16
+ expect { HTTParty::ConnectionAdapter.new('http://www.google.com') }.to raise_error ArgumentError
17
+ end
18
+
19
+ it "sets the uri" do
20
+ adapter = HTTParty::ConnectionAdapter.new(uri)
21
+ adapter.uri.should be uri
22
+ end
23
+
24
+ it "also accepts an optional options hash" do
25
+ HTTParty::ConnectionAdapter.new(uri, {})
26
+ end
27
+
28
+ it "sets the options" do
29
+ options = {foo: :bar}
30
+ adapter = HTTParty::ConnectionAdapter.new(uri, options)
31
+ adapter.options.should be options
32
+ end
33
+ end
34
+
35
+ describe ".call" do
36
+ it "generates an HTTParty::ConnectionAdapter instance with the given uri and options" do
37
+ HTTParty::ConnectionAdapter.should_receive(:new).with(@uri, @options).and_return(stub(connection: nil))
38
+ HTTParty::ConnectionAdapter.call(@uri, @options)
39
+ end
40
+
41
+ it "calls #connection on the connection adapter" do
42
+ adapter = mock('Adapter')
43
+ connection = mock('Connection')
44
+ adapter.should_receive(:connection).and_return(connection)
45
+ HTTParty::ConnectionAdapter.stub(new: adapter)
46
+ HTTParty::ConnectionAdapter.call(@uri, @options).should be connection
47
+ end
48
+ end
49
+
50
+ describe '#connection' do
51
+ let(:uri) { URI 'http://www.google.com' }
52
+ let(:options) { Hash.new }
53
+ let(:adapter) { HTTParty::ConnectionAdapter.new(uri, options) }
54
+
55
+ describe "the resulting connection" do
56
+ subject { adapter.connection }
57
+ it { should be_an_instance_of Net::HTTP }
58
+
59
+ context "using port 80" do
60
+ let(:uri) { URI 'http://foobar.com' }
61
+ it { should_not use_ssl }
62
+ end
63
+
64
+ context "when dealing with ssl" do
65
+ let(:uri) { URI 'https://foobar.com' }
66
+
67
+ context "uses the system cert_store, by default" do
68
+ let(:system_cert_store) do
69
+ system_cert_store = mock('default_cert_store')
70
+ system_cert_store.should_receive(:set_default_paths)
71
+ OpenSSL::X509::Store.should_receive(:new).and_return(system_cert_store)
72
+ system_cert_store
73
+ end
74
+ it { should use_cert_store(system_cert_store) }
75
+ end
76
+
77
+ context "should use the specified cert store, when one is given" do
78
+ let(:custom_cert_store) { mock('custom_cert_store') }
79
+ let(:options) { {cert_store: custom_cert_store} }
80
+ it { should use_cert_store(custom_cert_store) }
81
+ end
82
+
83
+ context "using port 443 for ssl" do
84
+ let(:uri) { URI 'https://api.foo.com/v1:443' }
85
+ it { should use_ssl }
86
+ end
87
+
88
+ context "https scheme with default port" do
89
+ it { should use_ssl }
90
+ end
91
+
92
+ context "https scheme with non-standard port" do
93
+ let(:uri) { URI 'https://foobar.com:123456' }
94
+ it { should use_ssl }
95
+ end
96
+
97
+
98
+ context "when ssl version is set" do
99
+ let(:options) { {ssl_version: :TLSv1} }
100
+
101
+ it "sets ssl version" do
102
+ subject.ssl_version.should == :TLSv1
103
+ end
104
+ end if RUBY_VERSION > '1.9'
105
+ end
106
+
107
+ context "when dealing with IPv6" do
108
+ let(:uri) { URI 'http://[fd00::1]' }
109
+
110
+ it "strips brackets from the address" do
111
+ subject.address.should == 'fd00::1'
112
+ end
113
+ end
114
+
115
+ context "specifying ciphers" do
116
+ let(:options) { {ciphers: 'RC4-SHA' } }
117
+
118
+ it "should set the ciphers on the connection" do
119
+ subject.ciphers.should == 'RC4-SHA'
120
+ end
121
+ end if RUBY_VERSION > '1.9'
122
+
123
+ context "when timeout is not set" do
124
+ it "doesn't set the timeout" do
125
+ http = mock("http", null_object: true)
126
+ http.should_not_receive(:open_timeout=)
127
+ http.should_not_receive(:read_timeout=)
128
+ Net::HTTP.stub(new: http)
129
+
130
+ adapter.connection
131
+ end
132
+ end
133
+
134
+ context "when setting timeout" do
135
+ context "to 5 seconds" do
136
+ let(:options) { {timeout: 5} }
137
+
138
+ its(:open_timeout) { should == 5 }
139
+ its(:read_timeout) { should == 5 }
140
+ end
141
+
142
+ context "and timeout is a string" do
143
+ let(:options) { {timeout: "five seconds"} }
144
+
145
+ it "doesn't set the timeout" do
146
+ http = mock("http", null_object: true)
147
+ http.should_not_receive(:open_timeout=)
148
+ http.should_not_receive(:read_timeout=)
149
+ Net::HTTP.stub(new: http)
150
+
151
+ adapter.connection
152
+ end
153
+ end
154
+ end
155
+
156
+ context "when timeout is not set and read_timeout is set to 6 seconds" do
157
+ let(:options) { {read_timeout: 6} }
158
+
159
+ its(:read_timeout) { should == 6 }
160
+
161
+ it "should not set the open_timeout" do
162
+ http = mock("http", null_object: true)
163
+ http.should_not_receive(:open_timeout=)
164
+ Net::HTTP.stub(new: http)
165
+ adapter.connection
166
+ end
167
+ end
168
+
169
+ context "when timeout is set and read_timeout is set to 6 seconds" do
170
+ let(:options) { {timeout: 5, read_timeout: 6} }
171
+
172
+ its(:open_timeout) { should == 5 }
173
+ its(:read_timeout) { should == 6 }
174
+
175
+ it "should override the timeout option" do
176
+ http = mock("http", null_object: true)
177
+ http.should_receive(:open_timeout=)
178
+ http.should_receive(:read_timeout=).twice
179
+ Net::HTTP.stub(new: http)
180
+ adapter.connection
181
+ end
182
+ end
183
+
184
+ context "when timeout is not set and open_timeout is set to 7 seconds" do
185
+ let(:options) { {open_timeout: 7} }
186
+
187
+ its(:open_timeout) { should == 7 }
188
+
189
+ it "should not set the read_timeout" do
190
+ http = mock("http", null_object: true)
191
+ http.should_not_receive(:read_timeout=)
192
+ Net::HTTP.stub(new: http)
193
+ adapter.connection
194
+ end
195
+ end
196
+
197
+ context "when timeout is set and open_timeout is set to 7 seconds" do
198
+ let(:options) { {timeout: 5, open_timeout: 7} }
199
+
200
+ its(:open_timeout) { should == 7 }
201
+ its(:read_timeout) { should == 5 }
202
+
203
+ it "should override the timeout option" do
204
+ http = mock("http", null_object: true)
205
+ http.should_receive(:open_timeout=).twice
206
+ http.should_receive(:read_timeout=)
207
+ Net::HTTP.stub(new: http)
208
+ adapter.connection
209
+ end
210
+ end
211
+
212
+ context "when debug_output" do
213
+ let(:http) { Net::HTTP.new(uri) }
214
+ before do
215
+ Net::HTTP.stub(new: http)
216
+ end
217
+
218
+ context "is set to $stderr" do
219
+ let(:options) { {debug_output: $stderr} }
220
+ it "has debug output set" do
221
+ http.should_receive(:set_debug_output).with($stderr)
222
+ adapter.connection
223
+ end
224
+ end
225
+
226
+ context "is not provided" do
227
+ it "does not set_debug_output" do
228
+ http.should_not_receive(:set_debug_output)
229
+ adapter.connection
230
+ end
231
+ end
232
+ end
233
+
234
+ context 'when providing proxy address and port' do
235
+ let(:options) { {http_proxyaddr: '1.2.3.4', http_proxyport: 8080} }
236
+
237
+ it { should be_a_proxy }
238
+ its(:proxy_address) { should == '1.2.3.4' }
239
+ its(:proxy_port) { should == 8080 }
240
+
241
+ context 'as well as proxy user and password' do
242
+ let(:options) do
243
+ {http_proxyaddr: '1.2.3.4', http_proxyport: 8080,
244
+ http_proxyuser: 'user', http_proxypass: 'pass'}
245
+ end
246
+ its(:proxy_user) { should == 'user' }
247
+ its(:proxy_pass) { should == 'pass' }
248
+ end
249
+ end
250
+
251
+ context 'when not providing a proxy address' do
252
+ let(:uri) { URI 'http://proxytest.com' }
253
+
254
+ it "does not pass any proxy parameters to the connection" do
255
+ http = Net::HTTP.new("proxytest.com")
256
+ Net::HTTP.should_receive(:new).once.with("proxytest.com", 80).and_return(http)
257
+ adapter.connection
258
+ end
259
+ end
260
+
261
+ context 'when providing a local bind address and port' do
262
+ let(:options) { {local_host: "127.0.0.1", local_port: 12345 } }
263
+
264
+ its(:local_host) { should == '127.0.0.1' }
265
+ its(:local_port) { should == 12345 }
266
+ end if RUBY_VERSION >= '2.0'
267
+
268
+ context "when providing PEM certificates" do
269
+ let(:pem) { :pem_contents }
270
+ let(:options) { {pem: pem, pem_password: "password"} }
271
+
272
+ context "when scheme is https" do
273
+ let(:uri) { URI 'https://google.com' }
274
+ let(:cert) { mock("OpenSSL::X509::Certificate") }
275
+ let(:key) { mock("OpenSSL::PKey::RSA") }
276
+
277
+ before do
278
+ OpenSSL::X509::Certificate.should_receive(:new).with(pem).and_return(cert)
279
+ OpenSSL::PKey::RSA.should_receive(:new).with(pem, "password").and_return(key)
280
+ end
281
+
282
+ it "uses the provided PEM certificate" do
283
+ subject.cert.should == cert
284
+ subject.key.should == key
285
+ end
286
+
287
+ it "will verify the certificate" do
288
+ subject.verify_mode.should == OpenSSL::SSL::VERIFY_PEER
289
+ end
290
+
291
+ context "when options include verify_peer=false" do
292
+ let(:options) { {pem: pem, pem_password: "password", verify_peer: false} }
293
+
294
+ it "should not verify the certificate" do
295
+ subject.verify_mode.should == OpenSSL::SSL::VERIFY_NONE
296
+ end
297
+ end
298
+ end
299
+
300
+ context "when scheme is not https" do
301
+ let(:uri) { URI 'http://google.com' }
302
+ let(:http) { Net::HTTP.new(uri) }
303
+
304
+ before do
305
+ Net::HTTP.stub(new: http)
306
+ OpenSSL::X509::Certificate.should_not_receive(:new).with(pem)
307
+ OpenSSL::PKey::RSA.should_not_receive(:new).with(pem, "password")
308
+ http.should_not_receive(:cert=)
309
+ http.should_not_receive(:key=)
310
+ end
311
+
312
+ it "has no PEM certificate " do
313
+ subject.cert.should be_nil
314
+ subject.key.should be_nil
315
+ end
316
+ end
317
+ end
318
+
319
+ context "when providing PKCS12 certificates" do
320
+ let(:p12) { :p12_contents }
321
+ let(:options) { {p12: p12, p12_password: "password"} }
322
+
323
+ context "when scheme is https" do
324
+ let(:uri) { URI 'https://google.com' }
325
+ let(:pkcs12) { mock("OpenSSL::PKCS12", certificate: cert, key: key) }
326
+ let(:cert) { mock("OpenSSL::X509::Certificate") }
327
+ let(:key) { mock("OpenSSL::PKey::RSA") }
328
+
329
+ before do
330
+ OpenSSL::PKCS12.should_receive(:new).with(p12, "password").and_return(pkcs12)
331
+ end
332
+
333
+ it "uses the provided P12 certificate " do
334
+ subject.cert.should == cert
335
+ subject.key.should == key
336
+ end
337
+
338
+ it "will verify the certificate" do
339
+ subject.verify_mode.should == OpenSSL::SSL::VERIFY_PEER
340
+ end
341
+
342
+ context "when options include verify_peer=false" do
343
+ let(:options) { {p12: p12, p12_password: "password", verify_peer: false} }
344
+
345
+ it "should not verify the certificate" do
346
+ subject.verify_mode.should == OpenSSL::SSL::VERIFY_NONE
347
+ end
348
+ end
349
+ end
350
+
351
+ context "when scheme is not https" do
352
+ let(:uri) { URI 'http://google.com' }
353
+ let(:http) { Net::HTTP.new(uri) }
354
+
355
+ before do
356
+ Net::HTTP.stub(new: http)
357
+ OpenSSL::PKCS12.new.should_not_receive(:new).with(p12, "password")
358
+ http.should_not_receive(:cert=)
359
+ http.should_not_receive(:key=)
360
+ end
361
+
362
+ it "has no PKCS12 certificate " do
363
+ subject.cert.should be_nil
364
+ subject.key.should be_nil
365
+ end
366
+ end
367
+ end
368
+ end
369
+ end
370
+ end
@@ -0,0 +1,83 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '../spec_helper'))
2
+
3
+ describe HTTParty::CookieHash do
4
+ before(:each) do
5
+ @cookie_hash = HTTParty::CookieHash.new
6
+ end
7
+
8
+ describe "#add_cookies" do
9
+ describe "with a hash" do
10
+ it "should add new key/value pairs to the hash" do
11
+ @cookie_hash.add_cookies(foo: "bar")
12
+ @cookie_hash.add_cookies(rofl: "copter")
13
+ @cookie_hash.length.should eql(2)
14
+ end
15
+
16
+ it "should overwrite any existing key" do
17
+ @cookie_hash.add_cookies(foo: "bar")
18
+ @cookie_hash.add_cookies(foo: "copter")
19
+ @cookie_hash.length.should eql(1)
20
+ @cookie_hash[:foo].should eql("copter")
21
+ end
22
+ end
23
+
24
+ describe "with a string" do
25
+ it "should add new key/value pairs to the hash" do
26
+ @cookie_hash.add_cookies("first=one; second=two; third")
27
+ @cookie_hash[:first].should == 'one'
28
+ @cookie_hash[:second].should == 'two'
29
+ @cookie_hash[:third].should == nil
30
+ end
31
+
32
+ it "should overwrite any existing key" do
33
+ @cookie_hash[:foo] = 'bar'
34
+ @cookie_hash.add_cookies("foo=tar")
35
+ @cookie_hash.length.should eql(1)
36
+ @cookie_hash[:foo].should eql("tar")
37
+ end
38
+
39
+ it "should handle '=' within cookie value" do
40
+ @cookie_hash.add_cookies("first=one=1; second=two=2==")
41
+ @cookie_hash.keys.should include(:first, :second)
42
+ @cookie_hash[:first].should == 'one=1'
43
+ @cookie_hash[:second].should == 'two=2=='
44
+ end
45
+ end
46
+
47
+ describe 'with other class' do
48
+ it "should error" do
49
+ lambda {
50
+ @cookie_hash.add_cookies(Array.new)
51
+ }.should raise_error
52
+ end
53
+ end
54
+ end
55
+
56
+ # The regexen are required because Hashes aren't ordered, so a test against
57
+ # a hardcoded string was randomly failing.
58
+ describe "#to_cookie_string" do
59
+ before(:each) do
60
+ @cookie_hash.add_cookies(foo: "bar")
61
+ @cookie_hash.add_cookies(rofl: "copter")
62
+ @s = @cookie_hash.to_cookie_string
63
+ end
64
+
65
+ it "should format the key/value pairs, delimited by semi-colons" do
66
+ @s.should match(/foo=bar/)
67
+ @s.should match(/rofl=copter/)
68
+ @s.should match(/^\w+=\w+; \w+=\w+$/)
69
+ end
70
+
71
+ it "should not include client side only cookies" do
72
+ @cookie_hash.add_cookies(path: "/")
73
+ @s = @cookie_hash.to_cookie_string
74
+ @s.should_not match(/path=\//)
75
+ end
76
+
77
+ it "should not include client side only cookies even when attributes use camal case" do
78
+ @cookie_hash.add_cookies(Path: "/")
79
+ @s = @cookie_hash.to_cookie_string
80
+ @s.should_not match(/Path=\//)
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,23 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
2
+
3
+ describe HTTParty::Error do
4
+ subject { described_class }
5
+
6
+ its(:ancestors) { should include(StandardError) }
7
+
8
+ describe HTTParty::UnsupportedFormat do
9
+ its(:ancestors) { should include(HTTParty::Error) }
10
+ end
11
+
12
+ describe HTTParty::UnsupportedURIScheme do
13
+ its(:ancestors) { should include(HTTParty::Error) }
14
+ end
15
+
16
+ describe HTTParty::ResponseError do
17
+ its(:ancestors) { should include(HTTParty::Error) }
18
+ end
19
+
20
+ describe HTTParty::RedirectionTooDeep do
21
+ its(:ancestors) { should include(HTTParty::ResponseError) }
22
+ end
23
+ end
@@ -0,0 +1,41 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'spec_helper'))
2
+
3
+ describe HTTParty::Logger::ApacheLogger do
4
+ let(:subject) { described_class.new(logger_double, :info) }
5
+ let(:logger_double) { double('Logger') }
6
+ let(:request_double) { double('Request', http_method: Net::HTTP::Get, path: "http://my.domain.com/my_path") }
7
+ let(:request_time) { Time.new.strftime("%Y-%m-%d %H:%M:%S %z") }
8
+
9
+ before do
10
+ subject.current_time = request_time
11
+ logger_double.should_receive(:info).with(log_message)
12
+ end
13
+
14
+ describe "#format" do
15
+ let(:log_message) { "[HTTParty] [#{request_time}] 302 \"GET http://my.domain.com/my_path\" - " }
16
+
17
+ it "formats a response in a style that resembles apache's access log" do
18
+ response_double = double(
19
+ code: 302,
20
+ :[] => nil
21
+ )
22
+
23
+ subject.format(request_double, response_double)
24
+ end
25
+
26
+ context 'when there is a parsed response' do
27
+ let(:log_message) { "[HTTParty] [#{request_time}] 200 \"GET http://my.domain.com/my_path\" 512 "}
28
+
29
+ it "can handle the Content-Length header" do
30
+ # Simulate a parsed response that is an array, where accessing a string key will raise an error. See Issue #299.
31
+ response_double = double(
32
+ code: 200,
33
+ headers: { 'Content-Length' => 512 }
34
+ )
35
+ response_double.stub(:[]).with('Content-Length').and_raise(TypeError.new('no implicit conversion of String into Integer'))
36
+
37
+ subject.format(request_double, response_double)
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,18 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'spec_helper'))
2
+
3
+ describe HTTParty::Logger::CurlLogger do
4
+ describe "#format" do
5
+ it "formats a response in a style that resembles a -v curl" do
6
+ logger_double = double
7
+ logger_double.should_receive(:info).with(
8
+ /\[HTTParty\] \[\d{4}-\d\d-\d\d \d\d:\d\d:\d\d\ [+-]\d{4}\] > GET http:\/\/localhost/)
9
+
10
+ subject = described_class.new(logger_double, :info)
11
+
12
+ stub_http_response_with("google.html")
13
+
14
+ response = HTTParty::Request.new.perform
15
+ subject.format(response.request, response)
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,22 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'spec_helper'))
2
+
3
+ describe HTTParty::Logger do
4
+ describe ".build" do
5
+ subject { HTTParty::Logger }
6
+
7
+ it "defaults level to :info" do
8
+ logger_double = double()
9
+ subject.build(logger_double, nil, nil).level.should == :info
10
+ end
11
+
12
+ it "defaults format to :apache" do
13
+ logger_double = double()
14
+ subject.build(logger_double, nil, nil).should be_an_instance_of(HTTParty::Logger::ApacheLogger)
15
+ end
16
+
17
+ it "builds :curl style logger" do
18
+ logger_double = double()
19
+ subject.build(logger_double, nil, :curl).should be_an_instance_of(HTTParty::Logger::CurlLogger)
20
+ end
21
+ end
22
+ end