weary 0.7.2 → 1.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. data/.gitignore +4 -1
  2. data/.rspec +2 -0
  3. data/.travis.yml +10 -0
  4. data/Gemfile +11 -8
  5. data/Gemfile.lock +49 -53
  6. data/LICENSE +1 -1
  7. data/README.md +134 -208
  8. data/Rakefile +6 -47
  9. data/lib/weary.rb +4 -66
  10. data/lib/weary/adapter.rb +23 -0
  11. data/lib/weary/adapters/net_http.rb +68 -0
  12. data/lib/weary/client.rb +243 -0
  13. data/lib/weary/deferred.rb +35 -0
  14. data/lib/weary/env.rb +32 -0
  15. data/lib/weary/middleware.rb +9 -0
  16. data/lib/weary/middleware/basic_auth.rb +17 -0
  17. data/lib/weary/middleware/content_type.rb +28 -0
  18. data/lib/weary/middleware/oauth.rb +31 -0
  19. data/lib/weary/request.rb +137 -124
  20. data/lib/weary/resource.rb +152 -128
  21. data/lib/weary/response.rb +48 -99
  22. data/lib/weary/route.rb +53 -0
  23. data/lib/weary/version.rb +3 -0
  24. data/spec/spec_helper.rb +4 -56
  25. data/spec/support/shared_examples_for_a_rack_app.rb +70 -0
  26. data/spec/support/shared_examples_for_a_rack_env.rb +14 -0
  27. data/spec/support/shared_examples_for_a_uri.rb +9 -0
  28. data/spec/weary/adapter_spec.rb +26 -0
  29. data/spec/weary/adapters/nethttp_spec.rb +88 -0
  30. data/spec/weary/client_spec.rb +258 -0
  31. data/spec/weary/deferred_spec.rb +35 -0
  32. data/spec/weary/env_spec.rb +12 -0
  33. data/spec/weary/middleware/basic_auth_spec.rb +23 -0
  34. data/spec/weary/middleware/content_type_spec.rb +34 -0
  35. data/spec/weary/middleware/oauth_spec.rb +27 -0
  36. data/spec/weary/request_spec.rb +227 -315
  37. data/spec/weary/resource_spec.rb +233 -233
  38. data/spec/weary/response_spec.rb +82 -159
  39. data/spec/weary/route_spec.rb +72 -0
  40. data/spec/weary_spec.rb +3 -56
  41. data/weary.gemspec +16 -79
  42. metadata +138 -98
  43. data/VERSION +0 -1
  44. data/examples/batch.rb +0 -20
  45. data/examples/repo.rb +0 -16
  46. data/examples/status.rb +0 -26
  47. data/lib/weary/base.rb +0 -124
  48. data/lib/weary/batch.rb +0 -37
  49. data/lib/weary/exceptions.rb +0 -15
  50. data/lib/weary/httpverb.rb +0 -32
  51. data/spec/fixtures/github.yml +0 -11
  52. data/spec/fixtures/twitter.xml +0 -763
  53. data/spec/fixtures/vimeo.json +0 -1
  54. data/spec/weary/base_spec.rb +0 -320
  55. data/spec/weary/batch_spec.rb +0 -71
  56. data/spec/weary/httpverb_spec.rb +0 -25
@@ -1,256 +1,256 @@
1
- require File.join(File.dirname(__FILE__), '..', 'spec_helper')
1
+ require 'spec_helper'
2
2
 
3
3
  describe Weary::Resource do
4
- before do
5
- @test = Weary::Resource.new("test")
4
+ describe "#url" do
5
+ it "is an Addressable::Template" do
6
+ url = "http://github.com/api/v2/json/repos/show/mwunsch/weary"
7
+ resource = Weary::Resource.new "GET", url
8
+ resource.url.should be_an Addressable::Template
9
+ end
10
+
11
+ it "gets a previously set url" do
12
+ url = "http://github.com/api/v2/json/repos/show/mwunsch/weary"
13
+ resource = Weary::Resource.new "GET", url
14
+ resource.url.pattern.should eql url
15
+ end
16
+
17
+ it "sets a new url" do
18
+ resource = Weary::Resource.new "GET", "http://api.twitter.com/version/users/show.json"
19
+ url = "http://github.com/api/v2/json/repos/show/mwunsch/weary"
20
+ resource.url url
21
+ resource.url.pattern.should eql url
22
+ end
23
+
24
+ it "accepts variables in the url" do
25
+ url = "http://github.com/api/v2/json/repos/show/{user}/{repo}"
26
+ resource = Weary::Resource.new "GET", url
27
+ resource.url.variables.should include 'user'
28
+ end
29
+
30
+ it "accepts variables in the sinatra style" do
31
+ url = "http://github.com/api/v2/json/repos/show/:user/:repo"
32
+ resource = Weary::Resource.new "GET", url
33
+ resource.url.variables.should include 'user'
34
+ end
35
+ end
36
+
37
+ describe "#optional" do
38
+ it "creates a list of optional parameters for the request" do
39
+ url = "http://github.com/api/v2/json/repos/show/{user}/{repo}"
40
+ resource = described_class.new "GET", url
41
+ resource.optional :login, :token
42
+ resource.optional.length.should be 2
43
+ end
44
+ end
45
+
46
+ describe "#required" do
47
+ it "creates a list of required parameters for the request" do
48
+ url = "http://api.twitter.com/version/users/show.{format}"
49
+ resource = described_class.new "GET", url
50
+ resource.required :screen_name
51
+ resource.required.length.should be 1
52
+ end
53
+ end
54
+
55
+ describe "#defaults" do
56
+ it "sets some default values for parameters" do
57
+ url = "http://github.com/api/v2/json/repos/show/{user}/{repo}"
58
+ resource = described_class.new "GET", url
59
+ resource.defaults :user => "mwunsch", :repo => "weary"
60
+ resource.defaults.should have_key :user
61
+ end
62
+ end
63
+
64
+ describe "#headers" do
65
+ it "prepares headers for the request" do
66
+ url = "http://github.com/api/v2/json/repos/show/{user}/{repo}"
67
+ resource = described_class.new "GET", url
68
+ resource.headers 'User-Agent' => 'RSpec'
69
+ resource.headers.should eql 'User-Agent' => 'RSpec'
70
+ end
71
+ end
72
+
73
+ describe "#use" do
74
+ it "adds a middleware to the stack and passes them onto the request" do
75
+ url = "http://github.com/api/v2/json/repos/show/mwunsch/weary"
76
+ resource = described_class.new "GET", url
77
+ resource.use Rack::Lobster
78
+ stack = resource.request.instance_variable_get :@middlewares
79
+ stack.flatten.should include Rack::Lobster
80
+ end
6
81
  end
7
-
8
- describe 'Name' do
9
- it 'has a name' do
10
- @test.name.should == "test"
11
- end
12
-
13
- it 'replaces the whitespace in the name' do
14
- @test.name = " test number two"
15
- @test.name.should == "test_number_two"
16
- @test.name = "test\nthree"
17
- @test.name.should == "test_three"
18
- end
19
-
20
- it 'downcases everything' do
21
- @test.name = "TEST"
22
- @test.name.should == "test"
23
- end
24
-
25
- it 'is a string' do
26
- @test.name = :test
27
- @test.name.should == "test"
82
+
83
+ describe "#user_agent" do
84
+ it "updates the #headers hash with a User-Agent" do
85
+ url = "http://github.com/api/v2/json/repos/show/{user}/{repo}"
86
+ resource = described_class.new "GET", url
87
+ resource.user_agent 'RSpec'
88
+ resource.headers.should eql 'User-Agent' => 'RSpec'
89
+ end
90
+ end
91
+
92
+ describe "#basic_auth!" do
93
+ subject do
94
+ url = "http://github.com/api/v2/json/repos/show/mwunsch/weary"
95
+ resource = described_class.new "GET", url
96
+ end
97
+
98
+ it "prepares the request to accept username and password parameters" do
99
+ subject.basic_auth!
100
+ req = subject.request :username => "mwunsch", :password => "secret"
101
+ req.basic_auth.should be
102
+ end
103
+
104
+ it "allows the default credential params to be overriden" do
105
+ subject.basic_auth! :login, :token
106
+ req = subject.request :login => "mwunsch", :token=> "secret"
107
+ req.basic_auth.should be
108
+ end
109
+
110
+ it "permits the credentials to be completely optional" do
111
+ subject.basic_auth!
112
+ req = subject.request
113
+ req.basic_auth.should_not be
28
114
  end
29
115
  end
30
-
31
- describe 'Via' do
32
- it 'defaults as a GET request' do
33
- @test.via.should == :get
116
+
117
+ describe "#oauth!" do
118
+ subject do
119
+ url = "http://github.com/api/v2/json/repos/show/mwunsch/weary"
120
+ resource = described_class.new "GET", url
121
+ end
122
+
123
+ it "prepares the request to accept consumer_key and token parameters" do
124
+ subject.oauth!
125
+ req = subject.request :consumer_key => "key", :token => "access"
126
+ req.oauth.should be
34
127
  end
35
128
 
36
- it 'normalizes HTTP request verbs' do
37
- @test.via = "POST"
38
- @test.via.should == :post
129
+ it "allows the default oauth params to be overriden" do
130
+ subject.oauth! :consumer, :access_token
131
+ req = subject.request :consumer => "key", :access_token => "access"
132
+ req.oauth.should be
39
133
  end
40
134
 
41
- it 'remains a GET if the input verb is not understood' do
42
- @test.via = "foobar"
43
- @test.via.should == :get
135
+ it "permits the oauth parameters to be completely optional" do
136
+ subject.oauth!
137
+ req = subject.request
138
+ req.oauth.should_not be
44
139
  end
45
140
  end
46
-
47
- describe 'Parameters' do
48
- it 'is an array of params' do
49
- @test.with = [:uid, :date]
50
- @test.with.should == [:uid, :date]
51
- @test.with = :user, :message
52
- @test.with.should == [:user, :message]
53
- end
54
-
55
- it 'stores the params as symbols' do
56
- @test.with = "user", "message"
57
- @test.with.should == [:user, :message]
58
- end
59
-
60
- it 'defines required params' do
61
- @test.requires = [:uid, :date]
62
- @test.requires.should == [:uid, :date]
63
- @test.requires = :user, :message
64
- @test.requires.should == [:user, :message]
65
- end
66
-
67
- it 'stores the required params as symbols' do
68
- @test.requires = "user", "message"
69
- @test.requires.should == [:user, :message]
70
- end
71
-
72
- it 'required params inherently become passed params' do
73
- @test.requires = [:user, :message]
74
- @test.requires.should == [:user, :message]
75
- @test.with.should == [:user, :message]
76
- end
77
-
78
- it 'merges required params with optional params' do
79
- @test.with = [:user, :message]
80
- @test.requires = [:id, :time]
81
- @test.with.should == [:user, :message, :id, :time]
82
- @test.requires.should == [:id, :time]
83
- end
84
-
85
- it 'optional params should merge with required params' do
86
- @test.requires = [:id, :time]
87
- @test.with.should == [:id, :time]
88
- @test.with = [:user, :message]
89
- @test.requires.should == [:id, :time]
90
- @test.with.should == [:id, :time, :user, :message]
141
+
142
+ describe "#authenticates?" do
143
+ subject do
144
+ url = "http://github.com/api/v2/json/repos/show/mwunsch/weary"
145
+ resource = described_class.new "GET", url
146
+ end
147
+
148
+ it "is false when the resource does not accept authentication" do
149
+ subject.authenticates?.should be_false
150
+ end
151
+
152
+ it "is true when basic authentication has been declared" do
153
+ subject.basic_auth!
154
+ subject.authenticates?.should be_true
155
+ end
156
+
157
+ it "is true when OAuth has been declared" do
158
+ subject.oauth!
159
+ subject.authenticates?.should be_true
91
160
  end
92
161
  end
93
-
94
- describe 'Authenticates' do
95
- it 'defaults to false' do
96
- @test.authenticates?.should == false
97
- end
98
-
99
- it 'is always set to a boolean' do
100
- @test.authenticates = "foobar"
101
- @test.authenticates?.should == true
102
- @test.authenticates = "false"
103
- @test.authenticates?.should == true
162
+
163
+ describe "#expected_params" do
164
+ it "contains the request's expected parameters" do
165
+ url = "http://github.com/api/v2/json/repos/show/{user}/{repo}"
166
+ resource = described_class.new "GET", url
167
+ resource.required :foo
168
+ resource.optional :baz
169
+ resource.expected_params.size.should be 2
170
+ end
171
+
172
+ it "contains the keys of the resource's defaults" do
173
+ url = "http://github.com/api/v2/json/repos/show/{user}/{repo}"
174
+ resource = described_class.new "GET", url
175
+ resource.defaults :foo => "baz"
176
+ resource.expected_params.should include "foo"
104
177
  end
105
178
  end
106
-
107
- describe 'Redirection' do
108
- it 'defaults to true' do
109
- @test.follows?.should == true
110
- end
111
-
112
- it 'is always set to a boolean' do
113
- @test.follows = "foobar"
114
- @test.follows?.should == true
115
- @test.follows = "false"
116
- @test.follows?.should == true
117
- @test.follows = false
118
- @test.follows?.should == false
179
+
180
+ describe "#expects?" do
181
+ it "is true if the parameter is expected by the request" do
182
+ url = "http://github.com/api/v2/json/repos/show/{user}/{repo}"
183
+ resource = described_class.new "GET", url
184
+ resource.required :foo
185
+ resource.should be_expects :foo
186
+ end
187
+
188
+ it "is false if the parameter is unexpected" do
189
+ url = "http://github.com/api/v2/json/repos/show/{user}/{repo}"
190
+ resource = described_class.new "GET", url
191
+ resource.required :foo
192
+ resource.should_not be_expects :baz
119
193
  end
120
194
  end
121
-
122
- describe 'URL' do
123
- it 'is a valid URI' do
124
- @test.url = 'http://foo.bar/foobar'
125
- @test.url.scheme.should == 'http'
126
- @test.url.host.should == 'foo.bar'
127
- @test.url.path.should == '/foobar'
128
- @test.url.normalize.to_s.should == 'http://foo.bar/foobar'
129
- end
130
-
131
- it "rejects fake url's" do
132
- lambda { @test.url = "this is not really a url" }.should raise_error
195
+
196
+ describe "#requirements" do
197
+ it "contains required parameters and url keys" do
198
+ url = "http://github.com/api/v2/json/repos/show/{user}/{repo}"
199
+ resource = described_class.new "GET", url
200
+ resource.required :foo
201
+ resource.requirements.size.should be 3
133
202
  end
134
203
  end
135
-
136
- describe 'Request Builder' do
137
- before do
138
- @test.url = 'http://foo.bar'
139
- @test.with = :user, :message
140
- @test.headers = {"User-Agent" => Weary::UserAgents["Safari 4.0.2 - Mac"]}
141
- end
142
-
143
- it "merges defaults in with passed params" do
144
- params = {:message => "Hello"}
145
- defaults = {:user => "me"}
146
- @test.setup_parameters(params, defaults).should == {:message => "Hello", :user => "me"}
147
- @test.setup_parameters(params).should == {:message => "Hello"}
148
- end
149
-
150
- it 'alerts if a required param is missing' do
151
- @test.requires = [:id]
152
- params = {:user => "me", :message => "Hello"}
153
- lambda { @test.find_missing_requirements(params) }.should raise_error
154
- end
155
-
156
- it 'removes unnecessary parameters' do
157
- params = {:message => "Hello", :user => "me", :foo => "bar"}
158
- @test.remove_unnecessary_params(params).should == {:message => "Hello", :user => "me"}
159
- end
160
-
161
- it 'prepares param options for the request' do
162
- params = {:user => "me", :message => "Hello"}
163
- @test.prepare_request_body(params)[:query].should == {:user => "me", :message => "Hello"}
164
- @test.prepare_request_body(params).has_key?(:body).should == false
165
- @test.via = :post
166
- @test.prepare_request_body(params)[:body].should == {:user => "me", :message => "Hello"}
167
- @test.prepare_request_body(params).has_key?(:query).should == false
168
- end
169
-
170
- it 'alerts if credentials are missing but authorization is required' do
171
- @test.authenticates = true
172
- lambda { @test.setup_authentication({}) }.should raise_error
173
- end
174
-
175
- it 'negotiates what form of authentication is used (basic or oauth)' do
176
- @test.authenticates = true
177
- basic_auth = {:username => "mwunsch", :password => "secret123"}
178
- oauth_consumer = OAuth::Consumer.new("consumer_token","consumer_secret",{:site => 'http://foo.bar'})
179
- oauth_token = OAuth::AccessToken.new(oauth_consumer, "token", "secret")
180
-
181
- basic_authentication = @test.setup_authentication({},basic_auth)
182
- oauth_authentication = @test.setup_authentication({},oauth_token)
183
-
184
- basic_authentication.has_key?(:basic_auth).should == true
185
- basic_authentication.has_key?(:oauth).should == false
186
- basic_authentication[:basic_auth].should == basic_auth
187
-
188
- oauth_authentication.has_key?(:oauth).should == true
189
- oauth_authentication.has_key?(:basic_auth).should == false
190
- oauth_authentication[:oauth].should == oauth_token
191
- end
192
-
193
- it 'sets request options' do
194
- setup = @test.setup_options({})
195
-
196
- setup.has_key?(:headers).should == true
197
- setup.has_key?(:no_follow).should == false
198
- setup[:headers].should == @test.headers
199
- end
200
-
201
- it 'sets redirection following options' do
202
- @test.follows = false
203
- setup = @test.setup_options({})
204
-
205
- setup[:no_follow].should == true
206
- end
207
-
208
- it 'sets parameter body options' do
209
- params = {:user => "me", :message => "Hello"}
210
- setup_get = @test.setup_options(params)
211
-
212
- setup_get.has_key?(:query).should == true
213
- setup_get[:query] == params
214
-
215
- @test.via = :post
216
- setup_post = @test.setup_options(params)
217
-
218
- setup_post.has_key?(:query).should == false
219
- setup_post.has_key?(:body).should == true
220
- setup_post[:body].should == params
221
- end
222
-
223
- it 'sets up authentication options' do
224
- @test.authenticates = true
225
- basic_auth = {:username => "mwunsch", :password => "secret123"}
226
- oauth_consumer = OAuth::Consumer.new("consumer_token","consumer_secret",{:site => 'http://foo.bar'})
227
- oauth_token = OAuth::AccessToken.new(oauth_consumer, "token", "secret")
228
- setup_basic = @test.setup_options({}, basic_auth)
229
- setup_oauth = @test.setup_options({}, oauth_token)
230
-
231
- setup_basic[:basic_auth].should == basic_auth
232
- setup_oauth[:oauth].should == oauth_token
233
- end
234
-
235
- it 'builds a Request' do
236
- @test.authenticates = true
237
- @test.requires = [:id]
238
- params = {:user => "me", :message => "Hello", :bar => "foo"}
239
- defaults = {:id => 1234, :foo => "bar"}
240
- basic_auth = {:username => "mwunsch", :password => "secret123"}
241
-
242
- request = @test.build!(params, defaults, basic_auth)
243
-
244
- request.class.should == Weary::Request
245
- request.via.should == :get
246
- request.credentials.should == basic_auth
204
+
205
+ describe "#meets_requirements?" do
206
+ it "is true if the set of parameters meet the request requirements" do
207
+ url = "http://github.com/api/v2/json/repos/show/{user}/{repo}"
208
+ hash = { :user => "mwunsch", :repo => "weary" }
209
+ resource = described_class.new "GET", url
210
+ resource.should be_meets_requirements hash
211
+ end
212
+
213
+ it "is false if the parameters do not meet requirements" do
214
+ url = "http://github.com/api/v2/json/repos/show/{user}/{repo}"
215
+ hash = { :user => "mwunsch" }
216
+ resource = described_class.new "GET", url
217
+ resource.should_not be_meets_requirements hash
247
218
  end
248
219
  end
249
-
250
- it 'can convert to a hash' do
251
- @test.to_hash.has_key?(:test).should == true
220
+
221
+ describe "#request" do
222
+ it "builds a request object" do
223
+ url = "http://github.com/api/v2/json/repos/show/{user}/{repo}"
224
+ resource = described_class.new "GET", url
225
+ req = resource.request(:repo => "weary", :user => "mwunsch")
226
+ req.should be_a Weary::Request
227
+ end
228
+
229
+ it "expands templated urls" do
230
+ url = "http://github.com/api/v2/json/repos/show/{user}/{repo}"
231
+ resource = described_class.new "GET", url
232
+ req = resource.request(:repo => "weary", :user => "mwunsch")
233
+ req.uri.to_s.should eql "http://github.com/api/v2/json/repos/show/mwunsch/weary"
234
+ end
235
+
236
+ it "raises an exception for missing requirements" do
237
+ url = "http://github.com/api/v2/json/repos/show/{user}/{repo}"
238
+ resource = described_class.new "GET", url
239
+ expect { resource.request }.to raise_error Weary::Resource::UnmetRequirementsError
240
+ end
241
+
242
+ it "passes headers along to the request" do
243
+ url = "http://github.com/api/v2/json/repos/show/mwunsch/weary"
244
+ resource = described_class.new "GET", url
245
+ resource.headers 'User-Agent' => 'RSpec'
246
+ resource.request.headers.should eql 'User-Agent' => 'RSpec'
247
+ end
248
+
249
+ it "passes parameters into the request body" do
250
+ resource = described_class.new "GET", "http://api.twitter.com/version/users/show.json"
251
+ resource.required :user_id
252
+ req = resource.request :user_id => "markwunsch"
253
+ req.params.should eql "user_id=markwunsch"
254
+ end
252
255
  end
253
-
254
-
255
-
256
256
  end