aboutsummaryrefslogtreecommitdiffstats
path: root/activesupport
diff options
context:
space:
mode:
authorJoshua Peek <josh@joshpeek.com>2009-05-29 16:06:21 -0500
committerJoshua Peek <josh@joshpeek.com>2009-05-29 16:06:21 -0500
commit69742ca8fa05509f7d7c5512cb6d8e002ecb3ab3 (patch)
tree044c2131cc87d21ee54027511aae2b7f2d2ae26a /activesupport
parent5f3f100ce2d689480da85abc88e5e940cf90189e (diff)
parent5ec2c7dc29b36d85b2658465b8a979deb0529d7e (diff)
downloadrails-69742ca8fa05509f7d7c5512cb6d8e002ecb3ab3.tar.gz
rails-69742ca8fa05509f7d7c5512cb6d8e002ecb3ab3.tar.bz2
rails-69742ca8fa05509f7d7c5512cb6d8e002ecb3ab3.zip
Merge branch 'master' into active_model
Conflicts: activemodel/lib/active_model/core.rb activemodel/test/cases/state_machine/event_test.rb activemodel/test/cases/state_machine/state_transition_test.rb activerecord/lib/active_record/validations.rb activerecord/test/cases/validations/i18n_validation_test.rb activeresource/lib/active_resource.rb activeresource/test/abstract_unit.rb
Diffstat (limited to 'activesupport')
-rw-r--r--activesupport/CHANGELOG21
-rw-r--r--activesupport/Rakefile6
-rw-r--r--activesupport/lib/active_support.rb38
-rw-r--r--activesupport/lib/active_support/all.rb3
-rw-r--r--activesupport/lib/active_support/autoload.rb26
-rw-r--r--activesupport/lib/active_support/cache.rb1
-rw-r--r--activesupport/lib/active_support/cache/mem_cache_store.rb22
-rw-r--r--activesupport/lib/active_support/cache/strategy/local_cache.rb4
-rw-r--r--activesupport/lib/active_support/callbacks.rb2
-rw-r--r--activesupport/lib/active_support/concern.rb22
-rw-r--r--activesupport/lib/active_support/core.rb7
-rw-r--r--activesupport/lib/active_support/core/all.rb4
-rw-r--r--activesupport/lib/active_support/core/time.rb4
-rw-r--r--activesupport/lib/active_support/core_ext/array/conversions.rb6
-rw-r--r--activesupport/lib/active_support/core_ext/class/attribute_accessors.rb2
-rw-r--r--activesupport/lib/active_support/core_ext/class/delegating_attributes.rb2
-rw-r--r--activesupport/lib/active_support/core_ext/class/inheritable_attributes.rb4
-rw-r--r--activesupport/lib/active_support/core_ext/class/removal.rb3
-rw-r--r--activesupport/lib/active_support/core_ext/date/calculations.rb6
-rw-r--r--activesupport/lib/active_support/core_ext/date/conversions.rb2
-rw-r--r--activesupport/lib/active_support/core_ext/date_time.rb3
-rw-r--r--activesupport/lib/active_support/core_ext/date_time/conversions.rb6
-rw-r--r--activesupport/lib/active_support/core_ext/hash/conversions.rb5
-rw-r--r--activesupport/lib/active_support/core_ext/integer/even_odd.rb4
-rw-r--r--activesupport/lib/active_support/core_ext/kernel/requires.rb4
-rw-r--r--activesupport/lib/active_support/core_ext/logger.rb5
-rw-r--r--activesupport/lib/active_support/core_ext/module.rb1
-rw-r--r--activesupport/lib/active_support/core_ext/module/attr_internal.rb8
-rw-r--r--activesupport/lib/active_support/core_ext/module/delegation.rb4
-rw-r--r--activesupport/lib/active_support/core_ext/module/introspection.rb6
-rw-r--r--activesupport/lib/active_support/core_ext/module/model_naming.rb8
-rw-r--r--activesupport/lib/active_support/core_ext/module/setup.rb26
-rw-r--r--activesupport/lib/active_support/core_ext/module/synchronization.rb2
-rw-r--r--activesupport/lib/active_support/core_ext/numeric/time.rb2
-rw-r--r--activesupport/lib/active_support/core_ext/object.rb1
-rw-r--r--activesupport/lib/active_support/core_ext/object/conversions.rb3
-rw-r--r--activesupport/lib/active_support/core_ext/object/misc.rb83
-rw-r--r--activesupport/lib/active_support/core_ext/object/returning.rb42
-rw-r--r--activesupport/lib/active_support/core_ext/object/tap.rb16
-rw-r--r--activesupport/lib/active_support/core_ext/object/with_options.rb24
-rw-r--r--activesupport/lib/active_support/core_ext/range/blockless_step.rb2
-rw-r--r--activesupport/lib/active_support/core_ext/string/conversions.rb3
-rw-r--r--activesupport/lib/active_support/core_ext/string/iterators.rb5
-rw-r--r--activesupport/lib/active_support/core_ext/string/multibyte.rb1
-rw-r--r--activesupport/lib/active_support/core_ext/symbol.rb15
-rw-r--r--activesupport/lib/active_support/core_ext/symbol/to_proc.rb14
-rw-r--r--activesupport/lib/active_support/core_ext/time/conversions.rb6
-rw-r--r--activesupport/lib/active_support/dependencies.rb9
-rw-r--r--activesupport/lib/active_support/dependency_module.rb17
-rw-r--r--activesupport/lib/active_support/deprecation/method_wrappers.rb1
-rw-r--r--activesupport/lib/active_support/deprecation/proxy_wrappers.rb6
-rw-r--r--activesupport/lib/active_support/duration.rb1
-rw-r--r--activesupport/lib/active_support/inflector.rb3
-rw-r--r--activesupport/lib/active_support/json.rb72
-rw-r--r--activesupport/lib/active_support/json/backends/jsongem.rb41
-rw-r--r--activesupport/lib/active_support/json/backends/yaml.rb88
-rw-r--r--activesupport/lib/active_support/json/decoding.rb84
-rw-r--r--activesupport/lib/active_support/json/encoders/date.rb37
-rw-r--r--activesupport/lib/active_support/json/encoders/date_time.rb37
-rw-r--r--activesupport/lib/active_support/json/encoders/enumerable.rb21
-rw-r--r--activesupport/lib/active_support/json/encoders/false_class.rb7
-rw-r--r--activesupport/lib/active_support/json/encoders/hash.rb87
-rw-r--r--activesupport/lib/active_support/json/encoders/nil_class.rb7
-rw-r--r--activesupport/lib/active_support/json/encoders/numeric.rb7
-rw-r--r--activesupport/lib/active_support/json/encoders/object.rb9
-rw-r--r--activesupport/lib/active_support/json/encoders/regexp.rb7
-rw-r--r--activesupport/lib/active_support/json/encoders/string.rb38
-rw-r--r--activesupport/lib/active_support/json/encoders/symbol.rb7
-rw-r--r--activesupport/lib/active_support/json/encoders/time.rb39
-rw-r--r--activesupport/lib/active_support/json/encoders/true_class.rb7
-rw-r--r--activesupport/lib/active_support/json/encoding.rb10
-rw-r--r--activesupport/lib/active_support/json/variable.rb7
-rw-r--r--activesupport/lib/active_support/memoizable.rb3
-rw-r--r--activesupport/lib/active_support/multibyte.rb2
-rw-r--r--activesupport/lib/active_support/multibyte/chars.rb1
-rw-r--r--activesupport/lib/active_support/new_callbacks.rb56
-rw-r--r--activesupport/lib/active_support/ordered_hash.rb14
-rw-r--r--activesupport/lib/active_support/ruby/shim.rb24
-rw-r--r--activesupport/lib/active_support/test_case.rb5
-rw-r--r--activesupport/lib/active_support/testing/assertions.rb2
-rw-r--r--activesupport/lib/active_support/testing/deprecation.rb18
-rw-r--r--activesupport/lib/active_support/testing/pending.rb5
-rw-r--r--activesupport/lib/active_support/time.rb14
-rw-r--r--activesupport/lib/active_support/time/autoload.rb (renamed from activesupport/lib/active_support/core/time/autoload.rb)0
-rw-r--r--activesupport/lib/active_support/time_with_zone.rb40
-rw-r--r--activesupport/lib/active_support/values/time_zone.rb4
-rw-r--r--activesupport/lib/active_support/xml_mini.rb2
-rw-r--r--activesupport/lib/active_support/xml_mini/jdom.rb166
-rw-r--r--activesupport/lib/active_support/xml_mini/libxml.rb16
-rw-r--r--activesupport/lib/active_support/xml_mini/nokogiri.rb16
-rw-r--r--activesupport/lib/active_support/xml_mini/rexml.rb16
-rw-r--r--activesupport/test/buffered_logger_test.rb14
-rw-r--r--activesupport/test/caching_test.rb38
-rw-r--r--activesupport/test/concern_test.rb88
-rw-r--r--activesupport/test/core_ext/array_ext_test.rb3
-rw-r--r--activesupport/test/core_ext/blank_test.rb1
-rw-r--r--activesupport/test/core_ext/class/attribute_accessor_test.rb1
-rw-r--r--activesupport/test/core_ext/class/class_inheritable_attributes_test.rb1
-rw-r--r--activesupport/test/core_ext/date_time_ext_test.rb1
-rw-r--r--activesupport/test/core_ext/duplicable_test.rb2
-rw-r--r--activesupport/test/core_ext/duration_test.rb21
-rw-r--r--activesupport/test/core_ext/exception_test.rb1
-rw-r--r--activesupport/test/core_ext/hash_ext_test.rb18
-rw-r--r--activesupport/test/core_ext/module/attr_accessor_with_default_test.rb1
-rw-r--r--activesupport/test/core_ext/module/attr_internal_test.rb7
-rw-r--r--activesupport/test/core_ext/module/attribute_accessor_test.rb1
-rw-r--r--activesupport/test/core_ext/module/attribute_aliasing_test.rb1
-rw-r--r--activesupport/test/core_ext/module/model_naming_test.rb1
-rw-r--r--activesupport/test/core_ext/name_error_test.rb1
-rw-r--r--activesupport/test/core_ext/numeric_ext_test.rb5
-rw-r--r--activesupport/test/core_ext/object_and_class_ext_test.rb2
-rw-r--r--activesupport/test/core_ext/proc_test.rb1
-rw-r--r--activesupport/test/core_ext/range_ext_test.rb1
-rw-r--r--activesupport/test/core_ext/string_ext_test.rb1
-rw-r--r--activesupport/test/core_ext/time_ext_test.rb9
-rw-r--r--activesupport/test/core_ext/time_with_zone_test.rb7
-rw-r--r--activesupport/test/dependencies_test.rb3
-rw-r--r--activesupport/test/i18n_test.rb2
-rw-r--r--activesupport/test/inflector_test.rb2
-rw-r--r--activesupport/test/json/decoding_test.rb82
-rw-r--r--activesupport/test/json/encoding_test.rb38
-rw-r--r--activesupport/test/new_callbacks_test.rb112
-rw-r--r--activesupport/test/ordered_hash_test.rb10
-rw-r--r--activesupport/test/test_test.rb1
-rw-r--r--activesupport/test/time_zone_test.rb1
-rw-r--r--activesupport/test/xml_mini/jdom_engine_test.rb153
-rw-r--r--activesupport/test/xml_mini/nokogiri_engine_test.rb14
-rw-r--r--activesupport/test/xml_mini/rexml_engine_test.rb14
128 files changed, 1585 insertions, 611 deletions
diff --git a/activesupport/CHANGELOG b/activesupport/CHANGELOG
index e208f56455..27d26b2ba5 100644
--- a/activesupport/CHANGELOG
+++ b/activesupport/CHANGELOG
@@ -1,5 +1,26 @@
*Edge*
+* Allow MemCacheStore to be initialized with a MemCache-like object instead of addresses and options [Bryan Helmkamp]
+
+* Change spelling of Kyev timezone to Kyiv #2613 [Alexander Dymo]
+
+* Add ActiveSupport.parse_json_times to disable time parsing in JSON backends that don't support it or don't need it. [rick]
+
+* Add pluggable JSON backends with support for the JSON gem. [rick]
+ Example: ActiveSupport::JSON.backend = "JSONGem"
+
+ All internal Rails JSON encoding is now handled by ActiveSupport::JSON.encode(). Use of #to_json is not recommended, as it may clash with other libraries that overwrite it. However, you can recover Rails specific functionality
+ if you really want to use #to_json.
+
+ gem 'json'
+ ActiveSupport::JSON.backend = "JSONGem"
+
+ class ActiveRecord::Base
+ alias to_json rails_to_json
+ end
+
+* require 'active_support' no longer orders the whole menu of core extensions. Ask for just what you need: e.g. require 'active_support/core/time' to use timezones, durations, and stdlib date/time extensions. [Jeremy Kemper]
+
* Removed rarely-used DRb cache store. [Jeremy Kemper]
* TimeWithZone.name returns 'Time', to further thwart type checking [Geoff Buesing]
diff --git a/activesupport/Rakefile b/activesupport/Rakefile
index f7fd52c7d8..c3ea09d424 100644
--- a/activesupport/Rakefile
+++ b/activesupport/Rakefile
@@ -21,6 +21,12 @@ Rake::TestTask.new { |t|
t.verbose = true
t.warning = true
}
+task :isolated_test do
+ ruby = File.join(*RbConfig::CONFIG.values_at('bindir', 'RUBY_INSTALL_NAME'))
+ Dir['test/**/*_test.rb'].all? do |file|
+ system(ruby, '-Ilib:test', file)
+ end or raise "Failures"
+end
# Create compressed packages
dist_dirs = [ "lib", "test"]
diff --git a/activesupport/lib/active_support.rb b/activesupport/lib/active_support.rb
index 21b730fa0c..a20635ba62 100644
--- a/activesupport/lib/active_support.rb
+++ b/activesupport/lib/active_support.rb
@@ -22,39 +22,19 @@
#++
module ActiveSupport
- def self.load_all!
- [Dependencies, Deprecation, Gzip, MessageVerifier, Multibyte, SecureRandom] + Core.load_all!
+ class << self
+ attr_accessor :load_all_hooks
+ def on_load_all(&hook) load_all_hooks << hook end
+ def load_all!; load_all_hooks.each { |hook| hook.call } end
end
+ self.load_all_hooks = []
- autoload :BacktraceCleaner, 'active_support/backtrace_cleaner'
- autoload :Base64, 'active_support/base64'
- autoload :BasicObject, 'active_support/basic_object'
- autoload :BufferedLogger, 'active_support/buffered_logger'
- autoload :Cache, 'active_support/cache'
- autoload :Callbacks, 'active_support/callbacks'
- autoload :NewCallbacks, 'active_support/new_callbacks'
- autoload :ConcurrentHash, 'active_support/concurrent_hash'
- autoload :Deprecation, 'active_support/deprecation'
- autoload :Gzip, 'active_support/gzip'
- autoload :Inflector, 'active_support/inflector'
- autoload :Memoizable, 'active_support/memoizable'
- autoload :MessageEncryptor, 'active_support/message_encryptor'
- autoload :MessageVerifier, 'active_support/message_verifier'
- autoload :Multibyte, 'active_support/multibyte'
- autoload :OptionMerger, 'active_support/option_merger'
- autoload :OrderedHash, 'active_support/ordered_hash'
- autoload :OrderedOptions, 'active_support/ordered_options'
- autoload :Rescuable, 'active_support/rescuable'
- autoload :SecureRandom, 'active_support/secure_random'
- autoload :StringInquirer, 'active_support/string_inquirer'
- autoload :XmlMini, 'active_support/xml_mini'
+ on_load_all do
+ [Dependencies, Deprecation, Gzip, MessageVerifier, Multibyte, SecureRandom]
+ end
end
-require 'active_support/core/all'
-
+require 'active_support/autoload'
require 'active_support/vendor'
-require 'active_support/core_ext'
-require 'active_support/dependencies'
-require 'active_support/json'
I18n.load_path << "#{File.dirname(__FILE__)}/active_support/locale/en.yml"
diff --git a/activesupport/lib/active_support/all.rb b/activesupport/lib/active_support/all.rb
new file mode 100644
index 0000000000..f537818300
--- /dev/null
+++ b/activesupport/lib/active_support/all.rb
@@ -0,0 +1,3 @@
+require 'active_support'
+require 'active_support/time'
+require 'active_support/core_ext'
diff --git a/activesupport/lib/active_support/autoload.rb b/activesupport/lib/active_support/autoload.rb
new file mode 100644
index 0000000000..75706855d6
--- /dev/null
+++ b/activesupport/lib/active_support/autoload.rb
@@ -0,0 +1,26 @@
+module ActiveSupport
+ autoload :BacktraceCleaner, 'active_support/backtrace_cleaner'
+ autoload :Base64, 'active_support/base64'
+ autoload :BasicObject, 'active_support/basic_object'
+ autoload :BufferedLogger, 'active_support/buffered_logger'
+ autoload :Cache, 'active_support/cache'
+ autoload :Callbacks, 'active_support/callbacks'
+ autoload :Concern, 'active_support/concern'
+ autoload :ConcurrentHash, 'active_support/concurrent_hash'
+ autoload :DependencyModule, 'active_support/dependency_module'
+ autoload :Deprecation, 'active_support/deprecation'
+ autoload :Gzip, 'active_support/gzip'
+ autoload :Inflector, 'active_support/inflector'
+ autoload :Memoizable, 'active_support/memoizable'
+ autoload :MessageEncryptor, 'active_support/message_encryptor'
+ autoload :MessageVerifier, 'active_support/message_verifier'
+ autoload :Multibyte, 'active_support/multibyte'
+ autoload :NewCallbacks, 'active_support/new_callbacks'
+ autoload :OptionMerger, 'active_support/option_merger'
+ autoload :OrderedHash, 'active_support/ordered_hash'
+ autoload :OrderedOptions, 'active_support/ordered_options'
+ autoload :Rescuable, 'active_support/rescuable'
+ autoload :SecureRandom, 'active_support/secure_random'
+ autoload :StringInquirer, 'active_support/string_inquirer'
+ autoload :XmlMini, 'active_support/xml_mini'
+end
diff --git a/activesupport/lib/active_support/cache.rb b/activesupport/lib/active_support/cache.rb
index 4b2eebb007..feb6b1f2cf 100644
--- a/activesupport/lib/active_support/cache.rb
+++ b/activesupport/lib/active_support/cache.rb
@@ -2,6 +2,7 @@ require 'benchmark'
require 'active_support/core_ext/benchmark'
require 'active_support/core_ext/exception'
require 'active_support/core_ext/class/attribute_accessors'
+require 'active_support/core_ext' # FIXME: pulling in all to_param extensions
module ActiveSupport
# See ActiveSupport::Cache::Store for documentation.
diff --git a/activesupport/lib/active_support/cache/mem_cache_store.rb b/activesupport/lib/active_support/cache/mem_cache_store.rb
index 4d8e1fdd67..38b3409ca6 100644
--- a/activesupport/lib/active_support/cache/mem_cache_store.rb
+++ b/activesupport/lib/active_support/cache/mem_cache_store.rb
@@ -23,7 +23,12 @@ module ActiveSupport
DELETED = "DELETED\r\n"
end
- attr_reader :addresses
+ def self.build_mem_cache(*addresses)
+ addresses = addresses.flatten
+ options = addresses.extract_options!
+ addresses = ["localhost"] if addresses.empty?
+ MemCache.new(addresses, options)
+ end
# Creates a new MemCacheStore object, with the given memcached server
# addresses. Each address is either a host name, or a host-with-port string
@@ -34,15 +39,20 @@ module ActiveSupport
# If no addresses are specified, then MemCacheStore will connect to
# localhost port 11211 (the default memcached port).
def initialize(*addresses)
- addresses = addresses.flatten
- options = addresses.extract_options!
- addresses = ["localhost"] if addresses.empty?
- @addresses = addresses
- @data = MemCache.new(addresses, options)
+ if addresses.first.respond_to?(:get)
+ @data = addresses.first
+ else
+ @data = self.class.build_mem_cache(*addresses)
+ end
extend Strategy::LocalCache
end
+ # Reads multiple keys from the cache.
+ def read_multi(*keys)
+ @data.get_multi keys
+ end
+
def read(key, options = nil) # :nodoc:
super
@data.get(key, raw?(options))
diff --git a/activesupport/lib/active_support/cache/strategy/local_cache.rb b/activesupport/lib/active_support/cache/strategy/local_cache.rb
index 84d9a0e6d8..3b5fccc737 100644
--- a/activesupport/lib/active_support/cache/strategy/local_cache.rb
+++ b/activesupport/lib/active_support/cache/strategy/local_cache.rb
@@ -1,3 +1,5 @@
+require 'active_support/core_ext/object/duplicable'
+
module ActiveSupport
module Cache
module Strategy
@@ -43,7 +45,7 @@ module ActiveSupport
elsif value.nil?
value = super
local_cache.write(key, value || NULL) if local_cache
- value
+ value.duplicable? ? value.dup : value
else
# forcing the value to be immutable
value.duplicable? ? value.dup : value
diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb
index 4bac8292e2..f049189b9a 100644
--- a/activesupport/lib/active_support/callbacks.rb
+++ b/activesupport/lib/active_support/callbacks.rb
@@ -1,3 +1,5 @@
+require 'active_support/core_ext/array/extract_options'
+
module ActiveSupport
# Callbacks are hooks into the lifecycle of an object that allow you to trigger logic
# before or after an alteration of the object state.
diff --git a/activesupport/lib/active_support/concern.rb b/activesupport/lib/active_support/concern.rb
new file mode 100644
index 0000000000..154f8807f7
--- /dev/null
+++ b/activesupport/lib/active_support/concern.rb
@@ -0,0 +1,22 @@
+require 'active_support/dependency_module'
+
+module ActiveSupport
+ module Concern
+ include DependencyModule
+
+ def append_features(base)
+ if super
+ base.extend const_get("ClassMethods") if const_defined?("ClassMethods")
+ base.class_eval(&@_included_block) if instance_variable_defined?("@_included_block")
+ end
+ end
+
+ def included(base = nil, &block)
+ if base.nil?
+ @_included_block = block
+ else
+ super
+ end
+ end
+ end
+end
diff --git a/activesupport/lib/active_support/core.rb b/activesupport/lib/active_support/core.rb
deleted file mode 100644
index ad8db94941..0000000000
--- a/activesupport/lib/active_support/core.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-module ActiveSupport
- module Core
- def self.load_all!
- [TimeWithZone]
- end
- end
-end
diff --git a/activesupport/lib/active_support/core/all.rb b/activesupport/lib/active_support/core/all.rb
deleted file mode 100644
index f397f48e9c..0000000000
--- a/activesupport/lib/active_support/core/all.rb
+++ /dev/null
@@ -1,4 +0,0 @@
-require 'active_support/core'
-Dir["#{File.dirname(__FILE__)}/*.rb"].sort.each do |path|
- require "active_support/core/#{File.basename(path, '.rb')}"
-end
diff --git a/activesupport/lib/active_support/core/time.rb b/activesupport/lib/active_support/core/time.rb
deleted file mode 100644
index 43e13b5e58..0000000000
--- a/activesupport/lib/active_support/core/time.rb
+++ /dev/null
@@ -1,4 +0,0 @@
-require 'active_support/core/time/autoload'
-require 'active_support/core_ext/time'
-require 'active_support/core_ext/date'
-require 'active_support/core_ext/date_time'
diff --git a/activesupport/lib/active_support/core_ext/array/conversions.rb b/activesupport/lib/active_support/core_ext/array/conversions.rb
index 81e466779e..5f1ce4142f 100644
--- a/activesupport/lib/active_support/core_ext/array/conversions.rb
+++ b/activesupport/lib/active_support/core_ext/array/conversions.rb
@@ -1,3 +1,7 @@
+require 'active_support/core_ext/hash/keys'
+require 'active_support/core_ext/hash/reverse_merge'
+require 'active_support/inflector'
+
class Array
# Converts the array to a comma-separated sentence where the last element is joined by the connector word. Options:
# * <tt>:words_connector</tt> - The sign or word used to join the elements in arrays with two or more elements (default: ", ")
@@ -155,7 +159,7 @@ class Array
raise "Not all elements respond to to_xml" unless all? { |e| e.respond_to? :to_xml }
require 'builder' unless defined?(Builder)
- options[:root] ||= all? { |e| e.is_a?(first.class) && first.class.to_s != "Hash" } ? first.class.to_s.underscore.pluralize : "records"
+ options[:root] ||= all? { |e| e.is_a?(first.class) && first.class.to_s != "Hash" } ? ActiveSupport::Inflector.pluralize(ActiveSupport::Inflector.underscore(first.class.name)) : "records"
options[:children] ||= options[:root].singularize
options[:indent] ||= 2
options[:builder] ||= Builder::XmlMarkup.new(:indent => options[:indent])
diff --git a/activesupport/lib/active_support/core_ext/class/attribute_accessors.rb b/activesupport/lib/active_support/core_ext/class/attribute_accessors.rb
index 75e481fc54..74ce85a1c2 100644
--- a/activesupport/lib/active_support/core_ext/class/attribute_accessors.rb
+++ b/activesupport/lib/active_support/core_ext/class/attribute_accessors.rb
@@ -1,3 +1,5 @@
+require 'active_support/core_ext/array/extract_options'
+
# Extends the class object with class and instance accessors for class attributes,
# just like the native attr* accessors for instance attributes.
#
diff --git a/activesupport/lib/active_support/core_ext/class/delegating_attributes.rb b/activesupport/lib/active_support/core_ext/class/delegating_attributes.rb
index da798c67e7..fd029544c3 100644
--- a/activesupport/lib/active_support/core_ext/class/delegating_attributes.rb
+++ b/activesupport/lib/active_support/core_ext/class/delegating_attributes.rb
@@ -1,3 +1,5 @@
+require 'active_support/core_ext/object/blank'
+
class Class
def superclass_delegating_reader(*names)
class_name_to_stop_searching_on = superclass.name.blank? ? "Object" : superclass.name
diff --git a/activesupport/lib/active_support/core_ext/class/inheritable_attributes.rb b/activesupport/lib/active_support/core_ext/class/inheritable_attributes.rb
index 2f18666ab9..cca93a0b9f 100644
--- a/activesupport/lib/active_support/core_ext/class/inheritable_attributes.rb
+++ b/activesupport/lib/active_support/core_ext/class/inheritable_attributes.rb
@@ -1,3 +1,5 @@
+require 'active_support/core_ext/object/duplicable'
+
# Retain for backward compatibility. Methods are now included in Class.
module ClassInheritableAttributes # :nodoc:
end
@@ -216,4 +218,4 @@ class Class
extlib_inheritable_reader(*syms)
extlib_inheritable_writer(*syms)
end
-end \ No newline at end of file
+end
diff --git a/activesupport/lib/active_support/core_ext/class/removal.rb b/activesupport/lib/active_support/core_ext/class/removal.rb
index 10660edb2c..2dea3c24d5 100644
--- a/activesupport/lib/active_support/core_ext/class/removal.rb
+++ b/activesupport/lib/active_support/core_ext/class/removal.rb
@@ -1,3 +1,6 @@
+require 'active_support/core_ext/object/extending'
+require 'active_support/core_ext/module/introspection'
+
class Class #:nodoc:
# Unassociates the class with its subclasses and removes the subclasses
diff --git a/activesupport/lib/active_support/core_ext/date/calculations.rb b/activesupport/lib/active_support/core_ext/date/calculations.rb
index 59efdbd1b6..1fe4ffb8e1 100644
--- a/activesupport/lib/active_support/core_ext/date/calculations.rb
+++ b/activesupport/lib/active_support/core_ext/date/calculations.rb
@@ -1,3 +1,5 @@
+require 'active_support/duration'
+
class Date
class << self
# Returns a new Date representing the date 1 day ago (i.e. yesterday's date).
@@ -130,7 +132,7 @@ class Date
# Short-hand for years_since(1)
def next_year
years_since(1)
- end
+ end unless method_defined?(:next_year)
# Short-hand for months_ago(1)
def last_month
@@ -140,7 +142,7 @@ class Date
# Short-hand for months_since(1)
def next_month
months_since(1)
- end
+ end unless method_defined?(:next_month)
# Returns a new Date/DateTime representing the "start" of this week (i.e, Monday; DateTime objects will have time set to 0:00)
def beginning_of_week
diff --git a/activesupport/lib/active_support/core_ext/date/conversions.rb b/activesupport/lib/active_support/core_ext/date/conversions.rb
index f6c870035b..54facf4430 100644
--- a/activesupport/lib/active_support/core_ext/date/conversions.rb
+++ b/activesupport/lib/active_support/core_ext/date/conversions.rb
@@ -1,4 +1,6 @@
require 'active_support/inflector'
+require 'active_support/core_ext/time/conversions'
+require 'active_support/core_ext/date_time/conversions'
class Date
DATE_FORMATS = {
diff --git a/activesupport/lib/active_support/core_ext/date_time.rb b/activesupport/lib/active_support/core_ext/date_time.rb
index 83a11da1c7..004fd0ad29 100644
--- a/activesupport/lib/active_support/core_ext/date_time.rb
+++ b/activesupport/lib/active_support/core_ext/date_time.rb
@@ -1,5 +1,4 @@
-require 'date'
-
+require 'active_support/core_ext/time'
require 'active_support/core_ext/date_time/acts_like'
require 'active_support/core_ext/date_time/calculations'
require 'active_support/core_ext/date_time/conversions'
diff --git a/activesupport/lib/active_support/core_ext/date_time/conversions.rb b/activesupport/lib/active_support/core_ext/date_time/conversions.rb
index ddfa8d610d..5f01bc4fd6 100644
--- a/activesupport/lib/active_support/core_ext/date_time/conversions.rb
+++ b/activesupport/lib/active_support/core_ext/date_time/conversions.rb
@@ -58,7 +58,7 @@ class DateTime
# Converts self to a Ruby Date object; time portion is discarded
def to_date
::Date.new(year, month, day)
- end
+ end unless method_defined?(:to_date)
# Attempts to convert self to a Ruby Time object; returns self if out of range of Ruby Time class
# If self has an offset other than 0, self will just be returned unaltered, since there's no clean way to map it to a Time
@@ -69,12 +69,12 @@ class DateTime
# To be able to keep Times, Dates and DateTimes interchangeable on conversions
def to_datetime
self
- end
+ end unless method_defined?(:to_datetime)
# Converts datetime to an appropriate format for use in XML
def xmlschema
strftime("%Y-%m-%dT%H:%M:%S%Z")
- end if RUBY_VERSION < '1.9'
+ end unless method_defined?(:xmlschema)
# Converts self to a floating-point number of seconds since the Unix epoch
def to_f
diff --git a/activesupport/lib/active_support/core_ext/hash/conversions.rb b/activesupport/lib/active_support/core_ext/hash/conversions.rb
index fa171720f9..2a34874d08 100644
--- a/activesupport/lib/active_support/core_ext/hash/conversions.rb
+++ b/activesupport/lib/active_support/core_ext/hash/conversions.rb
@@ -1,6 +1,7 @@
-require 'date'
+require 'active_support/time'
require 'active_support/core_ext/object/conversions'
require 'active_support/core_ext/array/conversions'
+require 'active_support/core_ext/hash/reverse_merge'
class Hash
# This module exists to decorate files deserialized using Hash.from_xml with
@@ -215,7 +216,7 @@ class Hash
case params.class.to_s
when "Hash"
params.inject({}) do |h,(k,v)|
- h[k.to_s.underscore.tr("-", "_")] = unrename_keys(v)
+ h[k.to_s.tr("-", "_")] = unrename_keys(v)
h
end
when "Array"
diff --git a/activesupport/lib/active_support/core_ext/integer/even_odd.rb b/activesupport/lib/active_support/core_ext/integer/even_odd.rb
index 6d005268a3..8f9a97b44c 100644
--- a/activesupport/lib/active_support/core_ext/integer/even_odd.rb
+++ b/activesupport/lib/active_support/core_ext/integer/even_odd.rb
@@ -7,10 +7,10 @@ class Integer
# Is the integer a multiple of 2?
def even?
multiple_of? 2
- end if RUBY_VERSION < '1.9'
+ end unless method_defined?(:even?)
# Is the integer not a multiple of 2?
def odd?
!even?
- end if RUBY_VERSION < '1.9'
+ end unless method_defined?(:odd?)
end
diff --git a/activesupport/lib/active_support/core_ext/kernel/requires.rb b/activesupport/lib/active_support/core_ext/kernel/requires.rb
index 323fea49fe..d2238898d6 100644
--- a/activesupport/lib/active_support/core_ext/kernel/requires.rb
+++ b/activesupport/lib/active_support/core_ext/kernel/requires.rb
@@ -1,3 +1,5 @@
+require 'active_support/core_ext/kernel/reporting'
+
module Kernel
# Require a library with fallback to RubyGems. Warnings during library
# loading are silenced to increase signal/noise for application warnings.
@@ -21,4 +23,4 @@ module Kernel
end
end
end
-end \ No newline at end of file
+end
diff --git a/activesupport/lib/active_support/core_ext/logger.rb b/activesupport/lib/active_support/core_ext/logger.rb
index 858da7aa07..22749229a3 100644
--- a/activesupport/lib/active_support/core_ext/logger.rb
+++ b/activesupport/lib/active_support/core_ext/logger.rb
@@ -1,6 +1,7 @@
-# Adds the 'around_level' method to Logger.
+require 'active_support/core_ext/class/attribute_accessors'
-class Logger
+# Adds the 'around_level' method to Logger.
+class Logger #:nodoc:
def self.define_around_helper(level)
module_eval <<-end_eval
def around_#{level}(before_message, after_message, &block) # def around_debug(before_message, after_message, &block)
diff --git a/activesupport/lib/active_support/core_ext/module.rb b/activesupport/lib/active_support/core_ext/module.rb
index fee91534e7..215c47b114 100644
--- a/activesupport/lib/active_support/core_ext/module.rb
+++ b/activesupport/lib/active_support/core_ext/module.rb
@@ -9,4 +9,3 @@ require 'active_support/core_ext/module/delegation'
require 'active_support/core_ext/module/loading'
require 'active_support/core_ext/module/model_naming'
require 'active_support/core_ext/module/synchronization'
-require 'active_support/core_ext/module/setup'
diff --git a/activesupport/lib/active_support/core_ext/module/attr_internal.rb b/activesupport/lib/active_support/core_ext/module/attr_internal.rb
index b66c0d7500..d052bfed2d 100644
--- a/activesupport/lib/active_support/core_ext/module/attr_internal.rb
+++ b/activesupport/lib/active_support/core_ext/module/attr_internal.rb
@@ -22,11 +22,11 @@ class Module
alias_method :attr_internal, :attr_internal_accessor
- private
- mattr_accessor :attr_internal_naming_format
- self.attr_internal_naming_format = '@_%s'
+ class << self; attr_accessor :attr_internal_naming_format end
+ self.attr_internal_naming_format = '@_%s'
+ private
def attr_internal_ivar_name(attr)
- attr_internal_naming_format % attr
+ Module.attr_internal_naming_format % attr
end
end
diff --git a/activesupport/lib/active_support/core_ext/module/delegation.rb b/activesupport/lib/active_support/core_ext/module/delegation.rb
index fb4b5f0f3c..a44344806d 100644
--- a/activesupport/lib/active_support/core_ext/module/delegation.rb
+++ b/activesupport/lib/active_support/core_ext/module/delegation.rb
@@ -110,8 +110,10 @@ class Module
allow_nil = options[:allow_nil] && "#{to} && "
+ file, line = caller[0].split(":")
+
methods.each do |method|
- module_eval(<<-EOS, "(__DELEGATION__)", 1)
+ module_eval(<<-EOS, file, line.to_i)
def #{prefix}#{method}(*args, &block) # def customer_name(*args, &block)
#{allow_nil}#{to}.__send__(#{method.inspect}, *args, &block) # client && client.__send__(:name, *args, &block)
end # end
diff --git a/activesupport/lib/active_support/core_ext/module/introspection.rb b/activesupport/lib/active_support/core_ext/module/introspection.rb
index 7708d573fa..23a1063901 100644
--- a/activesupport/lib/active_support/core_ext/module/introspection.rb
+++ b/activesupport/lib/active_support/core_ext/module/introspection.rb
@@ -1,3 +1,5 @@
+require 'active_support/inflector'
+
class Module
# Returns the name of the module containing this one.
#
@@ -26,7 +28,7 @@ class Module
# p Module.new.parent # => Object
#
def parent
- parent_name ? parent_name.constantize : Object
+ parent_name ? ActiveSupport::Inflector.constantize(parent_name) : Object
end
# Returns all the parents of this module according to its name, ordered from
@@ -47,7 +49,7 @@ class Module
if parent_name
parts = parent_name.split('::')
until parts.empty?
- parents << (parts * '::').constantize
+ parents << ActiveSupport::Inflector.constantize(parts * '::')
parts.pop
end
end
diff --git a/activesupport/lib/active_support/core_ext/module/model_naming.rb b/activesupport/lib/active_support/core_ext/module/model_naming.rb
index 004b96a3c1..36fde87b23 100644
--- a/activesupport/lib/active_support/core_ext/module/model_naming.rb
+++ b/activesupport/lib/active_support/core_ext/module/model_naming.rb
@@ -1,13 +1,15 @@
+require 'active_support/inflector'
+
module ActiveSupport
class ModelName < String
attr_reader :singular, :plural, :cache_key, :partial_path
def initialize(name)
super
- @singular = underscore.tr('/', '_').freeze
- @plural = @singular.pluralize.freeze
+ @singular = ActiveSupport::Inflector.underscore(self).tr('/', '_').freeze
+ @plural = ActiveSupport::Inflector.pluralize(@singular).freeze
@cache_key = tableize.freeze
- @partial_path = "#{@cache_key}/#{demodulize.underscore}".freeze
+ @partial_path = "#{@cache_key}/#{ActiveSupport::Inflector.underscore(ActiveSupport::Inflector.demodulize(self))}".freeze
end
end
end
diff --git a/activesupport/lib/active_support/core_ext/module/setup.rb b/activesupport/lib/active_support/core_ext/module/setup.rb
deleted file mode 100644
index e6dfd0cf56..0000000000
--- a/activesupport/lib/active_support/core_ext/module/setup.rb
+++ /dev/null
@@ -1,26 +0,0 @@
-class Module
- attr_accessor :_setup_block
- attr_accessor :_dependencies
-
- def setup(&blk)
- @_setup_block = blk
- end
-
- def use(mod)
- return if self < mod
-
- (mod._dependencies || []).each do |dep|
- use dep
- end
- # raise "Circular dependencies" if self < mod
- include mod
- extend mod.const_get("ClassMethods") if mod.const_defined?("ClassMethods")
- class_eval(&mod._setup_block) if mod._setup_block
- end
-
- def depends_on(mod)
- return if self < mod
- @_dependencies ||= []
- @_dependencies << mod
- end
-end \ No newline at end of file
diff --git a/activesupport/lib/active_support/core_ext/module/synchronization.rb b/activesupport/lib/active_support/core_ext/module/synchronization.rb
index 069db3fed0..f72d512340 100644
--- a/activesupport/lib/active_support/core_ext/module/synchronization.rb
+++ b/activesupport/lib/active_support/core_ext/module/synchronization.rb
@@ -1,3 +1,5 @@
+require 'active_support/core_ext/module/aliasing'
+
class Module
# Synchronize access around a method, delegating synchronization to a
# particular mutex. A mutex (either a Mutex, or any object that responds to
diff --git a/activesupport/lib/active_support/core_ext/numeric/time.rb b/activesupport/lib/active_support/core_ext/numeric/time.rb
index 2955e8ff1d..d1062805c5 100644
--- a/activesupport/lib/active_support/core_ext/numeric/time.rb
+++ b/activesupport/lib/active_support/core_ext/numeric/time.rb
@@ -1,3 +1,5 @@
+require 'active_support/duration'
+
class Numeric
# Enables the use of time calculations and declarations, like 45.minutes + 2.hours + 4.years.
#
diff --git a/activesupport/lib/active_support/core_ext/object.rb b/activesupport/lib/active_support/core_ext/object.rb
index 96385d2b87..04e8f06b3d 100644
--- a/activesupport/lib/active_support/core_ext/object.rb
+++ b/activesupport/lib/active_support/core_ext/object.rb
@@ -1,3 +1,4 @@
+require 'active_support/core_ext/object/acts_like'
require 'active_support/core_ext/object/blank'
require 'active_support/core_ext/object/duplicable'
require 'active_support/core_ext/object/try'
diff --git a/activesupport/lib/active_support/core_ext/object/conversions.rb b/activesupport/lib/active_support/core_ext/object/conversions.rb
index 278b856c45..638f0decc1 100644
--- a/activesupport/lib/active_support/core_ext/object/conversions.rb
+++ b/activesupport/lib/active_support/core_ext/object/conversions.rb
@@ -1,3 +1,6 @@
+require 'active_support/core_ext/array/conversions'
+require 'active_support/core_ext/hash/conversions'
+
class Object
# Alias of <tt>to_s</tt>.
def to_param
diff --git a/activesupport/lib/active_support/core_ext/object/misc.rb b/activesupport/lib/active_support/core_ext/object/misc.rb
index fb1bcdb98f..80011dfbed 100644
--- a/activesupport/lib/active_support/core_ext/object/misc.rb
+++ b/activesupport/lib/active_support/core_ext/object/misc.rb
@@ -1,80 +1,3 @@
-class Object
- # Returns +value+ after yielding +value+ to the block. This simplifies the
- # process of constructing an object, performing work on the object, and then
- # returning the object from a method. It is a Ruby-ized realization of the K
- # combinator, courtesy of Mikael Brockman.
- #
- # ==== Examples
- #
- # # Without returning
- # def foo
- # values = []
- # values << "bar"
- # values << "baz"
- # return values
- # end
- #
- # foo # => ['bar', 'baz']
- #
- # # returning with a local variable
- # def foo
- # returning values = [] do
- # values << 'bar'
- # values << 'baz'
- # end
- # end
- #
- # foo # => ['bar', 'baz']
- #
- # # returning with a block argument
- # def foo
- # returning [] do |values|
- # values << 'bar'
- # values << 'baz'
- # end
- # end
- #
- # foo # => ['bar', 'baz']
- def returning(value)
- yield(value)
- value
- end
-
- # Yields <code>x</code> to the block, and then returns <code>x</code>.
- # The primary purpose of this method is to "tap into" a method chain,
- # in order to perform operations on intermediate results within the chain.
- #
- # (1..10).tap { |x| puts "original: #{x.inspect}" }.to_a.
- # tap { |x| puts "array: #{x.inspect}" }.
- # select { |x| x%2 == 0 }.
- # tap { |x| puts "evens: #{x.inspect}" }.
- # map { |x| x*x }.
- # tap { |x| puts "squares: #{x.inspect}" }
- def tap
- yield self
- self
- end unless Object.respond_to?(:tap)
-
- # An elegant way to factor duplication out of options passed to a series of
- # method calls. Each method called in the block, with the block variable as
- # the receiver, will have its options merged with the default +options+ hash
- # provided. Each method called on the block variable must take an options
- # hash as its final argument.
- #
- # with_options :order => 'created_at', :class_name => 'Comment' do |post|
- # post.has_many :comments, :conditions => ['approved = ?', true], :dependent => :delete_all
- # post.has_many :unapproved_comments, :conditions => ['approved = ?', false]
- # post.has_many :all_comments
- # end
- #
- # Can also be used with an explicit receiver:
- #
- # map.with_options :controller => "people" do |people|
- # people.connect "/people", :action => "index"
- # people.connect "/people/:id", :action => "show"
- # end
- #
- def with_options(options)
- yield ActiveSupport::OptionMerger.new(self, options)
- end
-end
+require 'active_support/core_ext/object/returning'
+require 'active_support/core_ext/object/tap'
+require 'active_support/core_ext/object/with_options'
diff --git a/activesupport/lib/active_support/core_ext/object/returning.rb b/activesupport/lib/active_support/core_ext/object/returning.rb
new file mode 100644
index 0000000000..0dc2e1266a
--- /dev/null
+++ b/activesupport/lib/active_support/core_ext/object/returning.rb
@@ -0,0 +1,42 @@
+class Object
+ # Returns +value+ after yielding +value+ to the block. This simplifies the
+ # process of constructing an object, performing work on the object, and then
+ # returning the object from a method. It is a Ruby-ized realization of the K
+ # combinator, courtesy of Mikael Brockman.
+ #
+ # ==== Examples
+ #
+ # # Without returning
+ # def foo
+ # values = []
+ # values << "bar"
+ # values << "baz"
+ # return values
+ # end
+ #
+ # foo # => ['bar', 'baz']
+ #
+ # # returning with a local variable
+ # def foo
+ # returning values = [] do
+ # values << 'bar'
+ # values << 'baz'
+ # end
+ # end
+ #
+ # foo # => ['bar', 'baz']
+ #
+ # # returning with a block argument
+ # def foo
+ # returning [] do |values|
+ # values << 'bar'
+ # values << 'baz'
+ # end
+ # end
+ #
+ # foo # => ['bar', 'baz']
+ def returning(value)
+ yield(value)
+ value
+ end
+end
diff --git a/activesupport/lib/active_support/core_ext/object/tap.rb b/activesupport/lib/active_support/core_ext/object/tap.rb
new file mode 100644
index 0000000000..db7e715e2d
--- /dev/null
+++ b/activesupport/lib/active_support/core_ext/object/tap.rb
@@ -0,0 +1,16 @@
+class Object
+ # Yields <code>x</code> to the block, and then returns <code>x</code>.
+ # The primary purpose of this method is to "tap into" a method chain,
+ # in order to perform operations on intermediate results within the chain.
+ #
+ # (1..10).tap { |x| puts "original: #{x.inspect}" }.to_a.
+ # tap { |x| puts "array: #{x.inspect}" }.
+ # select { |x| x%2 == 0 }.
+ # tap { |x| puts "evens: #{x.inspect}" }.
+ # map { |x| x*x }.
+ # tap { |x| puts "squares: #{x.inspect}" }
+ def tap
+ yield self
+ self
+ end unless Object.respond_to?(:tap)
+end
diff --git a/activesupport/lib/active_support/core_ext/object/with_options.rb b/activesupport/lib/active_support/core_ext/object/with_options.rb
new file mode 100644
index 0000000000..dd38b7d261
--- /dev/null
+++ b/activesupport/lib/active_support/core_ext/object/with_options.rb
@@ -0,0 +1,24 @@
+class Object
+ # An elegant way to factor duplication out of options passed to a series of
+ # method calls. Each method called in the block, with the block variable as
+ # the receiver, will have its options merged with the default +options+ hash
+ # provided. Each method called on the block variable must take an options
+ # hash as its final argument.
+ #
+ # with_options :order => 'created_at', :class_name => 'Comment' do |post|
+ # post.has_many :comments, :conditions => ['approved = ?', true], :dependent => :delete_all
+ # post.has_many :unapproved_comments, :conditions => ['approved = ?', false]
+ # post.has_many :all_comments
+ # end
+ #
+ # Can also be used with an explicit receiver:
+ #
+ # map.with_options :controller => "people" do |people|
+ # people.connect "/people", :action => "index"
+ # people.connect "/people/:id", :action => "show"
+ # end
+ #
+ def with_options(options)
+ yield ActiveSupport::OptionMerger.new(self, options)
+ end
+end
diff --git a/activesupport/lib/active_support/core_ext/range/blockless_step.rb b/activesupport/lib/active_support/core_ext/range/blockless_step.rb
index f4792d03b7..db42ef5c47 100644
--- a/activesupport/lib/active_support/core_ext/range/blockless_step.rb
+++ b/activesupport/lib/active_support/core_ext/range/blockless_step.rb
@@ -1,3 +1,5 @@
+require 'active_support/core_ext/module/aliasing'
+
class Range
begin
(1..2).step
diff --git a/activesupport/lib/active_support/core_ext/string/conversions.rb b/activesupport/lib/active_support/core_ext/string/conversions.rb
index 39c2b1b8ed..2b9f8c70f6 100644
--- a/activesupport/lib/active_support/core_ext/string/conversions.rb
+++ b/activesupport/lib/active_support/core_ext/string/conversions.rb
@@ -1,10 +1,11 @@
require 'date'
+require 'active_support/core_ext/time/calculations'
class String
# 'a'.ord == 'a'[0] for Ruby 1.9 forward compatibility.
def ord
self[0]
- end if RUBY_VERSION < '1.9'
+ end unless method_defined?(:ord)
# Form can be either :utc (default) or :local.
def to_time(form = :utc)
diff --git a/activesupport/lib/active_support/core_ext/string/iterators.rb b/activesupport/lib/active_support/core_ext/string/iterators.rb
index 472de7bc24..2f8aa84024 100644
--- a/activesupport/lib/active_support/core_ext/string/iterators.rb
+++ b/activesupport/lib/active_support/core_ext/string/iterators.rb
@@ -1,11 +1,10 @@
unless '1.9'.respond_to?(:each_char)
- autoload :StringScanner, 'strscan' unless defined? :StringScanner
-
class String
# Yields a single-character string for each character in the string.
# When $KCODE = 'UTF8', multi-byte characters are yielded appropriately.
def each_char
- scanner, char = StringScanner.new(self), /./mu
+ require 'strscan' unless defined? ::StringScanner
+ scanner, char = ::StringScanner.new(self), /./mu
while c = scanner.scan(char)
yield c
end
diff --git a/activesupport/lib/active_support/core_ext/string/multibyte.rb b/activesupport/lib/active_support/core_ext/string/multibyte.rb
index 0f0dfb2443..13208c6ee2 100644
--- a/activesupport/lib/active_support/core_ext/string/multibyte.rb
+++ b/activesupport/lib/active_support/core_ext/string/multibyte.rb
@@ -1,4 +1,5 @@
# encoding: utf-8
+require 'active_support/multibyte'
class String
unless '1.9'.respond_to?(:force_encoding)
diff --git a/activesupport/lib/active_support/core_ext/symbol.rb b/activesupport/lib/active_support/core_ext/symbol.rb
index 520369452b..c103cd9dcf 100644
--- a/activesupport/lib/active_support/core_ext/symbol.rb
+++ b/activesupport/lib/active_support/core_ext/symbol.rb
@@ -1,14 +1 @@
-class Symbol
- # Turns the symbol into a simple proc, which is especially useful for enumerations. Examples:
- #
- # # The same as people.collect { |p| p.name }
- # people.collect(&:name)
- #
- # # The same as people.select { |p| p.manager? }.collect { |p| p.salary }
- # people.select(&:manager?).collect(&:salary)
- #
- # This is a builtin method in Ruby 1.8.7 and later.
- def to_proc
- Proc.new { |*args| args.shift.__send__(self, *args) }
- end unless :to_proc.respond_to?(:to_proc)
-end
+require 'active_support/core_ext/symbol/to_proc'
diff --git a/activesupport/lib/active_support/core_ext/symbol/to_proc.rb b/activesupport/lib/active_support/core_ext/symbol/to_proc.rb
new file mode 100644
index 0000000000..520369452b
--- /dev/null
+++ b/activesupport/lib/active_support/core_ext/symbol/to_proc.rb
@@ -0,0 +1,14 @@
+class Symbol
+ # Turns the symbol into a simple proc, which is especially useful for enumerations. Examples:
+ #
+ # # The same as people.collect { |p| p.name }
+ # people.collect(&:name)
+ #
+ # # The same as people.select { |p| p.manager? }.collect { |p| p.salary }
+ # people.select(&:manager?).collect(&:salary)
+ #
+ # This is a builtin method in Ruby 1.8.7 and later.
+ def to_proc
+ Proc.new { |*args| args.shift.__send__(self, *args) }
+ end unless :to_proc.respond_to?(:to_proc)
+end
diff --git a/activesupport/lib/active_support/core_ext/time/conversions.rb b/activesupport/lib/active_support/core_ext/time/conversions.rb
index 18261e139f..6d9c080442 100644
--- a/activesupport/lib/active_support/core_ext/time/conversions.rb
+++ b/activesupport/lib/active_support/core_ext/time/conversions.rb
@@ -63,13 +63,13 @@ class Time
# your_time.to_date # => Tue, 13 Jan 2009
def to_date
::Date.new(year, month, day)
- end
+ end unless method_defined?(:to_date)
# A method to keep Time, Date and DateTime instances interchangeable on conversions.
# In this case, it simply returns +self+.
def to_time
self
- end
+ end unless method_defined?(:to_time)
# Converts a Time instance to a Ruby DateTime instance, preserving UTC offset.
#
@@ -80,5 +80,5 @@ class Time
# your_time.to_datetime # => Tue, 13 Jan 2009 13:13:03 -0500
def to_datetime
::DateTime.civil(year, month, day, hour, min, sec, Rational(utc_offset, 86400))
- end
+ end unless method_defined?(:to_datetime)
end
diff --git a/activesupport/lib/active_support/dependencies.rb b/activesupport/lib/active_support/dependencies.rb
index 41b7e00c0c..855b720ef1 100644
--- a/activesupport/lib/active_support/dependencies.rb
+++ b/activesupport/lib/active_support/dependencies.rb
@@ -1,10 +1,13 @@
require 'set'
-require 'active_support/inflector'
-require 'active_support/core_ext/name_error'
-require 'active_support/core_ext/object/blank'
+require 'thread'
require 'active_support/core_ext/module/aliasing'
require 'active_support/core_ext/module/attribute_accessors'
require 'active_support/core_ext/module/introspection'
+require 'active_support/core_ext/object/blank'
+require 'active_support/core_ext/load_error'
+require 'active_support/core_ext/name_error'
+require 'active_support/core_ext/string/starts_ends_with'
+require 'active_support/inflector'
module ActiveSupport #:nodoc:
module Dependencies #:nodoc:
diff --git a/activesupport/lib/active_support/dependency_module.rb b/activesupport/lib/active_support/dependency_module.rb
new file mode 100644
index 0000000000..6847c0f86a
--- /dev/null
+++ b/activesupport/lib/active_support/dependency_module.rb
@@ -0,0 +1,17 @@
+module ActiveSupport
+ module DependencyModule
+ def append_features(base)
+ return false if base < self
+ (@_dependencies ||= []).each { |dep| base.send(:include, dep) }
+ super
+ end
+
+ def depends_on(*mods)
+ mods.each do |mod|
+ next if self < mod
+ @_dependencies ||= []
+ @_dependencies << mod
+ end
+ end
+ end
+end
diff --git a/activesupport/lib/active_support/deprecation/method_wrappers.rb b/activesupport/lib/active_support/deprecation/method_wrappers.rb
index b35d4daf9a..b9eb539aa7 100644
--- a/activesupport/lib/active_support/deprecation/method_wrappers.rb
+++ b/activesupport/lib/active_support/deprecation/method_wrappers.rb
@@ -1,4 +1,5 @@
require 'active_support/core_ext/module/deprecation'
+require 'active_support/core_ext/module/aliasing'
module ActiveSupport
class << Deprecation
diff --git a/activesupport/lib/active_support/deprecation/proxy_wrappers.rb b/activesupport/lib/active_support/deprecation/proxy_wrappers.rb
index 1c268d0d9c..dec56715be 100644
--- a/activesupport/lib/active_support/deprecation/proxy_wrappers.rb
+++ b/activesupport/lib/active_support/deprecation/proxy_wrappers.rb
@@ -1,7 +1,9 @@
+require 'active_support/inflector'
+
module ActiveSupport
module Deprecation
class DeprecationProxy #:nodoc:
- instance_methods.each { |m| undef_method m unless m =~ /^__/ }
+ instance_methods.each { |m| undef_method m unless m =~ /^__|^object_id$/ }
# Don't give a deprecation warning on inspect since test/unit and error
# logs rely on it for diagnostics.
@@ -61,7 +63,7 @@ module ActiveSupport
private
def target
- @new_const.to_s.constantize
+ ActiveSupport::Inflector.constantize(@new_const.to_s)
end
def warn(callstack, called, args)
diff --git a/activesupport/lib/active_support/duration.rb b/activesupport/lib/active_support/duration.rb
index f64661c5b1..a33586f77f 100644
--- a/activesupport/lib/active_support/duration.rb
+++ b/activesupport/lib/active_support/duration.rb
@@ -1,4 +1,5 @@
require 'active_support/basic_object'
+require 'active_support/core_ext/array/conversions'
module ActiveSupport
# Provides accurate date and time measurements using Date#advance and
diff --git a/activesupport/lib/active_support/inflector.rb b/activesupport/lib/active_support/inflector.rb
index 614afa1bd6..ff70d6d76e 100644
--- a/activesupport/lib/active_support/inflector.rb
+++ b/activesupport/lib/active_support/inflector.rb
@@ -1,6 +1,7 @@
# encoding: utf-8
require 'iconv'
-
+require 'active_support/core_ext/object/blank'
+require 'active_support/core_ext/string/access'
require 'active_support/core_ext/string/multibyte'
module ActiveSupport
diff --git a/activesupport/lib/active_support/json.rb b/activesupport/lib/active_support/json.rb
index 2bdb4a7b11..6d845182fb 100644
--- a/activesupport/lib/active_support/json.rb
+++ b/activesupport/lib/active_support/json.rb
@@ -1,11 +1,74 @@
+require 'active_support/core_ext/module/delegation'
+require 'active_support/core_ext/module/attribute_accessors'
+
module ActiveSupport
# If true, use ISO 8601 format for dates and times. Otherwise, fall back to the Active Support legacy format.
mattr_accessor :use_standard_json_time_format
+ # Look for and parse json strings that look like ISO 8601 times.
+ mattr_accessor :parse_json_times
- class << self
- def escape_html_entities_in_json
- @escape_html_entities_in_json
+ module JSON
+ # matches YAML-formatted dates
+ DATE_REGEX = /^(?:\d{4}-\d{2}-\d{2}|\d{4}-\d{1,2}-\d{1,2}[ \t]+\d{1,2}:\d{2}:\d{2}(\.[0-9]*)?(([ \t]*)Z|[-+]\d{2}?(:\d{2})?))$/
+
+ module Encoding #:nodoc:
+ mattr_accessor :escape_regex
+
+ ESCAPED_CHARS = {
+ "\010" => '\b',
+ "\f" => '\f',
+ "\n" => '\n',
+ "\r" => '\r',
+ "\t" => '\t',
+ '"' => '\"',
+ '\\' => '\\\\',
+ '>' => '\u003E',
+ '<' => '\u003C',
+ '&' => '\u0026'
+ }
+
+ def self.escape(string)
+ string = string.dup.force_encoding(::Encoding::BINARY) if string.respond_to?(:force_encoding)
+ json = string.gsub(escape_regex) { |s| ESCAPED_CHARS[s] }.
+ gsub(/([\xC0-\xDF][\x80-\xBF]|
+ [\xE0-\xEF][\x80-\xBF]{2}|
+ [\xF0-\xF7][\x80-\xBF]{3})+/nx) { |s|
+ s.unpack("U*").pack("n*").unpack("H*")[0].gsub(/.{4}/, '\\\\u\&')
+ }
+ %("#{json}")
+ end
+ end
+
+ class << self
+ delegate :decode, :to => :backend
+
+ def backend
+ unless defined? @backend
+ self.backend = defined?(::JSON) ? "JSONGem" : "Yaml"
+ end
+ @backend
+ end
+
+ def backend=(name)
+ if name.is_a?(Module)
+ @backend = name
+ else
+ require "active_support/json/backends/#{name.to_s.downcase}.rb"
+ @backend = ActiveSupport::JSON::Backends::const_get(name)
+ end
+ end
+
+ def with_backend(name)
+ old_backend, self.backend = backend, name
+ yield
+ ensure
+ self.backend = old_backend
+ end
end
+ end
+
+ class << self
+ attr_reader :escape_html_entities_in_json
def escape_html_entities_in_json=(value)
ActiveSupport::JSON::Encoding.escape_regex = \
@@ -19,5 +82,6 @@ module ActiveSupport
end
end
+ActiveSupport.escape_html_entities_in_json = true
+
require 'active_support/json/encoding'
-require 'active_support/json/decoding'
diff --git a/activesupport/lib/active_support/json/backends/jsongem.rb b/activesupport/lib/active_support/json/backends/jsongem.rb
new file mode 100644
index 0000000000..649e6301d1
--- /dev/null
+++ b/activesupport/lib/active_support/json/backends/jsongem.rb
@@ -0,0 +1,41 @@
+require 'json' unless defined?(JSON)
+
+module ActiveSupport
+ module JSON
+ ParseError = ::JSON::ParserError unless const_defined?(:ParseError)
+
+ module Backends
+ module JSONGem
+ extend self
+
+ # Parses a JSON string or IO and convert it into an object
+ def decode(json)
+ if json.respond_to?(:read)
+ json = json.read
+ end
+ data = ::JSON.parse(json)
+ if ActiveSupport.parse_json_times
+ convert_dates_from(data)
+ else
+ data
+ end
+ end
+
+ private
+ def convert_dates_from(data)
+ case data
+ when DATE_REGEX
+ DateTime.parse(data)
+ when Array
+ data.map! { |d| convert_dates_from(d) }
+ when Hash
+ data.each do |key, value|
+ data[key] = convert_dates_from(value)
+ end
+ else data
+ end
+ end
+ end
+ end
+ end
+end \ No newline at end of file
diff --git a/activesupport/lib/active_support/json/backends/yaml.rb b/activesupport/lib/active_support/json/backends/yaml.rb
new file mode 100644
index 0000000000..667016f45d
--- /dev/null
+++ b/activesupport/lib/active_support/json/backends/yaml.rb
@@ -0,0 +1,88 @@
+require 'active_support/core_ext/string/starts_ends_with'
+
+module ActiveSupport
+ module JSON
+ unless const_defined?(:ParseError)
+ class ParseError < StandardError
+ end
+ end
+
+ module Backends
+ module Yaml
+ extend self
+
+ # Parses a JSON string or IO and converts it into an object
+ def decode(json)
+ if json.respond_to?(:read)
+ json = json.read
+ end
+ YAML.load(convert_json_to_yaml(json))
+ rescue ArgumentError => e
+ raise ParseError, "Invalid JSON string"
+ end
+
+ protected
+ # Ensure that ":" and "," are always followed by a space
+ def convert_json_to_yaml(json) #:nodoc:
+ require 'strscan' unless defined? ::StringScanner
+ scanner, quoting, marks, pos, times = ::StringScanner.new(json), false, [], nil, []
+ while scanner.scan_until(/(\\['"]|['":,\\]|\\.)/)
+ case char = scanner[1]
+ when '"', "'"
+ if !quoting
+ quoting = char
+ pos = scanner.pos
+ elsif quoting == char
+ if json[pos..scanner.pos-2] =~ DATE_REGEX
+ # found a date, track the exact positions of the quotes so we can remove them later.
+ # oh, and increment them for each current mark, each one is an extra padded space that bumps
+ # the position in the final YAML output
+ total_marks = marks.size
+ times << pos+total_marks << scanner.pos+total_marks
+ end
+ quoting = false
+ end
+ when ":",","
+ marks << scanner.pos - 1 unless quoting
+ end
+ end
+
+ if marks.empty?
+ json.gsub(/\\([\\\/]|u[[:xdigit:]]{4})/) do
+ ustr = $1
+ if ustr.start_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).gsub(/\\([\\\/]|u[[:xdigit:]]{4})/) do
+ ustr = $1
+ if ustr.start_with?('u')
+ [ustr[1..-1].to_i(16)].pack("U")
+ elsif ustr == '\\'
+ '\\\\'
+ else
+ ustr
+ end
+ end
+ end
+ output = output * " "
+
+ times.each { |i| output[i-1] = ' ' }
+ output.gsub!(/\\\//, '/')
+ output
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/activesupport/lib/active_support/json/decoding.rb b/activesupport/lib/active_support/json/decoding.rb
deleted file mode 100644
index c66500aa9c..0000000000
--- a/activesupport/lib/active_support/json/decoding.rb
+++ /dev/null
@@ -1,84 +0,0 @@
-autoload :YAML, 'yaml' unless defined? YAML
-autoload :StringScanner, 'strscan' unless defined? StringScanner
-
-require 'active_support/core_ext/string/starts_ends_with'
-
-module ActiveSupport
- module JSON
- class ParseError < StandardError
- end
-
- class << self
- # Converts a JSON string into a Ruby object.
- def decode(json)
- YAML.load(convert_json_to_yaml(json))
- rescue ArgumentError => e
- raise ParseError, "Invalid JSON string"
- end
-
- protected
- # matches YAML-formatted dates
- DATE_REGEX = /^(?:\d{4}-\d{2}-\d{2}|\d{4}-\d{1,2}-\d{1,2}[ \t]+\d{1,2}:\d{2}:\d{2}(\.[0-9]*)?(([ \t]*)Z|[-+]\d{2}?(:\d{2})?)?)$/
-
- # Ensure that ":" and "," are always followed by a space
- def convert_json_to_yaml(json) #:nodoc:
- scanner, quoting, marks, pos, times = StringScanner.new(json), false, [], nil, []
- while scanner.scan_until(/(\\['"]|['":,\\]|\\.)/)
- case char = scanner[1]
- when '"', "'"
- if !quoting
- quoting = char
- pos = scanner.pos
- elsif quoting == char
- if json[pos..scanner.pos-2] =~ DATE_REGEX
- # found a date, track the exact positions of the quotes so we can remove them later.
- # oh, and increment them for each current mark, each one is an extra padded space that bumps
- # the position in the final YAML output
- total_marks = marks.size
- times << pos+total_marks << scanner.pos+total_marks
- end
- quoting = false
- end
- when ":",","
- marks << scanner.pos - 1 unless quoting
- end
- end
-
- if marks.empty?
- json.gsub(/\\([\\\/]|u[[:xdigit:]]{4})/) do
- ustr = $1
- if ustr.start_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).gsub(/\\([\\\/]|u[[:xdigit:]]{4})/) do
- ustr = $1
- if ustr.start_with?('u')
- [ustr[1..-1].to_i(16)].pack("U")
- elsif ustr == '\\'
- '\\\\'
- else
- ustr
- end
- end
- end
- output = output * " "
-
- times.each { |i| output[i-1] = ' ' }
- output.gsub!(/\\\//, '/')
- output
- end
- end
- end
- end
-end
diff --git a/activesupport/lib/active_support/json/encoders/date.rb b/activesupport/lib/active_support/json/encoders/date.rb
index cc84de1388..9adb3c20e2 100644
--- a/activesupport/lib/active_support/json/encoders/date.rb
+++ b/activesupport/lib/active_support/json/encoders/date.rb
@@ -1,21 +1,22 @@
class Date
- # Returns a JSON string representing the date. If ActiveSupport.use_standard_json_time_format is set to true, the
- # ISO 8601 format is used.
- #
- # ==== Examples
- #
- # # With ActiveSupport.use_standard_json_time_format = true
- # Date.new(2005,2,1).to_json
- # # => "2005-02-01"
- #
- # # With ActiveSupport.use_standard_json_time_format = false
- # Date.new(2005,2,1).to_json
- # # => "2005/02/01"
- def to_json(options = nil)
- if ActiveSupport.use_standard_json_time_format
- %("#{strftime("%Y-%m-%d")}")
- else
- %("#{strftime("%Y/%m/%d")}")
+ private
+ # Returns a JSON string representing the date. If ActiveSupport.use_standard_json_time_format is set to true, the
+ # ISO 8601 format is used.
+ #
+ # ==== Examples
+ #
+ # # With ActiveSupport.use_standard_json_time_format = true
+ # Date.new(2005,2,1).to_json
+ # # => "2005-02-01"
+ #
+ # # With ActiveSupport.use_standard_json_time_format = false
+ # Date.new(2005,2,1).to_json
+ # # => "2005/02/01"
+ def rails_to_json(*)
+ if ActiveSupport.use_standard_json_time_format
+ %("#{strftime("%Y-%m-%d")}")
+ else
+ %("#{strftime("%Y/%m/%d")}")
+ end
end
- end
end
diff --git a/activesupport/lib/active_support/json/encoders/date_time.rb b/activesupport/lib/active_support/json/encoders/date_time.rb
index 6c85824105..3a29292b24 100644
--- a/activesupport/lib/active_support/json/encoders/date_time.rb
+++ b/activesupport/lib/active_support/json/encoders/date_time.rb
@@ -1,21 +1,22 @@
class DateTime
- # Returns a JSON string representing the datetime. If ActiveSupport.use_standard_json_time_format is set to true, the
- # ISO 8601 format is used.
- #
- # ==== Examples
- #
- # # With ActiveSupport.use_standard_json_time_format = true
- # DateTime.civil(2005,2,1,15,15,10).to_json
- # # => "2005-02-01T15:15:10+00:00"
- #
- # # With ActiveSupport.use_standard_json_time_format = false
- # DateTime.civil(2005,2,1,15,15,10).to_json
- # # => "2005/02/01 15:15:10 +0000"
- def to_json(options = nil)
- if ActiveSupport.use_standard_json_time_format
- xmlschema.inspect
- else
- strftime('"%Y/%m/%d %H:%M:%S %z"')
+ private
+ # Returns a JSON string representing the datetime. If ActiveSupport.use_standard_json_time_format is set to true, the
+ # ISO 8601 format is used.
+ #
+ # ==== Examples
+ #
+ # # With ActiveSupport.use_standard_json_time_format = true
+ # DateTime.civil(2005,2,1,15,15,10).to_json
+ # # => "2005-02-01T15:15:10+00:00"
+ #
+ # # With ActiveSupport.use_standard_json_time_format = false
+ # DateTime.civil(2005,2,1,15,15,10).to_json
+ # # => "2005/02/01 15:15:10 +0000"
+ def rails_to_json(*)
+ if ActiveSupport.use_standard_json_time_format
+ xmlschema.inspect
+ else
+ strftime('"%Y/%m/%d %H:%M:%S %z"')
+ end
end
- end
end
diff --git a/activesupport/lib/active_support/json/encoders/enumerable.rb b/activesupport/lib/active_support/json/encoders/enumerable.rb
index 881b1d62c1..898990a59c 100644
--- a/activesupport/lib/active_support/json/encoders/enumerable.rb
+++ b/activesupport/lib/active_support/json/encoders/enumerable.rb
@@ -1,12 +1,13 @@
module Enumerable
- # Returns a JSON string representing the enumerable. Any +options+
- # given will be passed on to its elements. For example:
- #
- # users = User.find(:all)
- # # => users.to_json(:only => :name)
- #
- # will pass the <tt>:only => :name</tt> option to each user.
- def to_json(options = {}) #:nodoc:
- "[#{map { |value| ActiveSupport::JSON.encode(value, options) } * ', '}]"
- end
+ private
+ # Returns a JSON string representing the enumerable. Any +options+
+ # given will be passed on to its elements. For example:
+ #
+ # users = User.find(:all)
+ # # => users.to_json(:only => :name)
+ #
+ # will pass the <tt>:only => :name</tt> option to each user.
+ def rails_to_json(options = nil, *args) #:nodoc:
+ "[#{map { |value| ActiveSupport::JSON.encode(value, options, *args) } * ','}]"
+ end
end
diff --git a/activesupport/lib/active_support/json/encoders/false_class.rb b/activesupport/lib/active_support/json/encoders/false_class.rb
index bf0844334b..eb975fe542 100644
--- a/activesupport/lib/active_support/json/encoders/false_class.rb
+++ b/activesupport/lib/active_support/json/encoders/false_class.rb
@@ -1,5 +1,6 @@
class FalseClass
- def to_json(options = nil) #:nodoc:
- 'false'
- end
+ private
+ def rails_to_json(*)
+ 'false'
+ end
end
diff --git a/activesupport/lib/active_support/json/encoders/hash.rb b/activesupport/lib/active_support/json/encoders/hash.rb
index d87b880743..4771484843 100644
--- a/activesupport/lib/active_support/json/encoders/hash.rb
+++ b/activesupport/lib/active_support/json/encoders/hash.rb
@@ -1,48 +1,51 @@
require 'active_support/core_ext/array/wrap'
class Hash
- # Returns a JSON string representing the hash.
- #
- # Without any +options+, the returned JSON string will include all
- # the hash keys. For example:
- #
- # { :name => "Konata Izumi", 'age' => 16, 1 => 2 }.to_json
- # # => {"name": "Konata Izumi", "1": 2, "age": 16}
- #
- # The keys in the JSON string are unordered due to the nature of hashes.
- #
- # The <tt>:only</tt> and <tt>:except</tt> options can be used to limit the
- # attributes included, and will accept 1 or more hash keys to include/exclude.
- #
- # { :name => "Konata Izumi", 'age' => 16, 1 => 2 }.to_json(:only => [:name, 'age'])
- # # => {"name": "Konata Izumi", "age": 16}
- #
- # { :name => "Konata Izumi", 'age' => 16, 1 => 2 }.to_json(:except => 1)
- # # => {"name": "Konata Izumi", "age": 16}
- #
- # The +options+ also filter down to any hash values. This is particularly
- # useful for converting hashes containing ActiveRecord objects or any object
- # that responds to options in their <tt>to_json</tt> method. For example:
- #
- # users = User.find(:all)
- # { :users => users, :count => users.size }.to_json(:include => :posts)
- #
- # would pass the <tt>:include => :posts</tt> option to <tt>users</tt>,
- # allowing the posts association in the User model to be converted to JSON
- # as well.
- def to_json(options = {}) #:nodoc:
- hash_keys = self.keys
+ private
+ # Returns a JSON string representing the hash.
+ #
+ # Without any +options+, the returned JSON string will include all
+ # the hash keys. For example:
+ #
+ # { :name => "Konata Izumi", 'age' => 16, 1 => 2 }.to_json
+ # # => {"name": "Konata Izumi", "1": 2, "age": 16}
+ #
+ # The keys in the JSON string are unordered due to the nature of hashes.
+ #
+ # The <tt>:only</tt> and <tt>:except</tt> options can be used to limit the
+ # attributes included, and will accept 1 or more hash keys to include/exclude.
+ #
+ # { :name => "Konata Izumi", 'age' => 16, 1 => 2 }.to_json(:only => [:name, 'age'])
+ # # => {"name": "Konata Izumi", "age": 16}
+ #
+ # { :name => "Konata Izumi", 'age' => 16, 1 => 2 }.to_json(:except => 1)
+ # # => {"name": "Konata Izumi", "age": 16}
+ #
+ # The +options+ also filter down to any hash values. This is particularly
+ # useful for converting hashes containing ActiveRecord objects or any object
+ # that responds to options in their <tt>to_json</tt> method. For example:
+ #
+ # users = User.find(:all)
+ # { :users => users, :count => users.size }.to_json(:include => :posts)
+ #
+ # would pass the <tt>:include => :posts</tt> option to <tt>users</tt>,
+ # allowing the posts association in the User model to be converted to JSON
+ # as well.
+ def rails_to_json(options = nil, *args) #:nodoc:
+ hash_keys = self.keys
- if except = options[:except]
- hash_keys = hash_keys - Array.wrap(except)
- elsif only = options[:only]
- hash_keys = hash_keys & Array.wrap(only)
- end
+ if options
+ if except = options[:except]
+ hash_keys = hash_keys - Array.wrap(except)
+ elsif only = options[:only]
+ hash_keys = hash_keys & Array.wrap(only)
+ end
+ end
- result = '{'
- result << hash_keys.map do |key|
- "#{ActiveSupport::JSON.encode(key.to_s)}: #{ActiveSupport::JSON.encode(self[key], options)}"
- end * ', '
- result << '}'
- end
+ result = '{'
+ result << hash_keys.map do |key|
+ "#{ActiveSupport::JSON.encode(key.to_s)}:#{ActiveSupport::JSON.encode(self[key], options, *args)}"
+ end * ','
+ result << '}'
+ end
end
diff --git a/activesupport/lib/active_support/json/encoders/nil_class.rb b/activesupport/lib/active_support/json/encoders/nil_class.rb
index 4763471ac4..8c51dba384 100644
--- a/activesupport/lib/active_support/json/encoders/nil_class.rb
+++ b/activesupport/lib/active_support/json/encoders/nil_class.rb
@@ -1,5 +1,6 @@
class NilClass
- def to_json(options = nil) #:nodoc:
- 'null'
- end
+ private
+ def rails_to_json(*)
+ 'null'
+ end
end
diff --git a/activesupport/lib/active_support/json/encoders/numeric.rb b/activesupport/lib/active_support/json/encoders/numeric.rb
index 38713fb369..c7cd0df1d7 100644
--- a/activesupport/lib/active_support/json/encoders/numeric.rb
+++ b/activesupport/lib/active_support/json/encoders/numeric.rb
@@ -1,5 +1,6 @@
class Numeric
- def to_json(options = nil) #:nodoc:
- to_s
- end
+ private
+ def rails_to_json(*)
+ to_s
+ end
end
diff --git a/activesupport/lib/active_support/json/encoders/object.rb b/activesupport/lib/active_support/json/encoders/object.rb
index 0475967aee..9cc12d91ac 100644
--- a/activesupport/lib/active_support/json/encoders/object.rb
+++ b/activesupport/lib/active_support/json/encoders/object.rb
@@ -2,7 +2,12 @@ require 'active_support/core_ext/object/instance_variables'
class Object
# Dumps object in JSON (JavaScript Object Notation). See www.json.org for more info.
- def to_json(options = {})
- ActiveSupport::JSON.encode(instance_values, options)
+ def to_json(options = nil)
+ ActiveSupport::JSON.encode(self, options)
end
+
+ private
+ def rails_to_json(*args)
+ ActiveSupport::JSON.encode(instance_values, *args)
+ end
end
diff --git a/activesupport/lib/active_support/json/encoders/regexp.rb b/activesupport/lib/active_support/json/encoders/regexp.rb
index b6116b70b5..ee42db4d02 100644
--- a/activesupport/lib/active_support/json/encoders/regexp.rb
+++ b/activesupport/lib/active_support/json/encoders/regexp.rb
@@ -1,5 +1,6 @@
class Regexp
- def to_json(options = nil) #:nodoc:
- inspect
- end
+ private
+ def rails_to_json(*)
+ inspect
+ end
end
diff --git a/activesupport/lib/active_support/json/encoders/string.rb b/activesupport/lib/active_support/json/encoders/string.rb
index 5ef797955a..4a6b21c1c0 100644
--- a/activesupport/lib/active_support/json/encoders/string.rb
+++ b/activesupport/lib/active_support/json/encoders/string.rb
@@ -1,36 +1,6 @@
-module ActiveSupport
- module JSON
- module Encoding
- mattr_accessor :escape_regex
-
- ESCAPED_CHARS = {
- "\010" => '\b',
- "\f" => '\f',
- "\n" => '\n',
- "\r" => '\r',
- "\t" => '\t',
- '"' => '\"',
- '\\' => '\\\\',
- '>' => '\u003E',
- '<' => '\u003C',
- '&' => '\u0026'
- }
- end
- end
-end
-
-ActiveSupport.escape_html_entities_in_json = true
-
class String
- def to_json(options = nil) #:nodoc:
- json = '"' + gsub(ActiveSupport::JSON::Encoding.escape_regex) { |s|
- ActiveSupport::JSON::Encoding::ESCAPED_CHARS[s]
- }
- json.force_encoding('ascii-8bit') if respond_to?(:force_encoding)
- json.gsub(/([\xC0-\xDF][\x80-\xBF]|
- [\xE0-\xEF][\x80-\xBF]{2}|
- [\xF0-\xF7][\x80-\xBF]{3})+/nx) { |s|
- s.unpack("U*").pack("n*").unpack("H*")[0].gsub(/.{4}/, '\\\\u\&')
- } + '"'
- end
+ private
+ def rails_to_json(*)
+ ActiveSupport::JSON::Encoding.escape(self)
+ end
end
diff --git a/activesupport/lib/active_support/json/encoders/symbol.rb b/activesupport/lib/active_support/json/encoders/symbol.rb
index 485112f97c..d575350a4e 100644
--- a/activesupport/lib/active_support/json/encoders/symbol.rb
+++ b/activesupport/lib/active_support/json/encoders/symbol.rb
@@ -1,5 +1,6 @@
class Symbol
- def to_json(options = {}) #:nodoc:
- ActiveSupport::JSON.encode(to_s, options)
- end
+ private
+ def rails_to_json(*args)
+ ActiveSupport::JSON.encode(to_s, *args)
+ end
end
diff --git a/activesupport/lib/active_support/json/encoders/time.rb b/activesupport/lib/active_support/json/encoders/time.rb
index f45a0059e8..d434b9aace 100644
--- a/activesupport/lib/active_support/json/encoders/time.rb
+++ b/activesupport/lib/active_support/json/encoders/time.rb
@@ -1,21 +1,24 @@
+require 'active_support/core_ext/time/conversions'
+
class Time
- # Returns a JSON string representing the time. If ActiveSupport.use_standard_json_time_format is set to true, the
- # ISO 8601 format is used.
- #
- # ==== Examples
- #
- # # With ActiveSupport.use_standard_json_time_format = true
- # Time.utc(2005,2,1,15,15,10).to_json
- # # => "2005-02-01T15:15:10Z"
- #
- # # With ActiveSupport.use_standard_json_time_format = false
- # Time.utc(2005,2,1,15,15,10).to_json
- # # => "2005/02/01 15:15:10 +0000"
- def to_json(options = nil)
- if ActiveSupport.use_standard_json_time_format
- xmlschema.inspect
- else
- %("#{strftime("%Y/%m/%d %H:%M:%S")} #{formatted_offset(false)}")
+ private
+ # Returns a JSON string representing the time. If ActiveSupport.use_standard_json_time_format is set to true, the
+ # ISO 8601 format is used.
+ #
+ # ==== Examples
+ #
+ # # With ActiveSupport.use_standard_json_time_format = true
+ # Time.utc(2005,2,1,15,15,10).to_json
+ # # => "2005-02-01T15:15:10Z"
+ #
+ # # With ActiveSupport.use_standard_json_time_format = false
+ # Time.utc(2005,2,1,15,15,10).to_json
+ # # => "2005/02/01 15:15:10 +0000"
+ def rails_to_json(*)
+ if ActiveSupport.use_standard_json_time_format
+ xmlschema.inspect
+ else
+ %("#{strftime("%Y/%m/%d %H:%M:%S")} #{formatted_offset(false)}")
+ end
end
- end
end
diff --git a/activesupport/lib/active_support/json/encoders/true_class.rb b/activesupport/lib/active_support/json/encoders/true_class.rb
index 037d812b3f..bc25a6db78 100644
--- a/activesupport/lib/active_support/json/encoders/true_class.rb
+++ b/activesupport/lib/active_support/json/encoders/true_class.rb
@@ -1,5 +1,6 @@
class TrueClass
- def to_json(options = nil) #:nodoc:
- 'true'
- end
+ private
+ def rails_to_json(*)
+ 'true'
+ end
end
diff --git a/activesupport/lib/active_support/json/encoding.rb b/activesupport/lib/active_support/json/encoding.rb
index aaaa3cdfd2..5fefe5b88b 100644
--- a/activesupport/lib/active_support/json/encoding.rb
+++ b/activesupport/lib/active_support/json/encoding.rb
@@ -4,11 +4,13 @@ module ActiveSupport
end
# Converts a Ruby object into a JSON string.
- def self.encode(value, options = {})
- seen = (options[:seen] ||= [])
- raise CircularReferenceError, 'object references itself' if seen.include?(value)
+ def self.encode(value, options = nil, seen = nil)
+ seen ||= []
+ if seen.any? { |object| object.equal?(value) }
+ raise CircularReferenceError, 'object references itself'
+ end
seen << value
- value.send(:to_json, options)
+ value.__send__(:rails_to_json, options, seen)
ensure
seen.pop
end
diff --git a/activesupport/lib/active_support/json/variable.rb b/activesupport/lib/active_support/json/variable.rb
index 7fd23b0a9e..daa7449b71 100644
--- a/activesupport/lib/active_support/json/variable.rb
+++ b/activesupport/lib/active_support/json/variable.rb
@@ -2,9 +2,10 @@ module ActiveSupport
module JSON
# A string that returns itself as its JSON-encoded form.
class Variable < String
- def to_json(options=nil)
- self
- end
+ private
+ def rails_to_json(*)
+ self
+ end
end
end
end
diff --git a/activesupport/lib/active_support/memoizable.rb b/activesupport/lib/active_support/memoizable.rb
index 2b85fd7be4..fa6db683d4 100644
--- a/activesupport/lib/active_support/memoizable.rb
+++ b/activesupport/lib/active_support/memoizable.rb
@@ -1,3 +1,6 @@
+require 'active_support/core_ext/object/metaclass'
+require 'active_support/core_ext/module/aliasing'
+
module ActiveSupport
module SafelyMemoizable
def safely_memoize(*symbols)
diff --git a/activesupport/lib/active_support/multibyte.rb b/activesupport/lib/active_support/multibyte.rb
index 65a96af49a..d8d58f3bce 100644
--- a/activesupport/lib/active_support/multibyte.rb
+++ b/activesupport/lib/active_support/multibyte.rb
@@ -4,6 +4,8 @@ require 'active_support/multibyte/chars'
require 'active_support/multibyte/exceptions'
require 'active_support/multibyte/unicode_database'
+require 'active_support/core_ext/module/attribute_accessors'
+
module ActiveSupport #:nodoc:
module Multibyte
# A list of all available normalization forms. See http://www.unicode.org/reports/tr15/tr15-29.html for more
diff --git a/activesupport/lib/active_support/multibyte/chars.rb b/activesupport/lib/active_support/multibyte/chars.rb
index 60f082bcc1..96ed35f0e0 100644
--- a/activesupport/lib/active_support/multibyte/chars.rb
+++ b/activesupport/lib/active_support/multibyte/chars.rb
@@ -1,4 +1,5 @@
# encoding: utf-8
+require 'active_support/core_ext/string/behavior'
module ActiveSupport #:nodoc:
module Multibyte #:nodoc:
diff --git a/activesupport/lib/active_support/new_callbacks.rb b/activesupport/lib/active_support/new_callbacks.rb
index 356d70b650..f1d2ea7bb1 100644
--- a/activesupport/lib/active_support/new_callbacks.rb
+++ b/activesupport/lib/active_support/new_callbacks.rb
@@ -1,3 +1,6 @@
+require 'active_support/core_ext/array/wrap'
+require 'active_support/core_ext/class/inheritable_attributes'
+
module ActiveSupport
# Callbacks are hooks into the lifecycle of an object that allow you to trigger logic
# before or after an alteration of the object state.
@@ -284,6 +287,14 @@ module ActiveSupport
when Proc
@klass.send(:define_method, method_name, &filter)
method_name << (filter.arity == 1 ? "(self)" : "")
+ when Method
+ @klass.send(:define_method, "#{method_name}_method") { filter }
+ @klass.class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
+ def #{method_name}(&blk)
+ #{method_name}_method.call(self, &blk)
+ end
+ RUBY_EVAL
+ method_name
when String
@klass.class_eval <<-RUBY_EVAL
def #{method_name}
@@ -293,23 +304,39 @@ module ActiveSupport
method_name
else
kind, name = @kind, @name
- @klass.send(:define_method, method_name) do
- filter.send("#{kind}_#{name}", self)
+ @klass.send(:define_method, "#{method_name}_object") { filter }
+
+ if kind == :around
+ @klass.class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
+ def #{method_name}(&blk)
+ if :#{kind} == :around && #{method_name}_object.respond_to?(:filter)
+ #{method_name}_object.send("filter", self, &blk)
+ # TODO: Deprecate this
+ elsif #{method_name}_object.respond_to?(:before) && #{method_name}_object.respond_to?(:after)
+ should_continue = #{method_name}_object.before(self)
+ yield if should_continue
+ #{method_name}_object.after(self)
+ else
+ #{method_name}_object.send("#{kind}_#{name}", self, &blk)
+ end
+ end
+ RUBY_EVAL
+ else
+ @klass.class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
+ def #{method_name}(&blk)
+ if #{method_name}_object.respond_to?(:#{kind})
+ #{method_name}_object.#{kind}(self, &blk)
+ else
+ #{method_name}_object.send("#{kind}_#{name}", self, &blk)
+ end
+ end
+ RUBY_EVAL
end
method_name
end
end
end
- # This method_missing is supplied to catch callbacks with keys and create
- # the appropriate callback for future use.
- def method_missing(meth, *args, &blk)
- if meth.to_s =~ /_run__([\w:]+)__(\w+)__(\w+)__callbacks/
- return self.class._create_and_run_keyed_callback($1, $2.to_sym, $3.to_sym, self, &blk)
- end
- super
- end
-
# An Array with a compile method
class CallbackChain < Array
def initialize(symbol)
@@ -322,7 +349,7 @@ module ActiveSupport
each do |callback|
method << callback.start(key, options)
end
- method << "yield self if block_given?"
+ method << "yield self if block_given? && !halted"
reverse_each do |callback|
method << callback.end(key, options)
end
@@ -353,6 +380,7 @@ module ActiveSupport
str = <<-RUBY_EVAL
def _run_#{symbol}_callbacks(key = nil)
if key
+ key = key.hash.to_s.gsub(/-/, '_')
name = "_run__\#{self.class.name.split("::").last}__#{symbol}__\#{key}__callbacks"
if respond_to?(name)
@@ -445,7 +473,9 @@ module ActiveSupport
self._#{symbol}_callbacks.delete_if {|c| c.matches?(type, :#{symbol}, filter)}
Callback.new(filter, type, options.dup, self, :#{symbol})
end
- self._#{symbol}_callbacks.push(*filters)
+ options[:prepend] ?
+ self._#{symbol}_callbacks.unshift(*filters) :
+ self._#{symbol}_callbacks.push(*filters)
_define_runner(:#{symbol},
self._#{symbol}_callbacks.compile(nil, :terminator => _#{symbol}_terminator),
options)
diff --git a/activesupport/lib/active_support/ordered_hash.rb b/activesupport/lib/active_support/ordered_hash.rb
index fed8094a24..8d1c0f5160 100644
--- a/activesupport/lib/active_support/ordered_hash.rb
+++ b/activesupport/lib/active_support/ordered_hash.rb
@@ -10,6 +10,16 @@ module ActiveSupport
@keys = []
end
+ def self.[](*args)
+ ordered_hash = new
+ args.each_with_index { |val,ind|
+ # Only every second value is a key.
+ next if ind % 2 != 0
+ ordered_hash[val] = args[ind + 1]
+ }
+ ordered_hash
+ end
+
def initialize_copy(other)
super
# make a deep copy of keys
@@ -57,6 +67,10 @@ module ActiveSupport
self
end
+ def to_a
+ @keys.map { |key| [ key, self[key] ] }
+ end
+
def each_key
@keys.each { |key| yield key }
end
diff --git a/activesupport/lib/active_support/ruby/shim.rb b/activesupport/lib/active_support/ruby/shim.rb
new file mode 100644
index 0000000000..37c57c485a
--- /dev/null
+++ b/activesupport/lib/active_support/ruby/shim.rb
@@ -0,0 +1,24 @@
+# Backported Ruby builtins so you can code with the latest & greatest
+# but still run on any Ruby 1.8.x.
+#
+# Date next_year, next_month
+# DateTime to_date, to_datetime, xmlschema
+# Enumerable group_by, each_with_object, none?
+# Integer even?, odd?
+# Object tap
+# Process Process.daemon
+# REXML security fix
+# String ord
+# Symbol to_proc
+# Time to_date, to_time, to_datetime
+require 'active_support'
+require 'active_support/core_ext/date/calculations'
+require 'active_support/core_ext/date_time/conversions'
+require 'active_support/core_ext/enumerable'
+require 'active_support/core_ext/integer/even_odd'
+require 'active_support/core_ext/object/tap'
+require 'active_support/core_ext/process/daemon'
+require 'active_support/core_ext/string/conversions'
+require 'active_support/core_ext/rexml'
+require 'active_support/core_ext/symbol/to_proc'
+require 'active_support/core_ext/time/conversions'
diff --git a/activesupport/lib/active_support/test_case.rb b/activesupport/lib/active_support/test_case.rb
index 50e25ef740..bab2a401eb 100644
--- a/activesupport/lib/active_support/test_case.rb
+++ b/activesupport/lib/active_support/test_case.rb
@@ -32,6 +32,11 @@ module ActiveSupport
include ActiveSupport::Testing::Default
end
+ $tags = {}
+ def self.for_tag(tag)
+ yield if $tags[tag]
+ end
+
include ActiveSupport::Testing::SetupAndTeardown
include ActiveSupport::Testing::Assertions
include ActiveSupport::Testing::Deprecation
diff --git a/activesupport/lib/active_support/testing/assertions.rb b/activesupport/lib/active_support/testing/assertions.rb
index ca51adba1e..c529b92240 100644
--- a/activesupport/lib/active_support/testing/assertions.rb
+++ b/activesupport/lib/active_support/testing/assertions.rb
@@ -1,3 +1,5 @@
+require 'active_support/core_ext/array/wrap'
+
module ActiveSupport
module Testing
module Assertions
diff --git a/activesupport/lib/active_support/testing/deprecation.rb b/activesupport/lib/active_support/testing/deprecation.rb
index e9220605bd..0135185a47 100644
--- a/activesupport/lib/active_support/testing/deprecation.rb
+++ b/activesupport/lib/active_support/testing/deprecation.rb
@@ -1,3 +1,5 @@
+require 'active_support/deprecation'
+
module ActiveSupport
module Testing
module Deprecation #:nodoc:
@@ -35,21 +37,19 @@ end
begin
require 'test/unit/error'
-
+rescue LoadError
+ # Using miniunit, ignore.
+else
module Test
module Unit
- class Error # :nodoc:
+ class Error #:nodoc:
# Silence warnings when reporting test errors.
def message_with_silenced_deprecation
- ActiveSupport::Deprecation.silence do
- message_without_silenced_deprecation
- end
+ ActiveSupport::Deprecation.silence { message_without_silenced_deprecation }
end
-
- alias_method_chain :message, :silenced_deprecation
+ alias_method :message_without_silenced_deprecation, :message
+ alias_method :message, :message_with_silenced_deprecation
end
end
end
-rescue LoadError
- # Using miniunit, ignore.
end
diff --git a/activesupport/lib/active_support/testing/pending.rb b/activesupport/lib/active_support/testing/pending.rb
index d945c7e476..21134ff9e2 100644
--- a/activesupport/lib/active_support/testing/pending.rb
+++ b/activesupport/lib/active_support/testing/pending.rb
@@ -11,6 +11,11 @@ module ActiveSupport
@@at_exit = false
def pending(description = "", &block)
+ if description.is_a?(Symbol)
+ is_pending = $tags[description]
+ return block.call unless is_pending
+ end
+
if block_given?
failed = false
diff --git a/activesupport/lib/active_support/time.rb b/activesupport/lib/active_support/time.rb
new file mode 100644
index 0000000000..d36a683601
--- /dev/null
+++ b/activesupport/lib/active_support/time.rb
@@ -0,0 +1,14 @@
+require 'active_support'
+require 'active_support/core_ext/time'
+require 'active_support/core_ext/date'
+require 'active_support/core_ext/date_time'
+
+module ActiveSupport
+ autoload :Duration, 'active_support/duration'
+ autoload :TimeWithZone, 'active_support/time_with_zone'
+ autoload :TimeZone, 'active_support/values/time_zone'
+
+ on_load_all do
+ [Duration, TimeWithZone, TimeZone]
+ end
+end
diff --git a/activesupport/lib/active_support/core/time/autoload.rb b/activesupport/lib/active_support/time/autoload.rb
index c9a7731b39..c9a7731b39 100644
--- a/activesupport/lib/active_support/core/time/autoload.rb
+++ b/activesupport/lib/active_support/time/autoload.rb
diff --git a/activesupport/lib/active_support/time_with_zone.rb b/activesupport/lib/active_support/time_with_zone.rb
index aa448debda..069842c6c3 100644
--- a/activesupport/lib/active_support/time_with_zone.rb
+++ b/activesupport/lib/active_support/time_with_zone.rb
@@ -118,26 +118,6 @@ module ActiveSupport
end
alias_method :iso8601, :xmlschema
- # Returns a JSON string representing the TimeWithZone. If ActiveSupport.use_standard_json_time_format is set to
- # true, the ISO 8601 format is used.
- #
- # ==== Examples
- #
- # # With ActiveSupport.use_standard_json_time_format = true
- # Time.utc(2005,2,1,15,15,10).in_time_zone.to_json
- # # => "2005-02-01T15:15:10Z"
- #
- # # With ActiveSupport.use_standard_json_time_format = false
- # Time.utc(2005,2,1,15,15,10).in_time_zone.to_json
- # # => "2005/02/01 15:15:10 +0000"
- def to_json(options = nil)
- if ActiveSupport.use_standard_json_time_format
- xmlschema.inspect
- else
- %("#{time.strftime("%Y/%m/%d %H:%M:%S")} #{formatted_offset(false)}")
- end
- end
-
def to_yaml(options = {})
if options.kind_of?(YAML::Emitter)
utc.to_yaml(options)
@@ -321,6 +301,26 @@ module ActiveSupport
end
private
+ # Returns a JSON string representing the TimeWithZone. If ActiveSupport.use_standard_json_time_format is set to
+ # true, the ISO 8601 format is used.
+ #
+ # ==== Examples
+ #
+ # # With ActiveSupport.use_standard_json_time_format = true
+ # Time.utc(2005,2,1,15,15,10).in_time_zone.to_json
+ # # => "2005-02-01T15:15:10Z"
+ #
+ # # With ActiveSupport.use_standard_json_time_format = false
+ # Time.utc(2005,2,1,15,15,10).in_time_zone.to_json
+ # # => "2005/02/01 15:15:10 +0000"
+ def rails_to_json(*)
+ if !ActiveSupport.respond_to?(:use_standard_json_time_format) || ActiveSupport.use_standard_json_time_format
+ xmlschema.inspect
+ else
+ %("#{time.strftime("%Y/%m/%d %H:%M:%S")} #{formatted_offset(false)}")
+ end
+ end
+
def get_period_and_ensure_valid_local_time
# we don't want a Time.local instance enforcing its own DST rules as well,
# so transfer time values to a utc constructor if necessary
diff --git a/activesupport/lib/active_support/values/time_zone.rb b/activesupport/lib/active_support/values/time_zone.rb
index e2d759aa50..b37dae1c2a 100644
--- a/activesupport/lib/active_support/values/time_zone.rb
+++ b/activesupport/lib/active_support/values/time_zone.rb
@@ -92,7 +92,7 @@ module ActiveSupport
"Bucharest" => "Europe/Bucharest",
"Cairo" => "Africa/Cairo",
"Helsinki" => "Europe/Helsinki",
- "Kyev" => "Europe/Kiev",
+ "Kyiv" => "Europe/Kiev",
"Riga" => "Europe/Riga",
"Sofia" => "Europe/Sofia",
"Tallinn" => "Europe/Tallinn",
@@ -336,7 +336,7 @@ module ActiveSupport
"Copenhagen", "Madrid", "Paris", "Amsterdam", "Berlin",
"Bern", "Rome", "Stockholm", "Vienna",
"West Central Africa" ],
- [ 7_200, "Bucharest", "Cairo", "Helsinki", "Kyev", "Riga", "Sofia",
+ [ 7_200, "Bucharest", "Cairo", "Helsinki", "Kyiv", "Riga", "Sofia",
"Tallinn", "Vilnius", "Athens", "Istanbul", "Minsk",
"Jerusalem", "Harare", "Pretoria" ],
[ 10_800, "Moscow", "St. Petersburg", "Volgograd", "Kuwait", "Riyadh",
diff --git a/activesupport/lib/active_support/xml_mini.rb b/activesupport/lib/active_support/xml_mini.rb
index ccd1349491..f22fbcc0e1 100644
--- a/activesupport/lib/active_support/xml_mini.rb
+++ b/activesupport/lib/active_support/xml_mini.rb
@@ -1,3 +1,5 @@
+require 'active_support/core_ext/module/delegation'
+
module ActiveSupport
# = XmlMini
#
diff --git a/activesupport/lib/active_support/xml_mini/jdom.rb b/activesupport/lib/active_support/xml_mini/jdom.rb
new file mode 100644
index 0000000000..1cd714d864
--- /dev/null
+++ b/activesupport/lib/active_support/xml_mini/jdom.rb
@@ -0,0 +1,166 @@
+raise "JRuby is required to use the JDOM backend for XmlMini" unless RUBY_PLATFORM =~ /java/
+
+require 'jruby'
+include Java
+
+import javax.xml.parsers.DocumentBuilder unless defined? DocumentBuilder
+import javax.xml.parsers.DocumentBuilderFactory unless defined? DocumentBuilderFactory
+import java.io.StringReader unless defined? StringReader
+import org.xml.sax.InputSource unless defined? InputSource
+import org.xml.sax.Attributes unless defined? Attributes
+import org.w3c.dom.Node unless defined? Node
+
+# = XmlMini JRuby JDOM implementation
+module ActiveSupport
+ module XmlMini_JDOM #:nodoc:
+ extend self
+
+ CONTENT_KEY = '__content__'.freeze
+
+ NODE_TYPE_NAMES = %w{ATTRIBUTE_NODE CDATA_SECTION_NODE COMMENT_NODE DOCUMENT_FRAGMENT_NODE
+ DOCUMENT_NODE DOCUMENT_TYPE_NODE ELEMENT_NODE ENTITY_NODE ENTITY_REFERENCE_NODE NOTATION_NODE
+ PROCESSING_INSTRUCTION_NODE TEXT_NODE}
+
+ node_type_map = {}
+ NODE_TYPE_NAMES.each { |type| node_type_map[Node.send(type)] = type }
+
+ # Parse an XML Document string or IO into a simple hash using Java's jdom.
+ # data::
+ # XML Document string or IO to parse
+ def parse(data)
+ if data.respond_to?(:read)
+ data = data.read
+ end
+
+ if data.blank?
+ {}
+ else
+ @dbf = DocumentBuilderFactory.new_instance
+ xml_string_reader = StringReader.new(data)
+ xml_input_source = InputSource.new(xml_string_reader)
+ doc = @dbf.new_document_builder.parse(xml_input_source)
+ merge_element!({}, doc.document_element)
+ end
+ end
+
+ private
+
+ # Convert an XML element and merge into the hash
+ #
+ # hash::
+ # Hash to merge the converted element into.
+ # element::
+ # XML element to merge into hash
+ def merge_element!(hash, element)
+ merge!(hash, element.tag_name, collapse(element))
+ end
+
+ # Actually converts an XML document element into a data structure.
+ #
+ # element::
+ # The document element to be collapsed.
+ def collapse(element)
+ hash = get_attributes(element)
+
+ child_nodes = element.child_nodes
+ if child_nodes.length > 0
+ for i in 0...child_nodes.length
+ child = child_nodes.item(i)
+ merge_element!(hash, child) unless child.node_type == Node.TEXT_NODE
+ end
+ merge_texts!(hash, element) unless empty_content?(element)
+ hash
+ else
+ merge_texts!(hash, element)
+ end
+ end
+
+ # Merge all the texts of an element into the hash
+ #
+ # hash::
+ # Hash to add the converted emement to.
+ # element::
+ # XML element whose texts are to me merged into the hash
+ def merge_texts!(hash, element)
+ text_children = texts(element)
+ if text_children.join.empty?
+ hash
+ else
+ # must use value to prevent double-escaping
+ merge!(hash, CONTENT_KEY, text_children.join)
+ end
+ end
+
+ # Adds a new key/value pair to an existing Hash. If the key to be added
+ # already exists and the existing value associated with key is not
+ # an Array, it will be wrapped in an Array. Then the new value is
+ # appended to that Array.
+ #
+ # hash::
+ # Hash to add key/value pair to.
+ # key::
+ # Key to be added.
+ # value::
+ # Value to be associated with key.
+ def merge!(hash, key, value)
+ if hash.has_key?(key)
+ if hash[key].instance_of?(Array)
+ hash[key] << value
+ else
+ hash[key] = [hash[key], value]
+ end
+ elsif value.instance_of?(Array)
+ hash[key] = [value]
+ else
+ hash[key] = value
+ end
+ hash
+ end
+
+ # Converts the attributes array of an XML element into a hash.
+ # Returns an empty Hash if node has no attributes.
+ #
+ # element::
+ # XML element to extract attributes from.
+ def get_attributes(element)
+ attribute_hash = {}
+ attributes = element.attributes
+ for i in 0...attributes.length
+ attribute_hash[attributes.item(i).name] = attributes.item(i).value
+ end
+ attribute_hash
+ end
+
+ # Determines if a document element has text content
+ #
+ # element::
+ # XML element to be checked.
+ def texts(element)
+ texts = []
+ child_nodes = element.child_nodes
+ for i in 0...child_nodes.length
+ item = child_nodes.item(i)
+ if item.node_type == Node.TEXT_NODE
+ texts << item.get_data
+ end
+ end
+ texts
+ end
+
+ # Determines if a document element has text content
+ #
+ # element::
+ # XML element to be checked.
+ def empty_content?(element)
+ text = ''
+ child_nodes = element.child_nodes
+ for i in 0...child_nodes.length
+ item = child_nodes.item(i)
+ if item.node_type == Node.TEXT_NODE
+ text << item.get_data.strip
+ end
+ end
+ text.strip.length == 0
+ end
+ end
+end
diff --git a/activesupport/lib/active_support/xml_mini/libxml.rb b/activesupport/lib/active_support/xml_mini/libxml.rb
index 370205409a..d4c4dc7be5 100644
--- a/activesupport/lib/active_support/xml_mini/libxml.rb
+++ b/activesupport/lib/active_support/xml_mini/libxml.rb
@@ -5,16 +5,20 @@ module ActiveSupport
module XmlMini_LibXML #:nodoc:
extend self
- # Parse an XML Document string into a simple hash using libxml.
- # string::
- # XML Document string to parse
- def parse(string)
+ # Parse an XML Document string or IO into a simple hash using libxml.
+ # data::
+ # XML Document string or IO to parse
+ def parse(data)
+ if data.respond_to?(:read)
+ data = data.read
+ end
+
LibXML::XML.default_keep_blanks = false
- if string.blank?
+ if data.blank?
{}
else
- LibXML::XML::Parser.string(string.strip).parse.to_hash
+ LibXML::XML::Parser.string(data.strip).parse.to_hash
end
end
diff --git a/activesupport/lib/active_support/xml_mini/nokogiri.rb b/activesupport/lib/active_support/xml_mini/nokogiri.rb
index 8f9676e4f6..7337c143c9 100644
--- a/activesupport/lib/active_support/xml_mini/nokogiri.rb
+++ b/activesupport/lib/active_support/xml_mini/nokogiri.rb
@@ -5,14 +5,18 @@ 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?
+ # Parse an XML Document string or IO into a simple hash using libxml / nokogiri.
+ # data::
+ # XML Document string or IO to parse
+ def parse(data)
+ if data.respond_to?(:read)
+ data = data.read
+ end
+
+ if data.blank?
{}
else
- doc = Nokogiri::XML(string)
+ doc = Nokogiri::XML(data)
raise doc.errors.first if doc.errors.length > 0
doc.to_hash
end
diff --git a/activesupport/lib/active_support/xml_mini/rexml.rb b/activesupport/lib/active_support/xml_mini/rexml.rb
index 771109514c..1184d2d6c9 100644
--- a/activesupport/lib/active_support/xml_mini/rexml.rb
+++ b/activesupport/lib/active_support/xml_mini/rexml.rb
@@ -1,3 +1,5 @@
+require 'active_support/core_ext/object/blank'
+
# = XmlMini ReXML implementation
module ActiveSupport
module XmlMini_REXML #:nodoc:
@@ -5,16 +7,20 @@ module ActiveSupport
CONTENT_KEY = '__content__'.freeze
- # Parse an XML Document string into a simple hash
+ # Parse an XML Document string or IO into a simple hash
#
# Same as XmlSimple::xml_in but doesn't shoot itself in the foot,
# and uses the defaults from ActiveSupport
#
- # string::
- # XML Document string to parse
- def parse(string)
+ # data::
+ # XML Document string or IO to parse
+ def parse(data)
+ if data.respond_to?(:read)
+ data = data.read
+ end
+
require 'rexml/document' unless defined?(REXML::Document)
- doc = REXML::Document.new(string)
+ doc = REXML::Document.new(data)
merge_element!({}, doc.root)
end
diff --git a/activesupport/test/buffered_logger_test.rb b/activesupport/test/buffered_logger_test.rb
index d48c7fcc54..7a0ec2e910 100644
--- a/activesupport/test/buffered_logger_test.rb
+++ b/activesupport/test/buffered_logger_test.rb
@@ -4,11 +4,13 @@ require 'fileutils'
require 'active_support/buffered_logger'
class BufferedLoggerTest < Test::Unit::TestCase
+ Logger = ActiveSupport::BufferedLogger
+
def setup
@message = "A debug message"
@integer_message = 12345
@output = StringIO.new
- @logger = ActiveSupport::BufferedLogger.new(@output)
+ @logger = Logger.new(@output)
end
def test_should_log_debugging_message_when_debugging
@@ -76,9 +78,9 @@ class BufferedLoggerTest < Test::Unit::TestCase
define_method "test_disabling_auto_flush_with_#{disable.inspect}_should_flush_at_max_buffer_size_as_failsafe" do
@logger.auto_flushing = disable
- assert_equal ActiveSupport::BufferedLogger::MAX_BUFFER_SIZE, @logger.auto_flushing
+ assert_equal Logger::MAX_BUFFER_SIZE, @logger.auto_flushing
- (ActiveSupport::BufferedLogger::MAX_BUFFER_SIZE - 1).times do
+ (Logger::MAX_BUFFER_SIZE - 1).times do
@logger.info 'wait for it..'
assert @output.string.empty?, @output.string
end
@@ -89,8 +91,8 @@ class BufferedLoggerTest < Test::Unit::TestCase
end
def test_should_know_if_its_loglevel_is_below_a_given_level
- ActiveSupport::BufferedLogger::Severity.constants.each do |level|
- @logger.level = ActiveSupport::BufferedLogger::Severity.const_get(level) - 1
+ Logger::Severity.constants.each do |level|
+ @logger.level = Logger::Severity.const_get(level) - 1
assert @logger.send("#{level.downcase}?"), "didn't know if it was #{level.downcase}? or below"
end
end
@@ -111,7 +113,7 @@ class BufferedLoggerTest < Test::Unit::TestCase
tmp_directory = File.join(File.dirname(__FILE__), "tmp")
log_file = File.join(tmp_directory, "development.log")
assert !File.exist?(tmp_directory)
- @logger = ActiveSupport::BufferedLogger.new(log_file)
+ @logger = Logger.new(log_file)
assert File.exist?(tmp_directory)
ensure
FileUtils.rm_rf(tmp_directory)
diff --git a/activesupport/test/caching_test.rb b/activesupport/test/caching_test.rb
index 8bb0c155cf..51d04d9388 100644
--- a/activesupport/test/caching_test.rb
+++ b/activesupport/test/caching_test.rb
@@ -15,22 +15,34 @@ class CacheStoreSettingTest < ActiveSupport::TestCase
end
def test_mem_cache_fragment_cache_store
+ MemCache.expects(:new).with(%w[localhost], {})
store = ActiveSupport::Cache.lookup_store :mem_cache_store, "localhost"
assert_kind_of(ActiveSupport::Cache::MemCacheStore, store)
- assert_equal %w(localhost), store.addresses
+ end
+
+ def test_mem_cache_fragment_cache_store_with_given_mem_cache
+ mem_cache = MemCache.new
+ MemCache.expects(:new).never
+ store = ActiveSupport::Cache.lookup_store :mem_cache_store, mem_cache
+ assert_kind_of(ActiveSupport::Cache::MemCacheStore, store)
+ end
+
+ def test_mem_cache_fragment_cache_store_with_given_mem_cache_like_object
+ MemCache.expects(:new).never
+ store = ActiveSupport::Cache.lookup_store :mem_cache_store, stub("memcache", :get => true)
+ assert_kind_of(ActiveSupport::Cache::MemCacheStore, store)
end
def test_mem_cache_fragment_cache_store_with_multiple_servers
+ MemCache.expects(:new).with(%w[localhost 192.168.1.1], {})
store = ActiveSupport::Cache.lookup_store :mem_cache_store, "localhost", '192.168.1.1'
assert_kind_of(ActiveSupport::Cache::MemCacheStore, store)
- assert_equal %w(localhost 192.168.1.1), store.addresses
end
def test_mem_cache_fragment_cache_store_with_options
+ MemCache.expects(:new).with(%w[localhost 192.168.1.1], { :namespace => "foo" })
store = ActiveSupport::Cache.lookup_store :mem_cache_store, "localhost", '192.168.1.1', :namespace => 'foo'
assert_kind_of(ActiveSupport::Cache::MemCacheStore, store)
- assert_equal %w(localhost 192.168.1.1), store.addresses
- assert_equal 'foo', store.instance_variable_get('@data').instance_variable_get('@namespace')
end
def test_object_assigned_fragment_cache_store
@@ -168,6 +180,15 @@ uses_memcached 'memcached backed store' do
end
end
+ def test_stored_objects_should_not_be_frozen
+ @cache.with_local_cache do
+ @cache.write('foo', 'bar')
+ end
+ @cache.with_local_cache do
+ assert !@cache.read('foo').frozen?
+ end
+ end
+
def test_write_should_return_true_on_success
@cache.with_local_cache do
result = @cache.write('foo', 'bar')
@@ -251,6 +272,15 @@ uses_memcached 'memcached backed store' do
end
end
+ def test_multi_get
+ @cache.with_local_cache do
+ @cache.write('foo', 1)
+ @cache.write('goo', 2)
+ result = @cache.read_multi('foo', 'goo')
+ assert_equal({'foo' => 1, 'goo' => 2}, result)
+ end
+ end
+
def test_middleware
app = lambda { |env|
result = @cache.write('foo', 'bar')
diff --git a/activesupport/test/concern_test.rb b/activesupport/test/concern_test.rb
new file mode 100644
index 0000000000..22f7ec2064
--- /dev/null
+++ b/activesupport/test/concern_test.rb
@@ -0,0 +1,88 @@
+require 'abstract_unit'
+require 'active_support/concern'
+
+class ConcernTest < Test::Unit::TestCase
+ module Baz
+ extend ActiveSupport::Concern
+
+ module ClassMethods
+ def baz
+ "baz"
+ end
+
+ def included_ran=(value)
+ @@included_ran = value
+ end
+
+ def included_ran
+ @@included_ran
+ end
+ end
+
+ included do
+ self.included_ran = true
+ end
+
+ def baz
+ "baz"
+ end
+ end
+
+ module Bar
+ extend ActiveSupport::Concern
+
+ depends_on Baz
+
+ def bar
+ "bar"
+ end
+
+ def baz
+ "bar+" + super
+ end
+ end
+
+ module Foo
+ extend ActiveSupport::Concern
+
+ depends_on Bar, Baz
+ end
+
+ def setup
+ @klass = Class.new
+ end
+
+ def test_module_is_included_normally
+ @klass.send(:include, Baz)
+ assert_equal "baz", @klass.new.baz
+ assert_equal ConcernTest::Baz, @klass.included_modules[0]
+
+ @klass.send(:include, Baz)
+ assert_equal "baz", @klass.new.baz
+ assert_equal ConcernTest::Baz, @klass.included_modules[0]
+ end
+
+ def test_class_methods_are_extended
+ @klass.send(:include, Baz)
+ assert_equal "baz", @klass.baz
+ assert_equal ConcernTest::Baz::ClassMethods, (class << @klass; self.included_modules; end)[0]
+ end
+
+ def test_included_block_is_ran
+ @klass.send(:include, Baz)
+ assert_equal true, @klass.included_ran
+ end
+
+ def test_modules_dependencies_are_met
+ @klass.send(:include, Bar)
+ assert_equal "bar", @klass.new.bar
+ assert_equal "bar+baz", @klass.new.baz
+ assert_equal "baz", @klass.baz
+ assert_equal [ConcernTest::Bar, ConcernTest::Baz], @klass.included_modules[0..1]
+ end
+
+ def test_depends_on_with_multiple_modules
+ @klass.send(:include, Foo)
+ assert_equal [ConcernTest::Foo, ConcernTest::Bar, ConcernTest::Baz], @klass.included_modules[0..2]
+ end
+end
diff --git a/activesupport/test/core_ext/array_ext_test.rb b/activesupport/test/core_ext/array_ext_test.rb
index 112cb998b1..24d33896ce 100644
--- a/activesupport/test/core_ext/array_ext_test.rb
+++ b/activesupport/test/core_ext/array_ext_test.rb
@@ -1,6 +1,9 @@
require 'abstract_unit'
require 'active_support/core_ext/array'
require 'active_support/core_ext/big_decimal'
+require 'active_support/core_ext/object/conversions'
+
+require 'active_support/core_ext' # FIXME: pulling in all to_xml extensions
class ArrayExtAccessTests < Test::Unit::TestCase
def test_from
diff --git a/activesupport/test/core_ext/blank_test.rb b/activesupport/test/core_ext/blank_test.rb
index 00fea74639..1dbbf3ff30 100644
--- a/activesupport/test/core_ext/blank_test.rb
+++ b/activesupport/test/core_ext/blank_test.rb
@@ -1,4 +1,5 @@
require 'abstract_unit'
+require 'active_support/core_ext/object/blank'
class EmptyTrue
def empty?() true; end
diff --git a/activesupport/test/core_ext/class/attribute_accessor_test.rb b/activesupport/test/core_ext/class/attribute_accessor_test.rb
index 85d0dd89e2..2214ba9894 100644
--- a/activesupport/test/core_ext/class/attribute_accessor_test.rb
+++ b/activesupport/test/core_ext/class/attribute_accessor_test.rb
@@ -1,4 +1,5 @@
require 'abstract_unit'
+require 'active_support/core_ext/class/attribute_accessors'
class ClassAttributeAccessorTest < Test::Unit::TestCase
def setup
diff --git a/activesupport/test/core_ext/class/class_inheritable_attributes_test.rb b/activesupport/test/core_ext/class/class_inheritable_attributes_test.rb
index 7f859772e7..eeda468d9c 100644
--- a/activesupport/test/core_ext/class/class_inheritable_attributes_test.rb
+++ b/activesupport/test/core_ext/class/class_inheritable_attributes_test.rb
@@ -1,4 +1,5 @@
require 'abstract_unit'
+require 'active_support/core_ext/class/inheritable_attributes'
class ClassInheritableAttributesTest < Test::Unit::TestCase
def setup
diff --git a/activesupport/test/core_ext/date_time_ext_test.rb b/activesupport/test/core_ext/date_time_ext_test.rb
index 45eb52c720..a7b179b2be 100644
--- a/activesupport/test/core_ext/date_time_ext_test.rb
+++ b/activesupport/test/core_ext/date_time_ext_test.rb
@@ -1,4 +1,5 @@
require 'abstract_unit'
+require 'active_support/core_ext/date_time'
class DateTimeExtCalculationsTest < Test::Unit::TestCase
def test_to_s
diff --git a/activesupport/test/core_ext/duplicable_test.rb b/activesupport/test/core_ext/duplicable_test.rb
index 8b6127f31e..6e1f876959 100644
--- a/activesupport/test/core_ext/duplicable_test.rb
+++ b/activesupport/test/core_ext/duplicable_test.rb
@@ -1,4 +1,6 @@
require 'abstract_unit'
+require 'bigdecimal'
+require 'active_support/core_ext/object/duplicable'
class DuplicableTest < Test::Unit::TestCase
NO = [nil, false, true, :symbol, 1, 2.3, BigDecimal.new('4.56'), Class.new]
diff --git a/activesupport/test/core_ext/duration_test.rb b/activesupport/test/core_ext/duration_test.rb
index d4a4627e3e..6f16621ae5 100644
--- a/activesupport/test/core_ext/duration_test.rb
+++ b/activesupport/test/core_ext/duration_test.rb
@@ -1,4 +1,5 @@
require 'abstract_unit'
+require 'active_support/time'
class DurationTest < ActiveSupport::TestCase
def test_inspect
@@ -41,23 +42,23 @@ class DurationTest < ActiveSupport::TestCase
end
def test_since_and_ago_with_fractional_days
- Time.stubs(:now).returns Time.local(2000)
+ t = Time.local(2000)
# since
- assert_equal 36.hours.since, 1.5.days.since
- assert_equal((24 * 1.7).hours.since, 1.7.days.since)
+ assert_equal 36.hours.since(t), 1.5.days.since(t)
+ assert_in_delta((24 * 1.7).hours.since(t), 1.7.days.since(t), 1)
# ago
- assert_equal 36.hours.ago, 1.5.days.ago
- assert_equal((24 * 1.7).hours.ago, 1.7.days.ago)
+ assert_equal 36.hours.ago(t), 1.5.days.ago(t)
+ assert_in_delta((24 * 1.7).hours.ago(t), 1.7.days.ago(t), 1)
end
def test_since_and_ago_with_fractional_weeks
- Time.stubs(:now).returns Time.local(2000)
+ t = Time.local(2000)
# since
- assert_equal((7 * 36).hours.since, 1.5.weeks.since)
- assert_equal((7 * 24 * 1.7).hours.since, 1.7.weeks.since)
+ assert_equal((7 * 36).hours.since(t), 1.5.weeks.since(t))
+ assert_in_delta((7 * 24 * 1.7).hours.since(t), 1.7.weeks.since(t), 1)
# ago
- assert_equal((7 * 36).hours.ago, 1.5.weeks.ago)
- assert_equal((7 * 24 * 1.7).hours.ago, 1.7.weeks.ago)
+ assert_equal((7 * 36).hours.ago(t), 1.5.weeks.ago(t))
+ assert_in_delta((7 * 24 * 1.7).hours.ago(t), 1.7.weeks.ago(t), 1)
end
def test_since_and_ago_anchored_to_time_now_when_time_zone_default_not_set
diff --git a/activesupport/test/core_ext/exception_test.rb b/activesupport/test/core_ext/exception_test.rb
index dabd8c7c06..e63842c0bd 100644
--- a/activesupport/test/core_ext/exception_test.rb
+++ b/activesupport/test/core_ext/exception_test.rb
@@ -1,4 +1,5 @@
require 'abstract_unit'
+require 'active_support/core_ext/exception'
class ExceptionExtTests < Test::Unit::TestCase
diff --git a/activesupport/test/core_ext/hash_ext_test.rb b/activesupport/test/core_ext/hash_ext_test.rb
index bbb1c631f9..ece5466abb 100644
--- a/activesupport/test/core_ext/hash_ext_test.rb
+++ b/activesupport/test/core_ext/hash_ext_test.rb
@@ -1,5 +1,7 @@
require 'abstract_unit'
require 'active_support/core_ext/hash'
+require 'bigdecimal'
+require 'active_support/core_ext/string/access'
class HashExtTest < Test::Unit::TestCase
def setup
@@ -644,6 +646,22 @@ class HashToXmlTest < Test::Unit::TestCase
assert_equal expected_topic_hash, Hash.from_xml(topic_xml)["rsp"]["photos"]["photo"]
end
+ def test_all_caps_key_from_xml
+ test_xml = <<-EOT
+ <ABC3XYZ>
+ <TEST>Lorem Ipsum</TEST>
+ </ABC3XYZ>
+ EOT
+
+ expected_hash = {
+ "ABC3XYZ" => {
+ "TEST" => "Lorem Ipsum"
+ }
+ }
+
+ assert_equal expected_hash, Hash.from_xml(test_xml)
+ end
+
def test_empty_array_from_xml
blog_xml = <<-XML
<blog>
diff --git a/activesupport/test/core_ext/module/attr_accessor_with_default_test.rb b/activesupport/test/core_ext/module/attr_accessor_with_default_test.rb
index 7c59348af9..7c0d0bb242 100644
--- a/activesupport/test/core_ext/module/attr_accessor_with_default_test.rb
+++ b/activesupport/test/core_ext/module/attr_accessor_with_default_test.rb
@@ -1,4 +1,5 @@
require 'abstract_unit'
+require 'active_support/core_ext/module/attr_accessor_with_default'
class AttrAccessorWithDefaultTest < Test::Unit::TestCase
def setup
diff --git a/activesupport/test/core_ext/module/attr_internal_test.rb b/activesupport/test/core_ext/module/attr_internal_test.rb
index 52833019e7..93578c9610 100644
--- a/activesupport/test/core_ext/module/attr_internal_test.rb
+++ b/activesupport/test/core_ext/module/attr_internal_test.rb
@@ -1,4 +1,5 @@
require 'abstract_unit'
+require 'active_support/core_ext/module/attr_internal'
class AttrInternalTest < Test::Unit::TestCase
def setup
@@ -37,8 +38,8 @@ class AttrInternalTest < Test::Unit::TestCase
end
def test_naming_format
- assert_equal '@_%s', @target.attr_internal_naming_format
- assert_nothing_raised { @target.attr_internal_naming_format = '@abc%sdef' }
+ assert_equal '@_%s', Module.attr_internal_naming_format
+ assert_nothing_raised { Module.attr_internal_naming_format = '@abc%sdef' }
@target.attr_internal :foo
assert !@instance.instance_variable_defined?('@_foo')
@@ -47,6 +48,6 @@ class AttrInternalTest < Test::Unit::TestCase
assert !@instance.instance_variable_defined?('@_foo')
assert @instance.instance_variable_defined?('@abcfoodef')
ensure
- @target.attr_internal_naming_format = '@_%s'
+ Module.attr_internal_naming_format = '@_%s'
end
end
diff --git a/activesupport/test/core_ext/module/attribute_accessor_test.rb b/activesupport/test/core_ext/module/attribute_accessor_test.rb
index 96975085cf..bd9461e62c 100644
--- a/activesupport/test/core_ext/module/attribute_accessor_test.rb
+++ b/activesupport/test/core_ext/module/attribute_accessor_test.rb
@@ -1,4 +1,5 @@
require 'abstract_unit'
+require 'active_support/core_ext/module/attribute_accessors'
class ModuleAttributeAccessorTest < Test::Unit::TestCase
def setup
diff --git a/activesupport/test/core_ext/module/attribute_aliasing_test.rb b/activesupport/test/core_ext/module/attribute_aliasing_test.rb
index 570ac3b8d5..f17d031662 100644
--- a/activesupport/test/core_ext/module/attribute_aliasing_test.rb
+++ b/activesupport/test/core_ext/module/attribute_aliasing_test.rb
@@ -1,4 +1,5 @@
require 'abstract_unit'
+require 'active_support/core_ext/module/aliasing'
module AttributeAliasing
class Content
diff --git a/activesupport/test/core_ext/module/model_naming_test.rb b/activesupport/test/core_ext/module/model_naming_test.rb
index d08349dd97..da3b6c4932 100644
--- a/activesupport/test/core_ext/module/model_naming_test.rb
+++ b/activesupport/test/core_ext/module/model_naming_test.rb
@@ -1,4 +1,5 @@
require 'abstract_unit'
+require 'active_support/core_ext/module/model_naming'
class ModelNamingTest < Test::Unit::TestCase
def setup
diff --git a/activesupport/test/core_ext/name_error_test.rb b/activesupport/test/core_ext/name_error_test.rb
index bae004809f..10913e2ade 100644
--- a/activesupport/test/core_ext/name_error_test.rb
+++ b/activesupport/test/core_ext/name_error_test.rb
@@ -1,4 +1,5 @@
require 'abstract_unit'
+require 'active_support/core_ext/name_error'
class NameErrorTest < Test::Unit::TestCase
def test_name_error_should_set_missing_name
diff --git a/activesupport/test/core_ext/numeric_ext_test.rb b/activesupport/test/core_ext/numeric_ext_test.rb
index 9cca4d3aaf..992ec60302 100644
--- a/activesupport/test/core_ext/numeric_ext_test.rb
+++ b/activesupport/test/core_ext/numeric_ext_test.rb
@@ -1,6 +1,7 @@
require 'abstract_unit'
-
-require 'active_support/core_ext/numeric/bytes'
+require 'active_support/time'
+require 'active_support/core_ext/numeric'
+require 'active_support/core_ext/integer'
class NumericExtTimeAndDateTimeTest < Test::Unit::TestCase
def setup
diff --git a/activesupport/test/core_ext/object_and_class_ext_test.rb b/activesupport/test/core_ext/object_and_class_ext_test.rb
index c919698c0f..f0121b862d 100644
--- a/activesupport/test/core_ext/object_and_class_ext_test.rb
+++ b/activesupport/test/core_ext/object_and_class_ext_test.rb
@@ -1,5 +1,7 @@
require 'abstract_unit'
+require 'active_support/time'
require 'active_support/core_ext/object'
+require 'active_support/core_ext/class/removal'
class ClassA; end
class ClassB < ClassA; end
diff --git a/activesupport/test/core_ext/proc_test.rb b/activesupport/test/core_ext/proc_test.rb
index 29f85371de..dc7b2c957d 100644
--- a/activesupport/test/core_ext/proc_test.rb
+++ b/activesupport/test/core_ext/proc_test.rb
@@ -1,4 +1,5 @@
require 'abstract_unit'
+require 'active_support/core_ext/proc'
class ProcTests < Test::Unit::TestCase
def test_bind_returns_method_with_changed_self
diff --git a/activesupport/test/core_ext/range_ext_test.rb b/activesupport/test/core_ext/range_ext_test.rb
index 76e05e9954..2565c56b8a 100644
--- a/activesupport/test/core_ext/range_ext_test.rb
+++ b/activesupport/test/core_ext/range_ext_test.rb
@@ -1,5 +1,6 @@
require 'abstract_unit'
require 'active_support/core_ext/range'
+require 'active_support/core_ext/date/conversions'
class RangeTest < Test::Unit::TestCase
def test_to_s_from_dates
diff --git a/activesupport/test/core_ext/string_ext_test.rb b/activesupport/test/core_ext/string_ext_test.rb
index a357ba5852..237a843f9a 100644
--- a/activesupport/test/core_ext/string_ext_test.rb
+++ b/activesupport/test/core_ext/string_ext_test.rb
@@ -4,6 +4,7 @@ require 'abstract_unit'
require 'inflector_test_cases'
require 'active_support/core_ext/string'
+require 'active_support/core_ext/time'
class StringInflectionsTest < Test::Unit::TestCase
include InflectorTestCases
diff --git a/activesupport/test/core_ext/time_ext_test.rb b/activesupport/test/core_ext/time_ext_test.rb
index 8ee4904036..1c2d0fbce4 100644
--- a/activesupport/test/core_ext/time_ext_test.rb
+++ b/activesupport/test/core_ext/time_ext_test.rb
@@ -1,4 +1,5 @@
require 'abstract_unit'
+require 'active_support/time'
class TimeExtCalculationsTest < Test::Unit::TestCase
def test_seconds_since_midnight
@@ -423,10 +424,10 @@ class TimeExtCalculationsTest < Test::Unit::TestCase
assert_equal Time.local(2005,6,28,15,15,10), Time.local(2005,2,28,15,15,10).advance(:months => 4)
assert_equal Time.local(2005,3,21,15,15,10), Time.local(2005,2,28,15,15,10).advance(:weeks => 3)
assert_equal Time.local(2005,3,25,3,15,10), Time.local(2005,2,28,15,15,10).advance(:weeks => 3.5)
- assert_equal Time.local(2005,3,26,12,51,10), Time.local(2005,2,28,15,15,10).advance(:weeks => 3.7)
+ assert_in_delta Time.local(2005,3,26,12,51,10), Time.local(2005,2,28,15,15,10).advance(:weeks => 3.7), 1
assert_equal Time.local(2005,3,5,15,15,10), Time.local(2005,2,28,15,15,10).advance(:days => 5)
assert_equal Time.local(2005,3,6,3,15,10), Time.local(2005,2,28,15,15,10).advance(:days => 5.5)
- assert_equal Time.local(2005,3,6,8,3,10), Time.local(2005,2,28,15,15,10).advance(:days => 5.7)
+ assert_in_delta Time.local(2005,3,6,8,3,10), Time.local(2005,2,28,15,15,10).advance(:days => 5.7), 1
assert_equal Time.local(2012,9,28,15,15,10), Time.local(2005,2,28,15,15,10).advance(:years => 7, :months => 7)
assert_equal Time.local(2013,10,3,15,15,10), Time.local(2005,2,28,15,15,10).advance(:years => 7, :months => 19, :days => 5)
assert_equal Time.local(2013,10,17,15,15,10), Time.local(2005,2,28,15,15,10).advance(:years => 7, :months => 19, :weeks => 2, :days => 5)
@@ -445,10 +446,10 @@ class TimeExtCalculationsTest < Test::Unit::TestCase
assert_equal Time.utc(2005,6,22,15,15,10), Time.utc(2005,2,22,15,15,10).advance(:months => 4)
assert_equal Time.utc(2005,3,21,15,15,10), Time.utc(2005,2,28,15,15,10).advance(:weeks => 3)
assert_equal Time.utc(2005,3,25,3,15,10), Time.utc(2005,2,28,15,15,10).advance(:weeks => 3.5)
- assert_equal Time.utc(2005,3,26,12,51,10), Time.utc(2005,2,28,15,15,10).advance(:weeks => 3.7)
+ assert_in_delta Time.utc(2005,3,26,12,51,10), Time.utc(2005,2,28,15,15,10).advance(:weeks => 3.7), 1
assert_equal Time.utc(2005,3,5,15,15,10), Time.utc(2005,2,28,15,15,10).advance(:days => 5)
assert_equal Time.utc(2005,3,6,3,15,10), Time.utc(2005,2,28,15,15,10).advance(:days => 5.5)
- assert_equal Time.utc(2005,3,6,8,3,10), Time.utc(2005,2,28,15,15,10).advance(:days => 5.7)
+ assert_in_delta Time.utc(2005,3,6,8,3,10), Time.utc(2005,2,28,15,15,10).advance(:days => 5.7), 1
assert_equal Time.utc(2012,9,22,15,15,10), Time.utc(2005,2,22,15,15,10).advance(:years => 7, :months => 7)
assert_equal Time.utc(2013,10,3,15,15,10), Time.utc(2005,2,22,15,15,10).advance(:years => 7, :months => 19, :days => 11)
assert_equal Time.utc(2013,10,17,15,15,10), Time.utc(2005,2,28,15,15,10).advance(:years => 7, :months => 19, :weeks => 2, :days => 5)
diff --git a/activesupport/test/core_ext/time_with_zone_test.rb b/activesupport/test/core_ext/time_with_zone_test.rb
index 3dec4c95f4..03ae70d420 100644
--- a/activesupport/test/core_ext/time_with_zone_test.rb
+++ b/activesupport/test/core_ext/time_with_zone_test.rb
@@ -1,5 +1,6 @@
require 'abstract_unit'
require 'active_support/time_with_zone'
+require 'active_support/json'
class TimeWithZoneTest < Test::Unit::TestCase
@@ -56,12 +57,12 @@ class TimeWithZoneTest < Test::Unit::TestCase
end
def test_to_json
- assert_equal "\"1999/12/31 19:00:00 -0500\"", @twz.to_json
+ assert_equal "\"1999/12/31 19:00:00 -0500\"", ActiveSupport::JSON.encode(@twz)
end
def test_to_json_with_use_standard_json_time_format_config_set_to_true
old, ActiveSupport.use_standard_json_time_format = ActiveSupport.use_standard_json_time_format, true
- assert_equal "\"1999-12-31T19:00:00-05:00\"", @twz.to_json
+ assert_equal "\"1999-12-31T19:00:00-05:00\"", ActiveSupport::JSON.encode(@twz)
ensure
ActiveSupport.use_standard_json_time_format = old
end
@@ -91,7 +92,7 @@ class TimeWithZoneTest < Test::Unit::TestCase
end
def test_xmlschema_with_fractional_seconds
- @twz += 0.123456 # advance the time by a fraction of a second
+ @twz += 0.1234560001 # advance the time by a fraction of a second
assert_equal "1999-12-31T19:00:00.123-05:00", @twz.xmlschema(3)
assert_equal "1999-12-31T19:00:00.123456-05:00", @twz.xmlschema(6)
assert_equal "1999-12-31T19:00:00.123456-05:00", @twz.xmlschema(12)
diff --git a/activesupport/test/dependencies_test.rb b/activesupport/test/dependencies_test.rb
index a21f09403f..99c53924c2 100644
--- a/activesupport/test/dependencies_test.rb
+++ b/activesupport/test/dependencies_test.rb
@@ -1,5 +1,8 @@
require 'abstract_unit'
require 'pp'
+require 'active_support/dependencies'
+require 'active_support/core_ext/module/loading'
+require 'active_support/core_ext/kernel/reporting'
module ModuleWithMissing
mattr_accessor :missing_count
diff --git a/activesupport/test/i18n_test.rb b/activesupport/test/i18n_test.rb
index 7535f4ad7a..9868f1e87d 100644
--- a/activesupport/test/i18n_test.rb
+++ b/activesupport/test/i18n_test.rb
@@ -1,4 +1,6 @@
require 'abstract_unit'
+require 'active_support/time'
+require 'active_support/core_ext/array/conversions'
class I18nTest < Test::Unit::TestCase
def setup
diff --git a/activesupport/test/inflector_test.rb b/activesupport/test/inflector_test.rb
index 6b9fbd3156..8c4d831a39 100644
--- a/activesupport/test/inflector_test.rb
+++ b/activesupport/test/inflector_test.rb
@@ -1,4 +1,6 @@
require 'abstract_unit'
+require 'active_support/inflector'
+
require 'inflector_test_cases'
module Ace
diff --git a/activesupport/test/json/decoding_test.rb b/activesupport/test/json/decoding_test.rb
index 8fe40557d6..09fd0d09ba 100644
--- a/activesupport/test/json/decoding_test.rb
+++ b/activesupport/test/json/decoding_test.rb
@@ -1,48 +1,78 @@
# encoding: UTF-8
require 'abstract_unit'
+require 'active_support/json'
+require 'active_support/core_ext/kernel/reporting'
-class TestJSONDecoding < Test::Unit::TestCase
+class TestJSONDecoding < ActiveSupport::TestCase
TESTS = {
%q({"returnTo":{"\/categories":"\/"}}) => {"returnTo" => {"/categories" => "/"}},
- %q({returnTo:{"\/categories":"\/"}}) => {"returnTo" => {"/categories" => "/"}},
%q({"return\\"To\\":":{"\/categories":"\/"}}) => {"return\"To\":" => {"/categories" => "/"}},
%q({"returnTo":{"\/categories":1}}) => {"returnTo" => {"/categories" => 1}},
%({"returnTo":[1,"a"]}) => {"returnTo" => [1, "a"]},
%({"returnTo":[1,"\\"a\\",", "b"]}) => {"returnTo" => [1, "\"a\",", "b"]},
- %({a: "'", "b": "5,000"}) => {"a" => "'", "b" => "5,000"},
- %({a: "a's, b's and c's", "b": "5,000"}) => {"a" => "a's, b's and c's", "b" => "5,000"},
+ %({"a": "'", "b": "5,000"}) => {"a" => "'", "b" => "5,000"},
+ %({"a": "a's, b's and c's", "b": "5,000"}) => {"a" => "a's, b's and c's", "b" => "5,000"},
# multibyte
%({"matzue": "松江", "asakusa": "浅草"}) => {"matzue" => "松江", "asakusa" => "浅草"},
- %({a: "2007-01-01"}) => {'a' => Date.new(2007, 1, 1)},
- %({a: "2007-01-01 01:12:34 Z"}) => {'a' => Time.utc(2007, 1, 1, 1, 12, 34)},
+ %({"a": "2007-01-01"}) => {'a' => Date.new(2007, 1, 1)},
+ %({"a": "2007-01-01 01:12:34 Z"}) => {'a' => Time.utc(2007, 1, 1, 1, 12, 34)},
# no time zone
- %({a: "2007-01-01 01:12:34"}) => {'a' => "2007-01-01 01:12:34"},
+ %({"a": "2007-01-01 01:12:34"}) => {'a' => "2007-01-01 01:12:34"},
# needs to be *exact*
- %({a: " 2007-01-01 01:12:34 Z "}) => {'a' => " 2007-01-01 01:12:34 Z "},
- %({a: "2007-01-01 : it's your birthday"}) => {'a' => "2007-01-01 : it's your birthday"},
+ %({"a": " 2007-01-01 01:12:34 Z "}) => {'a' => " 2007-01-01 01:12:34 Z "},
+ %({"a": "2007-01-01 : it's your birthday"}) => {'a' => "2007-01-01 : it's your birthday"},
%([]) => [],
%({}) => {},
- %(1) => 1,
- %("") => "",
- %("\\"") => "\"",
- %(null) => nil,
- %(true) => true,
- %(false) => false,
- %q("http:\/\/test.host\/posts\/1") => "http://test.host/posts/1",
- %q("\u003cunicode\u0020escape\u003e") => "<unicode escape>",
- %q("\\\\u0020skip double backslashes") => "\\u0020skip double backslashes",
- %q({a: "\u003cbr /\u003e"}) => {'a' => "<br />"},
- %q({b:["\u003ci\u003e","\u003cb\u003e","\u003cu\u003e"]}) => {'b' => ["<i>","<b>","<u>"]}
+ %({"a":1}) => {"a" => 1},
+ %({"a": ""}) => {"a" => ""},
+ %({"a":"\\""}) => {"a" => "\""},
+ %({"a": null}) => {"a" => nil},
+ %({"a": true}) => {"a" => true},
+ %({"a": false}) => {"a" => false},
+ %q({"a": "http:\/\/test.host\/posts\/1"}) => {"a" => "http://test.host/posts/1"},
+ %q({"a": "\u003cunicode\u0020escape\u003e"}) => {"a" => "<unicode escape>"},
+ %q({"a": "\\\\u0020skip double backslashes"}) => {"a" => "\\u0020skip double backslashes"},
+ %q({"a": "\u003cbr /\u003e"}) => {'a' => "<br />"},
+ %q({"b":["\u003ci\u003e","\u003cb\u003e","\u003cu\u003e"]}) => {'b' => ["<i>","<b>","<u>"]}
}
-
- TESTS.each do |json, expected|
- define_method :"test_json_decoding_#{json}" do
- assert_nothing_raised do
- assert_equal expected, ActiveSupport::JSON.decode(json)
+
+ # load the default JSON backend
+ ActiveSupport::JSON.backend
+
+ backends = %w(Yaml)
+ begin
+ gem 'json', '>= 1.1'
+ require 'json'
+ backends << "JSONGem"
+ rescue Gem::LoadError
+ # Skip JSON gem tests
+ end
+
+ backends.each do |backend|
+ TESTS.each do |json, expected|
+ test "json decodes #{json} with the #{backend} backend" do
+ ActiveSupport.parse_json_times = true
+ silence_warnings do
+ ActiveSupport::JSON.with_backend backend do
+ assert_nothing_raised do
+ assert_equal expected, ActiveSupport::JSON.decode(json)
+ end
+ end
+ end
end
end
end
-
+
+ if backends.include?("JSONGem")
+ test "json decodes time json with time parsing disabled" do
+ ActiveSupport.parse_json_times = false
+ expected = {"a" => "2007-01-01 01:12:34 Z"}
+ ActiveSupport::JSON.with_backend "JSONGem" do
+ assert_equal expected, ActiveSupport::JSON.decode(%({"a": "2007-01-01 01:12:34 Z"}))
+ end
+ end
+ end
+
def test_failed_json_decoding
assert_raise(ActiveSupport::JSON::ParseError) { ActiveSupport::JSON.decode(%({: 1})) }
end
diff --git a/activesupport/test/json/encoding_test.rb b/activesupport/test/json/encoding_test.rb
index 9e6b4fa501..1a0e6d543c 100644
--- a/activesupport/test/json/encoding_test.rb
+++ b/activesupport/test/json/encoding_test.rb
@@ -19,14 +19,14 @@ class TestJSONEncoding < Test::Unit::TestCase
[ 'a "string" with quotes & an ampersand', %("a \\"string\\" with quotes \\u0026 an ampersand") ],
[ 'http://test.host/posts/1', %("http://test.host/posts/1")]]
- ArrayTests = [[ ['a', 'b', 'c'], %([\"a\", \"b\", \"c\"]) ],
- [ [1, 'a', :b, nil, false], %([1, \"a\", \"b\", null, false]) ]]
+ ArrayTests = [[ ['a', 'b', 'c'], %([\"a\",\"b\",\"c\"]) ],
+ [ [1, 'a', :b, nil, false], %([1,\"a\",\"b\",null,false]) ]]
SymbolTests = [[ :a, %("a") ],
[ :this, %("this") ],
[ :"a b", %("a b") ]]
- ObjectTests = [[ Foo.new(1, 2), %({\"a\": 1, \"b\": 2}) ]]
+ ObjectTests = [[ Foo.new(1, 2), %({\"a\":1,\"b\":2}) ]]
VariableTests = [[ ActiveSupport::JSON::Variable.new('foo'), 'foo'],
[ ActiveSupport::JSON::Variable.new('alert("foo")'), 'alert("foo")']]
@@ -47,7 +47,7 @@ class TestJSONEncoding < Test::Unit::TestCase
ActiveSupport.escape_html_entities_in_json = class_tests !~ /^Standard/
ActiveSupport.use_standard_json_time_format = class_tests =~ /^Standard/
self.class.const_get(class_tests).each do |pair|
- assert_equal pair.last, pair.first.to_json
+ assert_equal pair.last, ActiveSupport::JSON.encode(pair.first)
end
ensure
ActiveSupport.escape_html_entities_in_json = false
@@ -57,45 +57,45 @@ class TestJSONEncoding < Test::Unit::TestCase
end
def test_hash_encoding
- assert_equal %({\"a\": \"b\"}), { :a => :b }.to_json
- assert_equal %({\"a\": 1}), { 'a' => 1 }.to_json
- assert_equal %({\"a\": [1, 2]}), { 'a' => [1,2] }.to_json
- assert_equal %({"1": 2}), { 1 => 2 }.to_json
+ assert_equal %({\"a\":\"b\"}), ActiveSupport::JSON.encode(:a => :b)
+ assert_equal %({\"a\":1}), ActiveSupport::JSON.encode('a' => 1)
+ assert_equal %({\"a\":[1,2]}), ActiveSupport::JSON.encode('a' => [1,2])
+ assert_equal %({"1":2}), ActiveSupport::JSON.encode(1 => 2)
- sorted_json = '{' + {:a => :b, :c => :d}.to_json[1..-2].split(', ').sort.join(', ') + '}'
- assert_equal %({\"a\": \"b\", \"c\": \"d\"}), sorted_json
+ sorted_json = '{' + ActiveSupport::JSON.encode(:a => :b, :c => :d)[1..-2].split(',').sort.join(',') + '}'
+ assert_equal %({\"a\":\"b\",\"c\":\"d\"}), sorted_json
end
def test_utf8_string_encoded_properly_when_kcode_is_utf8
with_kcode 'UTF8' do
- assert_equal '"\\u20ac2.99"', '€2.99'.to_json
- assert_equal '"\\u270e\\u263a"', '✎☺'.to_json
+ assert_equal '"\\u20ac2.99"', ActiveSupport::JSON.encode('€2.99')
+ assert_equal '"\\u270e\\u263a"', ActiveSupport::JSON.encode('✎☺')
end
end
def test_exception_raised_when_encoding_circular_reference
a = [1]
a << a
- assert_raise(ActiveSupport::JSON::CircularReferenceError) { a.to_json }
+ assert_raise(ActiveSupport::JSON::CircularReferenceError) { ActiveSupport::JSON.encode(a) }
end
def test_hash_key_identifiers_are_always_quoted
values = {0 => 0, 1 => 1, :_ => :_, "$" => "$", "a" => "a", :A => :A, :A0 => :A0, "A0B" => "A0B"}
- assert_equal %w( "$" "A" "A0" "A0B" "_" "a" "0" "1" ).sort, object_keys(values.to_json)
+ assert_equal %w( "$" "A" "A0" "A0B" "_" "a" "0" "1" ).sort, object_keys(ActiveSupport::JSON.encode(values))
end
def test_hash_should_allow_key_filtering_with_only
- assert_equal %({"a": 1}), { 'a' => 1, :b => 2, :c => 3 }.to_json(:only => 'a')
+ assert_equal %({"a":1}), ActiveSupport::JSON.encode({'a' => 1, :b => 2, :c => 3}, :only => 'a')
end
def test_hash_should_allow_key_filtering_with_except
- assert_equal %({"b": 2}), { 'foo' => 'bar', :b => 2, :c => 3 }.to_json(:except => ['foo', :c])
+ assert_equal %({"b":2}), ActiveSupport::JSON.encode({'foo' => 'bar', :b => 2, :c => 3}, :except => ['foo', :c])
end
def test_time_to_json_includes_local_offset
ActiveSupport.use_standard_json_time_format = true
with_env_tz 'US/Eastern' do
- assert_equal %("2005-02-01T15:15:10-05:00"), Time.local(2005,2,1,15,15,10).to_json
+ assert_equal %("2005-02-01T15:15:10-05:00"), ActiveSupport::JSON.encode(Time.local(2005,2,1,15,15,10))
end
ensure
ActiveSupport.use_standard_json_time_format = false
@@ -109,7 +109,7 @@ class TestJSONEncoding < Test::Unit::TestCase
:latitude => 123.234
}
}
- result = hash.to_json
+ result = ActiveSupport::JSON.encode(hash)
end
end
@@ -134,6 +134,6 @@ class JsonOptionsTests < Test::Unit::TestCase
ActiveSupport::JSON.expects(:encode).with(2, json_options)
ActiveSupport::JSON.expects(:encode).with('foo', json_options)
- [1, 2, 'foo'].to_json(json_options)
+ [1, 2, 'foo'].send(:rails_to_json, json_options)
end
end
diff --git a/activesupport/test/new_callbacks_test.rb b/activesupport/test/new_callbacks_test.rb
index 5cde078b65..7bec47224d 100644
--- a/activesupport/test/new_callbacks_test.rb
+++ b/activesupport/test/new_callbacks_test.rb
@@ -19,11 +19,11 @@ module NewCallbacksTest
class << self
def callback_symbol(callback_method)
- returning(:"#{callback_method}_method") do |method_name|
- define_method(method_name) do
- history << [callback_method, :symbol]
- end
+ method_name = :"#{callback_method}_method"
+ define_method(method_name) do
+ history << [callback_method, :symbol]
end
+ method_name
end
def callback_string(callback_method)
@@ -255,6 +255,26 @@ module NewCallbacksTest
end
end
+ class HyphenatedCallbacks
+ include ActiveSupport::NewCallbacks
+ define_callbacks :save
+ attr_reader :stuff
+
+ save_callback :before, :omg, :per_key => {:if => :yes}
+
+ def yes() true end
+
+ def omg
+ @stuff = "OMG"
+ end
+
+ def save
+ _run_save_callbacks("hyphen-ated") do
+ @stuff
+ end
+ end
+ end
+
class AroundCallbacksTest < Test::Unit::TestCase
def test_save_around
around = AroundPerson.new
@@ -345,7 +365,7 @@ module NewCallbacksTest
save_callback :after, :third
- attr_reader :history
+ attr_reader :history, :saved
def initialize
@history = []
end
@@ -370,8 +390,72 @@ module NewCallbacksTest
end
def save
- _run_save_callbacks
+ _run_save_callbacks do
+ @saved = true
+ end
+ end
+ end
+
+ class CallbackObject
+ def before_save(caller)
+ caller.record << "before"
+ end
+
+ def around_save(caller)
+ caller.record << "around before"
+ yield
+ caller.record << "around after"
+ end
+ end
+
+ class UsingObjectBefore
+ include ActiveSupport::NewCallbacks
+
+ define_callbacks :save
+ save_callback :before, CallbackObject.new
+
+ attr_accessor :record
+ def initialize
+ @record = []
+ end
+
+ def save
+ _run_save_callbacks do
+ @record << "yielded"
+ end
+ end
+ end
+
+ class UsingObjectAround
+ include ActiveSupport::NewCallbacks
+
+ define_callbacks :save
+ save_callback :around, CallbackObject.new
+
+ attr_accessor :record
+ def initialize
+ @record = []
+ end
+
+ def save
+ _run_save_callbacks do
+ @record << "yielded"
+ end
+ end
+ end
+
+ class UsingObjectTest < Test::Unit::TestCase
+ def test_before_object
+ u = UsingObjectBefore.new
+ u.save
+ assert_equal ["before", "yielded"], u.record
end
+
+ def test_around_object
+ u = UsingObjectAround.new
+ u.save
+ assert_equal ["around before", "yielded", "around after"], u.record
+ end
end
class CallbackTerminatorTest < Test::Unit::TestCase
@@ -380,5 +464,19 @@ module NewCallbacksTest
terminator.save
assert_equal ["first", "second", "third", "second", "first"], terminator.history
end
+
+ def test_block_never_called_if_terminated
+ obj = CallbackTerminator.new
+ obj.save
+ assert !obj.saved
+ end
end
-end \ No newline at end of file
+
+ class HyphenatedKeyTest < Test::Unit::TestCase
+ def test_save
+ obj = HyphenatedCallbacks.new
+ obj.save
+ assert_equal obj.stuff, "OMG"
+ end
+ end
+end
diff --git a/activesupport/test/ordered_hash_test.rb b/activesupport/test/ordered_hash_test.rb
index 7cd8c8a8f4..647938dd87 100644
--- a/activesupport/test/ordered_hash_test.rb
+++ b/activesupport/test/ordered_hash_test.rb
@@ -51,6 +51,10 @@ class OrderedHashTest < Test::Unit::TestCase
assert_same @ordered_hash, @ordered_hash.to_hash
end
+ def test_to_a
+ assert_equal @keys.zip(@values), @ordered_hash.to_a
+ end
+
def test_has_key
assert_equal true, @ordered_hash.has_key?('blue')
assert_equal true, @ordered_hash.key?('blue')
@@ -158,4 +162,10 @@ class OrderedHashTest < Test::Unit::TestCase
def test_inspect
assert @ordered_hash.inspect.include?(@hash.inspect)
end
+
+ def test_alternate_initialization
+ alternate = ActiveSupport::OrderedHash[1,2,3,4]
+ assert_kind_of ActiveSupport::OrderedHash, alternate
+ assert_equal [1, 3], alternate.keys
+ end
end
diff --git a/activesupport/test/test_test.rb b/activesupport/test/test_test.rb
index d250b10822..40d3d612e7 100644
--- a/activesupport/test/test_test.rb
+++ b/activesupport/test/test_test.rb
@@ -1,4 +1,5 @@
require 'abstract_unit'
+require 'active_support/core_ext/kernel/reporting'
class AssertDifferenceTest < ActiveSupport::TestCase
def setup
diff --git a/activesupport/test/time_zone_test.rb b/activesupport/test/time_zone_test.rb
index 7e8047566e..99c4310854 100644
--- a/activesupport/test/time_zone_test.rb
+++ b/activesupport/test/time_zone_test.rb
@@ -1,4 +1,5 @@
require 'abstract_unit'
+require 'active_support/time'
class TimeZoneTest < Test::Unit::TestCase
def test_utc_to_local
diff --git a/activesupport/test/xml_mini/jdom_engine_test.rb b/activesupport/test/xml_mini/jdom_engine_test.rb
new file mode 100644
index 0000000000..b745228994
--- /dev/null
+++ b/activesupport/test/xml_mini/jdom_engine_test.rb
@@ -0,0 +1,153 @@
+require 'abstract_unit'
+require 'active_support/xml_mini'
+
+if RUBY_PLATFORM =~ /java/
+
+class JDOMEngineTest < Test::Unit::TestCase
+ include ActiveSupport
+
+ def setup
+ @default_backend = XmlMini.backend
+ XmlMini.backend = 'JDOM'
+ end
+
+ def teardown
+ XmlMini.backend = @default_backend
+ end
+
+ # def test_file_from_xml
+ # hash = Hash.from_xml(<<-eoxml)
+ # <blog>
+ # <logo type="file" name="logo.png" content_type="image/png">
+ # </logo>
+ # </blog>
+ # eoxml
+ # 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_exception_thrown_on_expansion_attack
+ assert_raise NativeException do
+ attack_xml = <<-EOT
+ <?xml version="1.0" encoding="UTF-8"?>
+ <!DOCTYPE member [
+ <!ENTITY a "&b;&b;&b;&b;&b;&b;&b;&b;&b;&b;">
+ <!ENTITY b "&c;&c;&c;&c;&c;&c;&c;&c;&c;&c;">
+ <!ENTITY c "&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;">
+ <!ENTITY d "&e;&e;&e;&e;&e;&e;&e;&e;&e;&e;">
+ <!ENTITY e "&f;&f;&f;&f;&f;&f;&f;&f;&f;&f;">
+ <!ENTITY f "&g;&g;&g;&g;&g;&g;&g;&g;&g;&g;">
+ <!ENTITY g "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx">
+ ]>
+ <member>
+ &a;
+ </member>
+ EOT
+ Hash.from_xml(attack_xml)
+ end
+ end
+
+ def test_setting_JDOM_as_backend
+ XmlMini.backend = 'JDOM'
+ assert_equal XmlMini_JDOM, XmlMini.backend
+ end
+
+ def test_blank_returns_empty_hash
+ assert_equal({}, XmlMini.parse(nil))
+ assert_equal({}, XmlMini.parse(''))
+ end
+
+ def test_array_type_makes_an_array
+ assert_equal_rexml(<<-eoxml)
+ <blog>
+ <posts type="array">
+ <post>a post</post>
+ <post>another post</post>
+ </posts>
+ </blog>
+ eoxml
+ end
+
+ def test_one_node_document_as_hash
+ assert_equal_rexml(<<-eoxml)
+ <products/>
+ eoxml
+ end
+
+ def test_one_node_with_attributes_document_as_hash
+ assert_equal_rexml(<<-eoxml)
+ <products foo="bar"/>
+ eoxml
+ end
+
+ def test_products_node_with_book_node_as_hash
+ assert_equal_rexml(<<-eoxml)
+ <products>
+ <book name="awesome" id="12345" />
+ </products>
+ eoxml
+ end
+
+ def test_products_node_with_two_book_nodes_as_hash
+ assert_equal_rexml(<<-eoxml)
+ <products>
+ <book name="awesome" id="12345" />
+ <book name="america" id="67890" />
+ </products>
+ eoxml
+ end
+
+ def test_single_node_with_content_as_hash
+ assert_equal_rexml(<<-eoxml)
+ <products>
+ hello world
+ </products>
+ eoxml
+ end
+
+ def test_children_with_children
+ assert_equal_rexml(<<-eoxml)
+ <root>
+ <products>
+ <book name="america" id="67890" />
+ </products>
+ </root>
+ eoxml
+ end
+
+ def test_children_with_text
+ assert_equal_rexml(<<-eoxml)
+ <root>
+ <products>
+ hello everyone
+ </products>
+ </root>
+ eoxml
+ end
+
+ def test_children_with_non_adjacent_text
+ assert_equal_rexml(<<-eoxml)
+ <root>
+ good
+ <products>
+ hello everyone
+ </products>
+ morning
+ </root>
+ eoxml
+ end
+
+ private
+ def assert_equal_rexml(xml)
+ hash = XmlMini.with_backend('REXML') { XmlMini.parse(xml) }
+ assert_equal(hash, XmlMini.parse(xml))
+ end
+end
+
+else
+ # don't run these test because we aren't running in JRuby
+end
diff --git a/activesupport/test/xml_mini/nokogiri_engine_test.rb b/activesupport/test/xml_mini/nokogiri_engine_test.rb
index e5174a0b57..7c3a591e63 100644
--- a/activesupport/test/xml_mini/nokogiri_engine_test.rb
+++ b/activesupport/test/xml_mini/nokogiri_engine_test.rb
@@ -1,5 +1,6 @@
require 'abstract_unit'
require 'active_support/xml_mini'
+require 'active_support/core_ext/hash/conversions'
begin
gem 'nokogiri', '>= 1.1.1'
@@ -147,6 +148,19 @@ class NokogiriEngineTest < Test::Unit::TestCase
eoxml
end
+ def test_parse_from_io
+ io = StringIO.new(<<-eoxml)
+ <root>
+ good
+ <products>
+ hello everyone
+ </products>
+ morning
+ </root>
+ eoxml
+ XmlMini.parse(io)
+ end
+
private
def assert_equal_rexml(xml)
hash = XmlMini.with_backend('REXML') { XmlMini.parse(xml) }
diff --git a/activesupport/test/xml_mini/rexml_engine_test.rb b/activesupport/test/xml_mini/rexml_engine_test.rb
index a412d8ca05..57bb35254a 100644
--- a/activesupport/test/xml_mini/rexml_engine_test.rb
+++ b/activesupport/test/xml_mini/rexml_engine_test.rb
@@ -12,4 +12,18 @@ class REXMLEngineTest < Test::Unit::TestCase
XmlMini.backend = 'REXML'
assert_equal XmlMini_REXML, XmlMini.backend
end
+
+ def test_parse_from_io
+ XmlMini.backend = 'REXML'
+ io = StringIO.new(<<-eoxml)
+ <root>
+ good
+ <products>
+ hello everyone
+ </products>
+ morning
+ </root>
+ eoxml
+ XmlMini.parse(io)
+ end
end