pillow 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2010 Alexander Kern and Artcentric Networks LLC
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,15 @@
1
+ # Pillow
2
+
3
+ Take a nap, Pillow lets you REST.
4
+
5
+ ## Description
6
+
7
+ Pillow lets you use HTTP to its absolute fullest extent. Rather than expose an API to cover up the details of the protocol, it uses the protocol to structure the client itself. URL's are not defined in the resources, forcing the use of links and URL templates to navigate throughout the web service. Think of it like an automated web browser.
8
+
9
+ ## Examples
10
+
11
+ _Coming soon_
12
+
13
+ ## License
14
+
15
+ Pillow is licensed under the MIT License.
@@ -0,0 +1,18 @@
1
+ begin
2
+ require 'jeweler'
3
+ Jeweler::Tasks.new do |gemspec|
4
+ gemspec.name = 'pillow'
5
+ gemspec.summary = 'Take a nap, Pillow lets you REST.'
6
+ gemspec.description = 'Ruby HTTP client that takes full advantage of HTTP.'
7
+ gemspec.email = 'alex@kernul.com'
8
+ gemspec.authors = ['Alexander Kern']
9
+
10
+ gemspec.add_dependency('patron')
11
+ gemspec.add_dependency('json')
12
+ gemspec.add_dependency('addressable')
13
+
14
+ gemspec.add_development_dependency('rspec')
15
+ end
16
+ rescue LoadError
17
+ puts 'Jeweler not available. Install it with: gem install jeweler'
18
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.5.0
@@ -0,0 +1,9 @@
1
+ module Pillow
2
+
3
+ autoload :Request, 'pillow/request'
4
+ autoload :Response, 'pillow/response'
5
+
6
+ autoload :Resource, 'pillow/resource'
7
+ autoload :Method, 'pillow/method'
8
+
9
+ end
@@ -0,0 +1,41 @@
1
+ class Pillow::Method
2
+
3
+ attr_reader :method, :resource
4
+
5
+ def initialize(method, resource)
6
+ @method = method
7
+ @resource = resource
8
+ end
9
+
10
+ def before(&before)
11
+ @before = before if before
12
+ @before
13
+ end
14
+
15
+ def after(&after)
16
+ @after = after if after
17
+ @after
18
+ end
19
+
20
+ def process(*args)
21
+ request = Pillow::Request.new(method, resource.url)
22
+ request.query_values.replace(resource.query_values)
23
+ request.headers.replace(resource.headers)
24
+
25
+ before.call(request, *args) if before
26
+
27
+ options = {}
28
+ options[:data] = request.raw_body if request.raw_body
29
+
30
+ raw_response = resource.session.request(request.method, request.full_url,
31
+ request.headers, options)
32
+
33
+ response = Pillow::Response.new
34
+ response.status = raw_response.status
35
+ response.headers = raw_response.headers
36
+ response.raw_body = raw_response.body
37
+
38
+ return after.call(response, *args) if after
39
+ response
40
+ end
41
+ end
@@ -0,0 +1,67 @@
1
+ require 'rubygems'
2
+ require 'addressable/uri'
3
+ require 'json'
4
+
5
+ class Pillow::Request
6
+
7
+ HTTP_METHODS = [:options, :get, :head, :post, :put, :delete, :trace, :patch]
8
+ HTTP_METHODS_WITH_BODY = [:post, :put, :patch]
9
+
10
+ attr_reader :method, :url, :query_values, :headers
11
+
12
+ def initialize(method, url)
13
+ self.method = method
14
+ @url = url
15
+ @query_values = {}
16
+ @headers = {}
17
+ end
18
+
19
+ def method=(method)
20
+ if HTTP_METHODS.include?(method)
21
+ @method = method
22
+ end
23
+
24
+ @method ||= :get
25
+ end
26
+
27
+ def body
28
+ if HTTP_METHODS_WITH_BODY.include?(method)
29
+ @body || ''
30
+ end
31
+ end
32
+
33
+ def body=(body)
34
+ if HTTP_METHODS_WITH_BODY.include?(method)
35
+ @body = body
36
+
37
+ if headers['Content-Type'] == 'application/json'
38
+ @raw_body = body.to_json
39
+ else
40
+ @raw_body = body
41
+ end
42
+ end
43
+ end
44
+
45
+ def raw_body
46
+ if HTTP_METHODS_WITH_BODY.include?(method)
47
+ @raw_body || ''
48
+ end
49
+ end
50
+
51
+ def raw_body=(raw_body)
52
+ if HTTP_METHODS_WITH_BODY.include?(method)
53
+ @raw_body = raw_body
54
+ @body = raw_body
55
+ end
56
+ end
57
+
58
+ def full_url
59
+ if query_values.empty?
60
+ return url
61
+ end
62
+
63
+ full_url = Addressable::URI.parse(url)
64
+ full_url.query_values = query_values
65
+ full_url.to_s
66
+ end
67
+ end
@@ -0,0 +1,100 @@
1
+ require 'rubygems'
2
+ require 'addressable/uri'
3
+ require 'addressable/template'
4
+ require 'patron'
5
+
6
+ class Pillow::Resource
7
+
8
+ attr_reader :url
9
+
10
+ def initialize(url)
11
+ @url = if url.is_a?(Hash)
12
+ self.class.template.expand(url).to_s
13
+ else
14
+ url.to_s
15
+ end
16
+ end
17
+
18
+ class << self
19
+ def session
20
+ @session ||= Patron::Session.new
21
+ end
22
+
23
+ def query_values
24
+ @query_values ||= {}
25
+ end
26
+
27
+ def headers
28
+ @headers ||= {}
29
+ end
30
+
31
+ def template(template = nil)
32
+ @template = Addressable::Template.new(template) if template
33
+ @template
34
+ end
35
+
36
+ def options
37
+ @options ||= Pillow::Method.new(:options, self)
38
+ end
39
+
40
+ def get
41
+ @get ||= Pillow::Method.new(:get, self)
42
+ end
43
+
44
+ def head
45
+ @head ||= Pillow::Method.new(:head, self)
46
+ end
47
+
48
+ def post
49
+ @post ||= Pillow::Method.new(:post, self)
50
+ end
51
+
52
+ def put
53
+ @put ||= Pillow::Method.new(:put, self)
54
+ end
55
+
56
+ def delete
57
+ @delete ||= Pillow::Method.new(:delete, self)
58
+ end
59
+
60
+ def trace
61
+ @trace ||= Pillow::Method.new(:trace, self)
62
+ end
63
+
64
+ def patch
65
+ @patch ||= Pillow::Method.new(:patch, self)
66
+ end
67
+ end
68
+
69
+ def options(*args)
70
+ self.class.options.process(*args)
71
+ end
72
+
73
+ def get(*args)
74
+ self.class.get.process(*args)
75
+ end
76
+
77
+ def head(*args)
78
+ self.class.head.process(*args)
79
+ end
80
+
81
+ def post(*args)
82
+ self.class.post.process(*args)
83
+ end
84
+
85
+ def put(*args)
86
+ self.class.put.process(*args)
87
+ end
88
+
89
+ def delete(*args)
90
+ self.class.delete.process(*args)
91
+ end
92
+
93
+ def trace(*args)
94
+ self.class.trace.process(*args)
95
+ end
96
+
97
+ def patch(*args)
98
+ self.class.patch.process(*args)
99
+ end
100
+ end
@@ -0,0 +1,18 @@
1
+ require 'rubygems'
2
+ require 'json'
3
+
4
+ class Pillow::Response
5
+
6
+ attr_accessor :status, :headers, :body
7
+ attr_reader :raw_body
8
+
9
+ def raw_body=(raw_body)
10
+ @raw_body = raw_body
11
+
12
+ if headers['Content-Type'] == 'application/json'
13
+ @body = JSON.parse(raw_body)
14
+ else
15
+ @body = raw_body
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,228 @@
1
+ require 'spec/spec_helper'
2
+
3
+ describe Pillow::Method do
4
+ before do
5
+ @resource = stub('resource')
6
+ @session = mock('session')
7
+ @response = stub('response')
8
+
9
+ @resource.stub!(:session).and_return(@session)
10
+ @resource.stub!(:url).and_return('http://foo.com/')
11
+ @resource.stub!(:query_values).and_return('foo' => 'bar')
12
+ @resource.stub!(:headers).and_return('X-Foo' => 'Bar')
13
+
14
+ @session.stub!(:request).and_return(@response)
15
+
16
+ @response.stub!(:body).and_return('test')
17
+ @response.stub!(:headers).and_return('X-Foo' => 'Bar')
18
+ @response.stub!(:status).and_return(200)
19
+
20
+ @method = Pillow::Method.new(:get, @resource)
21
+ end
22
+
23
+ context 'upon creation' do
24
+ it 'should have a method' do
25
+ @method.method.should == :get
26
+ end
27
+
28
+ it 'should have a resource' do
29
+ @method.resource.should == @resource
30
+ end
31
+
32
+ it 'should not have a before block' do
33
+ @method.before.should == nil
34
+ end
35
+
36
+ it 'should not have an after block' do
37
+ @method.after.should == nil
38
+ end
39
+ end
40
+
41
+ describe 'before block' do
42
+ it 'should be settable with a block' do
43
+ before_block = Proc.new {}
44
+ @method.before &before_block
45
+
46
+ @method.before.should equal(before_block)
47
+ end
48
+
49
+ it 'should be overwritable' do
50
+ before_block = Proc.new {}
51
+ before_block_2 = Proc.new {}
52
+ @method.before &before_block
53
+ @method.before &before_block_2
54
+
55
+ @method.before.should equal(before_block_2)
56
+ end
57
+ end
58
+
59
+ describe 'after block' do
60
+ it 'should be settable with a block' do
61
+ after_block = Proc.new {}
62
+ @method.after &after_block
63
+
64
+ @method.after.should equal(after_block)
65
+ end
66
+
67
+ it 'should be overwritable' do
68
+ after_block = Proc.new {}
69
+ after_block_2 = Proc.new {}
70
+ @method.after &after_block
71
+ @method.after &after_block_2
72
+
73
+ @method.after.should equal(after_block_2)
74
+ end
75
+ end
76
+
77
+ describe '#process' do
78
+ context 'when there is no before block' do
79
+ it 'should not call the before block' do
80
+ allow_message_expectations_on_nil
81
+ @method.before.should_not_receive(:call)
82
+
83
+ @method.process
84
+ end
85
+ end
86
+
87
+ context 'when there is a before block' do
88
+ before do
89
+ @method.before do |request|
90
+ end
91
+ end
92
+
93
+ it 'should create a request with the method' do
94
+ @method.should_receive(:method).once
95
+ @method.process
96
+ end
97
+
98
+ it 'should create a request with the resource url' do
99
+ @resource.should_receive(:url).once
100
+ @method.process
101
+ end
102
+
103
+ it 'should receive a request with the resource query values' do
104
+ @method.before do |request|
105
+ request.query_values.should == {'foo' => 'bar'}
106
+ end
107
+
108
+ @method.process
109
+ end
110
+
111
+ it 'should receive a request with the resource headers' do
112
+ @method.before do |request|
113
+ request.headers.should == {'X-Foo' => 'Bar'}
114
+ end
115
+
116
+ @method.process
117
+ end
118
+
119
+ context 'when arguments are supplied' do
120
+ it 'should call the before block with the arguments' do
121
+ @method.before do |request, mock_1, mock_2|
122
+ mock_1.should == 'foo'
123
+ mock_2.should == 'bar'
124
+ end
125
+
126
+ @method.process('foo', 'bar')
127
+ end
128
+ end
129
+ end
130
+
131
+ it 'should request using the method' do
132
+ @session.should_receive(:request).with(:get, anything(), anything(), anything())
133
+ @method.process
134
+ end
135
+
136
+ it 'should request the generated url with the resource session' do
137
+ @session.should_receive(:request).with(anything(), 'http://foo.com/?foo=bar', anything(), anything())
138
+ @method.process
139
+ end
140
+
141
+ it 'should include headers with the request' do
142
+ @session.should_receive(:request).with(anything(), anything(), {'X-Foo' => 'Bar'}, anything())
143
+ @method.process
144
+ end
145
+
146
+ it 'should include the raw body with the request' do
147
+ @method = Pillow::Method.new(:put, @resource)
148
+ @method.before do |request|
149
+ request.should_receive(:raw_body).at_least(:once).and_return('foo')
150
+ end
151
+
152
+ @session.should_receive(:request).with(:put, anything(), anything(), :data => 'foo')
153
+
154
+ @method.process
155
+ end
156
+
157
+ context 'when there is no after block' do
158
+ it 'should not call the after block' do
159
+ allow_message_expectations_on_nil
160
+ @method.before.should_not_receive(:call)
161
+
162
+ @method.process
163
+ end
164
+
165
+ it 'should return the response' do
166
+ @method.process.should be_a_kind_of(Pillow::Response)
167
+ end
168
+ end
169
+
170
+ context 'when there is an after block' do
171
+ before do
172
+ @method.after do |response|
173
+ end
174
+ end
175
+
176
+ it 'should receive a response with the response status' do
177
+ @method.after do |response|
178
+ response.status.should == 200
179
+ end
180
+
181
+ @method.process
182
+ end
183
+
184
+ it 'should receive a response with the response headers' do
185
+ @method.after do |response|
186
+ response.headers.should == {'X-Foo' => 'Bar'}
187
+ end
188
+
189
+ @method.process
190
+ end
191
+
192
+ it 'should receive a response with the response raw body' do
193
+ @method.after do |response|
194
+ response.raw_body.should == 'test'
195
+ end
196
+
197
+ @method.process
198
+ end
199
+
200
+ it 'should receive a response with the response body' do
201
+ @method.after do |response|
202
+ response.body.should == 'test'
203
+ end
204
+
205
+ @method.process
206
+ end
207
+
208
+ it 'should return the output of the after block' do
209
+ @method.after do |response|
210
+ 'test'
211
+ end
212
+
213
+ @method.process.should == 'test'
214
+ end
215
+
216
+ context 'when arguments are supplied' do
217
+ it 'should call the after block with the arguments' do
218
+ @method.after do |response, mock_1, mock_2|
219
+ mock_1.should == 'foo'
220
+ mock_2.should == 'bar'
221
+ end
222
+
223
+ @method.process('foo', 'bar')
224
+ end
225
+ end
226
+ end
227
+ end
228
+ end
@@ -0,0 +1,230 @@
1
+ require 'spec/spec_helper'
2
+
3
+ describe Pillow::Request do
4
+ before do
5
+ @request = Pillow::Request.new(:get, 'http://foo.com/')
6
+ end
7
+
8
+ it 'should have a url' do
9
+ @request.url.should == 'http://foo.com/'
10
+ end
11
+
12
+ describe '#method' do
13
+ it 'should have a method' do
14
+ @request.method.should == :get
15
+ end
16
+
17
+ context 'valid methods' do
18
+ it 'should allow the OPTIONS method' do
19
+ @request.method = :options
20
+ @request.method.should == :options
21
+ end
22
+
23
+ it 'should allow the GET method' do
24
+ @request.method = :get
25
+ @request.method.should == :get
26
+ end
27
+
28
+ it 'should allow the HEAD method' do
29
+ @request.method = :head
30
+ @request.method.should == :head
31
+ end
32
+
33
+ it 'should allow the POST method' do
34
+ @request.method = :post
35
+ @request.method.should == :post
36
+ end
37
+
38
+ it 'should allow the PUT method' do
39
+ @request.method = :put
40
+ @request.method.should == :put
41
+ end
42
+
43
+ it 'should allow the DELETE method' do
44
+ @request.method = :delete
45
+ @request.method.should == :delete
46
+ end
47
+
48
+ it 'should allow the TRACE method' do
49
+ @request.method = :trace
50
+ @request.method.should == :trace
51
+ end
52
+
53
+ it 'should allow the PATCH method' do
54
+ @request.method = :patch
55
+ @request.method.should == :patch
56
+ end
57
+ end
58
+
59
+ context 'invalid method' do
60
+ it 'should reset the method to GET' do
61
+ @request.method = :post
62
+ @request.method = :fake_method
63
+ @request.method = :get
64
+ end
65
+ end
66
+ end
67
+
68
+ describe 'query values' do
69
+ it 'should by default be empty' do
70
+ @request.query_values.should be_empty
71
+ end
72
+
73
+ it 'should have query values' do
74
+ @request.query_values['foo'] = 'bar'
75
+ @request.query_values['foo'].should == 'bar'
76
+ end
77
+ end
78
+
79
+ describe 'headers' do
80
+ it 'should by default be empty' do
81
+ @request.headers.should be_empty
82
+ end
83
+
84
+ it 'should have headers' do
85
+ @request.headers['foo'] = 'bar'
86
+ @request.headers['foo'].should == 'bar'
87
+ end
88
+ end
89
+
90
+ describe '#body' do
91
+ context 'when the method should contain a body' do
92
+ it 'should by default be a blank string' do
93
+ @request.method = :put
94
+ @request.body.should == ''
95
+ end
96
+
97
+ it 'should be settable for PUT' do
98
+ @request.method = :put
99
+ @request.body = 'foo'
100
+ @request.body.should == 'foo'
101
+ end
102
+
103
+ it 'should be settable for POST' do
104
+ @request.method = :post
105
+ @request.body = 'foo'
106
+ @request.body.should == 'foo'
107
+ end
108
+
109
+ it 'should be settable for PATCH' do
110
+ @request.method = :patch
111
+ @request.body = 'foo'
112
+ @request.body.should == 'foo'
113
+ end
114
+ end
115
+
116
+ context 'when the method should not contain a body' do
117
+ it 'should by default be nil' do
118
+ @request.body.should be_nil
119
+ end
120
+
121
+ it 'should not be settable' do
122
+ @request.method = :get
123
+ @request.body = 'foo'
124
+ @request.body.should be_nil
125
+ end
126
+ end
127
+ end
128
+
129
+ describe '#raw_body' do
130
+ context 'when the method should contain a body' do
131
+ it 'should by default be a blank string' do
132
+ @request.method = :put
133
+ @request.body.should == ''
134
+ end
135
+
136
+ it 'should be settable for PUT' do
137
+ @request.method = :put
138
+ @request.body = 'foo'
139
+ @request.body.should == 'foo'
140
+ end
141
+
142
+ it 'should be settable for POST' do
143
+ @request.method = :post
144
+ @request.body = 'foo'
145
+ @request.body.should == 'foo'
146
+ end
147
+
148
+ it 'should be settable for PATCH' do
149
+ @request.method = :patch
150
+ @request.body = 'foo'
151
+ @request.body.should == 'foo'
152
+ end
153
+ end
154
+
155
+ context 'when the method should not contain a body' do
156
+ describe 'raw body' do
157
+ it 'should by default be nil' do
158
+ @request.raw_body.should be_nil
159
+ end
160
+
161
+ it 'should not be settable' do
162
+ @request.method = :get
163
+ @request.raw_body = 'foo'
164
+ @request.raw_body.should be_nil
165
+ end
166
+ end
167
+ end
168
+ end
169
+
170
+ describe 'body parsing' do
171
+ before do
172
+ @request.method = :put
173
+ end
174
+
175
+ context 'when the Content-Type is not application/json' do
176
+ before do
177
+ @request.headers['Content-Type'] = 'application/xml'
178
+ end
179
+
180
+ it 'should be the same as the body' do
181
+ @request.body = 'foo'
182
+ @request.raw_body.should == 'foo'
183
+ end
184
+
185
+ it 'should be settable' do
186
+ @request.raw_body = 'foo'
187
+ @request.raw_body.should == 'foo'
188
+ end
189
+
190
+ it 'should be able to be set to change the body' do
191
+ @request.raw_body = 'foo'
192
+ @request.body.should == 'foo'
193
+ end
194
+ end
195
+
196
+ context 'when the Content-Type is application/json' do
197
+ before do
198
+ @request.headers['Content-Type'] = 'application/json'
199
+ end
200
+
201
+ it 'should convert the body from a hash to JSON' do
202
+ @request.body = {'foo' => 'bar'}
203
+ @request.raw_body.should == '{"foo":"bar"}'
204
+ end
205
+
206
+ it 'should keep the original body in body' do
207
+ @request.body = {'foo' => 'bar'}
208
+ @request.body.should == {'foo' => 'bar'}
209
+ end
210
+ end
211
+ end
212
+
213
+ describe '#full_url' do
214
+ context 'when there are no query values' do
215
+ it 'should be the same as the url' do
216
+ @request.full_url.should == @request.url
217
+ end
218
+ end
219
+
220
+ context 'when there are query values' do
221
+ before do
222
+ @request.query_values['foo'] = 'bar'
223
+ end
224
+
225
+ it 'should append the query values to the url' do
226
+ @request.full_url.should == @request.url + '?foo=bar'
227
+ end
228
+ end
229
+ end
230
+ end
@@ -0,0 +1,156 @@
1
+ require 'spec/spec_helper'
2
+
3
+ describe Pillow::Resource do
4
+ before do
5
+ @klass = Class.new(Pillow::Resource)
6
+ @resource = @klass.new('http://foo.com/')
7
+ end
8
+
9
+ describe '#self.session' do
10
+ subject { @klass.session }
11
+ it { should be_a_kind_of(Patron::Session) }
12
+ end
13
+
14
+ describe '#self.query_values' do
15
+ subject { @klass.query_values }
16
+
17
+ context 'when first created' do
18
+ it { should be_empty }
19
+ end
20
+
21
+ it 'should store query values for the resource' do
22
+ @klass.query_values['foo'] = 'bar'
23
+ @klass.query_values['foo'].should == 'bar'
24
+ end
25
+ end
26
+
27
+ describe '#self.headers' do
28
+ subject { @klass.headers }
29
+
30
+ context 'when first created' do
31
+ it { should be_empty }
32
+ end
33
+
34
+ it 'should store headers for the resource' do
35
+ @klass.headers['foo'] = 'bar'
36
+ @klass.headers['foo'].should == 'bar'
37
+ end
38
+ end
39
+
40
+ describe '#self.template' do
41
+ subject { @klass.template }
42
+
43
+ context 'when first created' do
44
+ it { should be_nil }
45
+ end
46
+
47
+ context 'when set to a template' do
48
+ before do
49
+ @klass.template 'http://example.com/{foo}'
50
+ end
51
+
52
+ it 'should store the template' do
53
+ @klass.template.should be_a_kind_of(Addressable::Template)
54
+ end
55
+ end
56
+ end
57
+
58
+ describe '#initialize' do
59
+ context 'when given a url' do
60
+ before do
61
+ @resource = @klass.new('http://exmaple.com')
62
+ end
63
+
64
+ it 'should store the url' do
65
+ @resource.url.should == 'http://exmaple.com'
66
+ end
67
+ end
68
+
69
+ context 'when given a params list' do
70
+ before do
71
+ @klass.template 'http://example.com/{foo}'
72
+ @resource = @klass.new('foo' => 'test')
73
+ end
74
+
75
+ it 'should expand the parent template with the params' do
76
+ @resource.url.should == 'http://example.com/test'
77
+ end
78
+ end
79
+ end
80
+
81
+ describe 'methods definitions' do
82
+ it 'should have an OPTIONS method' do
83
+ @klass.options.method.should == :options
84
+ end
85
+
86
+ it 'should have a GET method' do
87
+ @klass.get.method.should == :get
88
+ end
89
+
90
+ it 'should have a HEAD method' do
91
+ @klass.head.method.should == :head
92
+ end
93
+
94
+ it 'should have a POST method' do
95
+ @klass.post.method.should == :post
96
+ end
97
+
98
+ it 'should have a PUT method' do
99
+ @klass.put.method.should == :put
100
+ end
101
+
102
+ it 'should have a DELETE method' do
103
+ @klass.delete.method.should == :delete
104
+ end
105
+
106
+ it 'should have a TRACE method' do
107
+ @klass.trace.method.should == :trace
108
+ end
109
+
110
+ it 'should have a PATCH method' do
111
+ @klass.patch.method.should == :patch
112
+ end
113
+ end
114
+
115
+ describe 'methods' do
116
+ it 'should be able to call OPTIONS' do
117
+ @klass.options.should_receive(:process).with('test').and_return(123)
118
+ @resource.options('test').should == 123
119
+ end
120
+
121
+ it 'should be able to call GET' do
122
+ @klass.get.should_receive(:process).with('test').and_return(123)
123
+ @resource.get('test').should == 123
124
+ end
125
+
126
+ it 'should be able to call HEAD' do
127
+ @klass.head.should_receive(:process).with('test').and_return(123)
128
+ @resource.head('test').should == 123
129
+ end
130
+
131
+ it 'should be able to call POST' do
132
+ @klass.post.should_receive(:process).with('test').and_return(123)
133
+ @resource.post('test').should == 123
134
+ end
135
+
136
+ it 'should be able to call PUT' do
137
+ @klass.put.should_receive(:process).with('test').and_return(123)
138
+ @resource.put('test').should == 123
139
+ end
140
+
141
+ it 'should be able to call DELETE' do
142
+ @klass.delete.should_receive(:process).with('test').and_return(123)
143
+ @resource.delete('test').should == 123
144
+ end
145
+
146
+ it 'should be able to call TRACE' do
147
+ @klass.trace.should_receive(:process).with('test').and_return(123)
148
+ @resource.trace('test').should == 123
149
+ end
150
+
151
+ it 'should be able to call PATCH' do
152
+ @klass.patch.should_receive(:process).with('test').and_return(123)
153
+ @resource.patch('test').should == 123
154
+ end
155
+ end
156
+ end
@@ -0,0 +1,42 @@
1
+ require 'spec/spec_helper'
2
+
3
+ describe Pillow::Response do
4
+ before do
5
+ @response = Pillow::Response.new
6
+ @response.status = 200
7
+ @response.headers = {'X-Foo' => 'Bar'}
8
+ @response.raw_body = 'test'
9
+ end
10
+
11
+ it 'should store the status' do
12
+ @response.status.should == 200
13
+ end
14
+
15
+ it 'should store the headers' do
16
+ @response.headers.should == {'X-Foo' => 'Bar'}
17
+ end
18
+
19
+ it 'should store the body' do
20
+ @response.body.should == 'test'
21
+ end
22
+
23
+ it 'should store the origin raw body' do
24
+ @response.raw_body.should == 'test'
25
+ end
26
+
27
+ context 'when the Content-Type is application/json' do
28
+ before do
29
+ @data = {'foo' => 'bar'}
30
+ @response.headers['Content-Type'] = 'application/json'
31
+ @response.raw_body = @data.to_json
32
+ end
33
+
34
+ it 'should process the body' do
35
+ @response.body.should == @data
36
+ end
37
+
38
+ it 'should store the origin body' do
39
+ @response.raw_body.should == @data.to_json
40
+ end
41
+ end
42
+ end
@@ -0,0 +1 @@
1
+ --color
@@ -0,0 +1,17 @@
1
+ require 'spec'
2
+ require 'spec/autorun'
3
+
4
+ require File.join(File.dirname(__FILE__), '..', 'lib', 'pillow')
5
+
6
+ Spec::Runner.configure do |config|
7
+ end
8
+
9
+ def mock_response(status, headers, body)
10
+ response = Patron::Response.new
11
+ response.instance_eval do
12
+ @status = status
13
+ @headers = headers
14
+ @body = body
15
+ end
16
+ response
17
+ end
metadata ADDED
@@ -0,0 +1,141 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: pillow
3
+ version: !ruby/object:Gem::Version
4
+ hash: 11
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 5
9
+ - 0
10
+ version: 0.5.0
11
+ platform: ruby
12
+ authors:
13
+ - Alexander Kern
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-05-19 00:00:00 -07:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: patron
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 3
30
+ segments:
31
+ - 0
32
+ version: "0"
33
+ type: :runtime
34
+ version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ name: json
37
+ prerelease: false
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ hash: 3
44
+ segments:
45
+ - 0
46
+ version: "0"
47
+ type: :runtime
48
+ version_requirements: *id002
49
+ - !ruby/object:Gem::Dependency
50
+ name: addressable
51
+ prerelease: false
52
+ requirement: &id003 !ruby/object:Gem::Requirement
53
+ none: false
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ hash: 3
58
+ segments:
59
+ - 0
60
+ version: "0"
61
+ type: :runtime
62
+ version_requirements: *id003
63
+ - !ruby/object:Gem::Dependency
64
+ name: rspec
65
+ prerelease: false
66
+ requirement: &id004 !ruby/object:Gem::Requirement
67
+ none: false
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ hash: 3
72
+ segments:
73
+ - 0
74
+ version: "0"
75
+ type: :development
76
+ version_requirements: *id004
77
+ description: Ruby HTTP client that takes full advantage of HTTP.
78
+ email: alex@kernul.com
79
+ executables: []
80
+
81
+ extensions: []
82
+
83
+ extra_rdoc_files:
84
+ - LICENSE
85
+ - README.md
86
+ files:
87
+ - LICENSE
88
+ - README.md
89
+ - Rakefile
90
+ - VERSION
91
+ - lib/pillow.rb
92
+ - lib/pillow/method.rb
93
+ - lib/pillow/request.rb
94
+ - lib/pillow/resource.rb
95
+ - lib/pillow/response.rb
96
+ - spec/pillow/method_spec.rb
97
+ - spec/pillow/request_spec.rb
98
+ - spec/pillow/resource_spec.rb
99
+ - spec/pillow/response_spec.rb
100
+ - spec/spec.opts
101
+ - spec/spec_helper.rb
102
+ has_rdoc: true
103
+ homepage:
104
+ licenses: []
105
+
106
+ post_install_message:
107
+ rdoc_options:
108
+ - --charset=UTF-8
109
+ require_paths:
110
+ - lib
111
+ required_ruby_version: !ruby/object:Gem::Requirement
112
+ none: false
113
+ requirements:
114
+ - - ">="
115
+ - !ruby/object:Gem::Version
116
+ hash: 3
117
+ segments:
118
+ - 0
119
+ version: "0"
120
+ required_rubygems_version: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ">="
124
+ - !ruby/object:Gem::Version
125
+ hash: 3
126
+ segments:
127
+ - 0
128
+ version: "0"
129
+ requirements: []
130
+
131
+ rubyforge_project:
132
+ rubygems_version: 1.3.7
133
+ signing_key:
134
+ specification_version: 3
135
+ summary: Take a nap, Pillow lets you REST.
136
+ test_files:
137
+ - spec/pillow/method_spec.rb
138
+ - spec/pillow/request_spec.rb
139
+ - spec/pillow/resource_spec.rb
140
+ - spec/pillow/response_spec.rb
141
+ - spec/spec_helper.rb