sbf-dm-serializer 1.3.0.beta
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.
- checksums.yaml +7 -0
- data/.gitignore +38 -0
- data/.rspec +5 -0
- data/.rubocop.yml +468 -0
- data/Gemfile +80 -0
- data/LICENSE +20 -0
- data/README.rdoc +64 -0
- data/Rakefile +4 -0
- data/benchmarks/to_json.rb +137 -0
- data/benchmarks/to_xml.rb +89 -0
- data/dm-serializer.gemspec +24 -0
- data/lib/dm-serializer/common.rb +27 -0
- data/lib/dm-serializer/to_csv.rb +71 -0
- data/lib/dm-serializer/to_json.rb +99 -0
- data/lib/dm-serializer/to_xml.rb +123 -0
- data/lib/dm-serializer/to_yaml.rb +157 -0
- data/lib/dm-serializer/version.rb +5 -0
- data/lib/dm-serializer/xml/libxml.rb +44 -0
- data/lib/dm-serializer/xml/nokogiri.rb +44 -0
- data/lib/dm-serializer/xml/rexml.rb +36 -0
- data/lib/dm-serializer/xml.rb +56 -0
- data/lib/dm-serializer.rb +14 -0
- data/spec/fixtures/cow.rb +11 -0
- data/spec/fixtures/planet.rb +46 -0
- data/spec/fixtures/quan_tum_cat.rb +15 -0
- data/spec/fixtures/vehicle.rb +14 -0
- data/spec/lib/serialization_method_shared_spec.rb +287 -0
- data/spec/public/serializer_spec.rb +7 -0
- data/spec/public/to_csv_spec.rb +71 -0
- data/spec/public/to_json_spec.rb +75 -0
- data/spec/public/to_xml_spec.rb +108 -0
- data/spec/public/to_yaml_spec.rb +59 -0
- data/spec/rcov.opts +6 -0
- data/spec/spec_helper.rb +26 -0
- data/tasks/spec.rake +21 -0
- data/tasks/yard.rake +9 -0
- data/tasks/yardstick.rake +19 -0
- metadata +139 -0
@@ -0,0 +1,287 @@
|
|
1
|
+
shared_examples 'A serialization method that also serializes core classes' do
|
2
|
+
# This spec ensures that we don't break any serialization methods attached
|
3
|
+
# to core classes, such as Array
|
4
|
+
before(:all) do
|
5
|
+
%w(@harness).each do |ivar|
|
6
|
+
raise "+#{ivar}+ should be defined in before block" unless instance_variable_get(ivar)
|
7
|
+
end
|
8
|
+
DataMapper.auto_migrate!
|
9
|
+
end
|
10
|
+
|
11
|
+
before(:each) do
|
12
|
+
DataMapper::Model.descendants.each(&:destroy!)
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'serializes an array of extended objects' do
|
16
|
+
Cow.create(
|
17
|
+
id: 89,
|
18
|
+
composite: 34,
|
19
|
+
name: 'Berta',
|
20
|
+
breed: 'Guernsey'
|
21
|
+
)
|
22
|
+
result = @harness.test(Cow.all.to_a)
|
23
|
+
expect(result[0].values_at('id', 'composite', 'name', 'breed')).to eq [89, 34, 'Berta', 'Guernsey']
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'serializes an array of collections' do
|
27
|
+
query = DataMapper::Query.new(DataMapper::repository(:default), Cow)
|
28
|
+
|
29
|
+
keys = %w(id composite name breed)
|
30
|
+
|
31
|
+
resources = [
|
32
|
+
keys.zip([1, 2, 'Betsy', 'Jersey']).to_h,
|
33
|
+
keys.zip([89, 34, 'Berta', 'Guernsey']).to_h,
|
34
|
+
]
|
35
|
+
|
36
|
+
collection = DataMapper::Collection.new(query, query.model.load(resources, query))
|
37
|
+
|
38
|
+
result = @harness.test(collection)
|
39
|
+
expect(result[0].values_at(*keys)).to eq resources[0].values_at(*keys)
|
40
|
+
expect(result[1].values_at(*keys)).to eq resources[1].values_at(*keys)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
shared_examples 'A serialization method' do
|
45
|
+
before(:all) do
|
46
|
+
%w(@harness).each do |ivar|
|
47
|
+
raise "+#{ivar}+ should be defined in before block" unless instance_variable_get(ivar)
|
48
|
+
end
|
49
|
+
|
50
|
+
DataMapper.auto_migrate!
|
51
|
+
end
|
52
|
+
|
53
|
+
before(:each) do
|
54
|
+
DataMapper::Model.descendants.each(&:destroy!)
|
55
|
+
end
|
56
|
+
|
57
|
+
describe '(serializing single resources)' do
|
58
|
+
it 'serializes Model.first' do
|
59
|
+
# At the moment this is implied by serializing a resource, but this
|
60
|
+
# test ensures the contract even if dm-core changes
|
61
|
+
Cow.create(
|
62
|
+
id: 89,
|
63
|
+
composite: 34,
|
64
|
+
name: 'Berta',
|
65
|
+
breed: 'Guernsey'
|
66
|
+
)
|
67
|
+
result = @harness.test(Cow.first)
|
68
|
+
expect(result.values_at('name', 'breed')).to eq %w(Berta Guernsey)
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'serializes a resource' do
|
72
|
+
cow = Cow.new(
|
73
|
+
id: 89,
|
74
|
+
composite: 34,
|
75
|
+
name: 'Berta',
|
76
|
+
breed: 'Guernsey'
|
77
|
+
)
|
78
|
+
|
79
|
+
result = @harness.test(cow)
|
80
|
+
expect(result.values_at('id', 'composite', 'name', 'breed')).to eq [89, 34, 'Berta', 'Guernsey']
|
81
|
+
end
|
82
|
+
|
83
|
+
it 'excludes nil properties' do
|
84
|
+
cow = Cow.new(
|
85
|
+
id: 89,
|
86
|
+
name: nil
|
87
|
+
)
|
88
|
+
|
89
|
+
result = @harness.test(cow)
|
90
|
+
expect(result.values_at('id', 'composite')).to eq [89, nil]
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'only includes properties given to :only option' do
|
94
|
+
pending 'Psych provides no way to pass in parameters' if @ruby_192 && @to_yaml
|
95
|
+
|
96
|
+
planet = Planet.new(
|
97
|
+
name: 'Mars',
|
98
|
+
aphelion: 249_209_300.4
|
99
|
+
)
|
100
|
+
|
101
|
+
result = @harness.test(planet, only: [:name])
|
102
|
+
expect(result.values_at('name', 'aphelion')).to eq ['Mars', nil]
|
103
|
+
end
|
104
|
+
|
105
|
+
it 'serializes values returned by an array of methods given to :methods option' do
|
106
|
+
pending 'Psych provides no way to pass in parameters' if @ruby_192 && @to_yaml
|
107
|
+
|
108
|
+
planet = Planet.new(
|
109
|
+
name: 'Mars',
|
110
|
+
aphelion: 249_209_300.4
|
111
|
+
)
|
112
|
+
|
113
|
+
result = @harness.test(planet, methods: %i(category has_known_form_of_life?))
|
114
|
+
# XML currently can't serialize ? at the end of method names
|
115
|
+
boolean_method_name = (@harness.method_name == :to_xml) ? 'has_known_form_of_life' : 'has_known_form_of_life?'
|
116
|
+
expect(result.values_at('category', boolean_method_name)).to eq ['terrestrial', false]
|
117
|
+
end
|
118
|
+
|
119
|
+
it 'serializes values returned by a single method given to :methods option' do
|
120
|
+
pending 'Psych provides no way to pass in parameters' if @ruby_192 && @to_yaml
|
121
|
+
|
122
|
+
planet = Planet.new(
|
123
|
+
name: 'Mars',
|
124
|
+
aphelion: 249_209_300.4
|
125
|
+
)
|
126
|
+
|
127
|
+
result = @harness.test(planet, methods: :category)
|
128
|
+
expect(result.values_at('category')).to eq ['terrestrial']
|
129
|
+
end
|
130
|
+
|
131
|
+
it 'only includes properties given to :only option' do
|
132
|
+
pending 'Psych provides no way to pass in parameters' if @ruby_192 && @to_yaml
|
133
|
+
|
134
|
+
planet = Planet.new(
|
135
|
+
name: 'Mars',
|
136
|
+
aphelion: 249_209_300.4
|
137
|
+
)
|
138
|
+
|
139
|
+
result = @harness.test(planet, only: [:name])
|
140
|
+
expect(result.values_at('name', 'aphelion')).to eq ['Mars', nil]
|
141
|
+
end
|
142
|
+
|
143
|
+
it 'excludes properties given to :exclude option' do
|
144
|
+
pending 'Psych provides no way to pass in parameters' if @ruby_192 && @to_yaml
|
145
|
+
|
146
|
+
planet = Planet.new(
|
147
|
+
name: 'Mars',
|
148
|
+
aphelion: 249_209_300.4
|
149
|
+
)
|
150
|
+
|
151
|
+
result = @harness.test(planet, exclude: [:aphelion])
|
152
|
+
expect(result.values_at('name', 'aphelion')).to eq ['Mars', nil]
|
153
|
+
end
|
154
|
+
|
155
|
+
it 'gives higher precedence to :only option over :exclude' do
|
156
|
+
pending 'Psych provides no way to pass in parameters' if @ruby_192 && @to_yaml
|
157
|
+
|
158
|
+
planet = Planet.new(
|
159
|
+
name: 'Mars',
|
160
|
+
aphelion: 249_209_300.4
|
161
|
+
)
|
162
|
+
|
163
|
+
result = @harness.test(planet, only: [:name], exclude: [:name])
|
164
|
+
expect(result.values_at('name', 'aphelion')).to eq ['Mars', nil]
|
165
|
+
end
|
166
|
+
|
167
|
+
it 'supports child associations included via the :methods parameter' do
|
168
|
+
pending 'Psych provides no way to pass in parameters' if @ruby_192 && @to_yaml
|
169
|
+
|
170
|
+
solar_system = SolarSystem.create(name: 'one')
|
171
|
+
planet = Planet.new(name: 'earth')
|
172
|
+
planet.solar_system = solar_system
|
173
|
+
result = @harness.test(planet, methods: [:solar_system])
|
174
|
+
expect(result['solar_system'].values_at('name', 'id')).to eq ['one', 1]
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
describe '(collections and proxies)' do
|
179
|
+
it 'serializes Model.all' do
|
180
|
+
# At the moment this is implied by serializing a collection, but this
|
181
|
+
# test ensures the contract even if dm-core changes
|
182
|
+
Cow.create(
|
183
|
+
id: 89,
|
184
|
+
composite: 34,
|
185
|
+
name: 'Berta',
|
186
|
+
breed: 'Guernsey'
|
187
|
+
)
|
188
|
+
result = @harness.test(Cow.all)
|
189
|
+
expect(result[0].values_at('name', 'breed')).to eq %w(Berta Guernsey)
|
190
|
+
end
|
191
|
+
|
192
|
+
it 'serializes a collection' do
|
193
|
+
query = DataMapper::Query.new(DataMapper::repository(:default), Cow)
|
194
|
+
|
195
|
+
keys = %w(id composite name breed)
|
196
|
+
|
197
|
+
resources = [
|
198
|
+
keys.zip([1, 2, 'Betsy', 'Jersey']).to_h,
|
199
|
+
keys.zip([10, 20, 'Berta', 'Guernsey']).to_h,
|
200
|
+
]
|
201
|
+
|
202
|
+
collection = DataMapper::Collection.new(query, query.model.load(resources, query))
|
203
|
+
|
204
|
+
result = @harness.test(collection)
|
205
|
+
expect(result[0].values_at(*keys)).to eq resources[0].values_at(*keys)
|
206
|
+
expect(result[1].values_at(*keys)).to eq resources[1].values_at(*keys)
|
207
|
+
end
|
208
|
+
|
209
|
+
it 'serializes an empty collection' do
|
210
|
+
query = DataMapper::Query.new(DataMapper::repository(:default), Cow)
|
211
|
+
collection = DataMapper::Collection.new(query)
|
212
|
+
|
213
|
+
result = @harness.test(collection)
|
214
|
+
expect(result).to be_empty
|
215
|
+
end
|
216
|
+
|
217
|
+
it 'serializes a one to many relationship' do
|
218
|
+
parent = Cow.new(id: 1, composite: 322, name: 'Harry', breed: 'Angus')
|
219
|
+
baby = Cow.new(mother_cow: parent, id: 2, composite: 321, name: 'Felix', breed: 'Angus')
|
220
|
+
|
221
|
+
parent.save
|
222
|
+
baby.save
|
223
|
+
|
224
|
+
result = @harness.test(parent.baby_cows)
|
225
|
+
expect(result).to be_kind_of(Array)
|
226
|
+
|
227
|
+
expect(result[0].values_at(*%w(id composite name breed))).to eq [2, 321, 'Felix', 'Angus']
|
228
|
+
end
|
229
|
+
|
230
|
+
it 'serializes a many to one relationship' do
|
231
|
+
parent = Cow.new(id: 1, composite: 322, name: 'Harry', breed: 'Angus')
|
232
|
+
baby = Cow.new(mother_cow: parent, id: 2, composite: 321, name: 'Felix', breed: 'Angus')
|
233
|
+
|
234
|
+
parent.save
|
235
|
+
baby.save
|
236
|
+
|
237
|
+
result = @harness.test(baby.mother_cow)
|
238
|
+
expect(result).to be_kind_of(Hash)
|
239
|
+
expect(result.values_at(*%w(id composite name breed))).to eq [1, 322, 'Harry', 'Angus']
|
240
|
+
end
|
241
|
+
|
242
|
+
it 'serializes a many to many relationship' do
|
243
|
+
pending 'TODO: fix many to many in dm-core'
|
244
|
+
p1 = Planet.create(name: 'earth')
|
245
|
+
p2 = Planet.create(name: 'mars')
|
246
|
+
|
247
|
+
FriendedPlanet.create(planet: p1, friend_planet: p2)
|
248
|
+
|
249
|
+
result = @harness.test(p1.reload.friend_planets)
|
250
|
+
expect(result).to be_kind_of(Array)
|
251
|
+
|
252
|
+
expect(result[0]['name']).to eq 'mars'
|
253
|
+
end
|
254
|
+
end
|
255
|
+
|
256
|
+
with_alternate_adapter do
|
257
|
+
|
258
|
+
describe '(multiple repositories)' do
|
259
|
+
before(:all) do
|
260
|
+
%i(default alternate).each do |repository_name|
|
261
|
+
DataMapper.repository(repository_name) do
|
262
|
+
QuanTum::Cat.auto_migrate!
|
263
|
+
QuanTum::Cat.destroy!
|
264
|
+
end
|
265
|
+
end
|
266
|
+
end
|
267
|
+
|
268
|
+
it 'uses the repository for the model' do
|
269
|
+
alternate_repo = DataMapper::Spec.spec_adapters[:alternate].name
|
270
|
+
gerry = QuanTum::Cat.create(name: 'gerry')
|
271
|
+
george = DataMapper.repository(alternate_repo) { QuanTum::Cat.create(name: 'george', is_dead: false) }
|
272
|
+
expect(@harness.test(gerry)['is_dead']).to be(nil)
|
273
|
+
expect(@harness.test(george)['is_dead']).to be(false)
|
274
|
+
end
|
275
|
+
end
|
276
|
+
|
277
|
+
end
|
278
|
+
|
279
|
+
it 'integrates with dm-validations' do
|
280
|
+
planet = Planet.create(name: 'a')
|
281
|
+
results = @harness.test(planet.errors)
|
282
|
+
expect(results).to eq({
|
283
|
+
'name' => planet.errors[:name].map(&:to_s),
|
284
|
+
'solar_system_id' => planet.errors[:solar_system_id].map(&:to_s)
|
285
|
+
})
|
286
|
+
end
|
287
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require_relative '../spec_helper'
|
2
|
+
|
3
|
+
if defined?(::CSV)
|
4
|
+
describe DataMapper::Serialize, '#to_csv' do
|
5
|
+
#
|
6
|
+
# ==== blah, it's CSV
|
7
|
+
#
|
8
|
+
|
9
|
+
before(:all) do
|
10
|
+
DataMapper.finalize
|
11
|
+
query = DataMapper::Query.new(DataMapper::repository(:default), Cow)
|
12
|
+
|
13
|
+
resources = [
|
14
|
+
{id: 1, composite: 2, name: 'Betsy', breed: 'Jersey'},
|
15
|
+
{id: 10, composite: 20, name: 'Berta', breed: 'Guernsey'}
|
16
|
+
]
|
17
|
+
|
18
|
+
@collection = DataMapper::Collection.new(query, resources)
|
19
|
+
|
20
|
+
@empty_collection = DataMapper::Collection.new(query)
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'serializes a resource to CSV' do
|
24
|
+
peter = Cow.new
|
25
|
+
peter.id = 44
|
26
|
+
peter.composite = 344
|
27
|
+
peter.name = 'Peter'
|
28
|
+
peter.breed = 'Long Horn'
|
29
|
+
|
30
|
+
expect(peter.to_csv.chomp.split(',')[0..3]).to eq ['44','344','Peter','Long Horn']
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'serializes a collection to CSV' do
|
34
|
+
result = @collection.to_csv.gsub(/[[:space:]]+\n/, "\n")
|
35
|
+
expect(result.split("\n")[0].split(',')[0..3]).to eq %w(1 2 Betsy Jersey)
|
36
|
+
expect(result.split("\n")[1].split(',')[0..3]).to eq %w(10 20 Berta Guernsey)
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'integrates with dm-validations by providing one line per error' do
|
40
|
+
planet = Planet.create(name: 'a')
|
41
|
+
result = planet.errors.to_csv.gsub(/[[:space:]]+\n/, "\n").split("\n")
|
42
|
+
expect(result).to include("name,#{planet.errors[:name][0]}")
|
43
|
+
expect(result).to include("solar_system_id,#{planet.errors[:solar_system_id][0]}")
|
44
|
+
expect(result.length).to eq 2
|
45
|
+
end
|
46
|
+
|
47
|
+
with_alternate_adapter do
|
48
|
+
|
49
|
+
describe 'multiple repositories' do
|
50
|
+
before(:all) do
|
51
|
+
%i(default alternate).each do |repository_name|
|
52
|
+
DataMapper.repository(repository_name) do
|
53
|
+
DataMapper.finalize
|
54
|
+
QuanTum::Cat.auto_migrate!
|
55
|
+
QuanTum::Cat.destroy!
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'uses the repository for the model' do
|
61
|
+
gerry = QuanTum::Cat.create(name: 'gerry')
|
62
|
+
george = DataMapper.repository(:alternate){ QuanTum::Cat.create(name: 'george', is_dead: false) }
|
63
|
+
expect(gerry.to_csv).not_to match(/false/)
|
64
|
+
expect(george&.to_csv).not_to match(/false/)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
else
|
70
|
+
warn "[WARNING] Cannot require 'faster_csv' or 'csv', not running #to_csv specs"
|
71
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require_relative '../spec_helper'
|
2
|
+
|
3
|
+
describe DataMapper::Serializer, '#to_json' do
|
4
|
+
#
|
5
|
+
# ==== ajaxy JSON
|
6
|
+
#
|
7
|
+
|
8
|
+
before(:all) do
|
9
|
+
DataMapper.finalize
|
10
|
+
DataMapper.auto_migrate!
|
11
|
+
query = DataMapper::Query.new(DataMapper::repository(:default), Cow)
|
12
|
+
|
13
|
+
keys = %w(id composite name breed)
|
14
|
+
|
15
|
+
resources = [
|
16
|
+
keys.zip([1, 2, 'Betsy', 'Jersey']).to_h,
|
17
|
+
keys.zip([10, 20, 'Berta', 'Guernsey']).to_h,
|
18
|
+
]
|
19
|
+
|
20
|
+
@collection = DataMapper::Collection.new(query, query.model.load(resources, query))
|
21
|
+
|
22
|
+
@harness = Class.new(SerializerTestHarness) do
|
23
|
+
def method_name
|
24
|
+
:to_json
|
25
|
+
end
|
26
|
+
|
27
|
+
protected
|
28
|
+
|
29
|
+
def deserialize(result)
|
30
|
+
JSON.parse(result)
|
31
|
+
end
|
32
|
+
end.new
|
33
|
+
end
|
34
|
+
|
35
|
+
it_behaves_like 'A serialization method'
|
36
|
+
it_behaves_like 'A serialization method that also serializes core classes'
|
37
|
+
|
38
|
+
it 'handles options given to a collection properly' do
|
39
|
+
deserialized_collection = JSON.parse(@collection.to_json(only: [:composite]))
|
40
|
+
betsy = deserialized_collection.first
|
41
|
+
berta = deserialized_collection.last
|
42
|
+
|
43
|
+
expect(betsy['id']).to be_nil
|
44
|
+
expect(betsy['composite']).to eq 2
|
45
|
+
expect(betsy['name']).to be_nil
|
46
|
+
expect(betsy['breed']).to be_nil
|
47
|
+
|
48
|
+
expect(berta['id']).to be_nil
|
49
|
+
expect(berta['composite']).to eq 20
|
50
|
+
expect(berta['name']).to be_nil
|
51
|
+
expect(berta['breed']).to be_nil
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'supports :include option for one level depth'
|
55
|
+
|
56
|
+
it 'supports :include option for more than one level depth'
|
57
|
+
|
58
|
+
it 'has :repository option to override used repository'
|
59
|
+
|
60
|
+
it 'can be serialized within a Hash' do
|
61
|
+
hash = {'cows' => Cow.all}
|
62
|
+
expect(JSON.parse(hash.to_json)).to eq hash
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
describe DataMapper::Serializer, '#as_json' do
|
68
|
+
it 'handles nil for options' do
|
69
|
+
expect { Cow.new.as_json(nil) }.not_to raise_error
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'serializes Discriminator types as strings' do
|
73
|
+
expect(Motorcycle.new.as_json[:type]).to eq 'Motorcycle'
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
require_relative '../spec_helper'
|
2
|
+
require 'rexml/document'
|
3
|
+
|
4
|
+
%i(rexml libxml nokogiri).each do |lib|
|
5
|
+
begin
|
6
|
+
DataMapper::Serializer::XML.serializer = lib
|
7
|
+
rescue LoadError => e
|
8
|
+
warn "[WARNING] #{e.message}"
|
9
|
+
warn "[WARNING] Not running #to_xml specs for #{lib}"
|
10
|
+
next
|
11
|
+
end
|
12
|
+
|
13
|
+
describe DataMapper::Serializer, "#to_xml using #{lib}" do
|
14
|
+
before(:all) do
|
15
|
+
DataMapper.finalize
|
16
|
+
|
17
|
+
@harness = Class.new(SerializerTestHarness) do
|
18
|
+
def method_name
|
19
|
+
:to_xml
|
20
|
+
end
|
21
|
+
|
22
|
+
protected def deserialize(result)
|
23
|
+
f = lambda do |element|
|
24
|
+
case element.attributes['type']
|
25
|
+
when 'hash'
|
26
|
+
element.elements.to_a.inject({}) do |a, e|
|
27
|
+
a.update(e.name => f[e])
|
28
|
+
end
|
29
|
+
when 'array'
|
30
|
+
element.elements.collect do |e|
|
31
|
+
f[e]
|
32
|
+
end
|
33
|
+
else
|
34
|
+
if element.elements.empty?
|
35
|
+
cast(element.text, element.attributes['type'])
|
36
|
+
else
|
37
|
+
element.elements.to_a.inject({}) do |a, e|
|
38
|
+
a.update(e.name => f[e])
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
doc = REXML::Document.new(result)
|
45
|
+
f[doc.elements[1]]
|
46
|
+
end
|
47
|
+
|
48
|
+
protected def cast(value, type)
|
49
|
+
boolean_conversions = {'true' => true, 'false' => false}
|
50
|
+
value = boolean_conversions[value] if boolean_conversions.key?(value)
|
51
|
+
value = value.to_i if value && %w(integer datamapper::types::serial).include?(type)
|
52
|
+
value
|
53
|
+
end
|
54
|
+
end.new
|
55
|
+
end
|
56
|
+
|
57
|
+
it_behaves_like 'A serialization method'
|
58
|
+
|
59
|
+
it 'does not include the XML prologue, so that the result can be embedded in other XML documents' do
|
60
|
+
planet = Planet.new
|
61
|
+
xml = planet.to_xml(element_name: 'aplanet')
|
62
|
+
expect(xml).not_to match(/\A<?xml/)
|
63
|
+
end
|
64
|
+
|
65
|
+
describe ':element_name option for Resource' do
|
66
|
+
it 'is used as the root node name by #to_xml' do
|
67
|
+
planet = Planet.new
|
68
|
+
xml = planet.to_xml(element_name: 'aplanet')
|
69
|
+
expect(REXML::Document.new(xml).elements[1].name).to eq 'aplanet'
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'when not specified the class name underscored and with slashes replaced with dashes is used as the root node name' do
|
73
|
+
cat = QuanTum::Cat.new
|
74
|
+
xml = cat.to_xml
|
75
|
+
expect(REXML::Document.new(xml).elements[1].name).to eq 'quan_tum-cat'
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
describe ':collection_element_name for Collection' do
|
80
|
+
before(:each) do
|
81
|
+
@model = QuanTum::Cat
|
82
|
+
@query = DataMapper::Query.new(DataMapper::repository(:default), @model)
|
83
|
+
@collection = DataMapper::Collection.new(@query)
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'when not specified the class name tableized and with slashes replaced with dashes is used as the root node name' do
|
87
|
+
xml = DataMapper::Collection.new(@query).to_xml
|
88
|
+
expect(REXML::Document.new(xml).elements[1].name).to eq 'quan_tum-cats'
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'is used as the root node name by #to_xml' do
|
92
|
+
resources = @model.load([{'id' => 1}], @query)
|
93
|
+
@collection = DataMapper::Collection.new(@query, resources)
|
94
|
+
|
95
|
+
xml = @collection.to_xml(collection_element_name: 'somanycats')
|
96
|
+
expect(REXML::Document.new(xml).elements[1].name).to eq 'somanycats'
|
97
|
+
end
|
98
|
+
|
99
|
+
it 'respects :element_name for collection elements' do
|
100
|
+
resources = @model.load([{'id' => 1}], @query)
|
101
|
+
@collection = DataMapper::Collection.new(@query, resources)
|
102
|
+
|
103
|
+
xml = @collection.to_xml(collection_element_name: 'somanycats', element_name: 'cat')
|
104
|
+
expect(REXML::Document.new(xml).elements[1].elements[1].name).to eq 'cat'
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require_relative '../spec_helper'
|
2
|
+
|
3
|
+
describe DataMapper::Serializer, '#to_yaml' do
|
4
|
+
#
|
5
|
+
# ==== yummy YAML
|
6
|
+
#
|
7
|
+
|
8
|
+
before(:all) do
|
9
|
+
DataMapper.finalize
|
10
|
+
@harness = Class.new(SerializerTestHarness) do
|
11
|
+
def method_name
|
12
|
+
:to_yaml
|
13
|
+
end
|
14
|
+
|
15
|
+
def deserialize(result)
|
16
|
+
result = YAML.load(result)
|
17
|
+
process = lambda { |object|
|
18
|
+
if object.is_a?(Array)
|
19
|
+
object.collect(&process)
|
20
|
+
elsif object.is_a?(Hash)
|
21
|
+
object.inject({}) { |a, (key, value)| a.update(key.to_s => process[value]) }
|
22
|
+
else
|
23
|
+
object
|
24
|
+
end
|
25
|
+
}
|
26
|
+
process[result]
|
27
|
+
end
|
28
|
+
end.new
|
29
|
+
|
30
|
+
@ruby_192 = RUBY_VERSION >= '1.9.2'
|
31
|
+
@to_yaml = true
|
32
|
+
end
|
33
|
+
|
34
|
+
it_behaves_like 'A serialization method'
|
35
|
+
it_behaves_like 'A serialization method that also serializes core classes'
|
36
|
+
|
37
|
+
it 'allows static YAML dumping' do
|
38
|
+
object = Cow.create(
|
39
|
+
id: 89,
|
40
|
+
composite: 34,
|
41
|
+
name: 'Berta',
|
42
|
+
breed: 'Guernsey'
|
43
|
+
)
|
44
|
+
result = @harness.deserialize(YAML.dump(object))
|
45
|
+
expect(result['name']).to eq 'Berta'
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'allows static YAML dumping of a collection' do
|
49
|
+
Cow.create(
|
50
|
+
id: 89,
|
51
|
+
composite: 34,
|
52
|
+
name: 'Berta',
|
53
|
+
breed: 'Guernsey'
|
54
|
+
)
|
55
|
+
result = @harness.deserialize(YAML.dump(Cow.all))
|
56
|
+
expect(result[0]['name']).to eq 'Berta'
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
data/spec/rcov.opts
ADDED
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'dm-core/spec/setup'
|
2
|
+
require 'dm-core/spec/lib/adapter_helpers'
|
3
|
+
require 'dm-core/spec/lib/pending_helpers'
|
4
|
+
|
5
|
+
require 'dm-validations' # FIXME: must be required before dm-serializer
|
6
|
+
require 'dm-serializer'
|
7
|
+
require 'dm-migrations'
|
8
|
+
|
9
|
+
require File.expand_path('spec/lib/serialization_method_shared_spec')
|
10
|
+
|
11
|
+
# require fixture resources
|
12
|
+
SPEC_ROOT = Pathname(__FILE__).dirname.expand_path
|
13
|
+
Pathname.glob("#{SPEC_ROOT}fixtures/**/*.rb".to_s).each { |file| require file }
|
14
|
+
|
15
|
+
class SerializerTestHarness
|
16
|
+
def test(object, *args)
|
17
|
+
deserialize(object.send(method_name, *args))
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
DataMapper::Spec.setup
|
22
|
+
|
23
|
+
RSpec.configure do |config|
|
24
|
+
config.extend(DataMapper::Spec::Adapters::Helpers)
|
25
|
+
config.include(DataMapper::Spec::PendingHelpers)
|
26
|
+
end
|
data/tasks/spec.rake
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'rspec/core/rake_task'
|
2
|
+
|
3
|
+
begin
|
4
|
+
task(:default).clear
|
5
|
+
task(:spec).clear
|
6
|
+
|
7
|
+
RSpec::Core::RakeTask.new(:spec) do |spec|
|
8
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
9
|
+
|
10
|
+
require 'simplecov'
|
11
|
+
SimpleCov.start do
|
12
|
+
minimum_coverage 100
|
13
|
+
end
|
14
|
+
end
|
15
|
+
rescue LoadError
|
16
|
+
task :spec do
|
17
|
+
abort 'rspec is not available. In order to run spec, you must: gem install rspec'
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
task default: :spec
|
data/tasks/yard.rake
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
begin
|
2
|
+
require 'pathname'
|
3
|
+
require 'yardstick/rake/measurement'
|
4
|
+
require 'yardstick/rake/verify'
|
5
|
+
|
6
|
+
# yardstick_measure task
|
7
|
+
Yardstick::Rake::Measurement.new
|
8
|
+
|
9
|
+
# verify_measurements task
|
10
|
+
Yardstick::Rake::Verify.new do |verify|
|
11
|
+
verify.threshold = 100
|
12
|
+
end
|
13
|
+
rescue LoadError
|
14
|
+
%w[ yardstick_measure verify_measurements ].each do |name|
|
15
|
+
task name.to_s do
|
16
|
+
abort "Yardstick is not available. In order to run #{name}, you must: gem install yardstick"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|