crackoid 0.0.1

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