dm-rest-adapter 0.9.11 → 0.10.0
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/{History.txt → History.rdoc} +5 -3
- data/Manifest.txt +5 -8
- data/{README.markdown → README.rdoc} +0 -0
- data/Rakefile +2 -3
- data/lib/rest_adapter.rb +4 -6
- data/lib/rest_adapter/adapter.rb +109 -232
- data/lib/rest_adapter/connection.rb +12 -5
- data/lib/rest_adapter/exceptions.rb +2 -2
- data/lib/rest_adapter/formats.rb +1 -1
- data/lib/rest_adapter/version.rb +1 -1
- data/spec/fixtures/book.rb +8 -0
- data/spec/{connection_spec.rb → semipublic/connection_spec.rb} +8 -10
- data/spec/semipublic/rest_adapter_spec.rb +224 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +25 -14
- data/tasks/install.rb +1 -1
- data/tasks/spec.rb +4 -4
- metadata +16 -26
- data/README.txt +0 -47
- data/config/database.rb.example +0 -8
- data/dm-rest-adapter.gemspec +0 -34
- data/spec/crud_spec.rb +0 -250
- data/spec/ruby_forker.rb +0 -13
@@ -15,9 +15,16 @@ module DataMapperRest
|
|
15
15
|
# this is used to run the http verbs like http_post, http_put, http_delete etc.
|
16
16
|
# TODO: handle nested resources, see prefix in ActiveResource
|
17
17
|
def method_missing(method, *args)
|
18
|
-
|
19
|
-
|
20
|
-
|
18
|
+
if verb = method.to_s.match(/\Ahttp_(get|post|put|delete|head)\z/)
|
19
|
+
|
20
|
+
orig_uri, @uri = @uri, @uri.dup
|
21
|
+
begin
|
22
|
+
path, query = args[0].split('?', 2)
|
23
|
+
@uri.path = "#{path}.#{@format.extension}#{'?' << query if query}" # Should be the form of /resources
|
24
|
+
run_verb(verb.to_s.split('_').last, args[1])
|
25
|
+
ensure
|
26
|
+
@uri = orig_uri
|
27
|
+
end
|
21
28
|
end
|
22
29
|
end
|
23
30
|
|
@@ -25,8 +32,8 @@ module DataMapperRest
|
|
25
32
|
|
26
33
|
def run_verb(verb, data = nil)
|
27
34
|
request do |http|
|
28
|
-
|
29
|
-
request =
|
35
|
+
klass = Net::HTTP.find_const(Inflection.camelize(verb))
|
36
|
+
request = klass.new(@uri.to_s, @format.header)
|
30
37
|
request.basic_auth(@uri.user, @uri.password) if @uri.user && @uri.password
|
31
38
|
result = http.request(request, data)
|
32
39
|
|
@@ -44,9 +44,9 @@ module DataMapperRest
|
|
44
44
|
# 409 Conflict
|
45
45
|
class ResourceConflict < ClientError; end # :nodoc:
|
46
46
|
|
47
|
-
# 422
|
47
|
+
# 422 Unprocessable Entity
|
48
48
|
class ResourceInvalid < ClientError; # :nodoc:
|
49
|
-
#
|
49
|
+
# On this case, we could try to retrieve the validation_errors from message body:
|
50
50
|
attr_reader :body
|
51
51
|
def initialize(response, message = nil)
|
52
52
|
super(response, message)
|
data/lib/rest_adapter/formats.rb
CHANGED
data/lib/rest_adapter/version.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
$LOAD_PATH << File.dirname(__FILE__)
|
2
1
|
require 'spec_helper'
|
3
2
|
|
4
3
|
describe 'A Connection instance' do
|
@@ -6,15 +5,14 @@ describe 'A Connection instance' do
|
|
6
5
|
before do
|
7
6
|
@username = "admin"
|
8
7
|
@password = "tot@ls3crit"
|
9
|
-
@uri =
|
10
|
-
:scheme
|
11
|
-
:
|
12
|
-
:
|
13
|
-
:
|
14
|
-
:
|
15
|
-
:
|
16
|
-
|
17
|
-
))
|
8
|
+
@uri = Addressable::URI.new(
|
9
|
+
:scheme => 'http',
|
10
|
+
:user => @username,
|
11
|
+
:password => @password,
|
12
|
+
:host => 'localhost',
|
13
|
+
:port => '4000',
|
14
|
+
:query => nil
|
15
|
+
)
|
18
16
|
@connection = DataMapperRest::Connection.new(@uri, "xml")
|
19
17
|
end
|
20
18
|
|
@@ -0,0 +1,224 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe DataMapper::Adapters::RestAdapter do
|
4
|
+
before :all do
|
5
|
+
@adapter = DataMapper::Repository.adapters[:default]
|
6
|
+
end
|
7
|
+
|
8
|
+
after :all do
|
9
|
+
FakeWeb.clean_registry
|
10
|
+
end
|
11
|
+
|
12
|
+
describe '#create' do
|
13
|
+
describe 'when provided a Resource' do
|
14
|
+
before :all do
|
15
|
+
body = <<-XML.compress_lines
|
16
|
+
<book>
|
17
|
+
<id type='datamapper::types::serial'>1</id>
|
18
|
+
<created_at type='datetime'>2009-05-17T22:38:42-07:00</created_at>
|
19
|
+
<title>DataMapper</title>
|
20
|
+
<author>Dan Kubb</author>
|
21
|
+
</book>
|
22
|
+
XML
|
23
|
+
|
24
|
+
headers = { 'Content-Length' => body.respond_to?(:bytesize) ? body.bytesize : body.size }
|
25
|
+
|
26
|
+
FakeWeb.register_uri(:post, 'http://admin:secret@localhost:4000/books.xml', :status => 200, :headers => headers, :body => body)
|
27
|
+
end
|
28
|
+
|
29
|
+
before :all do
|
30
|
+
@resource = Book.new(:created_at => DateTime.parse('2009-05-17T22:38:42-07:00'), :title => 'DataMapper', :author => 'Dan Kubb')
|
31
|
+
@resources = [ @resource ]
|
32
|
+
|
33
|
+
@response = @adapter.create(@resources)
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'should return an Array containing the Resource' do
|
37
|
+
@response.should equal(@resources)
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'should set the identity field' do
|
41
|
+
@resource.id.should == 1
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe '#read' do
|
47
|
+
describe 'with unscoped query' do
|
48
|
+
before :all do
|
49
|
+
body = <<-XML.compress_lines
|
50
|
+
<books>
|
51
|
+
<book>
|
52
|
+
<id type='datamapper::types::serial'>1</id>
|
53
|
+
<created_at type='datetime'>2009-05-17T22:38:42-07:00</created_at>
|
54
|
+
<title>DataMapper</title>
|
55
|
+
<author>Dan Kubb</author>
|
56
|
+
</book>
|
57
|
+
</books>
|
58
|
+
XML
|
59
|
+
|
60
|
+
headers = { 'Content-Length' => body.respond_to?(:bytesize) ? body.bytesize : body.size }
|
61
|
+
|
62
|
+
FakeWeb.register_uri(:get, 'http://admin:secret@localhost:4000/books.xml', :status => 200, :headers => headers, :body => body)
|
63
|
+
end
|
64
|
+
|
65
|
+
before :all do
|
66
|
+
@query = Book.all.query
|
67
|
+
|
68
|
+
@response = @adapter.read(@query)
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'should return an Array with the matching Records' do
|
72
|
+
@response.should == [ { 'id' => 1, 'created_at' => DateTime.parse('2009-05-17T22:38:42-07:00'), 'title' => 'DataMapper', 'author' => 'Dan Kubb' } ]
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
describe 'with query scoped by a key' do
|
77
|
+
before :all do
|
78
|
+
|
79
|
+
end
|
80
|
+
|
81
|
+
|
82
|
+
before :all do
|
83
|
+
@query = Book.all(:id => 1, :limit => 1).query
|
84
|
+
|
85
|
+
body = <<-XML.compress_lines
|
86
|
+
<book>
|
87
|
+
<id type='datamapper::types::serial'>1</id>
|
88
|
+
<created_at type='datetime'>2009-05-17T22:38:42-07:00</created_at>
|
89
|
+
<title>DataMapper</title>
|
90
|
+
<author>Dan Kubb</author>
|
91
|
+
</book>
|
92
|
+
XML
|
93
|
+
|
94
|
+
headers = { 'Content-Length' => body.respond_to?(:bytesize) ? body.bytesize : body.size }
|
95
|
+
|
96
|
+
FakeWeb.register_uri(:get, 'http://admin:secret@localhost:4000/books/1.xml', :status => 200, :headers => headers, :body => body)
|
97
|
+
|
98
|
+
@response = @adapter.read(@query)
|
99
|
+
end
|
100
|
+
|
101
|
+
it 'should return an Array with the matching Records' do
|
102
|
+
@response.should == [ { 'id' => 1, 'created_at' => DateTime.parse('2009-05-17T22:38:42-07:00'), 'title' => 'DataMapper', 'author' => 'Dan Kubb' } ]
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
describe 'with query scoped by a non-key' do
|
107
|
+
before :all do
|
108
|
+
body = <<-XML.compress_lines
|
109
|
+
<books>
|
110
|
+
<book>
|
111
|
+
<id type='datamapper::types::serial'>1</id>
|
112
|
+
<created_at type='datetime'>2009-05-17T22:38:42-07:00</created_at>
|
113
|
+
<title>DataMapper</title>
|
114
|
+
<author>Dan Kubb</author>
|
115
|
+
</book>
|
116
|
+
|
117
|
+
<!-- provide an extra resource, which should be filtered out -->
|
118
|
+
<book>
|
119
|
+
<id type='datamapper::types::serial'>2</id>
|
120
|
+
<created_at type='datetime'>2009-05-17T22:38:42-07:00</created_at>
|
121
|
+
<title>DataMapper</title>
|
122
|
+
<author>John Doe</author>
|
123
|
+
</book>
|
124
|
+
</books>
|
125
|
+
XML
|
126
|
+
|
127
|
+
headers = { 'Content-Length' => body.respond_to?(:bytesize) ? body.bytesize : body.size }
|
128
|
+
|
129
|
+
FakeWeb.register_uri(:get, 'http://admin:secret@localhost:4000/books.xml?author=Dan+Kubb', :status => 200, :headers => headers, :body => body)
|
130
|
+
end
|
131
|
+
|
132
|
+
before :all do
|
133
|
+
@query = Book.all(:author => 'Dan Kubb').query
|
134
|
+
|
135
|
+
@response = @adapter.read(@query)
|
136
|
+
end
|
137
|
+
|
138
|
+
it 'should return an Array with the matching Records' do
|
139
|
+
@response.should == [ { 'id' => 1, 'created_at' => DateTime.parse('2009-05-17T22:38:42-07:00'), 'title' => 'DataMapper', 'author' => 'Dan Kubb' } ]
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
describe '#update' do
|
145
|
+
before :all do
|
146
|
+
body = <<-XML.compress_lines
|
147
|
+
<books>
|
148
|
+
<book>
|
149
|
+
<id type='datamapper::types::serial'>1</id>
|
150
|
+
<created_at type='datetime'>2009-05-17T22:38:42-07:00</created_at>
|
151
|
+
<title>DataMapper</title>
|
152
|
+
<author>Dan Kubb</author>
|
153
|
+
</book>
|
154
|
+
</books>
|
155
|
+
XML
|
156
|
+
|
157
|
+
headers = { 'Content-Length' => body.respond_to?(:bytesize) ? body.bytesize : body.size }
|
158
|
+
|
159
|
+
FakeWeb.register_uri(:get, 'http://admin:secret@localhost:4000/books.xml', :status => 200, :headers => headers, :body => body)
|
160
|
+
end
|
161
|
+
|
162
|
+
before :all do
|
163
|
+
body = <<-XML.compress_lines
|
164
|
+
<book>
|
165
|
+
<id type='datamapper::types::serial'>1</id>
|
166
|
+
<created_at type='datetime'>2009-05-17T22:38:42-07:00</created_at>
|
167
|
+
<title>DataMapper</title>
|
168
|
+
<author>John Doe</author>
|
169
|
+
</book>
|
170
|
+
XML
|
171
|
+
|
172
|
+
headers = { 'Content-Length' => body.respond_to?(:bytesize) ? body.bytesize : body.size }
|
173
|
+
|
174
|
+
FakeWeb.register_uri(:put, 'http://admin:secret@localhost:4000/books/1.xml', :status => 200, :headers => headers, :body => body)
|
175
|
+
end
|
176
|
+
|
177
|
+
before :all do
|
178
|
+
@resources = Book.all
|
179
|
+
|
180
|
+
@response = @adapter.update({ Book.properties[:author] => 'John Doe' }, @resources)
|
181
|
+
end
|
182
|
+
|
183
|
+
it 'should return the number of updated Resources' do
|
184
|
+
@response.should == 1
|
185
|
+
end
|
186
|
+
|
187
|
+
it 'should modify the Resource' do
|
188
|
+
@resources.first.author.should == 'John Doe'
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
describe '#delete' do
|
193
|
+
before :all do
|
194
|
+
body = <<-XML.compress_lines
|
195
|
+
<books>
|
196
|
+
<book>
|
197
|
+
<id type='datamapper::types::serial'>1</id>
|
198
|
+
<created_at type='datetime'>2009-05-17T22:38:42-07:00</created_at>
|
199
|
+
<title>DataMapper</title>
|
200
|
+
<author>Dan Kubb</author>
|
201
|
+
</book>
|
202
|
+
</books>
|
203
|
+
XML
|
204
|
+
|
205
|
+
headers = { 'Content-Length' => body.respond_to?(:bytesize) ? body.bytesize : body.size }
|
206
|
+
|
207
|
+
FakeWeb.register_uri(:get, 'http://admin:secret@localhost:4000/books.xml', :status => 200, :headers => headers, :body => body)
|
208
|
+
end
|
209
|
+
|
210
|
+
before :all do
|
211
|
+
FakeWeb.register_uri(:delete, 'http://admin:secret@localhost:4000/books/1.xml', :status => 204)
|
212
|
+
end
|
213
|
+
|
214
|
+
before :all do
|
215
|
+
@resources = Book.all
|
216
|
+
|
217
|
+
@response = @adapter.delete(@resources)
|
218
|
+
end
|
219
|
+
|
220
|
+
it 'should return the number of updated Resources' do
|
221
|
+
@response.should == 1
|
222
|
+
end
|
223
|
+
end
|
224
|
+
end
|
data/spec/spec.opts
CHANGED
data/spec/spec_helper.rb
CHANGED
@@ -1,20 +1,31 @@
|
|
1
|
-
require 'pathname'
|
2
1
|
require 'rubygems'
|
2
|
+
require 'pathname'
|
3
|
+
require 'fakeweb'
|
4
|
+
|
5
|
+
# use local dm-core if running from a typical dev checkout.
|
6
|
+
lib = File.join('..', '..', '..', 'dm-core', 'lib')
|
7
|
+
$LOAD_PATH.unshift(lib) if File.directory?(lib)
|
8
|
+
require 'dm-core'
|
9
|
+
|
10
|
+
# use local dm-validations if running from a typical dev checkout.
|
11
|
+
lib = File.join('..', '..', 'dm-validations', 'lib')
|
12
|
+
$LOAD_PATH.unshift(lib) if File.directory?(lib)
|
13
|
+
require 'dm-validations'
|
14
|
+
|
15
|
+
# use local dm-serializer if running from a typical dev checkout.
|
16
|
+
lib = File.join('..', '..', 'dm-serializer', 'lib')
|
17
|
+
$LOAD_PATH.unshift(lib) if File.directory?(lib)
|
18
|
+
require 'dm-serializer'
|
19
|
+
|
20
|
+
# Support running specs with 'rake spec' and 'spec'
|
21
|
+
$LOAD_PATH.unshift('lib') unless $LOAD_PATH.include?('lib')
|
3
22
|
|
4
|
-
|
23
|
+
require 'rest_adapter'
|
5
24
|
|
6
|
-
|
7
|
-
lib = ROOT.parent.parent.join('dm-serializer', 'lib').expand_path
|
8
|
-
$LOAD_PATH.unshift(lib) if lib.directory?
|
25
|
+
ROOT = Pathname(__FILE__).dirname.parent
|
9
26
|
|
10
|
-
|
27
|
+
DataMapper.setup(:default, 'rest://admin:secret@localhost:4000/?format=xml')
|
11
28
|
|
12
|
-
|
29
|
+
Dir[ROOT / 'spec' / 'fixtures' / '**' / '*.rb'].each { |rb| require rb }
|
13
30
|
|
14
|
-
|
15
|
-
include DataMapper::Resource
|
16
|
-
property :author, String
|
17
|
-
property :created_at, DateTime
|
18
|
-
property :id, Integer, :serial => true
|
19
|
-
property :title, String
|
20
|
-
end
|
31
|
+
FakeWeb.allow_net_connect = false
|
data/tasks/install.rb
CHANGED
@@ -4,7 +4,7 @@ end
|
|
4
4
|
|
5
5
|
desc "Install #{GEM_NAME} #{GEM_VERSION}"
|
6
6
|
task :install => [ :package ] do
|
7
|
-
sudo_gem "install
|
7
|
+
sudo_gem "install pkg/#{GEM_NAME}-#{GEM_VERSION} --no-update-sources"
|
8
8
|
end
|
9
9
|
|
10
10
|
desc "Uninstall #{GEM_NAME} #{GEM_VERSION}"
|
data/tasks/spec.rb
CHANGED
@@ -1,6 +1,4 @@
|
|
1
1
|
begin
|
2
|
-
gem 'rspec', '~>1.2'
|
3
|
-
require 'spec'
|
4
2
|
require 'spec/rake/spectask'
|
5
3
|
|
6
4
|
task :default => [ :spec ]
|
@@ -8,16 +6,18 @@ begin
|
|
8
6
|
desc 'Run specifications'
|
9
7
|
Spec::Rake::SpecTask.new(:spec) do |t|
|
10
8
|
t.spec_opts << '--options' << 'spec/spec.opts' if File.exists?('spec/spec.opts')
|
11
|
-
t.
|
9
|
+
t.libs << 'lib' << 'spec' # needed for CI rake spec task, duplicated in spec_helper
|
12
10
|
|
13
11
|
begin
|
14
|
-
|
12
|
+
require 'rcov'
|
15
13
|
t.rcov = JRUBY ? false : (ENV.has_key?('NO_RCOV') ? ENV['NO_RCOV'] != 'true' : true)
|
16
14
|
t.rcov_opts << '--exclude' << 'spec'
|
17
15
|
t.rcov_opts << '--text-summary'
|
18
16
|
t.rcov_opts << '--sort' << 'coverage' << '--sort-reverse'
|
19
17
|
rescue LoadError
|
20
18
|
# rcov not installed
|
19
|
+
rescue SyntaxError
|
20
|
+
# rcov syntax invalid
|
21
21
|
end
|
22
22
|
end
|
23
23
|
rescue LoadError
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dm-rest-adapter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.10.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Scott Burton @ Joyent Inc
|
@@ -9,19 +9,10 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-09-16 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
|
-
dependencies:
|
15
|
-
|
16
|
-
name: dm-core
|
17
|
-
type: :runtime
|
18
|
-
version_requirement:
|
19
|
-
version_requirements: !ruby/object:Gem::Requirement
|
20
|
-
requirements:
|
21
|
-
- - "="
|
22
|
-
- !ruby/object:Gem::Version
|
23
|
-
version: 0.9.11
|
24
|
-
version:
|
14
|
+
dependencies: []
|
15
|
+
|
25
16
|
description: REST Adapter for DataMapper
|
26
17
|
email:
|
27
18
|
- scott.burton [a] joyent [d] com
|
@@ -30,39 +21,38 @@ executables: []
|
|
30
21
|
extensions: []
|
31
22
|
|
32
23
|
extra_rdoc_files:
|
33
|
-
- README.
|
24
|
+
- README.rdoc
|
34
25
|
- LICENSE
|
35
26
|
- TODO
|
36
|
-
- History.
|
27
|
+
- History.rdoc
|
37
28
|
files:
|
38
|
-
- History.
|
29
|
+
- History.rdoc
|
39
30
|
- LICENSE
|
40
31
|
- Manifest.txt
|
41
|
-
- README.
|
42
|
-
- README.txt
|
32
|
+
- README.rdoc
|
43
33
|
- Rakefile
|
44
34
|
- TODO
|
45
|
-
- config/database.rb.example
|
46
|
-
- dm-rest-adapter.gemspec
|
47
35
|
- lib/rest_adapter.rb
|
48
36
|
- lib/rest_adapter/adapter.rb
|
49
37
|
- lib/rest_adapter/connection.rb
|
50
38
|
- lib/rest_adapter/exceptions.rb
|
51
39
|
- lib/rest_adapter/formats.rb
|
52
40
|
- lib/rest_adapter/version.rb
|
53
|
-
- spec/
|
54
|
-
- spec/
|
55
|
-
- spec/
|
41
|
+
- spec/fixtures/book.rb
|
42
|
+
- spec/semipublic/connection_spec.rb
|
43
|
+
- spec/semipublic/rest_adapter_spec.rb
|
56
44
|
- spec/spec.opts
|
57
45
|
- spec/spec_helper.rb
|
58
46
|
- tasks/install.rb
|
59
47
|
- tasks/spec.rb
|
60
48
|
has_rdoc: true
|
61
49
|
homepage: http://github.com/datamapper/dm-more/tree/master/adapters/dm-rest-adapter
|
50
|
+
licenses: []
|
51
|
+
|
62
52
|
post_install_message:
|
63
53
|
rdoc_options:
|
64
54
|
- --main
|
65
|
-
- README.
|
55
|
+
- README.rdoc
|
66
56
|
require_paths:
|
67
57
|
- lib
|
68
58
|
required_ruby_version: !ruby/object:Gem::Requirement
|
@@ -80,9 +70,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
80
70
|
requirements: []
|
81
71
|
|
82
72
|
rubyforge_project: datamapper
|
83
|
-
rubygems_version: 1.3.
|
73
|
+
rubygems_version: 1.3.5
|
84
74
|
signing_key:
|
85
|
-
specification_version:
|
75
|
+
specification_version: 3
|
86
76
|
summary: REST Adapter for DataMapper
|
87
77
|
test_files: []
|
88
78
|
|