alexvollmer-httparty 0.3.1 → 0.4.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,209 +0,0 @@
1
- require 'rexml/parsers/streamparser'
2
- require 'rexml/parsers/baseparser'
3
- require 'rexml/light/node'
4
-
5
- # This is a slighly modified version of the XMLUtilityNode from
6
- # http://merb.devjavu.com/projects/merb/ticket/95 (has.sox@gmail.com)
7
- # It's mainly just adding vowels, as I ht cd wth n vwls :)
8
- # This represents the hard part of the work, all I did was change the
9
- # underlying parser.
10
- class REXMLUtilityNode #:nodoc:
11
- attr_accessor :name, :attributes, :children, :type
12
-
13
- def self.typecasts
14
- @@typecasts
15
- end
16
-
17
- def self.typecasts=(obj)
18
- @@typecasts = obj
19
- end
20
-
21
- def self.available_typecasts
22
- @@available_typecasts
23
- end
24
-
25
- def self.available_typecasts=(obj)
26
- @@available_typecasts = obj
27
- end
28
-
29
- self.typecasts = {}
30
- self.typecasts["integer"] = lambda{|v| v.nil? ? nil : v.to_i}
31
- self.typecasts["boolean"] = lambda{|v| v.nil? ? nil : (v.strip != "false")}
32
- self.typecasts["datetime"] = lambda{|v| v.nil? ? nil : Time.parse(v).utc}
33
- self.typecasts["date"] = lambda{|v| v.nil? ? nil : Date.parse(v)}
34
- self.typecasts["dateTime"] = lambda{|v| v.nil? ? nil : Time.parse(v).utc}
35
- self.typecasts["decimal"] = lambda{|v| v.nil? ? nil : BigDecimal(v.to_s)}
36
- self.typecasts["double"] = lambda{|v| v.nil? ? nil : v.to_f}
37
- self.typecasts["float"] = lambda{|v| v.nil? ? nil : v.to_f}
38
- self.typecasts["symbol"] = lambda{|v| v.nil? ? nil : v.to_sym}
39
- self.typecasts["string"] = lambda{|v| v.to_s}
40
- self.typecasts["yaml"] = lambda{|v| v.nil? ? nil : YAML.load(v)}
41
- self.typecasts["base64Binary"] = lambda{|v| v.unpack('m').first }
42
-
43
- self.available_typecasts = self.typecasts.keys
44
-
45
- def initialize(name, attributes = {})
46
- @name = name.tr("-", "_")
47
- # leave the type alone if we don't know what it is
48
- @type = self.class.available_typecasts.include?(attributes["type"]) ? attributes.delete("type") : attributes["type"]
49
-
50
- @nil_element = attributes.delete("nil") == "true"
51
- @attributes = undasherize_keys(attributes)
52
- @children = []
53
- @text = false
54
- end
55
-
56
- def add_node(node)
57
- @text = true if node.is_a? String
58
- @children << node
59
- end
60
-
61
- def to_hash
62
- if @type == "file"
63
- f = StringIO.new((@children.first || '').unpack('m').first)
64
- class << f
65
- attr_accessor :original_filename, :content_type
66
- end
67
- f.original_filename = attributes['name'] || 'untitled'
68
- f.content_type = attributes['content_type'] || 'application/octet-stream'
69
- return {name => f}
70
- end
71
-
72
- if @text
73
- return { name => typecast_value( translate_xml_entities( inner_html ) ) }
74
- else
75
- #change repeating groups into an array
76
- groups = @children.inject({}) { |s,e| (s[e.name] ||= []) << e; s }
77
-
78
- out = nil
79
- if @type == "array"
80
- out = []
81
- groups.each do |k, v|
82
- if v.size == 1
83
- out << v.first.to_hash.entries.first.last
84
- else
85
- out << v.map{|e| e.to_hash[k]}
86
- end
87
- end
88
- out = out.flatten
89
-
90
- else # If Hash
91
- out = {}
92
- groups.each do |k,v|
93
- if v.size == 1
94
- out.merge!(v.first)
95
- else
96
- out.merge!( k => v.map{|e| e.to_hash[k]})
97
- end
98
- end
99
- out.merge! attributes unless attributes.empty?
100
- out = out.empty? ? nil : out
101
- end
102
-
103
- if @type && out.nil?
104
- { name => typecast_value(out) }
105
- else
106
- { name => out }
107
- end
108
- end
109
- end
110
-
111
- # Typecasts a value based upon its type. For instance, if
112
- # +node+ has #type == "integer",
113
- # {{[node.typecast_value("12") #=> 12]}}
114
- #
115
- # @param value<String> The value that is being typecast.
116
- #
117
- # @details [:type options]
118
- # "integer"::
119
- # converts +value+ to an integer with #to_i
120
- # "boolean"::
121
- # checks whether +value+, after removing spaces, is the literal
122
- # "true"
123
- # "datetime"::
124
- # Parses +value+ using Time.parse, and returns a UTC Time
125
- # "date"::
126
- # Parses +value+ using Date.parse
127
- #
128
- # @return <Integer, TrueClass, FalseClass, Time, Date, Object>
129
- # The result of typecasting +value+.
130
- #
131
- # @note
132
- # If +self+ does not have a "type" key, or if it's not one of the
133
- # options specified above, the raw +value+ will be returned.
134
- def typecast_value(value)
135
- return value unless @type
136
- proc = self.class.typecasts[@type]
137
- proc.nil? ? value : proc.call(value)
138
- end
139
-
140
- # Convert basic XML entities into their literal values.
141
- #
142
- # @param value<#gsub> An XML fragment.
143
- #
144
- # @return <#gsub> The XML fragment after converting entities.
145
- def translate_xml_entities(value)
146
- value.gsub(/&lt;/, "<").
147
- gsub(/&gt;/, ">").
148
- gsub(/&quot;/, '"').
149
- gsub(/&apos;/, "'").
150
- gsub(/&amp;/, "&")
151
- end
152
-
153
- # Take keys of the form foo-bar and convert them to foo_bar
154
- def undasherize_keys(params)
155
- params.keys.each do |key, value|
156
- params[key.tr("-", "_")] = params.delete(key)
157
- end
158
- params
159
- end
160
-
161
- # Get the inner_html of the REXML node.
162
- def inner_html
163
- @children.join
164
- end
165
-
166
- # Converts the node into a readable HTML node.
167
- #
168
- # @return <String> The HTML node in text form.
169
- def to_html
170
- attributes.merge!(:type => @type ) if @type
171
- "<#{name}#{attributes.to_xml_attributes}>#{@nil_element ? '' : inner_html}</#{name}>"
172
- end
173
-
174
- # @alias #to_html #to_s
175
- def to_s
176
- to_html
177
- end
178
- end
179
-
180
- module HTTParty
181
- module Parsers #:nodoc:
182
- module XML #:nodoc:
183
- def self.parse(xml)
184
- stack = []
185
- parser = REXML::Parsers::BaseParser.new(xml)
186
-
187
- while true
188
- event = parser.pull
189
- case event[0]
190
- when :end_document
191
- break
192
- when :end_doctype, :start_doctype
193
- # do nothing
194
- when :start_element
195
- stack.push REXMLUtilityNode.new(event[1], event[2])
196
- when :end_element
197
- if stack.size > 1
198
- temp = stack.pop
199
- stack.last.add_node(temp)
200
- end
201
- when :text, :cdata
202
- stack.last.add_node(event[1]) unless event[1].strip.length == 0 || stack.empty?
203
- end
204
- end
205
- stack.pop.to_hash
206
- end
207
- end
208
- end
209
- end
@@ -1,42 +0,0 @@
1
- require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper')
2
-
3
- describe HTTParty::Parsers::JSON do
4
- TESTS = {
5
- %q({"data": "G\u00fcnter"}) => {"data" => "Günter"},
6
- %q({"returnTo":{"\/categories":"\/"}}) => {"returnTo" => {"/categories" => "/"}},
7
- %q({returnTo:{"\/categories":"\/"}}) => {"returnTo" => {"/categories" => "/"}},
8
- %q({"return\\"To\\":":{"\/categories":"\/"}}) => {"return\"To\":" => {"/categories" => "/"}},
9
- %q({"returnTo":{"\/categories":1}}) => {"returnTo" => {"/categories" => 1}},
10
- %({"returnTo":[1,"a"]}) => {"returnTo" => [1, "a"]},
11
- %({"returnTo":[1,"\\"a\\",", "b"]}) => {"returnTo" => [1, "\"a\",", "b"]},
12
- %({a: "'", "b": "5,000"}) => {"a" => "'", "b" => "5,000"},
13
- %({a: "a's, b's and c's", "b": "5,000"}) => {"a" => "a's, b's and c's", "b" => "5,000"},
14
- %({a: "2007-01-01"}) => {'a' => Date.new(2007, 1, 1)},
15
- %({a: "2007-01-01 01:12:34 Z"}) => {'a' => Time.utc(2007, 1, 1, 1, 12, 34)},
16
- # no time zone
17
- %({a: "2007-01-01 01:12:34"}) => {'a' => "2007-01-01 01:12:34"},
18
- %([]) => [],
19
- %({}) => {},
20
- %(1) => 1,
21
- %("") => "",
22
- %("\\"") => "\"",
23
- %(null) => nil,
24
- %(true) => true,
25
- %(false) => false,
26
- %q("http:\/\/test.host\/posts\/1") => "http://test.host/posts/1"
27
- }
28
-
29
- TESTS.each do |json, expected|
30
- it "should decode json (#{json})" do
31
- lambda {
32
- HTTParty::Parsers::JSON.decode(json).should == expected
33
- }.should_not raise_error
34
- end
35
- end
36
-
37
- it "should raise error for failed decoding" do
38
- lambda {
39
- HTTParty::Parsers::JSON.decode(%({: 1}))
40
- }.should raise_error(HTTParty::Parsers::JSON::ParseError)
41
- end
42
- end
@@ -1,445 +0,0 @@
1
- require File.join(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
- end