aboutsummaryrefslogtreecommitdiffstats
path: root/activesupport/lib
diff options
context:
space:
mode:
Diffstat (limited to 'activesupport/lib')
-rw-r--r--activesupport/lib/active_support/core_ext/hash/indifferent_access.rb6
-rw-r--r--activesupport/lib/active_support/inflector.rb18
-rw-r--r--activesupport/lib/active_support/json/decoding.rb22
-rw-r--r--activesupport/lib/active_support/testing/setup_and_teardown.rb7
-rw-r--r--activesupport/lib/active_support/xml_mini.rb19
-rw-r--r--activesupport/lib/active_support/xml_mini/libxml.rb16
-rw-r--r--activesupport/lib/active_support/xml_mini/nokogiri.rb77
7 files changed, 144 insertions, 21 deletions
diff --git a/activesupport/lib/active_support/core_ext/hash/indifferent_access.rb b/activesupport/lib/active_support/core_ext/hash/indifferent_access.rb
index c96c5160b3..34ba8a005d 100644
--- a/activesupport/lib/active_support/core_ext/hash/indifferent_access.rb
+++ b/activesupport/lib/active_support/core_ext/hash/indifferent_access.rb
@@ -91,6 +91,12 @@ class HashWithIndifferentAccess < Hash
self.dup.update(hash)
end
+ # Performs the opposite of merge, with the keys and values from the first hash taking precedence over the second.
+ # This overloaded definition prevents returning a regular hash, if reverse_merge is called on a HashWithDifferentAccess.
+ def reverse_merge(other_hash)
+ super other_hash.with_indifferent_access
+ end
+
# Removes a specified key from the hash.
def delete(key)
super(convert_key(key))
diff --git a/activesupport/lib/active_support/inflector.rb b/activesupport/lib/active_support/inflector.rb
index 2e2a63c3e7..3ed30bdf56 100644
--- a/activesupport/lib/active_support/inflector.rb
+++ b/activesupport/lib/active_support/inflector.rb
@@ -257,20 +257,22 @@ module ActiveSupport
# <%= link_to(@person.name, person_path(@person)) %>
# # => <a href="/person/1-donald-e-knuth">Donald E. Knuth</a>
def parameterize(string, sep = '-')
- re_sep = Regexp.escape(sep)
- # Replace accented chars with their ASCII equivalents.
+ # replace accented chars with ther ascii equivalents
parameterized_string = transliterate(string)
- # Turn unwanted chars into the separator.
+ # Turn unwanted chars into the seperator
parameterized_string.gsub!(/[^a-z0-9\-_\+]+/i, sep)
- # No more than one of the separator in a row.
- parameterized_string.squeeze!(sep)
- # Remove leading/trailing separator.
- parameterized_string.gsub!(/^#{re_sep}|#{re_sep}$/i, '')
+ unless sep.blank?
+ re_sep = Regexp.escape(sep)
+ # No more than one of the separator in a row.
+ parameterized_string.gsub!(/#{re_sep}{2,}/, sep)
+ # Remove leading/trailing separator.
+ parameterized_string.gsub!(/^#{re_sep}|#{re_sep}$/i, '')
+ end
parameterized_string.downcase
end
- # Replaces accented characters with their ASCII equivalents.
+ # Replaces accented characters with their ascii equivalents.
def transliterate(string)
Iconv.iconv('ascii//ignore//translit', 'utf-8', string).to_s
end
diff --git a/activesupport/lib/active_support/json/decoding.rb b/activesupport/lib/active_support/json/decoding.rb
index 5eb8c0fd7d..0e079341ff 100644
--- a/activesupport/lib/active_support/json/decoding.rb
+++ b/activesupport/lib/active_support/json/decoding.rb
@@ -43,14 +43,32 @@ module ActiveSupport
end
if marks.empty?
- json.gsub(/\\\//, '/')
+ json.gsub(/\\([\\\/]|u[[:xdigit:]]{4})/) do
+ ustr = $1
+ if ustr.starts_with?('u')
+ [ustr[1..-1].to_i(16)].pack("U")
+ elsif ustr == '\\'
+ '\\\\'
+ else
+ ustr
+ end
+ end
else
left_pos = [-1].push(*marks)
right_pos = marks << scanner.pos + scanner.rest_size
output = []
left_pos.each_with_index do |left, i|
scanner.pos = left.succ
- output << scanner.peek(right_pos[i] - scanner.pos + 1)
+ output << scanner.peek(right_pos[i] - scanner.pos + 1).gsub(/\\([\\\/]|u[[:xdigit:]]{4})/) do
+ ustr = $1
+ if ustr.starts_with?('u')
+ [ustr[1..-1].to_i(16)].pack("U")
+ elsif ustr == '\\'
+ '\\\\'
+ else
+ ustr
+ end
+ end
end
output = output * " "
diff --git a/activesupport/lib/active_support/testing/setup_and_teardown.rb b/activesupport/lib/active_support/testing/setup_and_teardown.rb
index 7edf6fdb32..aaf9f8f42c 100644
--- a/activesupport/lib/active_support/testing/setup_and_teardown.rb
+++ b/activesupport/lib/active_support/testing/setup_and_teardown.rb
@@ -45,7 +45,12 @@ module ActiveSupport
return if @method_name.to_s == "default_test"
if using_mocha = respond_to?(:mocha_verify)
- assertion_counter = Mocha::TestCaseAdapter::AssertionCounter.new(result)
+ assertion_counter_klass = if defined?(Mocha::TestCaseAdapter::AssertionCounter)
+ Mocha::TestCaseAdapter::AssertionCounter
+ else
+ Mocha::Integration::TestUnit::AssertionCounter
+ end
+ assertion_counter = assertion_counter_klass.new(result)
end
yield(Test::Unit::TestCase::STARTED, name)
diff --git a/activesupport/lib/active_support/xml_mini.rb b/activesupport/lib/active_support/xml_mini.rb
index 99158e4ff7..ccd1349491 100644
--- a/activesupport/lib/active_support/xml_mini.rb
+++ b/activesupport/lib/active_support/xml_mini.rb
@@ -6,11 +6,24 @@ module ActiveSupport
# XmlMini.backend = 'LibXML'
module XmlMini
extend self
- delegate :parse, :to => :@backend
+
+ attr_reader :backend
+ delegate :parse, :to => :backend
def backend=(name)
- require "active_support/xml_mini/#{name.to_s.downcase}.rb"
- @backend = ActiveSupport.const_get("XmlMini_#{name}")
+ if name.is_a?(Module)
+ @backend = name
+ else
+ require "active_support/xml_mini/#{name.to_s.downcase}.rb"
+ @backend = ActiveSupport.const_get("XmlMini_#{name}")
+ end
+ end
+
+ def with_backend(name)
+ old_backend, self.backend = backend, name
+ yield
+ ensure
+ self.backend = old_backend
end
end
diff --git a/activesupport/lib/active_support/xml_mini/libxml.rb b/activesupport/lib/active_support/xml_mini/libxml.rb
index e1549d8c58..3586b24a6b 100644
--- a/activesupport/lib/active_support/xml_mini/libxml.rb
+++ b/activesupport/lib/active_support/xml_mini/libxml.rb
@@ -1,4 +1,6 @@
-# = XML Mini Libxml implementation
+require 'libxml'
+
+# = XmlMini LibXML implementation
module ActiveSupport
module XmlMini_LibXML #:nodoc:
extend self
@@ -7,19 +9,19 @@ module ActiveSupport
# string::
# XML Document string to parse
def parse(string)
- XML.default_keep_blanks = false
+ LibXML::XML.default_keep_blanks = false
if string.blank?
{}
else
- XML::Parser.string(string.strip).parse.to_hash
+ LibXML::XML::Parser.string(string.strip).parse.to_hash
end
end
end
end
-module XML
+module LibXML
module Conversions
module Document
def to_hash
@@ -37,7 +39,7 @@ module XML
# Hash to merge the converted element into.
def to_hash(hash={})
if text?
- raise RuntimeError if content.length >= LIB_XML_LIMIT
+ raise LibXML::XML::Error if content.length >= LIB_XML_LIMIT
hash[CONTENT_ROOT] = content
else
sub_hash = insert_name_into_hash(hash, name)
@@ -127,5 +129,5 @@ module XML
end
end
-XML::Document.send(:include, XML::Conversions::Document)
-XML::Node.send(:include, XML::Conversions::Node)
+LibXML::XML::Document.send(:include, LibXML::Conversions::Document)
+LibXML::XML::Node.send(:include, LibXML::Conversions::Node)
diff --git a/activesupport/lib/active_support/xml_mini/nokogiri.rb b/activesupport/lib/active_support/xml_mini/nokogiri.rb
new file mode 100644
index 0000000000..10281584fc
--- /dev/null
+++ b/activesupport/lib/active_support/xml_mini/nokogiri.rb
@@ -0,0 +1,77 @@
+require 'nokogiri'
+
+# = XmlMini Nokogiri implementation
+module ActiveSupport
+ module XmlMini_Nokogiri #:nodoc:
+ extend self
+
+ # Parse an XML Document string into a simple hash using libxml / nokogiri.
+ # string::
+ # XML Document string to parse
+ def parse(string)
+ if string.blank?
+ {}
+ else
+ doc = Nokogiri::XML(string)
+ raise doc.errors.first if doc.errors.length > 0
+ doc.to_hash
+ end
+ end
+
+ module Conversions
+ module Document
+ def to_hash
+ root.to_hash
+ end
+ end
+
+ module Node
+ CONTENT_ROOT = '__content__'
+
+ # Convert XML document to hash
+ #
+ # hash::
+ # Hash to merge the converted element into.
+ def to_hash(hash = {})
+ hash[name] ||= attributes_as_hash
+
+ walker = lambda { |memo, parent, child, callback|
+ next if child.blank? && 'file' != parent['type']
+
+ if child.text?
+ (memo[CONTENT_ROOT] ||= '') << child.content
+ next
+ end
+
+ name = child.name
+
+ child_hash = child.attributes_as_hash
+ if memo[name]
+ memo[name] = [memo[name]].flatten
+ memo[name] << child_hash
+ else
+ memo[name] = child_hash
+ end
+
+ # Recusively walk children
+ child.children.each { |c|
+ callback.call(child_hash, child, c, callback)
+ }
+ }
+
+ children.each { |c| walker.call(hash[name], self, c, walker) }
+ hash
+ end
+
+ def attributes_as_hash
+ Hash[*(attribute_nodes.map { |node|
+ [node.node_name, node.value]
+ }.flatten)]
+ end
+ end
+ end
+
+ Nokogiri::XML::Document.send(:include, Conversions::Document)
+ Nokogiri::XML::Node.send(:include, Conversions::Node)
+ end
+end