crackoid 0.0.1

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.
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