spreedly 1.0.0

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.
Files changed (67) hide show
  1. data/History.txt +6 -0
  2. data/Manifest.txt +66 -0
  3. data/README.txt +68 -0
  4. data/Rakefile +72 -0
  5. data/lib/spreedly.rb +154 -0
  6. data/lib/spreedly/common.rb +24 -0
  7. data/lib/spreedly/mock.rb +113 -0
  8. data/lib/spreedly/version.rb +3 -0
  9. data/test/spreedly_gem_test.rb +152 -0
  10. data/test/test_site.yml +2 -0
  11. data/vendor/httparty/History +108 -0
  12. data/vendor/httparty/MIT-LICENSE +20 -0
  13. data/vendor/httparty/Manifest +55 -0
  14. data/vendor/httparty/README +35 -0
  15. data/vendor/httparty/Rakefile +47 -0
  16. data/vendor/httparty/bin/httparty +98 -0
  17. data/vendor/httparty/cucumber.yml +1 -0
  18. data/vendor/httparty/examples/aaws.rb +32 -0
  19. data/vendor/httparty/examples/basic.rb +11 -0
  20. data/vendor/httparty/examples/delicious.rb +37 -0
  21. data/vendor/httparty/examples/google.rb +16 -0
  22. data/vendor/httparty/examples/rubyurl.rb +14 -0
  23. data/vendor/httparty/examples/twitter.rb +31 -0
  24. data/vendor/httparty/examples/whoismyrep.rb +10 -0
  25. data/vendor/httparty/features/basic_authentication.feature +20 -0
  26. data/vendor/httparty/features/command_line.feature +7 -0
  27. data/vendor/httparty/features/deals_with_http_error_codes.feature +26 -0
  28. data/vendor/httparty/features/handles_multiple_formats.feature +34 -0
  29. data/vendor/httparty/features/steps/env.rb +15 -0
  30. data/vendor/httparty/features/steps/httparty_response_steps.rb +26 -0
  31. data/vendor/httparty/features/steps/httparty_steps.rb +15 -0
  32. data/vendor/httparty/features/steps/mongrel_helper.rb +55 -0
  33. data/vendor/httparty/features/steps/remote_service_steps.rb +47 -0
  34. data/vendor/httparty/features/supports_redirection.feature +22 -0
  35. data/vendor/httparty/httparty.gemspec +37 -0
  36. data/vendor/httparty/lib/core_extensions.rb +189 -0
  37. data/vendor/httparty/lib/httparty.rb +201 -0
  38. data/vendor/httparty/lib/httparty/cookie_hash.rb +9 -0
  39. data/vendor/httparty/lib/httparty/exceptions.rb +7 -0
  40. data/vendor/httparty/lib/httparty/logging.rb +35 -0
  41. data/vendor/httparty/lib/httparty/module_inheritable_attributes.rb +25 -0
  42. data/vendor/httparty/lib/httparty/parsers.rb +4 -0
  43. data/vendor/httparty/lib/httparty/parsers/json.rb +74 -0
  44. data/vendor/httparty/lib/httparty/parsers/xml.rb +209 -0
  45. data/vendor/httparty/lib/httparty/request.rb +169 -0
  46. data/vendor/httparty/lib/httparty/response.rb +17 -0
  47. data/vendor/httparty/lib/httparty/version.rb +3 -0
  48. data/vendor/httparty/setup.rb +1585 -0
  49. data/vendor/httparty/spec/fixtures/delicious.xml +23 -0
  50. data/vendor/httparty/spec/fixtures/empty.xml +0 -0
  51. data/vendor/httparty/spec/fixtures/google.html +3 -0
  52. data/vendor/httparty/spec/fixtures/twitter.json +1 -0
  53. data/vendor/httparty/spec/fixtures/twitter.xml +403 -0
  54. data/vendor/httparty/spec/fixtures/undefined_method_add_node_for_nil.xml +2 -0
  55. data/vendor/httparty/spec/hash_spec.rb +49 -0
  56. data/vendor/httparty/spec/httparty/cookie_hash_spec.rb +38 -0
  57. data/vendor/httparty/spec/httparty/parsers/json_spec.rb +44 -0
  58. data/vendor/httparty/spec/httparty/parsers/xml_spec.rb +454 -0
  59. data/vendor/httparty/spec/httparty/request_spec.rb +203 -0
  60. data/vendor/httparty/spec/httparty/response_spec.rb +53 -0
  61. data/vendor/httparty/spec/httparty_spec.rb +259 -0
  62. data/vendor/httparty/spec/spec.opts +3 -0
  63. data/vendor/httparty/spec/spec_helper.rb +21 -0
  64. data/vendor/httparty/spec/string_spec.rb +29 -0
  65. data/vendor/httparty/website/css/common.css +47 -0
  66. data/vendor/httparty/website/index.html +74 -0
  67. metadata +141 -0
@@ -0,0 +1,38 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe HTTParty::CookieHash do
4
+ before(:each) do
5
+ @cookie_hash = HTTParty::CookieHash.new
6
+ end
7
+
8
+ describe "#add_cookies" do
9
+ it "should add new key/value pairs to the hash" do
10
+ @cookie_hash.add_cookies(:foo => "bar")
11
+ @cookie_hash.add_cookies(:rofl => "copter")
12
+ @cookie_hash.length.should eql(2)
13
+ end
14
+
15
+ it "should overwrite any existing key" do
16
+ @cookie_hash.add_cookies(:foo => "bar")
17
+ @cookie_hash.add_cookies(:foo => "copter")
18
+ @cookie_hash.length.should eql(1)
19
+ @cookie_hash[:foo].should eql("copter")
20
+ end
21
+ end
22
+
23
+ # The regexen are required because Hashes aren't ordered, so a test against
24
+ # a hardcoded string was randomly failing.
25
+ describe "#to_cookie_string" do
26
+ before(:each) do
27
+ @cookie_hash.add_cookies(:foo => "bar")
28
+ @cookie_hash.add_cookies(:rofl => "copter")
29
+ @s = @cookie_hash.to_cookie_string
30
+ end
31
+
32
+ it "should format the key/value pairs, delimited by semi-colons" do
33
+ @s.should match(/foo=bar/)
34
+ @s.should match(/rofl=copter/)
35
+ @s.should match(/^\w+=\w+; \w+=\w+$/)
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,44 @@
1
+ # encoding: utf-8
2
+
3
+ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
4
+
5
+ describe HTTParty::Parsers::JSON do
6
+ TESTS = {
7
+ %q({"data": "G\u00fcnter"}) => {"data" => "Günter"},
8
+ %q({"returnTo":{"\/categories":"\/"}}) => {"returnTo" => {"/categories" => "/"}},
9
+ %q({returnTo:{"\/categories":"\/"}}) => {"returnTo" => {"/categories" => "/"}},
10
+ %q({"return\\"To\\":":{"\/categories":"\/"}}) => {"return\"To\":" => {"/categories" => "/"}},
11
+ %q({"returnTo":{"\/categories":1}}) => {"returnTo" => {"/categories" => 1}},
12
+ %({"returnTo":[1,"a"]}) => {"returnTo" => [1, "a"]},
13
+ %({"returnTo":[1,"\\"a\\",", "b"]}) => {"returnTo" => [1, "\"a\",", "b"]},
14
+ %({a: "'", "b": "5,000"}) => {"a" => "'", "b" => "5,000"},
15
+ %({a: "a's, b's and c's", "b": "5,000"}) => {"a" => "a's, b's and c's", "b" => "5,000"},
16
+ %({a: "2007-01-01"}) => {'a' => Date.new(2007, 1, 1)},
17
+ %({a: "2007-01-01 01:12:34 Z"}) => {'a' => Time.utc(2007, 1, 1, 1, 12, 34)},
18
+ # no time zone
19
+ %({a: "2007-01-01 01:12:34"}) => {'a' => "2007-01-01 01:12:34"},
20
+ %([]) => [],
21
+ %({}) => {},
22
+ %(1) => 1,
23
+ %("") => "",
24
+ %("\\"") => "\"",
25
+ %(null) => nil,
26
+ %(true) => true,
27
+ %(false) => false,
28
+ %q("http:\/\/test.host\/posts\/1") => "http://test.host/posts/1"
29
+ }
30
+
31
+ TESTS.each do |json, expected|
32
+ it "should decode json (#{json})" do
33
+ lambda {
34
+ HTTParty::Parsers::JSON.decode(json).should == expected
35
+ }.should_not raise_error
36
+ end
37
+ end
38
+
39
+ it "should raise error for failed decoding" do
40
+ lambda {
41
+ HTTParty::Parsers::JSON.decode(%({: 1}))
42
+ }.should raise_error(HTTParty::Parsers::JSON::ParseError)
43
+ end
44
+ end
@@ -0,0 +1,454 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
+
3
+ require "date"
4
+ require 'bigdecimal'
5
+
6
+ describe HTTParty::Parsers::XML, "#parse" do
7
+ it "should transform a simple tag with content" do
8
+ xml = "<tag>This is the contents</tag>"
9
+ HTTParty::Parsers::XML.parse(xml).should == { 'tag' => 'This is the contents' }
10
+ end
11
+
12
+ it "should work with cdata tags" do
13
+ xml = <<-END
14
+ <tag>
15
+ <![CDATA[
16
+ text inside cdata
17
+ ]]>
18
+ </tag>
19
+ END
20
+ HTTParty::Parsers::XML.parse(xml)["tag"].strip.should == "text inside cdata"
21
+ end
22
+
23
+ it "should transform a simple tag with attributes" do
24
+ xml = "<tag attr1='1' attr2='2'></tag>"
25
+ hash = { 'tag' => { 'attr1' => '1', 'attr2' => '2' } }
26
+ HTTParty::Parsers::XML.parse(xml).should == hash
27
+ end
28
+
29
+ it "should transform repeating siblings into an array" do
30
+ xml =<<-XML
31
+ <opt>
32
+ <user login="grep" fullname="Gary R Epstein" />
33
+ <user login="stty" fullname="Simon T Tyson" />
34
+ </opt>
35
+ XML
36
+
37
+ HTTParty::Parsers::XML.parse(xml)['opt']['user'].should be_an_instance_of(Array)
38
+
39
+ hash = {
40
+ 'opt' => {
41
+ 'user' => [{
42
+ 'login' => 'grep',
43
+ 'fullname' => 'Gary R Epstein'
44
+ },{
45
+ 'login' => 'stty',
46
+ 'fullname' => 'Simon T Tyson'
47
+ }]
48
+ }
49
+ }
50
+
51
+ HTTParty::Parsers::XML.parse(xml).should == hash
52
+ end
53
+
54
+ it "should not transform non-repeating siblings into an array" do
55
+ xml =<<-XML
56
+ <opt>
57
+ <user login="grep" fullname="Gary R Epstein" />
58
+ </opt>
59
+ XML
60
+
61
+ HTTParty::Parsers::XML.parse(xml)['opt']['user'].should be_an_instance_of(Hash)
62
+
63
+ hash = {
64
+ 'opt' => {
65
+ 'user' => {
66
+ 'login' => 'grep',
67
+ 'fullname' => 'Gary R Epstein'
68
+ }
69
+ }
70
+ }
71
+
72
+ HTTParty::Parsers::XML.parse(xml).should == hash
73
+ end
74
+
75
+ it "should typecast an integer" do
76
+ xml = "<tag type='integer'>10</tag>"
77
+ HTTParty::Parsers::XML.parse(xml)['tag'].should == 10
78
+ end
79
+
80
+ it "should typecast a true boolean" do
81
+ xml = "<tag type='boolean'>true</tag>"
82
+ HTTParty::Parsers::XML.parse(xml)['tag'].should be_true
83
+ end
84
+
85
+ it "should typecast a false boolean" do
86
+ ["false"].each do |w|
87
+ HTTParty::Parsers::XML.parse("<tag type='boolean'>#{w}</tag>")['tag'].should be_false
88
+ end
89
+ end
90
+
91
+ it "should typecast a datetime" do
92
+ xml = "<tag type='datetime'>2007-12-31 10:32</tag>"
93
+ HTTParty::Parsers::XML.parse(xml)['tag'].should == Time.parse( '2007-12-31 10:32' ).utc
94
+ end
95
+
96
+ it "should typecast a date" do
97
+ xml = "<tag type='date'>2007-12-31</tag>"
98
+ HTTParty::Parsers::XML.parse(xml)['tag'].should == Date.parse('2007-12-31')
99
+ end
100
+
101
+ it "should unescape html entities" do
102
+ values = {
103
+ "<" => "&lt;",
104
+ ">" => "&gt;",
105
+ '"' => "&quot;",
106
+ "'" => "&apos;",
107
+ "&" => "&amp;"
108
+ }
109
+ values.each do |k,v|
110
+ xml = "<tag>Some content #{v}</tag>"
111
+ HTTParty::Parsers::XML.parse(xml)['tag'].should match(Regexp.new(k))
112
+ end
113
+ end
114
+
115
+ it "should undasherize keys as tags" do
116
+ xml = "<tag-1>Stuff</tag-1>"
117
+ HTTParty::Parsers::XML.parse(xml).keys.should include( 'tag_1' )
118
+ end
119
+
120
+ it "should undasherize keys as attributes" do
121
+ xml = "<tag1 attr-1='1'></tag1>"
122
+ HTTParty::Parsers::XML.parse(xml)['tag1'].keys.should include( 'attr_1')
123
+ end
124
+
125
+ it "should undasherize keys as tags and attributes" do
126
+ xml = "<tag-1 attr-1='1'></tag-1>"
127
+ HTTParty::Parsers::XML.parse(xml).keys.should include( 'tag_1' )
128
+ HTTParty::Parsers::XML.parse(xml)['tag_1'].keys.should include( 'attr_1')
129
+ end
130
+
131
+ it "should render nested content correctly" do
132
+ xml = "<root><tag1>Tag1 Content <em><strong>This is strong</strong></em></tag1></root>"
133
+ HTTParty::Parsers::XML.parse(xml)['root']['tag1'].should == "Tag1 Content <em><strong>This is strong</strong></em>"
134
+ end
135
+
136
+ it "should render nested content with split text nodes correctly" do
137
+ xml = "<root>Tag1 Content<em>Stuff</em> Hi There</root>"
138
+ HTTParty::Parsers::XML.parse(xml)['root'].should == "Tag1 Content<em>Stuff</em> Hi There"
139
+ end
140
+
141
+ it "should ignore attributes when a child is a text node" do
142
+ xml = "<root attr1='1'>Stuff</root>"
143
+ HTTParty::Parsers::XML.parse(xml).should == { "root" => "Stuff" }
144
+ end
145
+
146
+ it "should ignore attributes when any child is a text node" do
147
+ xml = "<root attr1='1'>Stuff <em>in italics</em></root>"
148
+ HTTParty::Parsers::XML.parse(xml).should == { "root" => "Stuff <em>in italics</em>" }
149
+ end
150
+
151
+ it "should correctly transform multiple children" do
152
+ xml = <<-XML
153
+ <user gender='m'>
154
+ <age type='integer'>35</age>
155
+ <name>Home Simpson</name>
156
+ <dob type='date'>1988-01-01</dob>
157
+ <joined-at type='datetime'>2000-04-28 23:01</joined-at>
158
+ <is-cool type='boolean'>true</is-cool>
159
+ </user>
160
+ XML
161
+
162
+ hash = {
163
+ "user" => {
164
+ "gender" => "m",
165
+ "age" => 35,
166
+ "name" => "Home Simpson",
167
+ "dob" => Date.parse('1988-01-01'),
168
+ "joined_at" => Time.parse("2000-04-28 23:01"),
169
+ "is_cool" => true
170
+ }
171
+ }
172
+
173
+ HTTParty::Parsers::XML.parse(xml).should == hash
174
+ end
175
+
176
+ it "should properly handle nil values (ActiveSupport Compatible)" do
177
+ topic_xml = <<-EOT
178
+ <topic>
179
+ <title></title>
180
+ <id type="integer"></id>
181
+ <approved type="boolean"></approved>
182
+ <written-on type="date"></written-on>
183
+ <viewed-at type="datetime"></viewed-at>
184
+ <content type="yaml"></content>
185
+ <parent-id></parent-id>
186
+ </topic>
187
+ EOT
188
+
189
+ expected_topic_hash = {
190
+ 'title' => nil,
191
+ 'id' => nil,
192
+ 'approved' => nil,
193
+ 'written_on' => nil,
194
+ 'viewed_at' => nil,
195
+ 'content' => nil,
196
+ 'parent_id' => nil
197
+ }
198
+ HTTParty::Parsers::XML.parse(topic_xml)["topic"].should == expected_topic_hash
199
+ end
200
+
201
+ it "should handle a single record from xml (ActiveSupport Compatible)" do
202
+ topic_xml = <<-EOT
203
+ <topic>
204
+ <title>The First Topic</title>
205
+ <author-name>David</author-name>
206
+ <id type="integer">1</id>
207
+ <approved type="boolean"> true </approved>
208
+ <replies-count type="integer">0</replies-count>
209
+ <replies-close-in type="integer">2592000000</replies-close-in>
210
+ <written-on type="date">2003-07-16</written-on>
211
+ <viewed-at type="datetime">2003-07-16T09:28:00+0000</viewed-at>
212
+ <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>
213
+ <author-email-address>david@loudthinking.com</author-email-address>
214
+ <parent-id></parent-id>
215
+ <ad-revenue type="decimal">1.5</ad-revenue>
216
+ <optimum-viewing-angle type="float">135</optimum-viewing-angle>
217
+ <resident type="symbol">yes</resident>
218
+ </topic>
219
+ EOT
220
+
221
+ expected_topic_hash = {
222
+ 'title' => "The First Topic",
223
+ 'author_name' => "David",
224
+ 'id' => 1,
225
+ 'approved' => true,
226
+ 'replies_count' => 0,
227
+ 'replies_close_in' => 2592000000,
228
+ 'written_on' => Date.new(2003, 7, 16),
229
+ 'viewed_at' => Time.utc(2003, 7, 16, 9, 28),
230
+ # Changed this line where the key is :message. The yaml specifies this as a symbol, and who am I to change what you specify
231
+ # The line in ActiveSupport is
232
+ # 'content' => { 'message' => "Have a nice day", 1 => "should be an integer", "array" => [{ "should-have-dashes" => true, "should_have_underscores" => true }] },
233
+ 'content' => { :message => "Have a nice day", 1 => "should be an integer", "array" => [{ "should-have-dashes" => true, "should_have_underscores" => true }] },
234
+ 'author_email_address' => "david@loudthinking.com",
235
+ 'parent_id' => nil,
236
+ 'ad_revenue' => BigDecimal("1.50"),
237
+ 'optimum_viewing_angle' => 135.0,
238
+ 'resident' => :yes
239
+ }
240
+
241
+ HTTParty::Parsers::XML.parse(topic_xml)["topic"].each do |k,v|
242
+ v.should == expected_topic_hash[k]
243
+ end
244
+ end
245
+
246
+ it "should handle multiple records (ActiveSupport Compatible)" do
247
+ topics_xml = <<-EOT
248
+ <topics type="array">
249
+ <topic>
250
+ <title>The First Topic</title>
251
+ <author-name>David</author-name>
252
+ <id type="integer">1</id>
253
+ <approved type="boolean">false</approved>
254
+ <replies-count type="integer">0</replies-count>
255
+ <replies-close-in type="integer">2592000000</replies-close-in>
256
+ <written-on type="date">2003-07-16</written-on>
257
+ <viewed-at type="datetime">2003-07-16T09:28:00+0000</viewed-at>
258
+ <content>Have a nice day</content>
259
+ <author-email-address>david@loudthinking.com</author-email-address>
260
+ <parent-id nil="true"></parent-id>
261
+ </topic>
262
+ <topic>
263
+ <title>The Second Topic</title>
264
+ <author-name>Jason</author-name>
265
+ <id type="integer">1</id>
266
+ <approved type="boolean">false</approved>
267
+ <replies-count type="integer">0</replies-count>
268
+ <replies-close-in type="integer">2592000000</replies-close-in>
269
+ <written-on type="date">2003-07-16</written-on>
270
+ <viewed-at type="datetime">2003-07-16T09:28:00+0000</viewed-at>
271
+ <content>Have a nice day</content>
272
+ <author-email-address>david@loudthinking.com</author-email-address>
273
+ <parent-id></parent-id>
274
+ </topic>
275
+ </topics>
276
+ EOT
277
+
278
+ expected_topic_hash = {
279
+ 'title' => "The First Topic",
280
+ 'author_name' => "David",
281
+ 'id' => 1,
282
+ 'approved' => false,
283
+ 'replies_count' => 0,
284
+ 'replies_close_in' => 2592000000,
285
+ 'written_on' => Date.new(2003, 7, 16),
286
+ 'viewed_at' => Time.utc(2003, 7, 16, 9, 28),
287
+ 'content' => "Have a nice day",
288
+ 'author_email_address' => "david@loudthinking.com",
289
+ 'parent_id' => nil
290
+ }
291
+ # puts HTTParty::Parsers::XML.parse(topics_xml)['topics'].first.inspect
292
+ HTTParty::Parsers::XML.parse(topics_xml)["topics"].first.each do |k,v|
293
+ v.should == expected_topic_hash[k]
294
+ end
295
+ end
296
+
297
+ it "should handle a single record from_xml with attributes other than type (ActiveSupport Compatible)" do
298
+ topic_xml = <<-EOT
299
+ <rsp stat="ok">
300
+ <photos page="1" pages="1" perpage="100" total="16">
301
+ <photo id="175756086" owner="55569174@N00" secret="0279bf37a1" server="76" title="Colored Pencil PhotoBooth Fun" ispublic="1" isfriend="0" isfamily="0"/>
302
+ </photos>
303
+ </rsp>
304
+ EOT
305
+
306
+ expected_topic_hash = {
307
+ 'id' => "175756086",
308
+ 'owner' => "55569174@N00",
309
+ 'secret' => "0279bf37a1",
310
+ 'server' => "76",
311
+ 'title' => "Colored Pencil PhotoBooth Fun",
312
+ 'ispublic' => "1",
313
+ 'isfriend' => "0",
314
+ 'isfamily' => "0",
315
+ }
316
+ HTTParty::Parsers::XML.parse(topic_xml)["rsp"]["photos"]["photo"].each do |k,v|
317
+ v.should == expected_topic_hash[k]
318
+ end
319
+ end
320
+
321
+ it "should handle an emtpy array (ActiveSupport Compatible)" do
322
+ blog_xml = <<-XML
323
+ <blog>
324
+ <posts type="array"></posts>
325
+ </blog>
326
+ XML
327
+ expected_blog_hash = {"blog" => {"posts" => []}}
328
+ HTTParty::Parsers::XML.parse(blog_xml).should == expected_blog_hash
329
+ end
330
+
331
+ it "should handle empty array with whitespace from xml (ActiveSupport Compatible)" do
332
+ blog_xml = <<-XML
333
+ <blog>
334
+ <posts type="array">
335
+ </posts>
336
+ </blog>
337
+ XML
338
+ expected_blog_hash = {"blog" => {"posts" => []}}
339
+ HTTParty::Parsers::XML.parse(blog_xml).should == expected_blog_hash
340
+ end
341
+
342
+ it "should handle array with one entry from_xml (ActiveSupport Compatible)" do
343
+ blog_xml = <<-XML
344
+ <blog>
345
+ <posts type="array">
346
+ <post>a post</post>
347
+ </posts>
348
+ </blog>
349
+ XML
350
+ expected_blog_hash = {"blog" => {"posts" => ["a post"]}}
351
+ HTTParty::Parsers::XML.parse(blog_xml).should == expected_blog_hash
352
+ end
353
+
354
+ it "should handle array with multiple entries from xml (ActiveSupport Compatible)" do
355
+ blog_xml = <<-XML
356
+ <blog>
357
+ <posts type="array">
358
+ <post>a post</post>
359
+ <post>another post</post>
360
+ </posts>
361
+ </blog>
362
+ XML
363
+ expected_blog_hash = {"blog" => {"posts" => ["a post", "another post"]}}
364
+ HTTParty::Parsers::XML.parse(blog_xml).should == expected_blog_hash
365
+ end
366
+
367
+ it "should handle file types (ActiveSupport Compatible)" do
368
+ blog_xml = <<-XML
369
+ <blog>
370
+ <logo type="file" name="logo.png" content_type="image/png">
371
+ </logo>
372
+ </blog>
373
+ XML
374
+ hash = HTTParty::Parsers::XML.parse(blog_xml)
375
+ hash.should have_key('blog')
376
+ hash['blog'].should have_key('logo')
377
+
378
+ file = hash['blog']['logo']
379
+ file.original_filename.should == 'logo.png'
380
+ file.content_type.should == 'image/png'
381
+ end
382
+
383
+ it "should handle file from xml with defaults (ActiveSupport Compatible)" do
384
+ blog_xml = <<-XML
385
+ <blog>
386
+ <logo type="file">
387
+ </logo>
388
+ </blog>
389
+ XML
390
+ file = HTTParty::Parsers::XML.parse(blog_xml)['blog']['logo']
391
+ file.original_filename.should == 'untitled'
392
+ file.content_type.should == 'application/octet-stream'
393
+ end
394
+
395
+ it "should handle xsd like types from xml (ActiveSupport Compatible)" do
396
+ bacon_xml = <<-EOT
397
+ <bacon>
398
+ <weight type="double">0.5</weight>
399
+ <price type="decimal">12.50</price>
400
+ <chunky type="boolean"> 1 </chunky>
401
+ <expires-at type="dateTime">2007-12-25T12:34:56+0000</expires-at>
402
+ <notes type="string"></notes>
403
+ <illustration type="base64Binary">YmFiZS5wbmc=</illustration>
404
+ </bacon>
405
+ EOT
406
+
407
+ expected_bacon_hash = {
408
+ 'weight' => 0.5,
409
+ 'chunky' => true,
410
+ 'price' => BigDecimal("12.50"),
411
+ 'expires_at' => Time.utc(2007,12,25,12,34,56),
412
+ 'notes' => "",
413
+ 'illustration' => "babe.png"
414
+ }
415
+
416
+ HTTParty::Parsers::XML.parse(bacon_xml)["bacon"].should == expected_bacon_hash
417
+ end
418
+
419
+ it "should let type trickle through when unknown (ActiveSupport Compatible)" do
420
+ product_xml = <<-EOT
421
+ <product>
422
+ <weight type="double">0.5</weight>
423
+ <image type="ProductImage"><filename>image.gif</filename></image>
424
+
425
+ </product>
426
+ EOT
427
+
428
+ expected_product_hash = {
429
+ 'weight' => 0.5,
430
+ 'image' => {'type' => 'ProductImage', 'filename' => 'image.gif' },
431
+ }
432
+
433
+ HTTParty::Parsers::XML.parse(product_xml)["product"].should == expected_product_hash
434
+ end
435
+
436
+ it "should handle unescaping from xml (ActiveResource Compatible)" do
437
+ xml_string = '<person><bare-string>First &amp; Last Name</bare-string><pre-escaped-string>First &amp;amp; Last Name</pre-escaped-string></person>'
438
+ expected_hash = {
439
+ 'bare_string' => 'First & Last Name',
440
+ 'pre_escaped_string' => 'First &amp; Last Name'
441
+ }
442
+
443
+ HTTParty::Parsers::XML.parse(xml_string)['person'].should == expected_hash
444
+ end
445
+
446
+ it "should handle an empty xml string" do
447
+ HTTParty::Parsers::XML.parse('').should == {}
448
+ end
449
+
450
+ # As returned in the response body by the unfuddle XML API when creating objects
451
+ it "should handle an xml string containing a single space" do
452
+ HTTParty::Parsers::XML.parse(' ').should == {}
453
+ end
454
+ end