Added Hash#to_xml and Array#to_xml that makes it much easier to produce XML from basic structures [DHH] Moved Jim Weirich's wonderful Builder from Action Pack to Active Support (it's simply too useful to be stuck in AP) [DHH]
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@3812 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
This commit is contained in:
parent
24fca9d92e
commit
cd989472a5
|
@ -1,5 +1,20 @@
|
|||
*SVN*
|
||||
|
||||
* Added Hash#to_xml and Array#to_xml that makes it much easier to produce XML from basic structures [DHH]. Examples:
|
||||
|
||||
{ :name => "David", :street_name => "Paulina", :age => 26, :moved_on => Date.new(2005, 11, 15) }.to_xml
|
||||
|
||||
...returns:
|
||||
|
||||
<person>
|
||||
<street-name type="string">Paulina</street>
|
||||
<name type="string">David</name>
|
||||
<age type="integer">26</age>
|
||||
<moved-on type="date">2005-11-15</moved-on>
|
||||
</person>
|
||||
|
||||
* Moved Jim Weirich's wonderful Builder from Action Pack to Active Support (it's simply too useful to be stuck in AP) [DHH]
|
||||
|
||||
* Fixed that Array#to_sentence will return "" on an empty array instead of ", and" #3842, #4031 [rubyonrails@beautifulpixel.com]
|
||||
|
||||
* Add Enumerable#group_by for grouping collections based on the result of some
|
||||
|
|
|
@ -18,7 +18,7 @@ task :default => :test
|
|||
Rake::TestTask.new { |t|
|
||||
t.pattern = 'test/**/*_test.rb'
|
||||
t.verbose = true
|
||||
t.warning = true
|
||||
t.warning = false
|
||||
}
|
||||
|
||||
# Create compressed packages
|
||||
|
|
|
@ -22,6 +22,9 @@
|
|||
#++
|
||||
|
||||
$:.unshift(File.dirname(__FILE__))
|
||||
$:.unshift(File.dirname(__FILE__) + "/../vendor")
|
||||
|
||||
require 'builder'
|
||||
|
||||
require 'active_support/inflector'
|
||||
|
||||
|
@ -35,4 +38,4 @@ require 'active_support/option_merger'
|
|||
|
||||
require 'active_support/values/time_zone'
|
||||
|
||||
require 'active_support/json'
|
||||
require 'active_support/json'
|
|
@ -1,7 +1,6 @@
|
|||
module ActiveSupport #:nodoc:
|
||||
module CoreExtensions #:nodoc:
|
||||
module Array #:nodoc:
|
||||
# Enables to conversion of Arrays to human readable lists. ['one', 'two', 'three'] => "one, two, and three"
|
||||
module Conversions
|
||||
# Converts the array to comma-seperated sentence where the last element is joined by the connector word. Options:
|
||||
# * <tt>:connector</tt>: The word used to join the last element in arrays with more than two elements (default: "and")
|
||||
|
@ -27,6 +26,12 @@ module ActiveSupport #:nodoc:
|
|||
join '/'
|
||||
end
|
||||
|
||||
def to_xml(options = {})
|
||||
raise "Not all elements respond to to_xml" unless all? { |e| e.respond_to? :to_xml }
|
||||
options[:root] ||= all? { |e| e.is_a? first.class } ? first.class.to_s.underscore.pluralize : "records"
|
||||
xml = options[:builder] || Builder::XmlMarkup.new
|
||||
xml.__send__(options[:root]) { each { |e| e.to_xml(:builder => xml) } }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
require File.dirname(__FILE__) + '/hash/keys'
|
||||
require File.dirname(__FILE__) + '/hash/indifferent_access'
|
||||
require File.dirname(__FILE__) + '/hash/reverse_merge'
|
||||
require File.dirname(__FILE__) + '/hash/conversions'
|
||||
|
||||
class Hash #:nodoc:
|
||||
include ActiveSupport::CoreExtensions::Hash::Keys
|
||||
include ActiveSupport::CoreExtensions::Hash::IndifferentAccess
|
||||
include ActiveSupport::CoreExtensions::Hash::ReverseMerge
|
||||
include ActiveSupport::CoreExtensions::Hash::Conversions
|
||||
end
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
module ActiveSupport #:nodoc:
|
||||
module CoreExtensions #:nodoc:
|
||||
module Hash #:nodoc:
|
||||
module Conversions
|
||||
XML_TYPE_NAMES = {
|
||||
"String" => "string",
|
||||
"Fixnum" => "integer",
|
||||
"Date" => "date",
|
||||
"Time" => "datetime"
|
||||
}
|
||||
|
||||
XML_FORMATTING = {
|
||||
"date" => Proc.new { |date| date.to_s(:db) },
|
||||
"datetime" => Proc.new { |time| time.to_s(:db) }
|
||||
}
|
||||
|
||||
def to_xml(options = {})
|
||||
options.reverse_merge!({ :builder => Builder::XmlMarkup.new, :root => "hash" })
|
||||
|
||||
options[:builder].__send__(options[:root]) do
|
||||
for key in keys
|
||||
value = self[key]
|
||||
|
||||
if value.is_a?(self.class)
|
||||
value.to_xml(:builder => options[:builder], :root => key)
|
||||
else
|
||||
type_name = XML_TYPE_NAMES[value.class.to_s]
|
||||
options[:builder].__send__(key.to_s.dasherize,
|
||||
XML_FORMATTING[type_name] ? XML_FORMATTING[type_name].call(value) : value,
|
||||
value.nil? ? { } : { :type => type_name }
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -26,6 +26,10 @@ module ActiveSupport #:nodoc:
|
|||
Inflector.underscore(self)
|
||||
end
|
||||
|
||||
def dasherize
|
||||
Inflector.dasherize(self)
|
||||
end
|
||||
|
||||
def demodulize
|
||||
Inflector.demodulize(self)
|
||||
end
|
||||
|
|
|
@ -120,6 +120,10 @@ module Inflector
|
|||
def underscore(camel_cased_word)
|
||||
camel_cased_word.to_s.gsub(/::/, '/').gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').gsub(/([a-z\d])([A-Z])/,'\1_\2').downcase
|
||||
end
|
||||
|
||||
def dasherize(underscored_word)
|
||||
underscored_word.gsub(/_/, '-')
|
||||
end
|
||||
|
||||
def humanize(lower_case_and_underscored_word)
|
||||
lower_case_and_underscored_word.to_s.gsub(/_id$/, "").gsub(/_/, " ").capitalize
|
||||
|
|
|
@ -67,5 +67,14 @@ class ArrayExtGroupingTests < Test::Unit::TestCase
|
|||
|
||||
assert_equal [%w(a b c), %w(d e f), ['g', false, false]], groups
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class ArraToXmlTests < Test::Unit::TestCase
|
||||
def test_to_xml
|
||||
a = [ { :name => "David", :street_address => "Paulina" }, { :name => "Jason", :street_address => "Evergreen" } ]
|
||||
assert_equal(
|
||||
"<hashes><hash><street-address type=\"string\">Paulina</street-address><name type=\"string\">David</name></hash><hash><street-address type=\"string\">Evergreen</street-address><name type=\"string\">Jason</name></hash></hashes>",
|
||||
a.to_xml
|
||||
)
|
||||
end
|
||||
end
|
|
@ -1,5 +1,5 @@
|
|||
require 'test/unit'
|
||||
require File.dirname(__FILE__) + '/../../lib/active_support/core_ext/hash'
|
||||
require File.dirname(__FILE__) + '/../../lib/active_support'
|
||||
|
||||
class HashExtTest < Test::Unit::TestCase
|
||||
def setup
|
||||
|
@ -165,3 +165,31 @@ class HashExtTest < Test::Unit::TestCase
|
|||
assert_equal({ :a => 1, :b => 2, :c => 10 }, { :a => 1, :b => 2 }.reverse_merge({:a => "x", :b => "y", :c => 10}) )
|
||||
end
|
||||
end
|
||||
|
||||
class HashToXmlTest < Test::Unit::TestCase
|
||||
def test_one_level
|
||||
h = { :name => "David", :street => "Paulina" }
|
||||
assert_equal %(<person><street type="string">Paulina</street><name type="string">David</name></person>), h.to_xml(:root => :person)
|
||||
end
|
||||
|
||||
def test_one_level_with_types
|
||||
h = { :name => "David", :street => "Paulina", :age => 26, :moved_on => Date.new(2005, 11, 15) }
|
||||
assert_equal(
|
||||
"<person><street type=\"string\">Paulina</street><name type=\"string\">David</name><age type=\"integer\">26</age><moved-on type=\"date\">2005-11-15</moved-on></person>",
|
||||
h.to_xml(:root => :person)
|
||||
)
|
||||
end
|
||||
|
||||
def test_one_level_with_nils
|
||||
h = { :name => "David", :street => "Paulina", :age => nil }
|
||||
assert_equal(
|
||||
"<person><street type=\"string\">Paulina</street><name type=\"string\">David</name><age></age></person>",
|
||||
h.to_xml(:root => :person)
|
||||
)
|
||||
end
|
||||
|
||||
def test_two_levels
|
||||
h = { :name => "David", :address => { :street => "Paulina" } }
|
||||
assert_equal %(<person><address><street type="string">Paulina</street></address><name type="string">David</name></person>), h.to_xml(:root => :person)
|
||||
end
|
||||
end
|
|
@ -187,6 +187,12 @@ class InflectorTest < Test::Unit::TestCase
|
|||
"1000" => "1000th",
|
||||
"1001" => "1001st"
|
||||
}
|
||||
|
||||
UnderscoresToDashes = {
|
||||
"street" => "street",
|
||||
"street_address" => "street-address",
|
||||
"person_street_address" => "person-street-address"
|
||||
}
|
||||
|
||||
def test_pluralize_plurals
|
||||
assert_equal "plurals", Inflector.pluralize("plurals")
|
||||
|
@ -290,4 +296,10 @@ class InflectorTest < Test::Unit::TestCase
|
|||
assert_equal(ordinalized, Inflector.ordinalize(number))
|
||||
end
|
||||
end
|
||||
|
||||
def test_dasherize
|
||||
UnderscoresToDashes.each do |underscored, dasherized|
|
||||
assert_equal(dasherized, Inflector.dasherize(underscored))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue