Added proper handling of arrays (closes #8537) [hasmanyjosh]
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@6924 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
This commit is contained in:
parent
83ce4c59be
commit
846e858727
@ -1,5 +1,28 @@
|
||||
*SVN*
|
||||
|
||||
* Added proper handling of arrays #8537 [hasmanyjosh]
|
||||
|
||||
Before:
|
||||
Hash.from_xml '<images></images>'
|
||||
# => {:images => nil}
|
||||
|
||||
Hash.from_xml '<images><image>foo.jpg</image></images>'
|
||||
# => {:images => {:image => "foo.jpg"}}
|
||||
|
||||
Hash.from_xml '<images><image>foo.jpg</image><image>bar.jpg</image></images>'
|
||||
# => {:images => {:image => ["foo.jpg", "bar.jpg"]}}
|
||||
|
||||
After:
|
||||
Hash.from_xml '<images type="array"></images>'
|
||||
# => {:images => []}
|
||||
|
||||
Hash.from_xml '<images type="array"><image>foo.jpg</image></images>'
|
||||
# => {:images => ["foo.jpg"]}
|
||||
|
||||
Hash.from_xml '<images type="array"><image>foo.jpg</image><image>bar.jpg</image></images>'
|
||||
# => {:images => ["foo.jpg", "bar.jpg"]}
|
||||
|
||||
|
||||
* Move common DateTime calculations to Date. #8536 [Geoff Buesing]
|
||||
|
||||
* Added Date#change (like Time#change) [DHH]
|
||||
|
@ -63,7 +63,7 @@ def to_xml(options = {})
|
||||
|
||||
opts = options.merge({ :root => children })
|
||||
|
||||
options[:builder].tag!(root) {
|
||||
options[:builder].tag!(root, options[:skip_types] ? {} : {:type => "array"}) {
|
||||
yield options[:builder] if block_given?
|
||||
each { |e| e.to_xml(opts.merge!({ :skip_instruct => true })) }
|
||||
}
|
||||
|
@ -163,6 +163,20 @@ def typecast_xml_value(value)
|
||||
else
|
||||
content
|
||||
end
|
||||
elsif value['type'] == 'array'
|
||||
child_key, entries = value.detect { |k,v| k != 'type' } # child_key is throwaway
|
||||
if entries.nil?
|
||||
[]
|
||||
else
|
||||
case entries.class.to_s # something weird with classes not matching here. maybe singleton methods breaking is_a?
|
||||
when "Array"
|
||||
entries.collect { |v| typecast_xml_value(v) }
|
||||
when "Hash"
|
||||
[typecast_xml_value(entries)]
|
||||
else
|
||||
raise "can't typecast #{entries.inspect}"
|
||||
end
|
||||
end
|
||||
elsif value['type'] == 'string' && value['nil'] != 'true'
|
||||
""
|
||||
else
|
||||
|
@ -121,7 +121,7 @@ def test_to_xml
|
||||
{ :name => "Jason", :age => 31, :age_in_millis => BigDecimal.new('1.0') }
|
||||
].to_xml(:skip_instruct => true, :indent => 0)
|
||||
|
||||
assert_equal "<records><record>", xml.first(17), xml
|
||||
assert_equal '<records type="array"><record>', xml.first(30)
|
||||
assert xml.include?(%(<age type="integer">26</age>)), xml
|
||||
assert xml.include?(%(<age-in-millis type="integer">820497600000</age-in-millis>)), xml
|
||||
assert xml.include?(%(<name>David</name>)), xml
|
||||
@ -135,7 +135,7 @@ def test_to_xml_with_dedicated_name
|
||||
{ :name => "David", :age => 26, :age_in_millis => 820497600000 }, { :name => "Jason", :age => 31 }
|
||||
].to_xml(:skip_instruct => true, :indent => 0, :root => "people")
|
||||
|
||||
assert_equal "<people><person>", xml.first(16)
|
||||
assert_equal '<people type="array"><person>', xml.first(29)
|
||||
end
|
||||
|
||||
def test_to_xml_with_options
|
||||
|
@ -370,7 +370,7 @@ def test_two_levels_with_second_level_overriding_to_xml
|
||||
def test_two_levels_with_array
|
||||
xml = { :name => "David", :addresses => [{ :street => "Paulina" }, { :street => "Evergreen" }] }.to_xml(@xml_options)
|
||||
assert_equal "<person>", xml.first(8)
|
||||
assert xml.include?(%(<addresses><address>))
|
||||
assert xml.include?(%(<addresses type="array"><address>))
|
||||
assert xml.include?(%(<address><street>Paulina</street></address>))
|
||||
assert xml.include?(%(<address><street>Evergreen</street></address>))
|
||||
assert xml.include?(%(<name>David</name>))
|
||||
@ -378,7 +378,7 @@ def test_two_levels_with_array
|
||||
|
||||
def test_three_levels_with_array
|
||||
xml = { :name => "David", :addresses => [{ :streets => [ { :name => "Paulina" }, { :name => "Paulina" } ] } ] }.to_xml(@xml_options)
|
||||
assert xml.include?(%(<addresses><address><streets><street><name>))
|
||||
assert xml.include?(%(<addresses type="array"><address><streets type="array"><street><name>))
|
||||
end
|
||||
|
||||
def test_single_record_from_xml
|
||||
@ -517,6 +517,41 @@ def test_single_record_from_xml_with_attributes_other_than_type
|
||||
assert_equal expected_topic_hash, Hash.from_xml(topic_xml)["rsp"]["photos"]["photo"]
|
||||
end
|
||||
|
||||
def test_empty_array_from_xml
|
||||
blog_xml = <<-XML
|
||||
<blog>
|
||||
<posts type="array"></posts>
|
||||
</blog>
|
||||
XML
|
||||
expected_blog_hash = {"blog" => {"posts" => []}}
|
||||
assert_equal expected_blog_hash, Hash.from_xml(blog_xml)
|
||||
end
|
||||
|
||||
def test_array_with_one_entry_from_xml
|
||||
blog_xml = <<-XML
|
||||
<blog>
|
||||
<posts type="array">
|
||||
<post>a post</post>
|
||||
</posts>
|
||||
</blog>
|
||||
XML
|
||||
expected_blog_hash = {"blog" => {"posts" => ["a post"]}}
|
||||
assert_equal expected_blog_hash, Hash.from_xml(blog_xml)
|
||||
end
|
||||
|
||||
def test_array_with_multiple_entries_from_xml
|
||||
blog_xml = <<-XML
|
||||
<blog>
|
||||
<posts type="array">
|
||||
<post>a post</post>
|
||||
<post>another post</post>
|
||||
</posts>
|
||||
</blog>
|
||||
XML
|
||||
expected_blog_hash = {"blog" => {"posts" => ["a post", "another post"]}}
|
||||
assert_equal expected_blog_hash, Hash.from_xml(blog_xml)
|
||||
end
|
||||
|
||||
def test_xsd_like_types_from_xml
|
||||
bacon_xml = <<-EOT
|
||||
<bacon>
|
||||
|
Loading…
Reference in New Issue
Block a user