multi_xml 0.2.2 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of multi_xml might be problematic. Click here for more details.

@@ -0,0 +1,550 @@
1
+ shared_examples_for "a parser" do |parser|
2
+
3
+ before do
4
+ begin
5
+ MultiXml.parser = parser
6
+ rescue LoadError
7
+ pending "Parser #{parser} couldn't be loaded"
8
+ end
9
+ end
10
+
11
+ describe ".parse" do
12
+ context "a blank string" do
13
+ before do
14
+ @xml = ''
15
+ end
16
+
17
+ it "should return an empty Hash" do
18
+ MultiXml.parse(@xml).should == {}
19
+ end
20
+ end
21
+
22
+ context "a whitespace string" do
23
+ before do
24
+ @xml = ' '
25
+ end
26
+
27
+ it "should return an empty Hash" do
28
+ MultiXml.parse(@xml).should == {}
29
+ end
30
+ end
31
+
32
+ context "an invalid XML document" do
33
+ before do
34
+ @xml = '<open></close>'
35
+ end
36
+
37
+ it "should raise MultiXml::ParseError" do
38
+ lambda do
39
+ MultiXml.parse(@xml)
40
+ end.should raise_error(MultiXml::ParseError)
41
+ end
42
+ end
43
+
44
+ context "a valid XML document" do
45
+ before do
46
+ @xml = '<user/>'
47
+ end
48
+
49
+ it "should parse correctly" do
50
+ MultiXml.parse(@xml).should == {'user' => nil}
51
+ end
52
+
53
+ context "with CDATA" do
54
+ before do
55
+ @xml = '<user><![CDATA[Erik Michaels-Ober]]></user>'
56
+ end
57
+
58
+ it "should return the correct CDATA" do
59
+ MultiXml.parse(@xml)['user'].should == "Erik Michaels-Ober"
60
+ end
61
+ end
62
+
63
+ context "with content" do
64
+ before do
65
+ @xml = '<user>Erik Michaels-Ober</user>'
66
+ end
67
+
68
+ it "should return the correct content" do
69
+ MultiXml.parse(@xml)['user'].should == "Erik Michaels-Ober"
70
+ end
71
+ end
72
+
73
+ context "with an attribute" do
74
+ before do
75
+ @xml = '<user name="Erik Michaels-Ober"/>'
76
+ end
77
+
78
+ it "should return the correct attribute" do
79
+ MultiXml.parse(@xml)['user']['name'].should == "Erik Michaels-Ober"
80
+ end
81
+ end
82
+
83
+ context "with multiple attributes" do
84
+ before do
85
+ @xml = '<user name="Erik Michaels-Ober" screen_name="sferik"/>'
86
+ end
87
+
88
+ it "should return the correct attributes" do
89
+ MultiXml.parse(@xml)['user']['name'].should be == "Erik Michaels-Ober"
90
+ MultiXml.parse(@xml)['user']['screen_name'].should be == "sferik"
91
+ end
92
+ end
93
+
94
+ context "with :symbolize_keys => true" do
95
+ before do
96
+ @xml = '<user><name>Erik Michaels-Ober</name></user>'
97
+ end
98
+
99
+ it "should symbolize keys" do
100
+ MultiXml.parse(@xml, :symbolize_keys => true).should == {:user => {:name => "Erik Michaels-Ober"}}
101
+ end
102
+ end
103
+
104
+ context "when value is true" do
105
+ before do
106
+ pending
107
+ @xml = '<tag>true</tag>'
108
+ end
109
+
110
+ it "should return true" do
111
+ MultiXml.parse(@xml)['tag'].should be_true
112
+ end
113
+ end
114
+
115
+ context "when value is false" do
116
+ before do
117
+ pending
118
+ @xml = '<tag>false</tag>'
119
+ end
120
+
121
+ it "should return false" do
122
+ MultiXml.parse(@xml)['tag'].should be_false
123
+ end
124
+ end
125
+
126
+ context "when key is id" do
127
+ before do
128
+ pending
129
+ @xml = '<id>1</id>'
130
+ end
131
+
132
+ it "should return a Fixnum" do
133
+ MultiXml.parse(@xml)['id'].should be_a(Fixnum)
134
+ end
135
+
136
+ it "should return the correct number" do
137
+ MultiXml.parse(@xml)['id'].should == 1
138
+ end
139
+ end
140
+
141
+ context "when key contains _id" do
142
+ before do
143
+ pending
144
+ @xml = '<tag_id>1</tag_id>'
145
+ end
146
+
147
+ it "should return a Fixnum" do
148
+ MultiXml.parse(@xml)['tag_id'].should be_a(Fixnum)
149
+ end
150
+
151
+ it "should return the correct number" do
152
+ MultiXml.parse(@xml)['tag_id'].should == 1
153
+ end
154
+ end
155
+
156
+ context "with an attribute type=\"boolean\"" do
157
+ %w(true false).each do |boolean|
158
+ context "when #{boolean}" do
159
+ it "should return #{boolean}" do
160
+ xml = "<tag type=\"boolean\">#{boolean}</tag>"
161
+ MultiXml.parse(xml)['tag'].should instance_eval("be_#{boolean}")
162
+ end
163
+ end
164
+ end
165
+
166
+ context "when 1" do
167
+ before do
168
+ @xml = '<tag type="boolean">1</tag>'
169
+ end
170
+
171
+ it "should return true" do
172
+ MultiXml.parse(@xml)['tag'].should be_true
173
+ end
174
+ end
175
+
176
+ context "when 0" do
177
+ before do
178
+ @xml = '<tag type="boolean">0</tag>'
179
+ end
180
+
181
+ it "should return false" do
182
+ MultiXml.parse(@xml)['tag'].should be_false
183
+ end
184
+ end
185
+ end
186
+
187
+ context "with an attribute type=\"integer\"" do
188
+ context "with a positive integer" do
189
+ before do
190
+ @xml = '<tag type="integer">1</tag>'
191
+ end
192
+
193
+ it "should return a Fixnum" do
194
+ MultiXml.parse(@xml)['tag'].should be_a(Fixnum)
195
+ end
196
+
197
+ it "should return a positive number" do
198
+ MultiXml.parse(@xml)['tag'].should > 0
199
+ end
200
+
201
+ it "should return the correct number" do
202
+ MultiXml.parse(@xml)['tag'].should == 1
203
+ end
204
+ end
205
+
206
+ context "with a negative integer" do
207
+ before do
208
+ @xml = '<tag type="integer">-1</tag>'
209
+ end
210
+
211
+ it "should return a Fixnum" do
212
+ MultiXml.parse(@xml)['tag'].should be_a(Fixnum)
213
+ end
214
+
215
+ it "should return a negative number" do
216
+ MultiXml.parse(@xml)['tag'].should < 0
217
+ end
218
+
219
+ it "should return the correct number" do
220
+ MultiXml.parse(@xml)['tag'].should == -1
221
+ end
222
+ end
223
+ end
224
+
225
+ context "with an attribute type=\"string\"" do
226
+ before do
227
+ @xml = '<tag type="string"></tag>'
228
+ end
229
+
230
+ it "should return a String" do
231
+ MultiXml.parse(@xml)['tag'].should be_a(String)
232
+ end
233
+
234
+ it "should return the correct string" do
235
+ MultiXml.parse(@xml)['tag'].should == ""
236
+ end
237
+ end
238
+
239
+ context "with an attribute type=\"date\"" do
240
+ before do
241
+ @xml = '<tag type="date">1970-01-01</tag>'
242
+ end
243
+
244
+ it "should return a Date" do
245
+ MultiXml.parse(@xml)['tag'].should be_a(Date)
246
+ end
247
+
248
+ it "should return the correct date" do
249
+ MultiXml.parse(@xml)['tag'].should == Date.parse('1970-01-01')
250
+ end
251
+ end
252
+
253
+ context "with an attribute type=\"datetime\"" do
254
+ before do
255
+ @xml = '<tag type="datetime">1970-01-01 00:00</tag>'
256
+ end
257
+
258
+ it "should return a Time" do
259
+ MultiXml.parse(@xml)['tag'].should be_a(Time)
260
+ end
261
+
262
+ it "should return the correct time" do
263
+ MultiXml.parse(@xml)['tag'].should == Time.parse('1970-01-01 00:00')
264
+ end
265
+ end
266
+
267
+ context "with an attribute type=\"dateTime\"" do
268
+ before do
269
+ @xml = '<tag type="datetime">1970-01-01 00:00</tag>'
270
+ end
271
+
272
+ it "should return a Time" do
273
+ MultiXml.parse(@xml)['tag'].should be_a(Time)
274
+ end
275
+
276
+ it "should return the correct time" do
277
+ MultiXml.parse(@xml)['tag'].should == Time.parse('1970-01-01 00:00')
278
+ end
279
+ end
280
+
281
+ context "with an attribute type=\"double\"" do
282
+ before do
283
+ @xml = '<tag type="double">3.14159265358979</tag>'
284
+ end
285
+
286
+ it "should return a Float" do
287
+ MultiXml.parse(@xml)['tag'].should be_a(Float)
288
+ end
289
+
290
+ it "should return the correct number" do
291
+ MultiXml.parse(@xml)['tag'].should == 3.14159265358979
292
+ end
293
+ end
294
+
295
+ context "with an attribute type=\"decimal\"" do
296
+ before do
297
+ @xml = '<tag type="decimal">3.14159265358979323846264338327950288419716939937510</tag>'
298
+ end
299
+
300
+ it "should return a BigDecimal" do
301
+ MultiXml.parse(@xml)['tag'].should be_a(BigDecimal)
302
+ end
303
+
304
+ it "should return the correct number" do
305
+ MultiXml.parse(@xml)['tag'].should == 3.14159265358979323846264338327950288419716939937510
306
+ end
307
+ end
308
+
309
+ context "with an attribute type=\"base64Binary\"" do
310
+ before do
311
+ @xml = '<tag type="base64Binary">aW1hZ2UucG5n</tag>'
312
+ end
313
+
314
+ it "should return a String" do
315
+ MultiXml.parse(@xml)['tag'].should be_a(String)
316
+ end
317
+
318
+ it "should return the correct string" do
319
+ MultiXml.parse(@xml)['tag'].should == "image.png"
320
+ end
321
+ end
322
+
323
+ context "with an attribute type=\"yaml\"" do
324
+ before do
325
+ @xml = "<tag type=\"yaml\">--- \n1: should return an integer\n:message: Have a nice day\narray: \n- should-have-dashes: true\n should_have_underscores: true\n</tag>"
326
+ end
327
+
328
+ it "should return a Hash" do
329
+ MultiXml.parse(@xml)['tag'].should be_a(Hash)
330
+ end
331
+
332
+ it "should return the correctly parsed YAML" do
333
+ MultiXml.parse(@xml)['tag'].should == {:message => "Have a nice day", 1 => "should return an integer", "array" => [{"should-have-dashes" => true, "should_have_underscores" => true}]}
334
+ end
335
+ end
336
+
337
+ context "with an attribute type=\"file\"" do
338
+ before do
339
+ @xml = '<tag type="file" name="data.txt" content_type="text/plain">ZGF0YQ==</tag>'
340
+ end
341
+
342
+ it "should return a StringIO" do
343
+ MultiXml.parse(@xml)['tag'].should be_a(StringIO)
344
+ end
345
+
346
+ it "should be decoded correctly" do
347
+ MultiXml.parse(@xml)['tag'].string.should == 'data'
348
+ end
349
+
350
+ it "should have the correct file name" do
351
+ MultiXml.parse(@xml)['tag'].original_filename.should == 'data.txt'
352
+ end
353
+
354
+ it "should have the correct content type" do
355
+ MultiXml.parse(@xml)['tag'].content_type.should == 'text/plain'
356
+ end
357
+
358
+ context "with missing name and content type" do
359
+ before do
360
+ @xml = '<tag type="file">ZGF0YQ==</tag>'
361
+ end
362
+
363
+ it "should return a StringIO" do
364
+ MultiXml.parse(@xml)['tag'].should be_a(StringIO)
365
+ end
366
+
367
+ it "should be decoded correctly" do
368
+ MultiXml.parse(@xml)['tag'].string.should == 'data'
369
+ end
370
+
371
+ it "should have the default file name" do
372
+ MultiXml.parse(@xml)['tag'].original_filename.should == 'untitled'
373
+ end
374
+
375
+ it "should have the default content type" do
376
+ MultiXml.parse(@xml)['tag'].content_type.should == 'application/octet-stream'
377
+ end
378
+ end
379
+ end
380
+
381
+ context "with an attribute type=\"array\"" do
382
+ before do
383
+ @xml = '<users type="array"><user>Erik Michaels-Ober</user><user>Wynn Netherland</user></users>'
384
+ end
385
+
386
+ it "should return an Array" do
387
+ MultiXml.parse(@xml)['users'].should be_a(Array)
388
+ end
389
+
390
+ it "should return the correct array" do
391
+ MultiXml.parse(@xml)['users'].should == ["Erik Michaels-Ober", "Wynn Netherland"]
392
+ end
393
+ end
394
+
395
+ %w(integer boolean date datetime yaml file).each do |type|
396
+ context "with an empty attribute type=\"#{type}\"" do
397
+ before do
398
+ @xml = "<tag type=\"#{type}\"/>"
399
+ end
400
+
401
+ it "should return nil" do
402
+ MultiXml.parse(@xml)['tag'].should be_nil
403
+ end
404
+ end
405
+ end
406
+
407
+ context "with an empty attribute type=\"array\"" do
408
+ before do
409
+ @xml = '<tag type="array"/>'
410
+ end
411
+
412
+ it "should return an empty Array" do
413
+ MultiXml.parse(@xml)['tag'].should == []
414
+ end
415
+
416
+ context "with whitespace" do
417
+ before do
418
+ @xml = '<tag type="array"> </tag>'
419
+ end
420
+
421
+ it "should return an empty Array" do
422
+ MultiXml.parse(@xml)['tag'].should == []
423
+ end
424
+ end
425
+ end
426
+
427
+ context "with XML entities" do
428
+ before do
429
+ @xml_entities = {
430
+ "<" => "&lt;",
431
+ ">" => "&gt;",
432
+ '"' => "&quot;",
433
+ "'" => "&apos;",
434
+ "&" => "&amp;"
435
+ }
436
+ end
437
+
438
+ context "in content" do
439
+ it "should return unescaped XML entities" do
440
+ @xml_entities.each do |key, value|
441
+ xml = "<tag>#{value}</tag>"
442
+ MultiXml.parse(xml)['tag'].should == key
443
+ end
444
+ end
445
+ end
446
+
447
+ context "in attribute" do
448
+ it "should return unescaped XML entities" do
449
+ @xml_entities.each do |key, value|
450
+ xml = "<tag attribute=\"#{value}\"/>"
451
+ MultiXml.parse(xml)['tag']['attribute'].should == key
452
+ end
453
+ end
454
+ end
455
+ end
456
+
457
+ context "with dasherized tag" do
458
+ before do
459
+ @xml = '<tag-1/>'
460
+ end
461
+
462
+ it "should return undasherize tag" do
463
+ MultiXml.parse(@xml).keys.should include('tag_1')
464
+ end
465
+ end
466
+
467
+ context "with dasherized attribute" do
468
+ before do
469
+ @xml = '<tag attribute-1="1"></tag>'
470
+ end
471
+
472
+ it "should return undasherize attribute" do
473
+ MultiXml.parse(@xml)['tag'].keys.should include('attribute_1')
474
+ end
475
+ end
476
+
477
+ context "with children" do
478
+ context "with attributes" do
479
+ before do
480
+ @xml = '<users><user name="Erik Michaels-Ober"/></users>'
481
+ end
482
+
483
+ it "should return the correct attributes" do
484
+ MultiXml.parse(@xml)['users']['user']['name'].should == "Erik Michaels-Ober"
485
+ end
486
+ end
487
+
488
+ context "with text" do
489
+ before do
490
+ @xml = '<user><name>Erik Michaels-Ober</name></user>'
491
+ end
492
+
493
+ it "should return the correct text" do
494
+ MultiXml.parse(@xml)['user']['name'].should == "Erik Michaels-Ober"
495
+ end
496
+ end
497
+
498
+ context "with an unrecognized attribute type" do
499
+ before do
500
+ @xml = '<user type="admin"><name>Erik Michaels-Ober</name></user>'
501
+ end
502
+
503
+ it "should pass through the type" do
504
+ MultiXml.parse(@xml)['user']['type'].should == 'admin'
505
+ end
506
+ end
507
+
508
+ context "with newlines and whitespace" do
509
+ before do
510
+ @xml = <<-XML
511
+ <user>
512
+ <name>Erik Michaels-Ober</name>
513
+ </user>
514
+ XML
515
+ end
516
+
517
+ it "should parse correctly" do
518
+ MultiXml.parse(@xml).should == {"user" => {"name" => "Erik Michaels-Ober"}}
519
+ end
520
+ end
521
+
522
+ # Babies having babies
523
+ context "with children" do
524
+ before do
525
+ @xml = '<users><user name="Erik Michaels-Ober"><status text="Hello"/></user></users>'
526
+ end
527
+
528
+ it "should parse correctly" do
529
+ MultiXml.parse(@xml).should == {"users" => {"user" => {"name" => "Erik Michaels-Ober", "status" => {"text" => "Hello"}}}}
530
+ end
531
+ end
532
+ end
533
+
534
+ context "with sibling children" do
535
+ before do
536
+ @xml = '<users><user>Erik Michaels-Ober</user><user>Wynn Netherland</user></users>'
537
+ end
538
+
539
+ it "should return an Array" do
540
+ MultiXml.parse(@xml)['users']['user'].should be_a(Array)
541
+ end
542
+
543
+ it "should parse correctly" do
544
+ MultiXml.parse(@xml).should == {"users" => {"user" => ["Erik Michaels-Ober", "Wynn Netherland"]}}
545
+ end
546
+ end
547
+ end
548
+ end
549
+
550
+ end