weary 0.7.2 → 1.0.0.rc1

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 (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