aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--activesupport/lib/active_support/core_ext/hash/conversions.rb21
-rw-r--r--activesupport/test/core_ext/hash_ext_test.rb34
2 files changed, 49 insertions, 6 deletions
diff --git a/activesupport/lib/active_support/core_ext/hash/conversions.rb b/activesupport/lib/active_support/core_ext/hash/conversions.rb
index f6ebb90400..8e80f6e4ff 100644
--- a/activesupport/lib/active_support/core_ext/hash/conversions.rb
+++ b/activesupport/lib/active_support/core_ext/hash/conversions.rb
@@ -24,10 +24,25 @@ class XmlSimple
end
end
+# This module exists to decorate files deserialized using Hash.from_xml with
+# the <tt>original_filename</tt> and <tt>content_type</tt> methods.
+module FileLike #:nodoc:
+ attr_writer :original_filename, :content_type
+
+ def original_filename
+ @original_filename || 'untitled'
+ end
+
+ def content_type
+ @content_type || 'application/octet-stream'
+ end
+end
+
module ActiveSupport #:nodoc:
module CoreExtensions #:nodoc:
module Hash #:nodoc:
module Conversions
+
XML_TYPE_NAMES = {
"Symbol" => "symbol",
"Fixnum" => "integer",
@@ -63,11 +78,11 @@ module ActiveSupport #:nodoc:
"string" => Proc.new { |string| string.to_s },
"yaml" => Proc.new { |yaml| YAML::load(yaml) rescue yaml },
"base64Binary" => Proc.new { |bin| Base64.decode64(bin) },
- # FIXME: Get rid of eval and institute a proper decorator here
"file" => Proc.new do |file, entity|
f = StringIO.new(Base64.decode64(file))
- eval "def f.original_filename() '#{entity["name"]}' || 'untitled' end"
- eval "def f.content_type() '#{entity["content_type"]}' || 'application/octet-stream' end"
+ f.extend(FileLike)
+ f.original_filename = entity['name']
+ f.content_type = entity['content_type']
f
end
}
diff --git a/activesupport/test/core_ext/hash_ext_test.rb b/activesupport/test/core_ext/hash_ext_test.rb
index 65f14d696f..706e218abc 100644
--- a/activesupport/test/core_ext/hash_ext_test.rb
+++ b/activesupport/test/core_ext/hash_ext_test.rb
@@ -533,9 +533,9 @@ class HashToXmlTest < Test::Unit::TestCase
def test_single_record_from_xml_with_attributes_other_than_type
topic_xml = <<-EOT
<rsp stat="ok">
- <photos page="1" pages="1" perpage="100" total="16">
- <photo id="175756086" owner="55569174@N00" secret="0279bf37a1" server="76" title="Colored Pencil PhotoBooth Fun" ispublic="1" isfriend="0" isfamily="0"/>
- </photos>
+ <photos page="1" pages="1" perpage="100" total="16">
+ <photo id="175756086" owner="55569174@N00" secret="0279bf37a1" server="76" title="Colored Pencil PhotoBooth Fun" ispublic="1" isfriend="0" isfamily="0"/>
+ </photos>
</rsp>
EOT
@@ -599,6 +599,34 @@ class HashToXmlTest < Test::Unit::TestCase
assert_equal expected_blog_hash, Hash.from_xml(blog_xml)
end
+ def test_file_from_xml
+ blog_xml = <<-XML
+ <blog>
+ <logo type="file" name="logo.png" content_type="image/png">
+ </logo>
+ </blog>
+ XML
+ hash = Hash.from_xml(blog_xml)
+ assert hash.has_key?('blog')
+ assert hash['blog'].has_key?('logo')
+
+ file = hash['blog']['logo']
+ assert_equal 'logo.png', file.original_filename
+ assert_equal 'image/png', file.content_type
+ end
+
+ def test_file_from_xml_with_defaults
+ blog_xml = <<-XML
+ <blog>
+ <logo type="file">
+ </logo>
+ </blog>
+ XML
+ file = Hash.from_xml(blog_xml)['blog']['logo']
+ assert_equal 'untitled', file.original_filename
+ assert_equal 'application/octet-stream', file.content_type
+ end
+
def test_xsd_like_types_from_xml
bacon_xml = <<-EOT
<bacon>