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