dm-serializer 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.
@@ -8,7 +8,8 @@ module DataMapper
8
8
  #
9
9
  # @return <REXML::Document> an XML representation of this Resource
10
10
  def to_xml(opts = {})
11
- to_xml_document(opts).to_s
11
+ xml = XMLSerializers::SERIALIZER
12
+ xml.output(to_xml_document(opts)).to_s
12
13
  end
13
14
 
14
15
  protected
@@ -21,7 +22,7 @@ module DataMapper
21
22
  def to_xml_document(opts={}, doc = nil)
22
23
  xml = XMLSerializers::SERIALIZER
23
24
  doc ||= xml.new_document
24
- default_xml_element_name = lambda { Extlib::Inflection.underscore(self.class.name).tr("/", "-") }
25
+ default_xml_element_name = lambda { Extlib::Inflection.underscore(model.name).tr("/", "-") }
25
26
  root = xml.root_node(doc, opts[:element_name] || default_xml_element_name[])
26
27
  properties_to_serialize(opts).each do |property|
27
28
  value = send(property.name)
@@ -33,10 +34,16 @@ module DataMapper
33
34
  if self.respond_to?(meth)
34
35
  xml_name = meth.to_s.gsub(/[^a-z0-9_]/, '')
35
36
  value = send(meth)
36
- xml.add_node(root, xml_name, value.to_s) unless value.nil?
37
+ unless value.nil?
38
+ if value.respond_to?(:to_xml_document)
39
+ xml.add_xml(root, value.send(:to_xml_document))
40
+ else
41
+ xml.add_node(root, xml_name, value.to_s)
42
+ end
43
+ end
37
44
  end
38
45
  end
39
- xml.output(doc)
46
+ doc
40
47
  end
41
48
  end
42
49
 
@@ -58,4 +65,34 @@ module DataMapper
58
65
  doc
59
66
  end
60
67
  end
68
+
69
+ if Serialize::Support.dm_validations_loaded?
70
+
71
+ module Validate
72
+ class ValidationErrors
73
+ def to_xml(opts = {})
74
+ to_xml_document(opts).to_s
75
+ end
76
+
77
+ protected
78
+
79
+ def to_xml_document(opts = {})
80
+ xml = DataMapper::Serialize::XMLSerializers::SERIALIZER
81
+ doc = xml.new_document
82
+ root = xml.root_node(doc, "errors", {'type' => 'hash'})
83
+
84
+ errors.each do |key, value|
85
+ property = xml.add_node(root, key.to_s, nil, {'type' => 'array'})
86
+ property.attributes["type"] = 'array'
87
+ value.each do |error|
88
+ xml.add_node(property, "error", error)
89
+ end
90
+ end
91
+
92
+ doc
93
+ end
94
+ end
95
+ end
96
+
97
+ end
61
98
  end
@@ -6,7 +6,7 @@ module DataMapper
6
6
  #
7
7
  # @return <YAML> a YAML representation of this Resource
8
8
  def to_yaml(opts_or_emitter = {})
9
- if opts_or_emitter.is_a?(YAML::Syck::Emitter)
9
+ if !opts_or_emitter.is_a?(Hash)
10
10
  emitter = opts_or_emitter
11
11
  opts = {}
12
12
  else
@@ -16,8 +16,7 @@ module DataMapper
16
16
 
17
17
  YAML::quick_emit(object_id,emitter) do |out|
18
18
  out.map(nil,to_yaml_style) do |map|
19
- propset = properties_to_serialize(opts)
20
- propset.each do |property|
19
+ properties_to_serialize(opts).each do |property|
21
20
  value = send(property.name.to_sym)
22
21
  map.add(property.name, value.is_a?(Class) ? value.to_s : value)
23
22
  end
@@ -37,7 +36,7 @@ module DataMapper
37
36
 
38
37
  class Collection
39
38
  def to_yaml(opts_or_emitter = {})
40
- if opts_or_emitter.is_a?(YAML::Syck::Emitter)
39
+ if !opts_or_emitter.is_a?(Hash)
41
40
  to_a.to_yaml(opts_or_emitter)
42
41
  else
43
42
  # FIXME: Don't double handle the YAML (remove the YAML.load)
@@ -45,4 +44,16 @@ module DataMapper
45
44
  end
46
45
  end
47
46
  end
47
+
48
+ if Serialize::Support.dm_validations_loaded?
49
+
50
+ module Validate
51
+ class ValidationErrors
52
+ def to_yaml(*args)
53
+ errors.to_hash.to_yaml(*args)
54
+ end
55
+ end
56
+ end
57
+
58
+ end
48
59
  end
@@ -1,5 +1,5 @@
1
1
  module DataMapper
2
2
  module Serializer
3
- VERSION = '0.9.11'
3
+ VERSION = '0.10.0'.freeze
4
4
  end
5
5
  end
@@ -22,6 +22,11 @@ module DataMapper
22
22
  node[attr_name] = attr_val
23
23
  end
24
24
  parent << node
25
+ node
26
+ end
27
+
28
+ def self.add_xml(parent, xml)
29
+ parent << xml.root.copy(true)
25
30
  end
26
31
 
27
32
  def self.output(doc)
@@ -23,6 +23,10 @@ module DataMapper
23
23
  node
24
24
  end
25
25
 
26
+ def self.add_xml(parent, xml)
27
+ parent << xml.root
28
+ end
29
+
26
30
  def self.output(doc)
27
31
  doc.root.to_s
28
32
  end
@@ -17,6 +17,10 @@ module DataMapper
17
17
  node
18
18
  end
19
19
 
20
+ def self.add_xml(parent, xml)
21
+ parent.add(xml)
22
+ end
23
+
20
24
  def self.output(doc)
21
25
  doc.to_s
22
26
  end
@@ -6,6 +6,6 @@ class Cow
6
6
  property :name, String
7
7
  property :breed, String
8
8
 
9
- has n, :baby_cows, :class_name => 'Cow'
10
- belongs_to :mother_cow, :class_name => 'Cow'
9
+ belongs_to :mother_cow, :model => self, :nullable => true
10
+ has n, :baby_cows, :model => self, :child_key => [ :mother_cow_id, :mother_cow_composite ]
11
11
  end
@@ -1,13 +1,17 @@
1
1
  class Planet
2
2
  include DataMapper::Resource
3
3
 
4
- property :name, String, :key => true
4
+ property :name, String, :key => true
5
5
  property :aphelion, Float
6
6
 
7
+ validates_length :name, :min => 2
8
+
7
9
  # Sorry these associations don't make any sense
8
10
  # I just needed a many-to-many association to test against
9
11
  has n, :friended_planets
10
- has n, :friend_planets, :through => :friended_planets, :class_name => 'Planet'
12
+ has n, :friend_planets, :through => :friended_planets, :model => 'Planet'
13
+
14
+ belongs_to :solar_system
11
15
 
12
16
  def category
13
17
  case self.name.downcase
@@ -28,6 +32,15 @@ class FriendedPlanet
28
32
  property :planet_name, String, :key => true
29
33
  property :friend_planet_name, String, :key => true
30
34
 
31
- belongs_to :planet, :child_key => [:planet_name]
32
- belongs_to :friend_planet, :class_name => 'Planet', :child_key => [:friend_planet_name]
35
+ belongs_to :planet, :child_key => [ :planet_name ]
36
+ belongs_to :friend_planet, :model => 'Planet', :child_key => [ :friend_planet_name ]
37
+ end
38
+
39
+ class SolarSystem
40
+ include DataMapper::Resource
41
+
42
+ property :id, Serial
43
+
44
+ property :name, String
45
+
33
46
  end
@@ -4,8 +4,8 @@ module QuanTum
4
4
  class Cat
5
5
  include DataMapper::Resource
6
6
 
7
- property :id, Serial
8
- property :name, String
7
+ property :id, Serial
8
+ property :name, String
9
9
  property :location, String
10
10
 
11
11
  repository(:alternate) do
@@ -1,5 +1,4 @@
1
- require 'pathname'
2
- require Pathname(__FILE__).dirname.expand_path.parent + 'spec_helper'
1
+ require 'spec_helper'
3
2
 
4
3
  share_examples_for 'A serialization method that also serializes core classes' do
5
4
  # This spec ensures that we don't break any serialization methods attached
@@ -32,13 +31,19 @@ share_examples_for 'A serialization method that also serializes core classes' do
32
31
 
33
32
  it 'serializes an array of collections' do
34
33
  query = DataMapper::Query.new(DataMapper::repository(:default), Cow)
35
- collection = DataMapper::Collection.new(query) do |c|
36
- c.load([1, 2, 'Betsy', 'Jersey'])
37
- c.load([89, 34, 'Berta', 'Guernsey'])
38
- end
39
- result = @harness.test([collection])
40
- result[0][1].values_at("id", "composite", "name", "breed").should ==
41
- [89, 34, "Berta", "Guernsey"]
34
+
35
+ keys = %w[ id composite name breed ]
36
+
37
+ resources = [
38
+ keys.zip([ 1, 2, 'Betsy', 'Jersey' ]).to_hash,
39
+ keys.zip([ 89, 34, 'Berta', 'Guernsey' ]).to_hash,
40
+ ]
41
+
42
+ collection = DataMapper::Collection.new(query, query.model.load(resources, query))
43
+
44
+ result = @harness.test(collection)
45
+ result[0].values_at(*keys).should == resources[0].values_at(*keys)
46
+ result[1].values_at(*keys).should == resources[1].values_at(*keys)
42
47
  end
43
48
  end
44
49
 
@@ -144,6 +149,14 @@ share_examples_for 'A serialization method' do
144
149
  result = @harness.test(planet, :only => [:name], :exclude => [:name])
145
150
  result.values_at("name", "aphelion").should == ["Mars", nil]
146
151
  end
152
+
153
+ it 'should support child associations included via the :methods parameter' do
154
+ solar_system = SolarSystem.create(:name => "one")
155
+ planet = Planet.new(:name => "earth")
156
+ planet.solar_system = solar_system
157
+ result = @harness.test(planet, :methods => [:solar_system])
158
+ result['solar_system'].values_at('name', 'id').should == ['one', 1]
159
+ end
147
160
  end
148
161
 
149
162
  describe "(collections and proxies)" do
@@ -162,19 +175,24 @@ share_examples_for 'A serialization method' do
162
175
 
163
176
  it 'should serialize a collection' do
164
177
  query = DataMapper::Query.new(DataMapper::repository(:default), Cow)
165
- collection = DataMapper::Collection.new(query) do |c|
166
- c.load([1, 2, 'Betsy', 'Jersey'])
167
- c.load([10, 20, 'Berta', 'Guernsey'])
168
- end
178
+
179
+ keys = %w[ id composite name breed ]
180
+
181
+ resources = [
182
+ keys.zip([ 1, 2, 'Betsy', 'Jersey' ]).to_hash,
183
+ keys.zip([ 10, 20, 'Berta', 'Guernsey' ]).to_hash,
184
+ ]
185
+
186
+ collection = DataMapper::Collection.new(query, query.model.load(resources, query))
169
187
 
170
188
  result = @harness.test(collection)
171
- result[0].values_at("id", "composite", "name", "breed").should == [1, 2, 'Betsy', 'Jersey']
172
- result[1].values_at("id", "composite", "name", "breed").should == [10, 20, 'Berta', 'Guernsey']
189
+ result[0].values_at(*keys).should == resources[0].values_at(*keys)
190
+ result[1].values_at(*keys).should == resources[1].values_at(*keys)
173
191
  end
174
192
 
175
193
  it 'should serialize an empty collection' do
176
194
  query = DataMapper::Query.new(DataMapper::repository(:default), Cow)
177
- collection = DataMapper::Collection.new(query) {}
195
+ collection = DataMapper::Collection.new(query)
178
196
 
179
197
  result = @harness.test(collection)
180
198
  result.should be_empty
@@ -206,29 +224,40 @@ share_examples_for 'A serialization method' do
206
224
  end
207
225
 
208
226
  it "serializes a many to many relationship" do
209
- p1 = Planet.create(:name => 'earth')
210
- p2 = Planet.create(:name => 'mars')
227
+ pending 'TODO: fix many to many in dm-core' do
228
+ p1 = Planet.create(:name => 'earth')
229
+ p2 = Planet.create(:name => 'mars')
211
230
 
212
- FriendedPlanet.create(:planet => p1, :friend_planet => p2)
231
+ FriendedPlanet.create(:planet => p1, :friend_planet => p2)
213
232
 
214
- result = @harness.test(p1.reload.friend_planets)
215
- result.should be_kind_of(Array)
233
+ result = @harness.test(p1.reload.friend_planets)
234
+ result.should be_kind_of(Array)
216
235
 
217
- result[0]["name"].should == "mars"
236
+ result[0]["name"].should == "mars"
237
+ end
218
238
  end
219
239
  end
220
240
 
221
241
  describe "(multiple repositories)" do
222
242
  before(:all) do
223
243
  QuanTum::Cat.auto_migrate!
224
- repository(:alternate){QuanTum::Cat.auto_migrate!}
244
+ DataMapper.repository(:alternate) { QuanTum::Cat.auto_migrate! }
225
245
  end
226
246
 
227
247
  it "should use the repsoitory for the model" do
228
248
  gerry = QuanTum::Cat.create(:name => "gerry")
229
- george = repository(:alternate){QuanTum::Cat.create(:name => "george", :is_dead => false)}
249
+ george = DataMapper.repository(:alternate){ QuanTum::Cat.create(:name => "george", :is_dead => false) }
230
250
  @harness.test(gerry )['is_dead'].should be(nil)
231
251
  @harness.test(george)['is_dead'].should be(false)
232
252
  end
233
253
  end
254
+
255
+ it 'should integrate with dm-validations' do
256
+ planet = Planet.create(:name => 'a')
257
+ results = @harness.test(planet.errors)
258
+ results.should == {
259
+ "name" => planet.errors[:name],
260
+ "solar_system_id" => planet.errors[:solar_system_id]
261
+ }
262
+ end
234
263
  end
@@ -1,5 +1,4 @@
1
- require 'pathname'
2
- require Pathname(__FILE__).dirname.expand_path.parent + 'spec_helper'
1
+ require 'spec_helper'
3
2
 
4
3
  describe DataMapper::Serialize do
5
4
  it "is included into DataMapper::Resource" do
@@ -1,48 +1,62 @@
1
- require 'pathname'
2
- require Pathname(__FILE__).dirname.expand_path.parent + 'spec_helper'
1
+ require 'spec_helper'
3
2
 
4
- describe DataMapper::Serialize, '#to_csv' do
5
- #
6
- # ==== blah, it's CSV
7
- #
3
+ if defined?(::CSV)
4
+ describe DataMapper::Serialize, '#to_csv' do
5
+ #
6
+ # ==== blah, it's CSV
7
+ #
8
8
 
9
- before(:all) do
10
- query = DataMapper::Query.new(DataMapper::repository(:default), Cow)
9
+ before(:all) do
10
+ query = DataMapper::Query.new(DataMapper::repository(:default), Cow)
11
+
12
+ resources = [
13
+ {:id => 1, :composite => 2, :name => 'Betsy', :breed => 'Jersey'},
14
+ {:id => 10, :composite => 20, :name => 'Berta', :breed => 'Guernsey'}
15
+ ]
16
+
17
+ @collection = DataMapper::Collection.new(query, resources)
11
18
 
12
- @collection = DataMapper::Collection.new(query) do |c|
13
- c.load([1, 2, 'Betsy', 'Jersey'])
14
- c.load([10, 20, 'Berta', 'Guernsey'])
19
+ @empty_collection = DataMapper::Collection.new(query)
15
20
  end
16
21
 
17
- @empty_collection = DataMapper::Collection.new(query) {}
18
- end
22
+ it "should serialize a resource to CSV" do
23
+ peter = Cow.new
24
+ peter.id = 44
25
+ peter.composite = 344
26
+ peter.name = 'Peter'
27
+ peter.breed = 'Long Horn'
19
28
 
20
- it "should serialize a resource to CSV" do
21
- peter = Cow.new
22
- peter.id = 44
23
- peter.composite = 344
24
- peter.name = 'Peter'
25
- peter.breed = 'Long Horn'
26
- peter.to_csv.chomp.split(',')[0..3].should == ['44','344','Peter','Long Horn']
27
- end
29
+ peter.to_csv.chomp.split(',')[0..3].should == ['44','344','Peter','Long Horn']
30
+ end
28
31
 
29
- it "should serialize a collection to CSV" do
30
- result = @collection.to_csv.gsub(/[[:space:]]+\n/, "\n")
31
- result.split("\n")[0].split(',')[0..3].should == ['1','2','Betsy','Jersey']
32
- result.split("\n")[1].split(',')[0..3].should == ['10','20','Berta','Guernsey']
33
- end
32
+ it "should serialize a collection to CSV" do
33
+ result = @collection.to_csv.gsub(/[[:space:]]+\n/, "\n")
34
+ result.split("\n")[0].split(',')[0..3].should == ['1','2','Betsy','Jersey']
35
+ result.split("\n")[1].split(',')[0..3].should == ['10','20','Berta','Guernsey']
36
+ end
34
37
 
35
- describe "multiple repositories" do
36
- before(:all) do
37
- QuanTum::Cat.auto_migrate!
38
- repository(:alternate){QuanTum::Cat.auto_migrate!}
38
+ it 'should integration with dm-validations by providing one line per error' do
39
+ planet = Planet.create(:name => 'a')
40
+ result = planet.errors.to_csv.gsub(/[[:space:]]+\n/, "\n").split("\n")
41
+ result.should include("name,#{planet.errors[:name][0]}")
42
+ result.should include("solar_system_id,#{planet.errors[:solar_system_id][0]}")
43
+ result.length.should == 2
39
44
  end
40
45
 
41
- it "should use the repsoitory for the model" do
42
- gerry = QuanTum::Cat.create(:name => "gerry")
43
- george = repository(:alternate){QuanTum::Cat.create(:name => "george", :is_dead => false)}
44
- gerry.to_csv.should_not match(/false/)
45
- george.to_csv.should match(/false/)
46
+ describe "multiple repositories" do
47
+ before(:all) do
48
+ QuanTum::Cat.auto_migrate!
49
+ DataMapper.repository(:alternate){ QuanTum::Cat.auto_migrate! }
50
+ end
51
+
52
+ it "should use the repsoitory for the model" do
53
+ gerry = QuanTum::Cat.create(:name => "gerry")
54
+ george = DataMapper.repository(:alternate){ QuanTum::Cat.create(:name => "george", :is_dead => false) }
55
+ gerry.to_csv.should_not match(/false/)
56
+ george.to_csv.should match(/false/)
57
+ end
46
58
  end
47
59
  end
60
+ else
61
+ warn "[WARNING] Cannot require 'faster_csv' or 'csv', not running #to_csv specs"
48
62
  end