restfully 0.5.1 → 0.5.2
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.
- data/CHANGELOG +10 -0
- data/VERSION +1 -1
- data/lib/restfully/collection.rb +7 -6
- data/lib/restfully/http/adapters/rest_client_adapter.rb +7 -0
- data/lib/restfully/resource.rb +33 -14
- data/lib/restfully/session.rb +6 -0
- data/lib/restfully.rb +1 -1
- data/restfully.gemspec +2 -2
- data/spec/http/rest_client_adapter_spec.rb +1 -1
- data/spec/resource_spec.rb +33 -7
- data/spec/session_spec.rb +8 -0
- metadata +2 -2
data/CHANGELOG
CHANGED
@@ -1,3 +1,13 @@
|
|
1
|
+
0.5.2
|
2
|
+
* support for DELETE requests. Use resource.delete(options)
|
3
|
+
* fixed bug in resource.load(:reload => true)
|
4
|
+
|
5
|
+
0.5.1
|
6
|
+
* fixed bug in resource.reload
|
7
|
+
|
8
|
+
0.5.0
|
9
|
+
* support for POST requests. Use resource.submit(payload, options)
|
10
|
+
|
1
11
|
0.4.1
|
2
12
|
* added a require 'yaml' in restfully.rb (priteau);
|
3
13
|
* added an introductory message when using the command-line tool;
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.5.
|
1
|
+
0.5.2
|
data/lib/restfully/collection.rb
CHANGED
@@ -38,6 +38,12 @@ module Restfully
|
|
38
38
|
super(property)
|
39
39
|
end
|
40
40
|
end
|
41
|
+
|
42
|
+
# Returns the current number of items (not the total number)
|
43
|
+
# in the collection.
|
44
|
+
def length
|
45
|
+
@items.length
|
46
|
+
end
|
41
47
|
|
42
48
|
def populate_object(key, value)
|
43
49
|
case key
|
@@ -68,12 +74,7 @@ module Restfully
|
|
68
74
|
def inspect
|
69
75
|
@items.inspect
|
70
76
|
end
|
71
|
-
|
72
|
-
# Returns the current number of items (not the total number)
|
73
|
-
# in the collection.
|
74
|
-
def length
|
75
|
-
@items.length
|
76
|
-
end
|
77
|
+
|
77
78
|
|
78
79
|
def pretty_print(pp)
|
79
80
|
super(pp) do |pp|
|
@@ -23,6 +23,13 @@ module Restfully
|
|
23
23
|
end
|
24
24
|
end # def get
|
25
25
|
|
26
|
+
|
27
|
+
def delete(request)
|
28
|
+
in_order_to_get_the_response_to(request) do |resource|
|
29
|
+
resource.delete(request.headers)
|
30
|
+
end
|
31
|
+
end # def delete
|
32
|
+
|
26
33
|
def post(request)
|
27
34
|
in_order_to_get_the_response_to(request) do |resource|
|
28
35
|
resource.post(request.raw_body, request.headers)
|
data/lib/restfully/resource.rb
CHANGED
@@ -52,6 +52,10 @@ module Restfully
|
|
52
52
|
@properties[key]
|
53
53
|
end
|
54
54
|
|
55
|
+
def respond_to?(method, *args)
|
56
|
+
@links.has_key?(method.to_s) || super(method, *args)
|
57
|
+
end
|
58
|
+
|
55
59
|
def method_missing(method, *args)
|
56
60
|
if link = @links[method.to_s]
|
57
61
|
session.logger.debug "Loading link #{method}, args=#{args.inspect}"
|
@@ -77,7 +81,7 @@ module Restfully
|
|
77
81
|
def load(options = {})
|
78
82
|
options = options.symbolize_keys
|
79
83
|
force_reload = !!options.delete(:reload)
|
80
|
-
stale! unless (request = executed_requests['GET']) && request['options'] == options && request['body']
|
84
|
+
stale! unless !force_reload && (request = executed_requests['GET']) && request['options'] == options && request['body']
|
81
85
|
if stale?
|
82
86
|
reset
|
83
87
|
if !force_reload && options[:body]
|
@@ -100,10 +104,17 @@ module Restfully
|
|
100
104
|
end
|
101
105
|
self
|
102
106
|
end
|
107
|
+
|
108
|
+
# Convenience function to make a resource.load(:reload => true)
|
109
|
+
def reload
|
110
|
+
current_options = executed_requests['GET']['options'] rescue {}
|
111
|
+
stale!
|
112
|
+
self.load(current_options.merge(:reload => true))
|
113
|
+
end
|
103
114
|
|
104
115
|
# == Description
|
105
116
|
# Executes a POST request on the resource, reload it and returns self if successful.
|
106
|
-
# If the response status is different
|
117
|
+
# If the response status is different from 2xx, raises a HTTP::ClientError or HTTP::ServerError.
|
107
118
|
# <tt>payload</tt>:: the input body of the request.
|
108
119
|
# It may be a serialized string, or a ruby object
|
109
120
|
# (that will be serialized according to the given or default content-type).
|
@@ -132,19 +143,27 @@ module Restfully
|
|
132
143
|
end
|
133
144
|
end
|
134
145
|
|
146
|
+
# == Description
|
147
|
+
# Executes a DELETE request on the resource, and returns true if successful.
|
148
|
+
# If the response status is different from 2xx or 3xx, raises an HTTP::ClientError or HTTP::ServerError.
|
149
|
+
# <tt>options</tt>:: list of options to pass to the request (see below)
|
150
|
+
# == Options
|
151
|
+
# <tt>:query</tt>:: a hash of query parameters to pass along the request.
|
152
|
+
# E.g. : resource.delete(:query => {:param1 => "value1"})
|
153
|
+
# <tt>:headers</tt>:: a hash of HTTP headers to pass along the request.
|
154
|
+
# E.g. : resource.delete(:headers => {:accept => 'application/json'})
|
155
|
+
def delete(options = {})
|
156
|
+
options = options.symbolize_keys
|
157
|
+
raise NotImplementedError, "The DELETE method is not allowed for this resource." unless http_methods.include?('DELETE')
|
158
|
+
response = session.delete(self.uri, options) # raises an exception if there is an error
|
159
|
+
stale!
|
160
|
+
(200..399).include?(response.status)
|
161
|
+
end
|
162
|
+
|
135
163
|
|
136
164
|
def stale!; @status = :stale; end
|
137
165
|
def stale?; @status == :stale; end
|
138
|
-
|
139
|
-
def uri_for(path)
|
140
|
-
uri.merge(URI.parse(path.to_s))
|
141
|
-
end
|
142
|
-
|
143
|
-
def reload
|
144
|
-
current_options = executed_requests['GET']['options'] rescue {}
|
145
|
-
stale!
|
146
|
-
self.load(current_options.merge(:reload => true))
|
147
|
-
end
|
166
|
+
|
148
167
|
|
149
168
|
# == Description
|
150
169
|
# Returns the list of allowed HTTP methods on the resource.
|
@@ -157,8 +176,8 @@ module Restfully
|
|
157
176
|
(executed_requests['GET']['headers']['Allow'] || "GET").split(/,\s*/)
|
158
177
|
end
|
159
178
|
|
160
|
-
def
|
161
|
-
|
179
|
+
def uri_for(path)
|
180
|
+
uri.merge(URI.parse(path.to_s))
|
162
181
|
end
|
163
182
|
|
164
183
|
def inspect(*args)
|
data/lib/restfully/session.rb
CHANGED
@@ -49,6 +49,12 @@ module Restfully
|
|
49
49
|
transmit :post, HTTP::Request.new(uri_for(path), :body => body, :headers => options.delete(:headers), :query => options.delete(:query))
|
50
50
|
end
|
51
51
|
|
52
|
+
# returns an HTTP::Response object or raise a Restfully::HTTP::Error
|
53
|
+
def delete(path, options = {})
|
54
|
+
options = options.symbolize_keys
|
55
|
+
transmit :delete, HTTP::Request.new(uri_for(path), :headers => options.delete(:headers), :query => options.delete(:query))
|
56
|
+
end
|
57
|
+
|
52
58
|
# builds the complete URI, based on the given path and the session's base_uri
|
53
59
|
def uri_for(path)
|
54
60
|
URI.join(base_uri.to_s, path.to_s)
|
data/lib/restfully.rb
CHANGED
data/restfully.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{restfully}
|
8
|
-
s.version = "0.5.
|
8
|
+
s.version = "0.5.2"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Cyril Rohr"]
|
12
|
-
s.date = %q{2009-12-
|
12
|
+
s.date = %q{2009-12-14}
|
13
13
|
s.default_executable = %q{restfully}
|
14
14
|
s.description = %q{Experimental code for auto-generation of wrappers on top of RESTful APIs that follow HATEOAS principles and provide OPTIONS methods and/or Allow headers.}
|
15
15
|
s.email = %q{cyril.rohr@gmail.com}
|
@@ -19,7 +19,7 @@ describe Restfully::HTTP::Adapters::RestClientAdapter do
|
|
19
19
|
end
|
20
20
|
it "should raise a not implemented error when trying to use functions not implemented yet" do
|
21
21
|
adapter = Restfully::HTTP::Adapters::RestClientAdapter.new("https://api.grid5000.fr")
|
22
|
-
lambda{adapter.
|
22
|
+
lambda{adapter.put(mock("restfully request"))}.should raise_error NotImplementedError, "PUT is not supported by your adapter."
|
23
23
|
end
|
24
24
|
it "should rescue any RestClient::Exception and correctly populate the response" do
|
25
25
|
res = mock(Net::HTTPResponse, :code => 404, :body => '{"message":"whatever"}', :to_hash => {'Content-Type' => 'application/json;charset=utf-8', 'Content-Length' => 22}, :[] => '')
|
data/spec/resource_spec.rb
CHANGED
@@ -9,15 +9,16 @@ describe Resource do
|
|
9
9
|
end
|
10
10
|
|
11
11
|
describe "accessors" do
|
12
|
+
before(:each) do
|
13
|
+
@resource = Resource.new(@uri, @session=mock("session"))
|
14
|
+
end
|
12
15
|
it "should have a reader on the session" do
|
13
|
-
resource
|
14
|
-
resource.
|
15
|
-
resource.session.should == session
|
16
|
+
@resource.should_not respond_to(:session=)
|
17
|
+
@resource.session.should == @session
|
16
18
|
end
|
17
19
|
it "should have a reader on the uri" do
|
18
|
-
resource
|
19
|
-
resource.
|
20
|
-
resource.uri.should == URI.parse("uri")
|
20
|
+
@resource.should_not respond_to(:uri=)
|
21
|
+
@resource.uri.should == @uri
|
21
22
|
end
|
22
23
|
end
|
23
24
|
|
@@ -177,11 +178,21 @@ describe Resource do
|
|
177
178
|
resource.links.keys.should =~ ['versions', 'clusters', 'environments', 'status', 'parent', 'version']
|
178
179
|
end
|
179
180
|
|
180
|
-
it "should reload the resource if user forces reload" do
|
181
|
+
it "should reload the resource if user forces reload [first loading]" do
|
181
182
|
resource = Resource.new(@uri, session = mock("session"))
|
182
183
|
session.should_receive(:get).and_return(response = mock("response", :headers => {}, :body => {}))
|
183
184
|
resource.load(:reload => true, :body => mock("body"))
|
184
185
|
end
|
186
|
+
it "should reload the resource when user forces reload [has been loaded at least once before]" do
|
187
|
+
resource = Resource.new(@uri, session = mock("session"))
|
188
|
+
resource.instance_variable_set "@status", :loaded
|
189
|
+
resource.should_not be_stale
|
190
|
+
resource.should_receive(:executed_requests).at_least(1).and_return({
|
191
|
+
'GET' => {'options' => {:query => {:q=>1}}, 'body' => {'a' => 'b'}}
|
192
|
+
})
|
193
|
+
session.should_receive(:get).and_return(response = mock("response", :headers => {}, :body => {}))
|
194
|
+
resource.load(:reload => true, :query => {:q => 1})
|
195
|
+
end
|
185
196
|
end
|
186
197
|
|
187
198
|
|
@@ -241,4 +252,19 @@ describe Resource do
|
|
241
252
|
@resource.submit("whatever").should == @resource
|
242
253
|
end
|
243
254
|
end
|
255
|
+
|
256
|
+
describe "deleting" do
|
257
|
+
before do
|
258
|
+
@resource = Resource.new(@uri, @session = mock("session", :logger => @logger))
|
259
|
+
@resource.stub!(:http_methods).and_return(['GET', 'DELETE'])
|
260
|
+
end
|
261
|
+
it "should raise an error if the DELETE method is not supported by the service" do
|
262
|
+
@resource.stub!(:http_methods).and_return(['GET'])
|
263
|
+
lambda{@resource.delete}.should raise_error(NotImplementedError, /DELETE method is not allowed/)
|
264
|
+
end
|
265
|
+
it "should send a DELETE request to the resource URI" do
|
266
|
+
@session.should_receive(:delete).with(@uri, :query => {:q => 'v'}, :headers => {'Accept' => 'application/json'}).and_return(response = mock("http response", :status => 204))
|
267
|
+
@resource.delete(:query => {:q => 'v'}, :headers => {'Accept' => 'application/json'}).should be_true
|
268
|
+
end
|
269
|
+
end
|
244
270
|
end
|
data/spec/session_spec.rb
CHANGED
@@ -153,4 +153,12 @@ describe Session do
|
|
153
153
|
end
|
154
154
|
end
|
155
155
|
|
156
|
+
describe "DELETEing resources" do
|
157
|
+
it "should create a new Request object and transmit it" do
|
158
|
+
Restfully::HTTP::Request.should_receive(:new).with(URI.parse('https://api.grid5000.fr/sid/some/path'), :headers => {:accept => 'application/json'}, :query => nil).and_return(@request)
|
159
|
+
@session.should_receive(:transmit).with(:delete, @request)
|
160
|
+
@session.delete('some/path', 'headers' => {:accept => 'application/json'})
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
156
164
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: restfully
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
4
|
+
version: 0.5.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Cyril Rohr
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-12-
|
12
|
+
date: 2009-12-14 00:00:00 +01:00
|
13
13
|
default_executable: restfully
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|