dm-rest-adapter 0.9.3 → 0.9.4

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.
@@ -23,4 +23,4 @@ stories/helper.rb
23
23
  stories/resources/helpers/book.rb
24
24
  stories/resources/helpers/story_helper.rb
25
25
  stories/resources/steps/read.rb
26
- stories/resources/steps/using_rest_adapter.rb
26
+ stories/resources/steps/using_rest_adapter.rb
@@ -3,7 +3,10 @@ require 'pathname'
3
3
  require Pathname(__FILE__).dirname + 'rest_adapter/version'
4
4
  gem 'dm-core', DataMapper::More::RestAdapter::VERSION
5
5
  require 'dm-core'
6
+
7
+ gem 'extlib', '=0.9.4'
6
8
  require 'extlib'
9
+
7
10
  require 'dm-serializer'
8
11
  require 'net/http'
9
12
  require 'rexml/document'
@@ -14,7 +17,7 @@ module DataMapper
14
17
  module Adapters
15
18
  class RestAdapter < AbstractAdapter
16
19
  include Extlib
17
-
20
+
18
21
  # Creates a new resource in the specified repository.
19
22
  def create(resources)
20
23
  count = 0
@@ -22,7 +25,7 @@ module DataMapper
22
25
  resource_name = Inflection.underscore(resource.class.name)
23
26
  result = http_post("/#{resource_name.pluralize}.xml", resource.to_xml)
24
27
  # TODO: Raise error if cannot reach server
25
- success = result.instance_of?(Net::HTTPCreated)
28
+ success = result.instance_of?(Net::HTTPCreated)
26
29
  if success
27
30
  count += 1
28
31
  # TODO: Fix commented out code below to work through the identity_map of the repository
@@ -33,7 +36,7 @@ module DataMapper
33
36
  end
34
37
  count
35
38
  end
36
-
39
+
37
40
  # read_set
38
41
  #
39
42
  # Examples of query string:
@@ -62,7 +65,7 @@ module DataMapper
62
65
  end
63
66
  end
64
67
  end
65
-
68
+
66
69
  def read_one(query)
67
70
  resource = nil
68
71
  resource_name = resource_name_from_query(query)
@@ -73,16 +76,16 @@ module DataMapper
73
76
  else
74
77
  id = query.conditions.first[2]
75
78
  # KLUGE: Again, we're assuming below that we're dealing with a pluralized resource mapping
76
-
79
+
77
80
  response = http_get("/#{resource_name.pluralize}/#{id}.xml")
78
-
81
+
79
82
  # KLUGE: Rails returns HTML if it can't find a resource. A properly RESTful app would return a 404, right?
80
83
  return nil if response.is_a? Net::HTTPNotFound || response.content_type == "text/html"
81
-
84
+
82
85
  data = response.body
83
86
  resource_meta = parse_resource(data, query.model, query)
84
87
  end
85
- if resource_meta
88
+ if resource_meta
86
89
  if resource_meta.has_key?(:associations)
87
90
  load_nested_resources_from resource_meta[:associations], query
88
91
  end
@@ -90,13 +93,13 @@ module DataMapper
90
93
  end
91
94
  resource
92
95
  end
93
-
96
+
94
97
  def update(attributes, query)
95
98
  # TODO What if we have a compound key?
96
99
  raise NotImplementedError.new unless is_single_resource_query? query
97
100
  id = query.conditions.first[2]
98
101
  resource = nil
99
- query.repository.scope do
102
+ query.repository.scope do
100
103
  resource = query.model.get(id)
101
104
  end
102
105
  attributes.each do |attr, val|
@@ -107,15 +110,15 @@ module DataMapper
107
110
  # TODO: Raise error if cannot reach server
108
111
  res.kind_of?(Net::HTTPSuccess) ? 1 : 0
109
112
  end
110
-
113
+
111
114
  def delete(query)
112
115
  raise NotImplementedError.new unless is_single_resource_query? query
113
116
  id = query.conditions.first[2]
114
117
  res = http_delete("/#{resource_name_from_query(query).pluralize}/#{id}.xml")
115
118
  res.kind_of?(Net::HTTPSuccess) ? 1 : 0
116
119
  end
117
-
118
- protected
120
+
121
+ protected
119
122
  def load_nested_resources_from(nested_resources, query)
120
123
  nested_resources.each do |resource_meta|
121
124
  # TODO: Houston, we have a problem. Model#load expects a Query. When we're nested, we don't have a query yet...
@@ -125,7 +128,7 @@ module DataMapper
125
128
  #end
126
129
  end
127
130
  end
128
-
131
+
129
132
  def read_set_all(repository, query, resource_name)
130
133
  # TODO: how do we know whether the resource we're talking to is singular or plural?
131
134
  res = http_get("/#{resource_name.pluralize}.xml")
@@ -133,18 +136,18 @@ module DataMapper
133
136
  parse_resources(data, query.model, query)
134
137
  # TODO: Raise error if cannot reach server
135
138
  end
136
-
139
+
137
140
  # GET /books/4200
138
141
  def read_set_for_condition(repository, query, resource_name)
139
142
  # More complex conditions
140
143
  raise NotImplementedError.new
141
- end
142
-
144
+ end
145
+
143
146
  # query.conditions like [[:eql, #<Property:Book:id>, 4200]]
144
147
  def is_single_resource_query?(query)
145
148
  query.conditions.length == 1 && query.conditions.first.first == :eql && query.conditions.first[1].name == :id
146
149
  end
147
-
150
+
148
151
  def http_put(uri, data = nil)
149
152
  request { |http| http.put(uri, data, {"Content-Type", "application/xml"}) }
150
153
  end
@@ -167,13 +170,13 @@ module DataMapper
167
170
  res = yield(http)
168
171
  end
169
172
  res
170
- end
173
+ end
171
174
 
172
175
  def values_from_rexml(entity_element, dm_model_class)
173
176
  resource = {}
174
177
  resource[:values] = []
175
178
  entity_element.elements.each do |field_element|
176
- attribute = dm_model_class.properties(repository.name).find do |property|
179
+ attribute = dm_model_class.properties(repository.name).find do |property|
177
180
  # *MUST* use Inflection.underscore on the XML as Rails converts '_' to '-' in the XML
178
181
  property.name.to_s == Inflection.underscore(field_element.name.to_s)
179
182
  end
@@ -188,7 +191,7 @@ module DataMapper
188
191
  field_element.each_element do |associated_element|
189
192
  model = association[1].child_model
190
193
  (resource[:associations] ||= []) << {
191
- :model => model,
194
+ :model => model,
192
195
  :value => values_from_rexml(associated_element, association[1].child_model)
193
196
  }
194
197
  end
@@ -204,7 +207,7 @@ module DataMapper
204
207
  return nil unless entity_element
205
208
  values_from_rexml(entity_element, dm_model_class)
206
209
  end
207
-
210
+
208
211
  def parse_resources(xml, dm_model_class, query = nil)
209
212
  doc = REXML::Document::new(xml)
210
213
  # # TODO: handle singular resource case as well....
@@ -216,15 +219,15 @@ module DataMapper
216
219
  doc.elements.collect("#{resource_name.pluralize}/#{resource_name}") do |entity_element|
217
220
  values_from_rexml(entity_element, dm_model_class)
218
221
  end
219
- end
220
-
222
+ end
223
+
221
224
  def resource_name_from_model(model)
222
225
  Inflection.underscore(model.name)
223
226
  end
224
-
227
+
225
228
  def resource_name_from_query(query)
226
229
  resource_name_from_model(query.model)
227
230
  end
228
231
  end
229
232
  end
230
- end
233
+ end
@@ -1,7 +1,7 @@
1
1
  module DataMapper
2
2
  module More
3
3
  class RestAdapter
4
- VERSION = "0.9.3"
4
+ VERSION = "0.9.4"
5
5
  end
6
6
  end
7
- end
7
+ end
@@ -2,20 +2,20 @@ $LOAD_PATH << File.dirname(__FILE__)
2
2
  require 'spec_helper'
3
3
 
4
4
  describe 'A REST adapter' do
5
-
5
+
6
6
  before do
7
7
  @adapter = DataMapper::Repository.adapters[:default]
8
8
  end
9
-
9
+
10
10
  describe 'when saving a resource' do
11
-
11
+
12
12
  before do
13
13
  @book = Book.new(:title => 'Hello, World!', :author => 'Anonymous')
14
14
  end
15
-
15
+
16
16
  it 'should make an HTTP Post' do
17
17
  @adapter.should_receive(:http_post).with('/books.xml', @book.to_xml)
18
18
  @book.save
19
19
  end
20
20
  end
21
- end
21
+ end
@@ -2,21 +2,21 @@ $LOAD_PATH << File.dirname(__FILE__)
2
2
  require 'spec_helper'
3
3
 
4
4
  describe 'A REST adapter' do
5
-
5
+
6
6
  before do
7
7
  @adapter = DataMapper::Repository.adapters[:default]
8
8
  end
9
-
9
+
10
10
  describe 'when deleting an existing resource' do
11
11
  before do
12
12
  @book = Book.new(:title => 'Hello, World!', :author => 'Anonymous')
13
13
  @book.stub!(:new_record?).and_return(false)
14
14
  end
15
-
15
+
16
16
  it 'should do an HTTP DELETE' do
17
17
  @adapter.should_receive(:http_delete)
18
18
  @book.destroy
19
19
  end
20
-
20
+
21
21
  end
22
- end
22
+ end
@@ -2,15 +2,15 @@ $LOAD_PATH << File.dirname(__FILE__)
2
2
  require 'spec_helper'
3
3
 
4
4
  describe 'A REST adapter' do
5
-
5
+
6
6
  before do
7
7
  @adapter = DataMapper::Repository.adapters[:default]
8
8
  end
9
-
9
+
10
10
  describe 'when getting one resource' do
11
11
 
12
12
  describe 'if the resource exists' do
13
-
13
+
14
14
  before do
15
15
  book_xml = <<-BOOK
16
16
  <?xml version='1.0' encoding='UTF-8'?>
@@ -27,25 +27,25 @@ describe 'A REST adapter' do
27
27
  @response.stub!(:body).and_return(book_xml)
28
28
  @adapter.stub!(:http_get).and_return(@response)
29
29
  end
30
-
30
+
31
31
  it 'should return the resource' do
32
32
  book = Book.get(@id)
33
33
  book.should_not be_nil
34
34
  book.id.should be_an_instance_of(Fixnum)
35
35
  book.id.should == 1
36
36
  end
37
-
37
+
38
38
  it 'should do an HTTP GET' do
39
39
  @adapter.should_receive(:http_get).with('/books/1.xml').and_return(@response)
40
40
  Book.get(@id)
41
41
  end
42
-
42
+
43
43
  it "it be equal to itself" do
44
44
  Book.get(@id).should == Book.get(@id)
45
- end
45
+ end
46
46
  end
47
-
48
-
47
+
48
+
49
49
  describe 'if the resource does not exist' do
50
50
  it 'should return nil' do
51
51
  @id = 1
@@ -58,9 +58,9 @@ describe 'A REST adapter' do
58
58
  end
59
59
  end
60
60
  end
61
-
61
+
62
62
  describe 'when getting all resource of a particular type' do
63
- before do
63
+ before do
64
64
  books_xml = <<-BOOK
65
65
  <?xml version='1.0' encoding='UTF-8'?>
66
66
  <books type='array'>
@@ -70,7 +70,7 @@ describe 'A REST adapter' do
70
70
  <id type='integer'>1</id>
71
71
  <title>The Dispossed</title>
72
72
  <updated-at type='datetime'>2008-06-08T17:02:28Z</updated-at>
73
- </book>
73
+ </book>
74
74
  <book>
75
75
  <author>Stephen King</author>
76
76
  <created-at type='datetime'>2008-06-08T17:03:07Z</created-at>
@@ -84,18 +84,18 @@ describe 'A REST adapter' do
84
84
  @response.stub!(:body).and_return(books_xml)
85
85
  @adapter.stub!(:http_get).and_return(@response)
86
86
  end
87
-
87
+
88
88
  it 'should get a non-empty list' do
89
89
  Book.all.should_not be_empty
90
90
  end
91
-
91
+
92
92
  it 'should receive one Resource for each entity in the XML' do
93
93
  Book.all.size.should == 2
94
94
  end
95
-
95
+
96
96
  it 'should do an HTTP GET' do
97
97
  @adapter.should_receive(:http_get).and_return(@response)
98
98
  Book.first
99
- end
99
+ end
100
100
  end
101
- end
101
+ end
@@ -10,4 +10,4 @@ module RubyForker
10
10
  cmd << " 2> #{stderr}" unless stderr.nil?
11
11
  `#{cmd}`
12
12
  end
13
- end
13
+ end
@@ -2,7 +2,7 @@ $LOAD_PATH << File.dirname(__FILE__)
2
2
  require 'spec_helper'
3
3
 
4
4
  describe 'A REST adapter' do
5
-
5
+
6
6
  describe 'when updating an existing resource' do
7
7
  before do
8
8
  @books_xml = <<-XML
@@ -16,11 +16,11 @@ describe 'A REST adapter' do
16
16
  repository do |repo|
17
17
  @repository = repo
18
18
  @book = Book.new(:id => 42,
19
- :title => 'Starship Troopers',
20
- :author => 'Robert Heinlein',
19
+ :title => 'Starship Troopers',
20
+ :author => 'Robert Heinlein',
21
21
  :created_at => DateTime.parse('2008-06-08T17:02:28Z'))
22
22
  @book.instance_eval { @new_record = false }
23
- @repository.identity_map(Book).set(@book.key, @book)
23
+ @repository.identity_map(Book).set(@book.key, @book)
24
24
  @book.title = "Mary Had a Little Lamb"
25
25
  end
26
26
  end
@@ -28,9 +28,9 @@ describe 'A REST adapter' do
28
28
  it 'should do an HTTP PUT' do
29
29
  adapter = @repository.adapter #DataMapper::Repository.adapters[:default]
30
30
  adapter.should_receive(:http_put).with('/books/42.xml', @book.to_xml)
31
- @repository.scope do
31
+ @repository.scope do
32
32
  @book.save
33
33
  end
34
34
  end
35
35
  end
36
- end
36
+ end
@@ -28,12 +28,12 @@ Story: remote app wants to create a resource
28
28
 
29
29
  Scenario: remote app supplies a new valid Resource associated with another new invalid Resource
30
30
  Given a new Resource
31
- And another new invalid Resource associted with the first
31
+ And another new invalid Resource associated with the first
32
32
  When I try to save the first Resource
33
33
  Neither Resource should save
34
34
 
35
35
  Scenario: remote app supplies a new invalid Resource associated with another new invalid Resource
36
36
  Given a new invalid Resource
37
- And another new invalid Resource associted with the first
37
+ And another new invalid Resource associated with the first
38
38
  When I try to save the first Resource
39
39
  Neither Resource should save
@@ -15,4 +15,4 @@ Dir["#{File.dirname(__FILE__)}/*"].each do |file|
15
15
  run file if File.file?(file)
16
16
  end
17
17
  end
18
- end
18
+ end
@@ -6,4 +6,4 @@ require 'dm-core'
6
6
  #require 'pathname'
7
7
  #require Pathname(__FILE__).dirname.parent.expand_path + '../../lib/rest_adapter'
8
8
  require File.join(File.dirname(__FILE__), *%w[resources helpers story_helper])
9
- require File.join(File.dirname(__FILE__), *%w[resources steps using_rest_adapter])
9
+ require File.join(File.dirname(__FILE__), *%w[resources steps using_rest_adapter])
@@ -1,2 +1,2 @@
1
1
  require 'spec/story'
2
- require File.dirname(__FILE__) + '/../../../spec/ruby_forker'
2
+ require File.dirname(__FILE__) + '/../../../spec/ruby_forker'
@@ -7,9 +7,9 @@ steps_for :read do
7
7
  has n, :books
8
8
  end
9
9
  end
10
-
10
+
11
11
  Given "the ID of an existing Resource that has associated Resources" do
12
- # Assuming that resource 1 is there.
12
+ # Assuming that resource 1 is there.
13
13
  # @type.first would do a GET; that's what we're testing
14
14
  @resource_id = 1
15
15
  end
@@ -21,15 +21,15 @@ steps_for :read do
21
21
  When "I GET <nested resource>/<id>" do
22
22
  @resource = Shelf.get(@resource_id)
23
23
  end
24
-
24
+
25
25
  Then "I should get the Resource" do
26
26
  @resource.should_not be_nil
27
27
  @resource.should be_an_instance_of(Shelf)
28
28
  @resource.id.should == 1
29
29
  end
30
-
30
+
31
31
  Then "the Resource will have associated Resources" do
32
32
  @resource.books.should_not be_empty
33
33
  @resource.books.first.should be_an_instance_of(Book)
34
34
  end
35
- end
35
+ end
@@ -39,18 +39,18 @@ steps_for :using_rest_adapter do
39
39
  @resource = Book.first
40
40
  @resource_id = @resource.id
41
41
  end
42
-
42
+
43
43
  When("I try to save the Resource") do
44
44
  @result = @resource.save
45
45
  end
46
-
46
+
47
47
  When("I request all of the Resources of that type") do
48
48
  require File.join(File.dirname(__FILE__), '..', 'helpers', 'book')
49
49
  @resources = Book.all
50
50
  end
51
-
51
+
52
52
  When("I request the Resource") do
53
- require File.join(File.dirname(__FILE__), '..', 'helpers', 'book')
53
+ require File.join(File.dirname(__FILE__), '..', 'helpers', 'book')
54
54
  @resource = Book.get(@resource_id)
55
55
  end
56
56
 
@@ -61,19 +61,19 @@ steps_for :using_rest_adapter do
61
61
  When("I make invalid changes to that Resource") do
62
62
  @resource.title = nil
63
63
  end
64
-
64
+
65
65
  When("I destroy the Resource") do
66
66
  @resource.destroy
67
67
  end
68
-
68
+
69
69
  Then("the Resource should save") do
70
70
  @result.should be_true
71
71
  end
72
-
72
+
73
73
  Then("the Resource should not save") do
74
74
  @result.should be_false
75
75
  end
76
-
76
+
77
77
  Then("I should not receive an empty list") do
78
78
  @resources.should_not be_empty
79
79
  end
@@ -86,7 +86,7 @@ steps_for :using_rest_adapter do
86
86
  Then("I should get nothing in return") do
87
87
  @resource.should be_nil
88
88
  end
89
-
89
+
90
90
  Then("the Resource will no longer be available") do
91
91
  # TODO refactor
92
92
  require File.join(File.dirname(__FILE__), '..', 'helpers', 'book')
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.3
4
+ version: 0.9.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Potomac Ruby Hackers
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-07-24 00:00:00 -05:00
12
+ date: 2008-08-21 00:00:00 -05:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -20,7 +20,7 @@ dependencies:
20
20
  requirements:
21
21
  - - "="
22
22
  - !ruby/object:Gem::Version
23
- version: 0.9.3
23
+ version: 0.9.4
24
24
  version:
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: hoe