dm-rest-adapter 0.9.11 → 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
- @uri.path = "/#{args[0]}.#{@format.extension}" # Should be the form of /resources
19
- if verb = method.to_s.match(/^http_(get|post|put|delete|head)$/)
20
- run_verb(verb.to_s.split("_").last, args[1])
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
- mod = Net::HTTP::module_eval(Inflection.camelize(verb))
29
- request = mod.new(@uri.to_s, @format.header)
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
- # On this case, we could try to retrieve the validation_errors from message body:
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)
@@ -9,7 +9,7 @@ module DataMapperRest
9
9
  end
10
10
 
11
11
  def header
12
- {'Content-Type' => @mime}
12
+ { 'Content-Type' => @mime }
13
13
  end
14
14
 
15
15
  end
@@ -1,3 +1,3 @@
1
1
  module DataMapperRest
2
- VERSION = '0.9.11'
2
+ VERSION = '0.10.0'.freeze
3
3
  end
@@ -0,0 +1,8 @@
1
+ class Book
2
+ include DataMapper::Resource
3
+
4
+ property :id, Serial
5
+ property :created_at, DateTime
6
+ property :title, String
7
+ property :author, String
8
+ end
@@ -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 = DataObjects::URI.parse(Addressable::URI.new(
10
- :scheme => 'http',
11
- :adapter => 'rest',
12
- :user => @username,
13
- :password => @password,
14
- :host => 'localhost',
15
- :port => '4000',
16
- :query => nil
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
@@ -1 +1,2 @@
1
1
  --colour
2
+ --loadby random
@@ -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
- ROOT = Pathname(__FILE__).dirname.parent.expand_path
23
+ require 'rest_adapter'
5
24
 
6
- # use local dm-serializer if running from dm-more directly
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
- require ROOT + 'lib/rest_adapter'
27
+ DataMapper.setup(:default, 'rest://admin:secret@localhost:4000/?format=xml')
11
28
 
12
- load ROOT + 'config/database.rb.example'
29
+ Dir[ROOT / 'spec' / 'fixtures' / '**' / '*.rb'].each { |rb| require rb }
13
30
 
14
- class Book
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
@@ -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 --local pkg/#{GEM_NAME}-#{GEM_VERSION} --no-update-sources"
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}"
@@ -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.spec_files = Pathname.glob((ROOT + 'spec/**/*_spec.rb').to_s).map { |f| f.to_s }
9
+ t.libs << 'lib' << 'spec' # needed for CI rake spec task, duplicated in spec_helper
12
10
 
13
11
  begin
14
- gem 'rcov', '~>0.8'
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.9.11
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-03-29 00:00:00 -07:00
12
+ date: 2009-09-16 00:00:00 -07:00
13
13
  default_executable:
14
- dependencies:
15
- - !ruby/object:Gem::Dependency
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.txt
24
+ - README.rdoc
34
25
  - LICENSE
35
26
  - TODO
36
- - History.txt
27
+ - History.rdoc
37
28
  files:
38
- - History.txt
29
+ - History.rdoc
39
30
  - LICENSE
40
31
  - Manifest.txt
41
- - README.markdown
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/connection_spec.rb
54
- - spec/crud_spec.rb
55
- - spec/ruby_forker.rb
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.txt
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.1
73
+ rubygems_version: 1.3.5
84
74
  signing_key:
85
- specification_version: 2
75
+ specification_version: 3
86
76
  summary: REST Adapter for DataMapper
87
77
  test_files: []
88
78