sbf-dm-serializer 1.3.0.beta
Sign up to get free protection for your applications and to get access to all the features.
- 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
|