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,176 +1,99 @@
1
- require File.join(File.dirname(__FILE__), '..', 'spec_helper')
1
+ require 'spec_helper'
2
2
 
3
3
  describe Weary::Response do
4
- before do
5
- FakeWeb.register_uri(:get, "http://twitter.com", :body => get_fixture('twitter.xml'))
6
- FakeWeb.register_uri(:get, "http://github.com", :body => get_fixture('github.yml'))
7
- end
8
-
9
- after do
10
- FakeWeb.clean_registry
11
- end
12
-
13
- it 'wraps a raw Net::HTTPResponse' do
14
- FakeWeb.register_uri(:get, "http://vimeo.com", :body => get_fixture('vimeo.json'))
15
-
16
- request = Weary::Request.new('http://vimeo.com')
17
- response = request.perform
18
- response.raw.is_a?(Net::HTTPResponse).should == true
19
- end
20
-
21
- it 'stores the Request object that requested it' do
22
- FakeWeb.register_uri(:get, "http://vimeo.com", :body => get_fixture('vimeo.json'))
23
-
24
- request = Weary::Request.new('http://vimeo.com')
25
- response = request.perform
26
- response.requester.should == request
27
- end
28
-
29
- it 'has an HTTP code' do
30
- FakeWeb.register_uri(:get, "http://vimeo.com", :body => get_fixture('vimeo.json'), :status => http_status_message(418))
31
-
32
- request = Weary::Request.new('http://vimeo.com')
33
- response = request.perform
34
- response.code.should == 418
35
- end
36
-
37
- it 'has an HTTP message associated with it' do
38
- FakeWeb.register_uri(:get, "http://vimeo.com", :body => get_fixture('vimeo.json'), :status => http_status_message(418))
39
-
40
- request = Weary::Request.new('http://vimeo.com')
41
- response = request.perform
42
- response.message.should == "I'm a teapot"
43
- end
44
-
45
- it 'knows if the request cycle was successful' do
46
- FakeWeb.register_uri(:get, "http://vimeo.com", :body => get_fixture('vimeo.json'))
47
-
48
- request = Weary::Request.new('http://vimeo.com')
49
- response = request.perform
50
- response.success?.should == true
51
- end
52
-
53
- it 'stores the HTTP header' do
54
- FakeWeb.register_uri(:get, "http://vimeo.com", :body => get_fixture('vimeo.json'), :Server => 'Apache')
55
-
56
- request = Weary::Request.new('http://vimeo.com')
57
- response = request.perform
58
- response.header['server'][0].should == 'Apache'
59
- end
60
-
61
- it 'stores the content-type of the response' do
62
- FakeWeb.register_uri(:get, "http://vimeo.com", :body => get_fixture('vimeo.json'), :'Content-Type' => 'text/json')
63
-
64
- request = Weary::Request.new('http://vimeo.com')
65
- response = request.perform
66
- response.content_type.should == 'text/json'
4
+ describe "#status" do
5
+ subject { Weary::Response.new [""], 200, {'Content-Type' => 'text/plain'} }
6
+ it "returns a response code" do
7
+ subject.status.should eql 200
8
+ end
67
9
  end
68
-
69
- it 'stores the cookies sent by the response' do
70
- FakeWeb.register_uri(:get, "http://vimeo.com", :body => get_fixture('vimeo.json'), :'Set-Cookie' => 'cookie=true')
71
-
72
- request = Weary::Request.new('http://vimeo.com')
73
- response = request.perform
74
- response.cookie.should == 'cookie=true'
10
+
11
+ describe "#header" do
12
+ subject { Weary::Response.new [""], 200, {'Content-Type' => 'text/plain'} }
13
+ it "returns the headers as a hash" do
14
+ subject.header.should have_key 'Content-Type'
15
+ end
75
16
  end
76
-
77
- it 'stores the body of the response' do
78
- FakeWeb.register_uri(:get, "http://vimeo.com", :body => get_fixture('vimeo.json'))
79
-
80
- request = Weary::Request.new('http://vimeo.com')
81
- response = request.perform
82
- response.body.should == get_fixture('vimeo.json')
17
+
18
+ describe "#body" do
19
+ subject { Weary::Response.new ["Hi"], 200, {'Content-Type' => 'text/plain'} }
20
+ it "returns the body, compacted" do
21
+ subject.body.should eql "Hi"
22
+ end
83
23
  end
84
-
85
- it 'normalizes the format type of the response' do
86
- FakeWeb.register_uri(:get, "http://vimeo.com", :body => get_fixture('vimeo.json'), :'Content-Type' => 'text/json')
87
-
88
- request = Weary::Request.new('http://vimeo.com')
89
- response = request.perform
90
- response.format.should == :json
24
+
25
+ describe "#each" do
26
+ subject { Weary::Response.new ["Hi"], 200, {'Content-Type' => 'text/plain'} }
27
+ it "calls #each on the body" do
28
+ iterated = false
29
+ subject.each {|body| iterated = body.downcase.to_sym }
30
+ iterated.should eql :hi
31
+ end
91
32
  end
92
-
93
- it 'can follow redirects' do
94
- FakeWeb.register_uri(:get, "http://markwunsch.com", :status => http_status_message(301), :Location => 'http://redirected.com')
95
- FakeWeb.register_uri(:get, "http://redirected.com", :body => "Hello world")
96
-
97
- request = Weary::Request.new('http://markwunsch.com')
98
- request.follows = false
99
- response = request.perform
100
- response.code.should == 301
101
- response.follow_redirect.code.should == 200
102
- response.follow_redirect.body.should == "Hello world"
33
+
34
+ describe "#finish" do
35
+ subject { Weary::Response.new [""], 200, {'Content-Type' => 'text/plain'} }
36
+ it "provides a Rack tuple" do
37
+ subject.finish.length.should be 3
38
+ end
103
39
  end
104
-
105
- it 'stores the url' do
106
- FakeWeb.register_uri(:get, "http://vimeo.com", :body => get_fixture('vimeo.json'))
107
-
108
- request = Weary::Request.new('http://vimeo.com')
109
- response = request.perform
110
- response.url.to_s.should == 'http://vimeo.com'
40
+
41
+ describe "#success?" do
42
+ subject { Weary::Response.new ["Hi"], 200, {'Content-Type' => 'text/plain'} }
43
+ it "returns true if the request was successful" do
44
+ subject.success?.should be true
45
+ end
111
46
  end
112
-
113
- describe 'Parsing' do
114
- it 'parses JSON' do
115
- FakeWeb.register_uri(:get, "http://vimeo.com", :body => get_fixture('vimeo.json'), :'Content-Type' => 'text/json')
116
-
117
- request = Weary::Request.new('http://vimeo.com')
118
- response = request.perform
119
- response.parse[0].class.should == Hash
120
- response.parse[0]['title'].should == '"The Noises Rest"'
47
+
48
+ describe "#redirected?" do
49
+ subject { Weary::Response.new ["Hi"], 301, {'Content-Type' => 'text/plain'} }
50
+ it "returns true if the request was redirected" do
51
+ subject.redirected?.should be true
121
52
  end
122
-
123
- it 'parses XML' do
124
- FakeWeb.register_uri(:get, "http://twitter.com", :body => get_fixture('twitter.xml'), :'Content-Type' => 'application/xml')
125
-
126
- request = Weary::Request.new('http://twitter.com')
127
- response = request.perform
128
- response.parse.class.should == Hash
129
- response.parse['statuses'].size.should == 20
53
+ end
54
+
55
+ describe "#length" do
56
+ subject { Weary::Response.new ["Hi"], 301, {'Content-Type' => 'text/plain'} }
57
+ it "returns the content-length" do
58
+ subject.length.should eql subject.header['Content-Length'].to_i
130
59
  end
131
-
132
- it 'parses YAML' do
133
- FakeWeb.register_uri(:get, "http://github.com", :body => get_fixture('github.yml'), :'Content-Type' => 'text/yaml')
134
-
135
- request = Weary::Request.new('http://github.com')
136
- response = request.perform
137
- response.parse.class.should == Hash
138
- response.parse['repository'][:name].should == 'rails'
60
+ end
61
+
62
+ describe "#call" do
63
+ it_behaves_like "a Rack application" do
64
+ subject { Weary::Response.new [""], 200, {'Content-Type' => 'text/plain'}}
65
+ let(:env) { Weary::Request.new("http://github.com/api/v2/json/repos/show/mwunsch/weary").env }
139
66
  end
140
-
141
- it 'can parse with the [] method' do
142
- FakeWeb.register_uri(:get, "http://github.com", :body => get_fixture('github.yml'), :'Content-Type' => 'text/yaml')
143
-
144
- request = Weary::Request.new('http://github.com')
145
- response = request.perform
146
- response['repository'][:name].should == 'rails'
67
+ end
68
+
69
+ describe "#parse" do
70
+ before do
71
+ @body = {
72
+ :sales => [
73
+ :name => "Spring: Just Around the Corner",
74
+ :sale => "https://api.gilt.com/v1/sales/men/spring-just-arou-108/detail.json",
75
+ :sale_key => "spring-just-arou-108",
76
+ :store => "men",
77
+ :description => "Were you aware that there are seasons? Spring will start soon so etc",
78
+ :begins => "2012-02-09T17:00:00Z"
79
+ ]
80
+ }
147
81
  end
148
-
149
- it 'converts to a string by printing the body' do
150
- fixture = get_fixture('github.yml')
151
- FakeWeb.register_uri(:get, "http://github.com", :body => fixture, :'Content-Type' => 'text/yaml')
152
- request = Weary::Request.new('http://github.com')
153
- response = request.perform
154
- response.to_s.should == get_fixture('github.yml')
82
+
83
+ it "parses json out of the response" do
84
+ json = MultiJson.encode @body
85
+ response = Weary::Response.new json, 200, {'Content-Type' => 'application/json'}
86
+ response.parse.should eql MultiJson.decode(json)
155
87
  end
156
- end
157
-
158
- describe 'Exceptions' do
159
- it 'raises an exception if there is a Server Error' do
160
- FakeWeb.register_uri(:get, "http://github.com", :status => http_status_message(500))
161
-
162
- request = Weary::Request.new('http://github.com')
163
- response = request.perform
164
- lambda { response.parse }.should raise_error
88
+
89
+ it "raises an error if the content type is unknown" do
90
+ response = Weary::Response.new "<lolxml />", 200, {'Content-Type' => 'application/xml'}
91
+ expect { response.parse }.to raise_error
165
92
  end
166
-
167
- it 'raises an exception if there is a Client Error' do
168
- FakeWeb.register_uri(:get, "http://github.com", :status => http_status_message(404))
169
-
170
- request = Weary::Request.new('http://github.com')
171
- response = request.perform
172
- lambda { response.parse }.should raise_error
93
+
94
+ it "raises an error if there is no body" do
95
+ response = Weary::Response.new "", 404, {'Content-Type' => 'text/plain'}
96
+ expect { response.parse }.to raise_error
173
97
  end
174
98
  end
175
-
176
99
  end
@@ -0,0 +1,72 @@
1
+ require 'spec_helper'
2
+
3
+ describe Weary::Route do
4
+ before do
5
+ @client = Class.new(Weary::Client)
6
+ @client.domain "https://api.github.com"
7
+ @client.get(:list, "/user/repos") {|r| r.basic_auth! }
8
+ @client.get(:user, "/users/{user}/repos")
9
+ @client.post(:create, "/user/repos") {|r| r.basic_auth! }
10
+ @client.get(:repo, "/repos/{user}/{repo}")
11
+ @client.patch(:edit, "/repos/{user}/{repo}") {|r| r.basic_auth! }
12
+ @resources = @client.resources
13
+ end
14
+
15
+ describe "#call" do
16
+ it_behaves_like "a Rack application" do
17
+ subject { described_class.new @resources.values, @client.domain }
18
+ let(:env) { @resources[:list].request.env }
19
+ end
20
+
21
+ it "returns a 404 when the url can't be routed" do
22
+ route = described_class.new @resources.values, @client.domain
23
+ dummy = @resources[:list].dup
24
+ dummy.url "http://foo.com/baz"
25
+ status, header, body = route.call dummy.request.env
26
+ status.should eql 404
27
+ end
28
+
29
+ it "returns a 405 when the request method is invalid" do
30
+ route = described_class.new @resources.values, @client.domain
31
+ bad_request = @resources[:list].request do |request|
32
+ request.method = "PUT"
33
+ end
34
+ status, header, body = route.call bad_request.env
35
+ status.should eql 405
36
+ end
37
+
38
+ it "returns a 403 (forbidden) when requirements are unmet" do
39
+ dummy = @resources[:edit].dup
40
+ dummy.required :name
41
+ route = described_class.new [dummy], @client.domain
42
+ env = @resources[:edit].request(:user => "mwunsch", :repo => "weary").env
43
+ status, header, body = route.call(env)
44
+ status.should eql 403
45
+ end
46
+ end
47
+
48
+ describe "#route" do
49
+ subject { described_class.new @resources.values, @client.domain }
50
+
51
+ it "accepts a Rack::Request and returns the best resource" do
52
+ req = @resources[:list].request
53
+ rack_req = Rack::Request.new(req.env)
54
+ subject.route(rack_req).should be @resources[:list]
55
+ end
56
+
57
+ it "raises a 404 (not found) error if no url can be matched" do
58
+ dummy = @resources[:list].dup
59
+ dummy.url "http://foo.com/baz"
60
+ rack_req = Rack::Request.new(dummy.request.env)
61
+ expect { subject.route(rack_req) }.to raise_error Weary::Route::NotFoundError
62
+ end
63
+
64
+ it "raises a 405 (not allowed) error if no request method can be matched" do
65
+ bad_request = @resources[:list].request do |request|
66
+ request.method = "PUT"
67
+ end
68
+ rack_req = Rack::Request.new(bad_request.env)
69
+ expect { subject.route(rack_req) }.to raise_error Weary::Route::NotAllowedError
70
+ end
71
+ end
72
+ end
data/spec/weary_spec.rb CHANGED
@@ -1,57 +1,4 @@
1
- require File.join(File.dirname(__FILE__), 'spec_helper')
1
+ require 'spec_helper'
2
+
3
+
2
4
 
3
- describe Weary do
4
- it 'makes a request' do
5
- r = Weary.request('http://google.com')
6
- r.class.should == Weary::Request
7
- r.uri.to_s.should == 'http://google.com'
8
- r.via.should == :get
9
- end
10
-
11
- it 'can alter the request' do
12
- r = Weary.request('http://google.com', :get) {|r| r.via = 'POST' }
13
- r.via.should == :post
14
- end
15
-
16
- it 'makes a GET request' do
17
- r = Weary.get 'http://google.com'
18
- r.class.should == Weary::Request
19
- r.uri.to_s.should == 'http://google.com'
20
- r.via.should == :get
21
- end
22
-
23
- it 'makes a POST request' do
24
- r = Weary.post 'http://google.com'
25
- r.via.should == :post
26
- end
27
-
28
- it 'makes a PUT request' do
29
- r = Weary.put 'http://google.com'
30
- r.via.should == :put
31
- end
32
-
33
- it 'makes a DELETE request' do
34
- r = Weary.delete 'http://google.com'
35
- r.via.should == :delete
36
- end
37
-
38
- it 'makes a HEAD request' do
39
- r = Weary.head 'http://google.com'
40
- r.via.should == :head
41
- end
42
-
43
- it 'makes requests with an optional block' do
44
- r = Weary.get 'http://google.com' do |req|
45
- req.with = {:id => 'markwunsch'}
46
- end
47
- r.uri.query.should == r.with
48
- end
49
-
50
- it 'prepares a Batch request' do
51
- requests = [ Weary.get('http://twitter.com'),
52
- Weary.get('http://github.com'),
53
- Weary.get('http://vimeo.com'),
54
- Weary.get('http://tumblr.com')]
55
- Weary.batch(requests).class.should == Weary::Batch
56
- end
57
- end
data/weary.gemspec CHANGED
@@ -1,90 +1,27 @@
1
- # Generated by jeweler
2
- # DO NOT EDIT THIS FILE DIRECTLY
3
- # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
1
  # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "weary/version"
5
4
 
6
5
  Gem::Specification.new do |s|
7
6
  s.name = %q{weary}
8
- s.version = "0.7.2"
9
-
10
- s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
7
+ s.version = "#{Weary::VERSION}"
11
8
  s.authors = ["Mark Wunsch"]
12
- s.date = %q{2010-03-08}
13
- s.description = %q{A tiny DSL that makes the consumption of RESTful web services simple.}
14
9
  s.email = %q{mark@markwunsch.com}
15
- s.extra_rdoc_files = [
16
- "LICENSE",
17
- "README.md"
18
- ]
19
- s.files = [
20
- ".gitignore",
21
- "Gemfile",
22
- "Gemfile.lock",
23
- "LICENSE",
24
- "README.md",
25
- "Rakefile",
26
- "VERSION",
27
- "examples/batch.rb",
28
- "examples/repo.rb",
29
- "examples/status.rb",
30
- "lib/weary.rb",
31
- "lib/weary/base.rb",
32
- "lib/weary/batch.rb",
33
- "lib/weary/exceptions.rb",
34
- "lib/weary/httpverb.rb",
35
- "lib/weary/request.rb",
36
- "lib/weary/resource.rb",
37
- "lib/weary/response.rb",
38
- "spec/fixtures/github.yml",
39
- "spec/fixtures/twitter.xml",
40
- "spec/fixtures/vimeo.json",
41
- "spec/spec_helper.rb",
42
- "spec/weary/base_spec.rb",
43
- "spec/weary/batch_spec.rb",
44
- "spec/weary/httpverb_spec.rb",
45
- "spec/weary/request_spec.rb",
46
- "spec/weary/resource_spec.rb",
47
- "spec/weary/response_spec.rb",
48
- "spec/weary_spec.rb",
49
- "weary.gemspec"
50
- ]
10
+ s.summary = %q{A framework and DSL for the consumption of RESTful web services.}
11
+ s.description = %q{A framework and DSL to Ruby clients to RESTful web services. }
51
12
  s.homepage = %q{http://github.com/mwunsch/weary}
52
- s.rdoc_options = ["--charset=UTF-8"]
53
- s.require_paths = ["lib"]
54
13
  s.rubyforge_project = %q{weary}
55
- s.rubygems_version = %q{1.3.6}
56
- s.summary = %q{A little DSL for consuming RESTful web services}
57
- s.test_files = [
58
- "spec/spec_helper.rb",
59
- "spec/weary/base_spec.rb",
60
- "spec/weary/batch_spec.rb",
61
- "spec/weary/httpverb_spec.rb",
62
- "spec/weary/request_spec.rb",
63
- "spec/weary/resource_spec.rb",
64
- "spec/weary/response_spec.rb",
65
- "spec/weary_spec.rb",
66
- "examples/batch.rb",
67
- "examples/repo.rb",
68
- "examples/status.rb"
69
- ]
70
14
 
71
- if s.respond_to? :specification_version then
72
- current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
73
- s.specification_version = 3
15
+ s.files = `git ls-files`.split "\n"
16
+ s.test_files = `git ls-files -- {spec,examples}/*`.split "\n"
74
17
 
75
- if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
76
- s.add_runtime_dependency(%q<crack>, [">= 0.1.7"])
77
- s.add_runtime_dependency(%q<oauth>, [">= 0.3.5"])
78
- s.add_development_dependency(%q<bundler>, [">= 0.9.7"])
79
- else
80
- s.add_dependency(%q<crack>, [">= 0.1.7"])
81
- s.add_dependency(%q<oauth>, [">= 0.3.5"])
82
- s.add_dependency(%q<bundler>, [">= 0.9.7"])
83
- end
84
- else
85
- s.add_dependency(%q<crack>, [">= 0.1.7"])
86
- s.add_dependency(%q<oauth>, [">= 0.3.5"])
87
- s.add_dependency(%q<bundler>, [">= 0.9.7"])
88
- end
89
- end
18
+ s.require_paths = ['lib']
90
19
 
20
+ s.add_runtime_dependency "rack", "~> 1.4.0"
21
+ s.add_runtime_dependency "addressable", "~> 2.2.6"
22
+ s.add_runtime_dependency "promise", "~> 0.3.0"
23
+ s.add_runtime_dependency "simple_oauth", "~> 0.1.5"
24
+ s.add_runtime_dependency "multi_json", "~> 1.1.0"
25
+ s.add_development_dependency "rspec", "~> 2.8.0"
26
+ s.add_development_dependency "webmock", "~> 1.7.10"
27
+ end