jugend-httparty 0.5.2.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 (54) hide show
  1. data/.gitignore +7 -0
  2. data/History +209 -0
  3. data/MIT-LICENSE +20 -0
  4. data/Manifest +47 -0
  5. data/README.rdoc +54 -0
  6. data/Rakefile +80 -0
  7. data/VERSION +1 -0
  8. data/bin/httparty +108 -0
  9. data/cucumber.yml +1 -0
  10. data/examples/aaws.rb +32 -0
  11. data/examples/basic.rb +11 -0
  12. data/examples/custom_parsers.rb +67 -0
  13. data/examples/delicious.rb +37 -0
  14. data/examples/google.rb +16 -0
  15. data/examples/rubyurl.rb +14 -0
  16. data/examples/twitter.rb +31 -0
  17. data/examples/whoismyrep.rb +10 -0
  18. data/features/basic_authentication.feature +20 -0
  19. data/features/command_line.feature +7 -0
  20. data/features/deals_with_http_error_codes.feature +26 -0
  21. data/features/handles_multiple_formats.feature +34 -0
  22. data/features/steps/env.rb +23 -0
  23. data/features/steps/httparty_response_steps.rb +26 -0
  24. data/features/steps/httparty_steps.rb +27 -0
  25. data/features/steps/mongrel_helper.rb +78 -0
  26. data/features/steps/remote_service_steps.rb +61 -0
  27. data/features/supports_redirection.feature +22 -0
  28. data/features/supports_timeout_option.feature +13 -0
  29. data/jugend-httparty.gemspec +127 -0
  30. data/lib/httparty/cookie_hash.rb +22 -0
  31. data/lib/httparty/core_extensions.rb +31 -0
  32. data/lib/httparty/exceptions.rb +26 -0
  33. data/lib/httparty/module_inheritable_attributes.rb +25 -0
  34. data/lib/httparty/parser.rb +141 -0
  35. data/lib/httparty/request.rb +206 -0
  36. data/lib/httparty/response.rb +62 -0
  37. data/lib/httparty.rb +343 -0
  38. data/spec/fixtures/delicious.xml +23 -0
  39. data/spec/fixtures/empty.xml +0 -0
  40. data/spec/fixtures/google.html +3 -0
  41. data/spec/fixtures/twitter.json +1 -0
  42. data/spec/fixtures/twitter.xml +403 -0
  43. data/spec/fixtures/undefined_method_add_node_for_nil.xml +2 -0
  44. data/spec/httparty/cookie_hash_spec.rb +71 -0
  45. data/spec/httparty/parser_spec.rb +154 -0
  46. data/spec/httparty/request_spec.rb +415 -0
  47. data/spec/httparty/response_spec.rb +83 -0
  48. data/spec/httparty_spec.rb +514 -0
  49. data/spec/spec.opts +3 -0
  50. data/spec/spec_helper.rb +19 -0
  51. data/spec/support/stub_response.rb +30 -0
  52. data/website/css/common.css +47 -0
  53. data/website/index.html +73 -0
  54. metadata +209 -0
@@ -0,0 +1,514 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), 'spec_helper'))
2
+
3
+ class CustomParser
4
+ def self.parse(body)
5
+ return {:sexy => true}
6
+ end
7
+ end
8
+
9
+ describe HTTParty do
10
+ before(:each) do
11
+ @klass = Class.new
12
+ @klass.instance_eval { include HTTParty }
13
+ end
14
+
15
+ describe "AllowedFormats deprecated" do
16
+ before do
17
+ Kernel.stub(:warn)
18
+ end
19
+ it "warns with a deprecation message" do
20
+ Kernel.should_receive(:warn).with("Deprecated: Use HTTParty::Parser::SupportedFormats")
21
+ HTTParty::AllowedFormats
22
+ end
23
+
24
+ it "returns HTTPart::Parser::SupportedFormats" do
25
+ HTTParty::AllowedFormats.should == HTTParty::Parser::SupportedFormats
26
+ end
27
+ end
28
+
29
+ describe "base uri" do
30
+ before(:each) do
31
+ @klass.base_uri('api.foo.com/v1')
32
+ end
33
+
34
+ it "should have reader" do
35
+ @klass.base_uri.should == 'http://api.foo.com/v1'
36
+ end
37
+
38
+ it 'should have writer' do
39
+ @klass.base_uri('http://api.foobar.com')
40
+ @klass.base_uri.should == 'http://api.foobar.com'
41
+ end
42
+
43
+ it 'should not modify the parameter during assignment' do
44
+ uri = 'http://api.foobar.com'
45
+ @klass.base_uri(uri)
46
+ uri.should == 'http://api.foobar.com'
47
+ end
48
+ end
49
+
50
+ describe "#normalize_base_uri" do
51
+ it "should add http if not present for non ssl requests" do
52
+ uri = HTTParty.normalize_base_uri('api.foobar.com')
53
+ uri.should == 'http://api.foobar.com'
54
+ end
55
+
56
+ it "should add https if not present for ssl requests" do
57
+ uri = HTTParty.normalize_base_uri('api.foo.com/v1:443')
58
+ uri.should == 'https://api.foo.com/v1:443'
59
+ end
60
+
61
+ it "should not remove https for ssl requests" do
62
+ uri = HTTParty.normalize_base_uri('https://api.foo.com/v1:443')
63
+ uri.should == 'https://api.foo.com/v1:443'
64
+ end
65
+
66
+ it 'should not modify the parameter' do
67
+ uri = 'http://api.foobar.com'
68
+ HTTParty.normalize_base_uri(uri)
69
+ uri.should == 'http://api.foobar.com'
70
+ end
71
+ end
72
+
73
+ describe "headers" do
74
+ def expect_headers(header={})
75
+ HTTParty::Request.should_receive(:new) \
76
+ .with(anything, anything, hash_including({ :headers => header })) \
77
+ .and_return(mock("mock response", :perform => nil))
78
+ end
79
+
80
+ it "should default to empty hash" do
81
+ @klass.headers.should == {}
82
+ end
83
+
84
+ it "should be able to be updated" do
85
+ init_headers = {:foo => 'bar', :baz => 'spax'}
86
+ @klass.headers init_headers
87
+ @klass.headers.should == init_headers
88
+ end
89
+
90
+ it "uses the class headers when sending a request" do
91
+ expect_headers(:foo => 'bar')
92
+ @klass.headers(:foo => 'bar')
93
+ @klass.get('')
94
+ end
95
+
96
+ it "overwrites class headers when passing in headers" do
97
+ expect_headers(:baz => 'spax')
98
+ @klass.headers(:foo => 'bar')
99
+ @klass.get('', :headers => {:baz => 'spax'})
100
+ end
101
+
102
+ context "with cookies" do
103
+ it 'utilizes the class-level cookies' do
104
+ expect_headers(:foo => 'bar', 'cookie' => 'type=snickerdoodle')
105
+ @klass.headers(:foo => 'bar')
106
+ @klass.cookies(:type => 'snickerdoodle')
107
+ @klass.get('')
108
+ end
109
+
110
+ it 'adds cookies to the headers' do
111
+ expect_headers(:foo => 'bar', 'cookie' => 'type=snickerdoodle')
112
+ @klass.headers(:foo => 'bar')
113
+ @klass.get('', :cookies => {:type => 'snickerdoodle'})
114
+ end
115
+
116
+ it 'adds optional cookies to the optional headers' do
117
+ expect_headers(:baz => 'spax', 'cookie' => 'type=snickerdoodle')
118
+ @klass.get('', :cookies => {:type => 'snickerdoodle'}, :headers => {:baz => 'spax'})
119
+ end
120
+ end
121
+ end
122
+
123
+ describe "cookies" do
124
+ def expect_cookie_header(s)
125
+ HTTParty::Request.should_receive(:new) \
126
+ .with(anything, anything, hash_including({ :headers => { "cookie" => s } })) \
127
+ .and_return(mock("mock response", :perform => nil))
128
+ end
129
+
130
+ it "should not be in the headers by default" do
131
+ HTTParty::Request.stub!(:new).and_return(stub(nil, :perform => nil))
132
+ @klass.get("")
133
+ @klass.headers.keys.should_not include("cookie")
134
+ end
135
+
136
+ it "should raise an ArgumentError if passed a non-Hash" do
137
+ lambda do
138
+ @klass.cookies("nonsense")
139
+ end.should raise_error(ArgumentError)
140
+ end
141
+
142
+ it "should allow a cookie to be specified with a one-off request" do
143
+ expect_cookie_header "type=snickerdoodle"
144
+ @klass.get("", :cookies => { :type => "snickerdoodle" })
145
+ end
146
+
147
+ describe "when a cookie is set at the class level" do
148
+ before(:each) do
149
+ @klass.cookies({ :type => "snickerdoodle" })
150
+ end
151
+
152
+ it "should include that cookie in the request" do
153
+ expect_cookie_header "type=snickerdoodle"
154
+ @klass.get("")
155
+ end
156
+
157
+ it "should pass the proper cookies when requested multiple times" do
158
+ 2.times do
159
+ expect_cookie_header "type=snickerdoodle"
160
+ @klass.get("")
161
+ end
162
+ end
163
+
164
+ it "should allow the class defaults to be overridden" do
165
+ expect_cookie_header "type=chocolate_chip"
166
+
167
+ @klass.get("", :cookies => { :type => "chocolate_chip" })
168
+ end
169
+ end
170
+
171
+ describe "in a class with multiple methods that use different cookies" do
172
+ before(:each) do
173
+ @klass.instance_eval do
174
+ def first_method
175
+ get("first_method", :cookies => { :first_method_cookie => "foo" })
176
+ end
177
+
178
+ def second_method
179
+ get("second_method", :cookies => { :second_method_cookie => "foo" })
180
+ end
181
+ end
182
+ end
183
+
184
+ it "should not allow cookies used in one method to carry over into other methods" do
185
+ expect_cookie_header "first_method_cookie=foo"
186
+ @klass.first_method
187
+
188
+ expect_cookie_header "second_method_cookie=foo"
189
+ @klass.second_method
190
+ end
191
+ end
192
+ end
193
+
194
+ describe "default params" do
195
+ it "should default to empty hash" do
196
+ @klass.default_params.should == {}
197
+ end
198
+
199
+ it "should be able to be updated" do
200
+ new_defaults = {:foo => 'bar', :baz => 'spax'}
201
+ @klass.default_params new_defaults
202
+ @klass.default_params.should == new_defaults
203
+ end
204
+ end
205
+
206
+ describe "default timeout" do
207
+ it "should default to nil" do
208
+ @klass.default_options[:timeout].should == nil
209
+ end
210
+
211
+ it "should support updating" do
212
+ @klass.default_timeout 10
213
+ @klass.default_options[:timeout].should == 10
214
+ end
215
+ end
216
+
217
+ describe "debug_output" do
218
+ it "stores the given stream as a default_option" do
219
+ @klass.debug_output $stdout
220
+ @klass.default_options[:debug_output].should == $stdout
221
+ end
222
+
223
+ it "stores the $stderr stream by default" do
224
+ @klass.debug_output
225
+ @klass.default_options[:debug_output].should == $stderr
226
+ end
227
+ end
228
+
229
+ describe "basic http authentication" do
230
+ it "should work" do
231
+ @klass.basic_auth 'foobar', 'secret'
232
+ @klass.default_options[:basic_auth].should == {:username => 'foobar', :password => 'secret'}
233
+ end
234
+ end
235
+
236
+ describe "digest http authentication" do
237
+ it "should work" do
238
+ @klass.digest_auth 'foobar', 'secret'
239
+ @klass.default_options[:digest_auth].should == {:username => 'foobar', :password => 'secret'}
240
+ end
241
+ end
242
+
243
+ describe "parser" do
244
+ let(:parser) do
245
+ Proc.new{ |data, format| CustomParser.parse(data) }
246
+ end
247
+
248
+ it "should set parser options" do
249
+ @klass.parser parser
250
+ @klass.default_options[:parser].should == parser
251
+ end
252
+
253
+ it "should be able parse response with custom parser" do
254
+ @klass.parser parser
255
+ FakeWeb.register_uri(:get, 'http://twitter.com/statuses/public_timeline.xml', :body => 'tweets')
256
+ custom_parsed_response = @klass.get('http://twitter.com/statuses/public_timeline.xml')
257
+ custom_parsed_response[:sexy].should == true
258
+ end
259
+
260
+ it "raises UnsupportedFormat when the parser cannot handle the format" do
261
+ @klass.format :json
262
+ class MyParser < HTTParty::Parser
263
+ SupportedFormats = {}
264
+ end unless defined?(MyParser)
265
+ expect do
266
+ @klass.parser MyParser
267
+ end.to raise_error(HTTParty::UnsupportedFormat)
268
+ end
269
+
270
+ it 'does not validate format whe custom parser is a proc' do
271
+ expect do
272
+ @klass.format :json
273
+ @klass.parser lambda {|body, format|}
274
+ end.to_not raise_error(HTTParty::UnsupportedFormat)
275
+ end
276
+ end
277
+
278
+ describe "format" do
279
+ it "should allow xml" do
280
+ @klass.format :xml
281
+ @klass.default_options[:format].should == :xml
282
+ end
283
+
284
+ it "should allow json" do
285
+ @klass.format :json
286
+ @klass.default_options[:format].should == :json
287
+ end
288
+
289
+ it "should allow yaml" do
290
+ @klass.format :yaml
291
+ @klass.default_options[:format].should == :yaml
292
+ end
293
+
294
+ it "should allow plain" do
295
+ @klass.format :plain
296
+ @klass.default_options[:format].should == :plain
297
+ end
298
+
299
+ it 'should not allow funky format' do
300
+ lambda do
301
+ @klass.format :foobar
302
+ end.should raise_error(HTTParty::UnsupportedFormat)
303
+ end
304
+
305
+ it 'should only print each format once with an exception' do
306
+ lambda do
307
+ @klass.format :foobar
308
+ end.should raise_error(HTTParty::UnsupportedFormat, "':foobar' Must be one of: html, json, plain, xml, yaml")
309
+ end
310
+
311
+ it 'sets the default parser' do
312
+ @klass.default_options[:parser].should be_nil
313
+ @klass.format :json
314
+ @klass.default_options[:parser].should == HTTParty::Parser
315
+ end
316
+
317
+ it 'does not reset parser to the default parser' do
318
+ my_parser = lambda {}
319
+ @klass.parser my_parser
320
+ @klass.format :json
321
+ @klass.parser.should == my_parser
322
+ end
323
+ end
324
+
325
+ describe "#no_follow" do
326
+ it "sets no_follow to false by default" do
327
+ @klass.no_follow
328
+ @klass.default_options[:no_follow].should be_false
329
+ end
330
+
331
+ it "sets the no_follow option to true" do
332
+ @klass.no_follow true
333
+ @klass.default_options[:no_follow].should be_true
334
+ end
335
+ end
336
+
337
+ describe "#maintain_method_across_redirects" do
338
+ it "sets maintain_method_across_redirects to true by default" do
339
+ @klass.maintain_method_across_redirects
340
+ @klass.default_options[:maintain_method_across_redirects].should be_true
341
+ end
342
+
343
+ it "sets the maintain_method_across_redirects option to false" do
344
+ @klass.maintain_method_across_redirects false
345
+ @klass.default_options[:maintain_method_across_redirects].should be_false
346
+ end
347
+ end
348
+
349
+ describe "with explicit override of automatic redirect handling" do
350
+ before do
351
+ @request = HTTParty::Request.new(Net::HTTP::Get, 'http://api.foo.com/v1', :format => :xml, :no_follow => true)
352
+ @redirect = stub_response 'first redirect', 302
353
+ @redirect['location'] = 'http://foo.com/bar'
354
+ HTTParty::Request.stub(:new => @request)
355
+ end
356
+
357
+ it "should fail with redirected GET" do
358
+ lambda do
359
+ @error = @klass.get('/foo', :no_follow => true)
360
+ end.should raise_error(HTTParty::RedirectionTooDeep) {|e| e.response.body.should == 'first redirect'}
361
+ end
362
+
363
+ it "should fail with redirected POST" do
364
+ lambda do
365
+ @klass.post('/foo', :no_follow => true)
366
+ end.should raise_error(HTTParty::RedirectionTooDeep) {|e| e.response.body.should == 'first redirect'}
367
+ end
368
+
369
+ it "should fail with redirected DELETE" do
370
+ lambda do
371
+ @klass.delete('/foo', :no_follow => true)
372
+ end.should raise_error(HTTParty::RedirectionTooDeep) {|e| e.response.body.should == 'first redirect'}
373
+ end
374
+
375
+ it "should fail with redirected PUT" do
376
+ lambda do
377
+ @klass.put('/foo', :no_follow => true)
378
+ end.should raise_error(HTTParty::RedirectionTooDeep) {|e| e.response.body.should == 'first redirect'}
379
+ end
380
+
381
+ it "should fail with redirected HEAD" do
382
+ lambda do
383
+ @klass.head('/foo', :no_follow => true)
384
+ end.should raise_error(HTTParty::RedirectionTooDeep) {|e| e.response.body.should == 'first redirect'}
385
+ end
386
+
387
+ it "should fail with redirected OPTIONS" do
388
+ lambda do
389
+ @klass.options('/foo', :no_follow => true)
390
+ end.should raise_error(HTTParty::RedirectionTooDeep) {|e| e.response.body.should == 'first redirect'}
391
+ end
392
+ end
393
+
394
+ describe "with multiple class definitions" do
395
+ before(:each) do
396
+ @klass.instance_eval do
397
+ base_uri "http://first.com"
398
+ default_params :one => 1
399
+ end
400
+
401
+ @additional_klass = Class.new
402
+ @additional_klass.instance_eval do
403
+ include HTTParty
404
+ base_uri "http://second.com"
405
+ default_params :two => 2
406
+ end
407
+ end
408
+
409
+ it "should not run over each others options" do
410
+ @klass.default_options.should == { :base_uri => 'http://first.com', :default_params => { :one => 1 } }
411
+ @additional_klass.default_options.should == { :base_uri => 'http://second.com', :default_params => { :two => 2 } }
412
+ end
413
+ end
414
+
415
+ describe "two child classes inheriting from one parent" do
416
+ before(:each) do
417
+ @parent = Class.new do
418
+ include HTTParty
419
+ end
420
+
421
+ @child1 = Class.new(@parent)
422
+ @child2 = Class.new(@parent)
423
+ end
424
+
425
+ it "does not modify each others inherited attributes" do
426
+ @child1.default_params :joe => "alive"
427
+ @child2.default_params :joe => "dead"
428
+
429
+ @child1.default_options.should == { :default_params => {:joe => "alive"} }
430
+ @child2.default_options.should == { :default_params => {:joe => "dead"} }
431
+
432
+ @parent.default_options.should == { }
433
+ end
434
+ end
435
+
436
+ describe "#get" do
437
+ it "should be able to get html" do
438
+ stub_http_response_with('google.html')
439
+ HTTParty.get('http://www.google.com').should == file_fixture('google.html')
440
+ end
441
+
442
+ it "should be able parse response type json automatically" do
443
+ stub_http_response_with('twitter.json')
444
+ tweets = HTTParty.get('http://twitter.com/statuses/public_timeline.json')
445
+ tweets.size.should == 20
446
+ tweets.first['user'].should == {
447
+ "name" => "Pyk",
448
+ "url" => nil,
449
+ "id" => "7694602",
450
+ "description" => nil,
451
+ "protected" => false,
452
+ "screen_name" => "Pyk",
453
+ "followers_count" => 1,
454
+ "location" => "Opera Plaza, California",
455
+ "profile_image_url" => "http://static.twitter.com/images/default_profile_normal.png"
456
+ }
457
+ end
458
+
459
+ it "should be able parse response type xml automatically" do
460
+ stub_http_response_with('twitter.xml')
461
+ tweets = HTTParty.get('http://twitter.com/statuses/public_timeline.xml')
462
+ tweets['statuses'].size.should == 20
463
+ tweets['statuses'].first['user'].should == {
464
+ "name" => "Magic 8 Bot",
465
+ "url" => nil,
466
+ "id" => "17656026",
467
+ "description" => "ask me a question",
468
+ "protected" => "false",
469
+ "screen_name" => "magic8bot",
470
+ "followers_count" => "90",
471
+ "profile_image_url" => "http://s3.amazonaws.com/twitter_production/profile_images/65565851/8ball_large_normal.jpg",
472
+ "location" => nil
473
+ }
474
+ end
475
+
476
+ it "should not get undefined method add_node for nil class for the following xml" do
477
+ stub_http_response_with('undefined_method_add_node_for_nil.xml')
478
+ result = HTTParty.get('http://foobar.com')
479
+ result.should == {"Entities"=>{"href"=>"https://s3-sandbox.parature.com/api/v1/5578/5633/Account", "results"=>"0", "total"=>"0", "page_size"=>"25", "page"=>"1"}}
480
+ end
481
+
482
+ it "should parse empty response fine" do
483
+ stub_http_response_with('empty.xml')
484
+ result = HTTParty.get('http://foobar.com')
485
+ result.should be_nil
486
+ end
487
+
488
+ it "should accept http URIs" do
489
+ stub_http_response_with('google.html')
490
+ lambda do
491
+ HTTParty.get('http://google.com')
492
+ end.should_not raise_error(HTTParty::UnsupportedURIScheme)
493
+ end
494
+
495
+ it "should accept https URIs" do
496
+ stub_http_response_with('google.html')
497
+ lambda do
498
+ HTTParty.get('https://google.com')
499
+ end.should_not raise_error(HTTParty::UnsupportedURIScheme)
500
+ end
501
+
502
+ it "should raise an ArgumentError on URIs that are not http or https" do
503
+ lambda do
504
+ HTTParty.get("file:///there_is_no_party_on/my/filesystem")
505
+ end.should raise_error(HTTParty::UnsupportedURIScheme)
506
+ end
507
+
508
+ it "should raise an InvalidURIError on URIs that can't be parsed at all" do
509
+ lambda do
510
+ HTTParty.get("It's the one that says 'Bad URI'")
511
+ end.should raise_error(URI::InvalidURIError)
512
+ end
513
+ end
514
+ end
data/spec/spec.opts ADDED
@@ -0,0 +1,3 @@
1
+ --colour
2
+ --format specdoc
3
+ --backtrace
@@ -0,0 +1,19 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'lib', 'httparty')
2
+ require 'spec/autorun'
3
+ require 'fakeweb'
4
+
5
+ def file_fixture(filename)
6
+ open(File.join(File.dirname(__FILE__), 'fixtures', "#{filename.to_s}")).read
7
+ end
8
+
9
+ Dir[File.expand_path(File.join(File.dirname(__FILE__),'support','**','*.rb'))].each {|f| require f}
10
+
11
+ Spec::Runner.configure do |config|
12
+ config.include HTTParty::StubResponse
13
+ config.before(:suite) do
14
+ FakeWeb.allow_net_connect = false
15
+ end
16
+ config.after(:suite) do
17
+ FakeWeb.allow_net_connect = true
18
+ end
19
+ end
@@ -0,0 +1,30 @@
1
+ module HTTParty
2
+ module StubResponse
3
+ def stub_http_response_with(filename)
4
+ format = filename.split('.').last.intern
5
+ data = file_fixture(filename)
6
+
7
+ response = Net::HTTPOK.new("1.1", 200, "Content for you")
8
+ response.stub!(:body).and_return(data)
9
+
10
+ http_request = HTTParty::Request.new(Net::HTTP::Get, 'http://localhost', :format => format)
11
+ http_request.stub!(:perform_actual_request).and_return(response)
12
+
13
+ HTTParty::Request.should_receive(:new).and_return(http_request)
14
+ end
15
+
16
+ def stub_response(body, code = 200)
17
+ unless defined?(@http) && @http
18
+ @http = Net::HTTP.new('localhost', 80)
19
+ @request.stub!(:http).and_return(@http)
20
+ @request.stub!(:uri).and_return(URI.parse("http://foo.com/foobar"))
21
+ end
22
+
23
+ response = Net::HTTPResponse::CODE_TO_OBJ[code.to_s].new("1.1", code, body)
24
+ response.stub!(:body).and_return(body)
25
+
26
+ @http.stub!(:request).and_return(response)
27
+ response
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,47 @@
1
+ @media screen, projection {
2
+ /*
3
+ Copyright (c) 2007, Yahoo! Inc. All rights reserved.
4
+ Code licensed under the BSD License:
5
+ http://developer.yahoo.net/yui/license.txt
6
+ version: 2.2.0
7
+ */
8
+ body {font:13px arial,helvetica,clean,sans-serif;*font-size:small;*font:x-small;}table {font-size:inherit;font:100%;}select, input, textarea {font:99% arial,helvetica,clean,sans-serif;}pre, code {font:115% monospace;*font-size:100%;}body * {line-height:1.22em;}
9
+ body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form,fieldset,input,textarea,p,blockquote,th,td{margin:0;padding:0;}table{border-collapse:collapse;border-spacing:0;}fieldset,img{border:0;}address,caption,cite,code,dfn,em,strong,th,var{font-style:normal;font-weight:normal;}/*ol,ul {list-style:none;}*/caption,th {text-align:left;}h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:normal;}q:before,q:after{content:'';}abbr,acronym {border:0;}
10
+ /* end of yahoo reset and fonts */
11
+
12
+ body {color:#333; background:#4b1a1a; line-height:1.3;}
13
+ p {margin:0 0 20px;}
14
+ a {color:#4b1a1a;}
15
+ a:hover {text-decoration:none;}
16
+ strong {font-weight:bold;}
17
+ em {font-style:italics;}
18
+ h1,h2,h3,h4,h5,h6 {font-weight:bold;}
19
+ h1 {font-size:197%; margin:30px 0; color:#4b1a1a;}
20
+ h2 {font-size:174%; margin:20px 0; color:#b8111a;}
21
+ h3 {font-size:152%; margin:10px 0;}
22
+ h4 {font-size:129%; margin:10px 0;}
23
+ pre {background:#eee; margin:0 0 20px; padding:20px; border:1px solid #ccc; font-size:100%; overflow:auto;}
24
+ code {font-size:100%; margin:0; padding:0;}
25
+ ul, ol {margin:10px 0 10px 25px;}
26
+ ol li {margin:0 0 10px;}
27
+
28
+
29
+
30
+
31
+
32
+ div#wrapper {background:#fff; width:560px; margin:0 auto; padding:20px; border:10px solid #bc8c46; border-width:0 10px;}
33
+ div#header {position:relative; border-bottom:1px dotted; margin:0 0 10px; padding:0 0 10px;}
34
+ div#header p {margin:0; padding:0;}
35
+ div#header h1 {margin:0; padding:0;}
36
+ ul#nav {position:absolute; top:0; right:0; list-style:none; margin:0; padding:0;}
37
+ ul#nav li {display:inline; padding:0 0 0 5px;}
38
+ ul#nav li a {}
39
+ div#content {}
40
+ div#footer {margin:40px 0 0; border-top:1px dotted; padding:10px 0 0;}
41
+
42
+
43
+
44
+
45
+
46
+
47
+ }
@@ -0,0 +1,73 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
2
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
3
+ <head>
4
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
5
+ <title>HTTParty by John Nunemaker</title>
6
+ <link rel="stylesheet" href="css/common.css" type="text/css" />
7
+ </head>
8
+ <body>
9
+
10
+ <div id="wrapper">
11
+ <div id="header">
12
+ <h1>HTTParty</h1>
13
+ <p>Tonight we're gonna HTTParty like it's 1999!</p>
14
+
15
+ <ul id="nav">
16
+ <li><a href="rdoc/">Docs</a></li>
17
+ <li><a href="http://github.com/jnunemaker/httparty">Github</a></li>
18
+ <li><a href="http://rubyforge.org/projects/httparty/">Rubyforge</a></li>
19
+ </ul>
20
+ </div>
21
+
22
+ <div id="content">
23
+ <h2>Install</h2>
24
+ <pre><code>$ sudo gem install httparty</code></pre>
25
+
26
+ <h2>Some Quick Examples</h2>
27
+
28
+ <p>The following is a simple example of wrapping Twitter's API for posting updates.</p>
29
+
30
+ <pre><code>class Twitter
31
+ include HTTParty
32
+ base_uri 'twitter.com'
33
+ basic_auth 'username', 'password'
34
+ end
35
+
36
+ Twitter.post('/statuses/update.json', :query => {:status => "It's an HTTParty and everyone is invited!"})</code></pre>
37
+
38
+ <p>That is really it! The object returned is a ruby hash that is decoded from Twitter's json response. JSON parsing is used because of the .json extension in the path of the request. You can also explicitly set a format (see the examples). </p>
39
+
40
+ <p>That works and all but what if you don't want to embed your username and password in the class? Below is an example to fix that:</p>
41
+
42
+ <pre><code>class Twitter
43
+ include HTTParty
44
+ base_uri 'twitter.com'
45
+
46
+ def initialize(u, p)
47
+ @auth = {:username => u, :password => p}
48
+ end
49
+
50
+ def post(text)
51
+ options = { :query => {:status => text}, :basic_auth => @auth }
52
+ self.class.post('/statuses/update.json', options)
53
+ end
54
+ end
55
+
56
+ Twitter.new('username', 'password').post("It's an HTTParty and everyone is invited!")</code></pre>
57
+
58
+ <p><strong>More Examples:</strong> There are <a href="http://github.com/jnunemaker/httparty/tree/master/examples/">several examples in the gem itself</a>.</p>
59
+
60
+ <h2>Support</h2>
61
+ <p>Conversations welcome in the <a href="http://groups.google.com/group/httparty-gem">google group</a> and bugs/features over at <a href="http://github.com/jnunemaker/httparty">Github</a>.</p>
62
+
63
+
64
+ </div>
65
+
66
+ <div id="footer">
67
+ <p>Created by <a href="http://addictedtonew.com/about/">John Nunemaker</a> |
68
+ <a href="http://orderedlist.com/">Hire Me at Ordered List</a></p>
69
+ </div>
70
+ </div>
71
+
72
+ </body>
73
+ </html>