crack 0.4.3 → 0.4.6
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 +5 -5
- data/History +23 -2
- data/README.md +9 -12
- data/lib/crack/json.rb +25 -23
- data/lib/crack/version.rb +1 -1
- data/lib/crack.rb +1 -0
- metadata +33 -41
- data/.gitignore +0 -8
- data/.travis.yml +0 -14
- data/Gemfile +0 -5
- data/crack.gemspec +0 -20
- data/script/bootstrap +0 -21
- data/script/release +0 -42
- data/script/test +0 -25
- data/test/data/large_dataset.json +0 -139988
- data/test/data/twittersearch-firefox.json +0 -1
- data/test/data/twittersearch-ie.json +0 -1
- data/test/hash_test.rb +0 -26
- data/test/json_test.rb +0 -91
- data/test/parser_test.rb +0 -27
- data/test/string_test.rb +0 -31
- data/test/test_helper.rb +0 -3
- data/test/xml_test.rb +0 -514
data/test/xml_test.rb
DELETED
@@ -1,514 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
|
3
|
-
describe Crack::XML do
|
4
|
-
it "should transform a simple tag with content" do
|
5
|
-
xml = "<tag>This is the contents</tag>"
|
6
|
-
Crack::XML.parse(xml).must_equal({ 'tag' => 'This is the contents' })
|
7
|
-
end
|
8
|
-
|
9
|
-
it "should work with cdata tags" do
|
10
|
-
xml = <<-END
|
11
|
-
<tag>
|
12
|
-
<![CDATA[
|
13
|
-
text inside cdata
|
14
|
-
]]>
|
15
|
-
</tag>
|
16
|
-
END
|
17
|
-
Crack::XML.parse(xml)["tag"].strip.must_equal "text inside cdata"
|
18
|
-
end
|
19
|
-
|
20
|
-
it "should transform a simple tag with attributes" do
|
21
|
-
xml = "<tag attr1='1' attr2='2'></tag>"
|
22
|
-
hash = { 'tag' => { 'attr1' => '1', 'attr2' => '2' } }
|
23
|
-
Crack::XML.parse(xml).must_equal hash
|
24
|
-
end
|
25
|
-
|
26
|
-
it "should transform repeating siblings into an array" do
|
27
|
-
xml =<<-XML
|
28
|
-
<opt>
|
29
|
-
<user login="grep" fullname="Gary R Epstein" />
|
30
|
-
<user login="stty" fullname="Simon T Tyson" />
|
31
|
-
</opt>
|
32
|
-
XML
|
33
|
-
|
34
|
-
Crack::XML.parse(xml)['opt']['user'].class.must_equal Array
|
35
|
-
|
36
|
-
hash = {
|
37
|
-
'opt' => {
|
38
|
-
'user' => [{
|
39
|
-
'login' => 'grep',
|
40
|
-
'fullname' => 'Gary R Epstein'
|
41
|
-
},{
|
42
|
-
'login' => 'stty',
|
43
|
-
'fullname' => 'Simon T Tyson'
|
44
|
-
}]
|
45
|
-
}
|
46
|
-
}
|
47
|
-
|
48
|
-
Crack::XML.parse(xml).must_equal hash
|
49
|
-
end
|
50
|
-
|
51
|
-
it "should not transform non-repeating siblings into an array" do
|
52
|
-
xml =<<-XML
|
53
|
-
<opt>
|
54
|
-
<user login="grep" fullname="Gary R Epstein" />
|
55
|
-
</opt>
|
56
|
-
XML
|
57
|
-
|
58
|
-
Crack::XML.parse(xml)['opt']['user'].class.must_equal Hash
|
59
|
-
|
60
|
-
hash = {
|
61
|
-
'opt' => {
|
62
|
-
'user' => {
|
63
|
-
'login' => 'grep',
|
64
|
-
'fullname' => 'Gary R Epstein'
|
65
|
-
}
|
66
|
-
}
|
67
|
-
}
|
68
|
-
|
69
|
-
Crack::XML.parse(xml).must_equal hash
|
70
|
-
end
|
71
|
-
|
72
|
-
describe "Parsing xml with text and attributes" do
|
73
|
-
before do
|
74
|
-
xml =<<-XML
|
75
|
-
<opt>
|
76
|
-
<user login="grep">Gary R Epstein</user>
|
77
|
-
<user>Simon T Tyson</user>
|
78
|
-
</opt>
|
79
|
-
XML
|
80
|
-
@data = Crack::XML.parse(xml)
|
81
|
-
end
|
82
|
-
|
83
|
-
it "correctly parse text nodes" do
|
84
|
-
@data.must_equal({
|
85
|
-
'opt' => {
|
86
|
-
'user' => [
|
87
|
-
'Gary R Epstein',
|
88
|
-
'Simon T Tyson'
|
89
|
-
]
|
90
|
-
}
|
91
|
-
})
|
92
|
-
end
|
93
|
-
|
94
|
-
it "be parse attributes for text node if present" do
|
95
|
-
@data['opt']['user'][0].attributes.must_equal({'login' => 'grep'})
|
96
|
-
end
|
97
|
-
|
98
|
-
it "default attributes to empty hash if not present" do
|
99
|
-
@data['opt']['user'][1].attributes.must_equal({})
|
100
|
-
end
|
101
|
-
|
102
|
-
it "add 'attributes' accessor methods to parsed instances of String" do
|
103
|
-
@data['opt']['user'][0].respond_to?(:attributes).must_equal(true)
|
104
|
-
@data['opt']['user'][0].respond_to?(:attributes=).must_equal(true)
|
105
|
-
end
|
106
|
-
|
107
|
-
it "not add 'attributes' accessor methods to all instances of String" do
|
108
|
-
"some-string".respond_to?(:attributes).must_equal(false)
|
109
|
-
"some-string".respond_to?(:attributes=).must_equal(false)
|
110
|
-
end
|
111
|
-
end
|
112
|
-
|
113
|
-
it "should typecast an integer" do
|
114
|
-
xml = "<tag type='integer'>10</tag>"
|
115
|
-
Crack::XML.parse(xml)['tag'].must_equal 10
|
116
|
-
end
|
117
|
-
|
118
|
-
it "should typecast a true boolean" do
|
119
|
-
xml = "<tag type='boolean'>true</tag>"
|
120
|
-
Crack::XML.parse(xml)['tag'].must_equal(true)
|
121
|
-
end
|
122
|
-
|
123
|
-
it "should typecast a false boolean" do
|
124
|
-
["false"].each do |w|
|
125
|
-
Crack::XML.parse("<tag type='boolean'>#{w}</tag>")['tag'].must_equal(false)
|
126
|
-
end
|
127
|
-
end
|
128
|
-
|
129
|
-
it "should typecast a datetime" do
|
130
|
-
xml = "<tag type='datetime'>2007-12-31 10:32</tag>"
|
131
|
-
Crack::XML.parse(xml)['tag'].must_equal Time.parse( '2007-12-31 10:32' ).utc
|
132
|
-
end
|
133
|
-
|
134
|
-
it "should typecast a date" do
|
135
|
-
xml = "<tag type='date'>2007-12-31</tag>"
|
136
|
-
Crack::XML.parse(xml)['tag'].must_equal Date.parse('2007-12-31')
|
137
|
-
end
|
138
|
-
|
139
|
-
xml_entities = {
|
140
|
-
"<" => "<",
|
141
|
-
">" => ">",
|
142
|
-
'"' => """,
|
143
|
-
"'" => "'",
|
144
|
-
"&" => "&"
|
145
|
-
}
|
146
|
-
it "should unescape html entities" do
|
147
|
-
xml_entities.each do |k,v|
|
148
|
-
xml = "<tag>Some content #{v}</tag>"
|
149
|
-
Crack::XML.parse(xml)['tag'].must_match Regexp.new(k)
|
150
|
-
end
|
151
|
-
end
|
152
|
-
|
153
|
-
it "should unescape XML entities in attributes" do
|
154
|
-
xml_entities.each do |k,v|
|
155
|
-
xml = "<tag attr='Some content #{v}'></tag>"
|
156
|
-
Crack::XML.parse(xml)['tag']['attr'].must_match Regexp.new(k)
|
157
|
-
end
|
158
|
-
end
|
159
|
-
|
160
|
-
it "should undasherize keys as tags" do
|
161
|
-
xml = "<tag-1>Stuff</tag-1>"
|
162
|
-
Crack::XML.parse(xml).keys.must_include( 'tag_1' )
|
163
|
-
end
|
164
|
-
|
165
|
-
it "should undasherize keys as attributes" do
|
166
|
-
xml = "<tag1 attr-1='1'></tag1>"
|
167
|
-
Crack::XML.parse(xml)['tag1'].keys.must_include( 'attr_1')
|
168
|
-
end
|
169
|
-
|
170
|
-
it "should undasherize keys as tags and attributes" do
|
171
|
-
xml = "<tag-1 attr-1='1'></tag-1>"
|
172
|
-
Crack::XML.parse(xml).keys.must_include( 'tag_1' )
|
173
|
-
Crack::XML.parse(xml)['tag_1'].keys.must_include( 'attr_1')
|
174
|
-
end
|
175
|
-
|
176
|
-
it "should render nested content correctly" do
|
177
|
-
xml = "<root><tag1>Tag1 Content <em><strong>This is strong</strong></em></tag1></root>"
|
178
|
-
Crack::XML.parse(xml)['root']['tag1'].must_equal "Tag1 Content <em><strong>This is strong</strong></em>"
|
179
|
-
end
|
180
|
-
|
181
|
-
it "should render nested content with splshould text nodes correctly" do
|
182
|
-
xml = "<root>Tag1 Content<em>Stuff</em> Hi There</root>"
|
183
|
-
Crack::XML.parse(xml)['root'].must_equal "Tag1 Content<em>Stuff</em> Hi There"
|
184
|
-
end
|
185
|
-
|
186
|
-
it "should ignore attributes when a child is a text node" do
|
187
|
-
xml = "<root attr1='1'>Stuff</root>"
|
188
|
-
Crack::XML.parse(xml).must_equal({ "root" => "Stuff" })
|
189
|
-
end
|
190
|
-
|
191
|
-
it "should ignore attributes when any child is a text node" do
|
192
|
-
xml = "<root attr1='1'>Stuff <em>in italics</em></root>"
|
193
|
-
Crack::XML.parse(xml).must_equal({ "root" => "Stuff <em>in italics</em>" })
|
194
|
-
end
|
195
|
-
|
196
|
-
it "should correctly transform multiple children" do
|
197
|
-
xml = <<-XML
|
198
|
-
<user gender='m'>
|
199
|
-
<age type='integer'>35</age>
|
200
|
-
<name>Home Simpson</name>
|
201
|
-
<dob type='date'>1988-01-01</dob>
|
202
|
-
<joined-at type='datetime'>2000-04-28 23:01</joined-at>
|
203
|
-
<is-cool type='boolean'>true</is-cool>
|
204
|
-
</user>
|
205
|
-
XML
|
206
|
-
|
207
|
-
hash = {
|
208
|
-
"user" => {
|
209
|
-
"gender" => "m",
|
210
|
-
"age" => 35,
|
211
|
-
"name" => "Home Simpson",
|
212
|
-
"dob" => Date.parse('1988-01-01'),
|
213
|
-
"joined_at" => Time.parse("2000-04-28 23:01"),
|
214
|
-
"is_cool" => true
|
215
|
-
}
|
216
|
-
}
|
217
|
-
|
218
|
-
Crack::XML.parse(xml).must_equal hash
|
219
|
-
end
|
220
|
-
|
221
|
-
it "should properly handle nil values (ActiveSupport Compatible)" do
|
222
|
-
topic_xml = <<-EOT
|
223
|
-
<topic>
|
224
|
-
<title></title>
|
225
|
-
<id type="integer"></id>
|
226
|
-
<approved type="boolean"></approved>
|
227
|
-
<written-on type="date"></written-on>
|
228
|
-
<viewed-at type="datetime"></viewed-at>
|
229
|
-
<parent-id></parent-id>
|
230
|
-
</topic>
|
231
|
-
EOT
|
232
|
-
|
233
|
-
expected_topic_hash = {
|
234
|
-
'title' => nil,
|
235
|
-
'id' => nil,
|
236
|
-
'approved' => nil,
|
237
|
-
'written_on' => nil,
|
238
|
-
'viewed_at' => nil,
|
239
|
-
'parent_id' => nil
|
240
|
-
}
|
241
|
-
Crack::XML.parse(topic_xml)["topic"].must_equal expected_topic_hash
|
242
|
-
end
|
243
|
-
|
244
|
-
it "should handle a single record from xml (ActiveSupport Compatible)" do
|
245
|
-
topic_xml = <<-EOT
|
246
|
-
<topic>
|
247
|
-
<title>The First Topic</title>
|
248
|
-
<author-name>David</author-name>
|
249
|
-
<id type="integer">1</id>
|
250
|
-
<approved type="boolean"> true </approved>
|
251
|
-
<replies-count type="integer">0</replies-count>
|
252
|
-
<replies-close-in type="integer">2592000000</replies-close-in>
|
253
|
-
<written-on type="date">2003-07-16</written-on>
|
254
|
-
<viewed-at type="datetime">2003-07-16T09:28:00+0000</viewed-at>
|
255
|
-
<author-email-address>david@loudthinking.com</author-email-address>
|
256
|
-
<parent-id></parent-id>
|
257
|
-
<ad-revenue type="decimal">1.5</ad-revenue>
|
258
|
-
<optimum-viewing-angle type="float">135</optimum-viewing-angle>
|
259
|
-
<resident type="symbol">yes</resident>
|
260
|
-
</topic>
|
261
|
-
EOT
|
262
|
-
|
263
|
-
expected_topic_hash = {
|
264
|
-
'title' => "The First Topic",
|
265
|
-
'author_name' => "David",
|
266
|
-
'id' => 1,
|
267
|
-
'approved' => true,
|
268
|
-
'replies_count' => 0,
|
269
|
-
'replies_close_in' => 2592000000,
|
270
|
-
'written_on' => Date.new(2003, 7, 16),
|
271
|
-
'viewed_at' => Time.utc(2003, 7, 16, 9, 28),
|
272
|
-
'author_email_address' => "david@loudthinking.com",
|
273
|
-
'parent_id' => nil,
|
274
|
-
'ad_revenue' => BigDecimal("1.50"),
|
275
|
-
'optimum_viewing_angle' => 135.0,
|
276
|
-
'resident' => 'yes',
|
277
|
-
}
|
278
|
-
|
279
|
-
Crack::XML.parse(topic_xml)["topic"].each do |k,v|
|
280
|
-
v.must_equal expected_topic_hash[k]
|
281
|
-
end
|
282
|
-
end
|
283
|
-
|
284
|
-
it "should handle multiple records (ActiveSupport Compatible)" do
|
285
|
-
topics_xml = <<-EOT
|
286
|
-
<topics type="array">
|
287
|
-
<topic>
|
288
|
-
<title>The First Topic</title>
|
289
|
-
<author-name>David</author-name>
|
290
|
-
<id type="integer">1</id>
|
291
|
-
<approved type="boolean">false</approved>
|
292
|
-
<replies-count type="integer">0</replies-count>
|
293
|
-
<replies-close-in type="integer">2592000000</replies-close-in>
|
294
|
-
<written-on type="date">2003-07-16</written-on>
|
295
|
-
<viewed-at type="datetime">2003-07-16T09:28:00+0000</viewed-at>
|
296
|
-
<content>Have a nice day</content>
|
297
|
-
<author-email-address>david@loudthinking.com</author-email-address>
|
298
|
-
<parent-id nil="true"></parent-id>
|
299
|
-
</topic>
|
300
|
-
<topic>
|
301
|
-
<title>The Second Topic</title>
|
302
|
-
<author-name>Jason</author-name>
|
303
|
-
<id type="integer">1</id>
|
304
|
-
<approved type="boolean">false</approved>
|
305
|
-
<replies-count type="integer">0</replies-count>
|
306
|
-
<replies-close-in type="integer">2592000000</replies-close-in>
|
307
|
-
<written-on type="date">2003-07-16</written-on>
|
308
|
-
<viewed-at type="datetime">2003-07-16T09:28:00+0000</viewed-at>
|
309
|
-
<content>Have a nice day</content>
|
310
|
-
<author-email-address>david@loudthinking.com</author-email-address>
|
311
|
-
<parent-id></parent-id>
|
312
|
-
</topic>
|
313
|
-
</topics>
|
314
|
-
EOT
|
315
|
-
|
316
|
-
expected_topic_hash = {
|
317
|
-
'title' => "The First Topic",
|
318
|
-
'author_name' => "David",
|
319
|
-
'id' => 1,
|
320
|
-
'approved' => false,
|
321
|
-
'replies_count' => 0,
|
322
|
-
'replies_close_in' => 2592000000,
|
323
|
-
'written_on' => Date.new(2003, 7, 16),
|
324
|
-
'viewed_at' => Time.utc(2003, 7, 16, 9, 28),
|
325
|
-
'content' => "Have a nice day",
|
326
|
-
'author_email_address' => "david@loudthinking.com",
|
327
|
-
'parent_id' => nil
|
328
|
-
}
|
329
|
-
# puts Crack::XML.parse(topics_xml)['topics'].first.inspect
|
330
|
-
Crack::XML.parse(topics_xml)["topics"].first.each do |k,v|
|
331
|
-
v.must_equal expected_topic_hash[k]
|
332
|
-
end
|
333
|
-
end
|
334
|
-
|
335
|
-
it "should handle a single record from_xml with attributes other than type (ActiveSupport Compatible)" do
|
336
|
-
topic_xml = <<-EOT
|
337
|
-
<rsp stat="ok">
|
338
|
-
<photos page="1" pages="1" perpage="100" total="16">
|
339
|
-
<photo id="175756086" owner="55569174@N00" secret="0279bf37a1" server="76" title="Colored Pencil PhotoBooth Fun" ispublic="1" isfriend="0" isfamily="0"/>
|
340
|
-
</photos>
|
341
|
-
</rsp>
|
342
|
-
EOT
|
343
|
-
|
344
|
-
expected_topic_hash = {
|
345
|
-
'id' => "175756086",
|
346
|
-
'owner' => "55569174@N00",
|
347
|
-
'secret' => "0279bf37a1",
|
348
|
-
'server' => "76",
|
349
|
-
'title' => "Colored Pencil PhotoBooth Fun",
|
350
|
-
'ispublic' => "1",
|
351
|
-
'isfriend' => "0",
|
352
|
-
'isfamily' => "0",
|
353
|
-
}
|
354
|
-
Crack::XML.parse(topic_xml)["rsp"]["photos"]["photo"].each do |k,v|
|
355
|
-
v.must_equal expected_topic_hash[k]
|
356
|
-
end
|
357
|
-
end
|
358
|
-
|
359
|
-
it "should handle an emtpy array (ActiveSupport Compatible)" do
|
360
|
-
blog_xml = <<-XML
|
361
|
-
<blog>
|
362
|
-
<posts type="array"></posts>
|
363
|
-
</blog>
|
364
|
-
XML
|
365
|
-
expected_blog_hash = {"blog" => {"posts" => []}}
|
366
|
-
Crack::XML.parse(blog_xml).must_equal expected_blog_hash
|
367
|
-
end
|
368
|
-
|
369
|
-
it "should handle empty array with whitespace from xml (ActiveSupport Compatible)" do
|
370
|
-
blog_xml = <<-XML
|
371
|
-
<blog>
|
372
|
-
<posts type="array">
|
373
|
-
</posts>
|
374
|
-
</blog>
|
375
|
-
XML
|
376
|
-
expected_blog_hash = {"blog" => {"posts" => []}}
|
377
|
-
Crack::XML.parse(blog_xml).must_equal expected_blog_hash
|
378
|
-
end
|
379
|
-
|
380
|
-
it "should handle array with one entry from_xml (ActiveSupport Compatible)" do
|
381
|
-
blog_xml = <<-XML
|
382
|
-
<blog>
|
383
|
-
<posts type="array">
|
384
|
-
<post>a post</post>
|
385
|
-
</posts>
|
386
|
-
</blog>
|
387
|
-
XML
|
388
|
-
expected_blog_hash = {"blog" => {"posts" => ["a post"]}}
|
389
|
-
Crack::XML.parse(blog_xml).must_equal expected_blog_hash
|
390
|
-
end
|
391
|
-
|
392
|
-
it "should handle array with multiple entries from xml (ActiveSupport Compatible)" do
|
393
|
-
blog_xml = <<-XML
|
394
|
-
<blog>
|
395
|
-
<posts type="array">
|
396
|
-
<post>a post</post>
|
397
|
-
<post>another post</post>
|
398
|
-
</posts>
|
399
|
-
</blog>
|
400
|
-
XML
|
401
|
-
expected_blog_hash = {"blog" => {"posts" => ["a post", "another post"]}}
|
402
|
-
Crack::XML.parse(blog_xml).must_equal expected_blog_hash
|
403
|
-
end
|
404
|
-
|
405
|
-
it "should handle file types (ActiveSupport Compatible)" do
|
406
|
-
blog_xml = <<-XML
|
407
|
-
<blog>
|
408
|
-
<logo type="file" name="logo.png" content_type="image/png">
|
409
|
-
</logo>
|
410
|
-
</blog>
|
411
|
-
XML
|
412
|
-
hash = Crack::XML.parse(blog_xml)
|
413
|
-
hash.keys.must_include('blog')
|
414
|
-
hash['blog'].keys.must_include('logo')
|
415
|
-
|
416
|
-
file = hash['blog']['logo']
|
417
|
-
file.original_filename.must_equal 'logo.png'
|
418
|
-
file.content_type.must_equal 'image/png'
|
419
|
-
end
|
420
|
-
|
421
|
-
it "should handle file from xml with defaults (ActiveSupport Compatible)" do
|
422
|
-
blog_xml = <<-XML
|
423
|
-
<blog>
|
424
|
-
<logo type="file">
|
425
|
-
</logo>
|
426
|
-
</blog>
|
427
|
-
XML
|
428
|
-
file = Crack::XML.parse(blog_xml)['blog']['logo']
|
429
|
-
file.original_filename.must_equal 'untitled'
|
430
|
-
file.content_type.must_equal 'application/octet-stream'
|
431
|
-
end
|
432
|
-
|
433
|
-
it "should handle xsd like types from xml (ActiveSupport Compatible)" do
|
434
|
-
bacon_xml = <<-EOT
|
435
|
-
<bacon>
|
436
|
-
<weight type="double">0.5</weight>
|
437
|
-
<price type="decimal">12.50</price>
|
438
|
-
<chunky type="boolean"> 1 </chunky>
|
439
|
-
<expires-at type="dateTime">2007-12-25T12:34:56+0000</expires-at>
|
440
|
-
<notes type="string"></notes>
|
441
|
-
<illustration type="base64Binary">YmFiZS5wbmc=</illustration>
|
442
|
-
</bacon>
|
443
|
-
EOT
|
444
|
-
|
445
|
-
expected_bacon_hash = {
|
446
|
-
'weight' => 0.5,
|
447
|
-
'chunky' => true,
|
448
|
-
'price' => BigDecimal("12.50"),
|
449
|
-
'expires_at' => Time.utc(2007,12,25,12,34,56),
|
450
|
-
'notes' => "",
|
451
|
-
'illustration' => "babe.png"
|
452
|
-
}
|
453
|
-
|
454
|
-
Crack::XML.parse(bacon_xml)["bacon"].must_equal expected_bacon_hash
|
455
|
-
end
|
456
|
-
|
457
|
-
it "should let type trickle through when unknown (ActiveSupport Compatible)" do
|
458
|
-
product_xml = <<-EOT
|
459
|
-
<product>
|
460
|
-
<weight type="double">0.5</weight>
|
461
|
-
<image type="ProductImage"><filename>image.gif</filename></image>
|
462
|
-
|
463
|
-
</product>
|
464
|
-
EOT
|
465
|
-
|
466
|
-
expected_product_hash = {
|
467
|
-
'weight' => 0.5,
|
468
|
-
'image' => {'type' => 'ProductImage', 'filename' => 'image.gif' },
|
469
|
-
}
|
470
|
-
|
471
|
-
Crack::XML.parse(product_xml)["product"].must_equal expected_product_hash
|
472
|
-
end
|
473
|
-
|
474
|
-
it "should handle unescaping from xml (ActiveResource Compatible)" do
|
475
|
-
xml_string = '<person><bare-string>First & Last Name</bare-string><pre-escaped-string>First &amp; Last Name</pre-escaped-string></person>'
|
476
|
-
expected_hash = {
|
477
|
-
'bare_string' => 'First & Last Name',
|
478
|
-
'pre_escaped_string' => 'First & Last Name'
|
479
|
-
}
|
480
|
-
|
481
|
-
Crack::XML.parse(xml_string)['person'].must_equal expected_hash
|
482
|
-
end
|
483
|
-
|
484
|
-
it "handle an empty xml string" do
|
485
|
-
Crack::XML.parse('').must_equal({})
|
486
|
-
end
|
487
|
-
|
488
|
-
# As returned in the response body by the unfuddle XML API when creating objects
|
489
|
-
it "handle an xml string containing a single space" do
|
490
|
-
Crack::XML.parse(' ').must_equal({})
|
491
|
-
end
|
492
|
-
|
493
|
-
it "can dump parsed xml" do
|
494
|
-
xml = <<-XML
|
495
|
-
<blog>
|
496
|
-
<posts language="english">I like big butts and I cannot Lie</posts>
|
497
|
-
</blog>
|
498
|
-
XML
|
499
|
-
|
500
|
-
Marshal.dump(Crack::XML.parse(xml))
|
501
|
-
end
|
502
|
-
|
503
|
-
it "properly handles a node with type == file that has children" do
|
504
|
-
# Example is an excerpt from a problematic kvm domain config file
|
505
|
-
example_xml = <<-EOT
|
506
|
-
<disk type='file' device='cdrom'>
|
507
|
-
<driver name='qemu' type='raw' cache='none' io='native'/>
|
508
|
-
<source file='/tmp/cdrom.iso'/>
|
509
|
-
</disk>
|
510
|
-
EOT
|
511
|
-
|
512
|
-
Crack::XML.parse(example_xml).must_equal({"disk"=>{"driver"=>{"name"=>"qemu", "type"=>"raw", "cache"=>"none", "io"=>"native"}, "source"=>{"file"=>"/tmp/cdrom.iso"}, "type"=>"file", "device"=>"cdrom"}})
|
513
|
-
end
|
514
|
-
end
|