diff options
16 files changed, 126 insertions, 5 deletions
diff --git a/activesupport/CHANGELOG b/activesupport/CHANGELOG index 609d56ff68..12692c659c 100644 --- a/activesupport/CHANGELOG +++ b/activesupport/CHANGELOG @@ -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 diff --git a/activesupport/Rakefile b/activesupport/Rakefile index d77a24f72b..74a8635a9c 100644 --- a/activesupport/Rakefile +++ b/activesupport/Rakefile @@ -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 diff --git a/activesupport/lib/active_support.rb b/activesupport/lib/active_support.rb index 7bd74101f5..a4c2462bdd 100644 --- a/activesupport/lib/active_support.rb +++ b/activesupport/lib/active_support.rb @@ -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'
\ No newline at end of file diff --git a/activesupport/lib/active_support/core_ext/array/conversions.rb b/activesupport/lib/active_support/core_ext/array/conversions.rb index f119bb6c78..50777f9e1e 100644 --- a/activesupport/lib/active_support/core_ext/array/conversions.rb +++ b/activesupport/lib/active_support/core_ext/array/conversions.rb @@ -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 diff --git a/activesupport/lib/active_support/core_ext/hash.rb b/activesupport/lib/active_support/core_ext/hash.rb index f16368b18b..b8309baea3 100644 --- a/activesupport/lib/active_support/core_ext/hash.rb +++ b/activesupport/lib/active_support/core_ext/hash.rb @@ -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 diff --git a/activesupport/lib/active_support/core_ext/hash/conversions.rb b/activesupport/lib/active_support/core_ext/hash/conversions.rb new file mode 100644 index 0000000000..3218f6302c --- /dev/null +++ b/activesupport/lib/active_support/core_ext/hash/conversions.rb @@ -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 diff --git a/activesupport/lib/active_support/core_ext/string/inflections.rb b/activesupport/lib/active_support/core_ext/string/inflections.rb index 5d19702719..eef8a5bc89 100644 --- a/activesupport/lib/active_support/core_ext/string/inflections.rb +++ b/activesupport/lib/active_support/core_ext/string/inflections.rb @@ -26,6 +26,10 @@ module ActiveSupport #:nodoc: Inflector.underscore(self) end + def dasherize + Inflector.dasherize(self) + end + def demodulize Inflector.demodulize(self) end diff --git a/activesupport/lib/active_support/inflector.rb b/activesupport/lib/active_support/inflector.rb index f91a73c7f3..bbc5e10579 100644 --- a/activesupport/lib/active_support/inflector.rb +++ b/activesupport/lib/active_support/inflector.rb @@ -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 diff --git a/activesupport/test/core_ext/array_ext_test.rb b/activesupport/test/core_ext/array_ext_test.rb index 266b5eefab..e13c57d262 100644 --- a/activesupport/test/core_ext/array_ext_test.rb +++ b/activesupport/test/core_ext/array_ext_test.rb @@ -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
\ No newline at end of file diff --git a/activesupport/test/core_ext/hash_ext_test.rb b/activesupport/test/core_ext/hash_ext_test.rb index d74cea0991..b7d024f754 100644 --- a/activesupport/test/core_ext/hash_ext_test.rb +++ b/activesupport/test/core_ext/hash_ext_test.rb @@ -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
\ No newline at end of file diff --git a/activesupport/test/inflector_test.rb b/activesupport/test/inflector_test.rb index c513abc967..d3f4a7727e 100644 --- a/activesupport/test/inflector_test.rb +++ b/activesupport/test/inflector_test.rb @@ -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 diff --git a/actionpack/lib/action_view/vendor/builder.rb b/activesupport/vendor/builder.rb index 9719277669..9719277669 100644 --- a/actionpack/lib/action_view/vendor/builder.rb +++ b/activesupport/vendor/builder.rb diff --git a/actionpack/lib/action_view/vendor/builder/blankslate.rb b/activesupport/vendor/builder/blankslate.rb index 1408c872cc..1408c872cc 100644 --- a/actionpack/lib/action_view/vendor/builder/blankslate.rb +++ b/activesupport/vendor/builder/blankslate.rb diff --git a/actionpack/lib/action_view/vendor/builder/xmlbase.rb b/activesupport/vendor/builder/xmlbase.rb index 7202bb2ead..7202bb2ead 100644 --- a/actionpack/lib/action_view/vendor/builder/xmlbase.rb +++ b/activesupport/vendor/builder/xmlbase.rb diff --git a/actionpack/lib/action_view/vendor/builder/xmlevents.rb b/activesupport/vendor/builder/xmlevents.rb index 15dc7b6421..15dc7b6421 100644 --- a/actionpack/lib/action_view/vendor/builder/xmlevents.rb +++ b/activesupport/vendor/builder/xmlevents.rb diff --git a/actionpack/lib/action_view/vendor/builder/xmlmarkup.rb b/activesupport/vendor/builder/xmlmarkup.rb index b7e3b2d009..b7e3b2d009 100644 --- a/actionpack/lib/action_view/vendor/builder/xmlmarkup.rb +++ b/activesupport/vendor/builder/xmlmarkup.rb |