aboutsummaryrefslogtreecommitdiffstats
path: root/activesupport/lib/active_support
diff options
context:
space:
mode:
Diffstat (limited to 'activesupport/lib/active_support')
-rw-r--r--activesupport/lib/active_support/cache.rb2
-rw-r--r--activesupport/lib/active_support/core_ext/big_decimal/conversions.rb15
-rw-r--r--activesupport/lib/active_support/core_ext/big_decimal/yaml_conversions.rb14
-rw-r--r--activesupport/lib/active_support/core_ext/enumerable.rb2
-rw-r--r--activesupport/lib/active_support/core_ext/module/attr_internal.rb3
-rw-r--r--activesupport/lib/active_support/core_ext/module/concerning.rb2
-rw-r--r--activesupport/lib/active_support/core_ext/object/json.rb8
-rw-r--r--activesupport/lib/active_support/core_ext/object/to_param.rb10
-rw-r--r--activesupport/lib/active_support/core_ext/object/to_query.rb7
-rw-r--r--activesupport/lib/active_support/dependencies.rb11
-rw-r--r--activesupport/lib/active_support/inflections.rb6
-rw-r--r--activesupport/lib/active_support/inflector/methods.rb2
-rw-r--r--activesupport/lib/active_support/json/encoding.rb8
-rw-r--r--activesupport/lib/active_support/key_generator.rb16
-rw-r--r--activesupport/lib/active_support/message_encryptor.rb2
-rw-r--r--activesupport/lib/active_support/multibyte/unicode.rb8
-rw-r--r--activesupport/lib/active_support/testing/isolation.rb2
-rw-r--r--activesupport/lib/active_support/testing/time_helpers.rb76
-rw-r--r--activesupport/lib/active_support/time_with_zone.rb15
-rw-r--r--activesupport/lib/active_support/values/time_zone.rb4
-rw-r--r--activesupport/lib/active_support/xml_mini.rb6
21 files changed, 155 insertions, 64 deletions
diff --git a/activesupport/lib/active_support/cache.rb b/activesupport/lib/active_support/cache.rb
index 53154aef27..2b7f5943b5 100644
--- a/activesupport/lib/active_support/cache.rb
+++ b/activesupport/lib/active_support/cache.rb
@@ -452,7 +452,7 @@ module ActiveSupport
# Clear the entire cache. Be careful with this method since it could
# affect other processes if shared cache is being used.
#
- # Options are passed to the underlying cache implementation.
+ # The options hash is passed to the underlying cache implementation.
#
# All implementations may not support this method.
def clear(options = nil)
diff --git a/activesupport/lib/active_support/core_ext/big_decimal/conversions.rb b/activesupport/lib/active_support/core_ext/big_decimal/conversions.rb
index 39b8cea807..843c592669 100644
--- a/activesupport/lib/active_support/core_ext/big_decimal/conversions.rb
+++ b/activesupport/lib/active_support/core_ext/big_decimal/conversions.rb
@@ -1,22 +1,7 @@
require 'bigdecimal'
require 'bigdecimal/util'
-require 'yaml'
class BigDecimal
- YAML_MAPPING = { 'Infinity' => '.Inf', '-Infinity' => '-.Inf', 'NaN' => '.NaN' }
-
- def encode_with(coder)
- string = to_s
- coder.represent_scalar(nil, YAML_MAPPING[string] || string)
- end
-
- # Backport this method if it doesn't exist
- unless method_defined?(:to_d)
- def to_d
- self
- end
- end
-
DEFAULT_STRING_FORMAT = 'F'
def to_formatted_s(*args)
if args[0].is_a?(Symbol)
diff --git a/activesupport/lib/active_support/core_ext/big_decimal/yaml_conversions.rb b/activesupport/lib/active_support/core_ext/big_decimal/yaml_conversions.rb
new file mode 100644
index 0000000000..46ba93ead4
--- /dev/null
+++ b/activesupport/lib/active_support/core_ext/big_decimal/yaml_conversions.rb
@@ -0,0 +1,14 @@
+ActiveSupport::Deprecation.warn 'core_ext/big_decimal/yaml_conversions is deprecated and will be removed in the future.'
+
+require 'bigdecimal'
+require 'yaml'
+require 'active_support/core_ext/big_decimal/conversions'
+
+class BigDecimal
+ YAML_MAPPING = { 'Infinity' => '.Inf', '-Infinity' => '-.Inf', 'NaN' => '.NaN' }
+
+ def encode_with(coder)
+ string = to_s
+ coder.represent_scalar(nil, YAML_MAPPING[string] || string)
+ end
+end
diff --git a/activesupport/lib/active_support/core_ext/enumerable.rb b/activesupport/lib/active_support/core_ext/enumerable.rb
index 4501b7ff58..1343beb87a 100644
--- a/activesupport/lib/active_support/core_ext/enumerable.rb
+++ b/activesupport/lib/active_support/core_ext/enumerable.rb
@@ -35,7 +35,7 @@ module Enumerable
if block_given?
Hash[map { |elem| [yield(elem), elem] }]
else
- to_enum :index_by
+ to_enum(:index_by) { size if respond_to?(:size) }
end
end
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 db07d549b0..67f0e0335d 100644
--- a/activesupport/lib/active_support/core_ext/module/attr_internal.rb
+++ b/activesupport/lib/active_support/core_ext/module/attr_internal.rb
@@ -27,7 +27,8 @@ class Module
def attr_internal_define(attr_name, type)
internal_name = attr_internal_ivar_name(attr_name).sub(/\A@/, '')
- class_eval do # class_eval is necessary on 1.9 or else the methods a made private
+ # class_eval is necessary on 1.9 or else the methods are made private
+ class_eval do
# use native attr_* methods as they are faster on some Ruby implementations
send("attr_#{type}", internal_name)
end
diff --git a/activesupport/lib/active_support/core_ext/module/concerning.rb b/activesupport/lib/active_support/core_ext/module/concerning.rb
index b22dc5ff1e..07a392404e 100644
--- a/activesupport/lib/active_support/core_ext/module/concerning.rb
+++ b/activesupport/lib/active_support/core_ext/module/concerning.rb
@@ -63,7 +63,7 @@ class Module
#
# == Mix-in noise exiled to its own file:
#
- # Once our chunk of behavior starts pushing the scroll-to-understand it
+ # Once our chunk of behavior starts pushing the scroll-to-understand it's
# boundary, we give in and move it to a separate file. At this size, the
# overhead feels in good proportion to the size of our extraction, despite
# diluting our at-a-glance sense of how things really work.
diff --git a/activesupport/lib/active_support/core_ext/object/json.rb b/activesupport/lib/active_support/core_ext/object/json.rb
index 1675145ffe..8e08cfbf26 100644
--- a/activesupport/lib/active_support/core_ext/object/json.rb
+++ b/activesupport/lib/active_support/core_ext/object/json.rb
@@ -16,12 +16,12 @@ require 'active_support/core_ext/module/aliasing'
# otherwise they will always use to_json gem implementation, which is backwards incompatible in
# several cases (for instance, the JSON implementation for Hash does not work) with inheritance
# and consequently classes as ActiveSupport::OrderedHash cannot be serialized to json.
-#
+#
# On the other hand, we should avoid conflict with ::JSON.{generate,dump}(obj). Unfortunately, the
# JSON gem's encoder relies on its own to_json implementation to encode objects. Since it always
# passes a ::JSON::State object as the only argument to to_json, we can detect that and forward the
# calls to the original to_json method.
-#
+#
# It should be noted that when using ::JSON.{generate,dump} directly, ActiveSupport's encoder is
# bypassed completely. This means that as_json won't be invoked and the JSON gem will simply
# ignore any options it does not natively understand. This also means that ::JSON.{generate,dump}
@@ -163,7 +163,7 @@ end
class Time
def as_json(options = nil) #:nodoc:
if ActiveSupport.use_standard_json_time_format
- xmlschema(3)
+ xmlschema(ActiveSupport::JSON::Encoding.time_precision)
else
%(#{strftime("%Y/%m/%d %H:%M:%S")} #{formatted_offset(false)})
end
@@ -183,7 +183,7 @@ end
class DateTime
def as_json(options = nil) #:nodoc:
if ActiveSupport.use_standard_json_time_format
- xmlschema(3)
+ xmlschema(ActiveSupport::JSON::Encoding.time_precision)
else
strftime('%Y/%m/%d %H:%M:%S %z')
end
diff --git a/activesupport/lib/active_support/core_ext/object/to_param.rb b/activesupport/lib/active_support/core_ext/object/to_param.rb
index 3b137ce6ae..13be0038c2 100644
--- a/activesupport/lib/active_support/core_ext/object/to_param.rb
+++ b/activesupport/lib/active_support/core_ext/object/to_param.rb
@@ -51,8 +51,12 @@ class Hash
#
# This method is also aliased as +to_query+.
def to_param(namespace = nil)
- collect do |key, value|
- value.to_query(namespace ? "#{namespace}[#{key}]" : key)
- end.sort! * '&'
+ if empty?
+ namespace ? nil.to_query(namespace) : ''
+ else
+ collect do |key, value|
+ value.to_query(namespace ? "#{namespace}[#{key}]" : key)
+ end.sort! * '&'
+ end
end
end
diff --git a/activesupport/lib/active_support/core_ext/object/to_query.rb b/activesupport/lib/active_support/core_ext/object/to_query.rb
index 5d5fcf00e0..37352fa608 100644
--- a/activesupport/lib/active_support/core_ext/object/to_query.rb
+++ b/activesupport/lib/active_support/core_ext/object/to_query.rb
@@ -18,7 +18,12 @@ class Array
# ['Rails', 'coding'].to_query('hobbies') # => "hobbies%5B%5D=Rails&hobbies%5B%5D=coding"
def to_query(key)
prefix = "#{key}[]"
- collect { |value| value.to_query(prefix) }.join '&'
+
+ if empty?
+ nil.to_query(prefix)
+ else
+ collect { |value| value.to_query(prefix) }.join '&'
+ end
end
end
diff --git a/activesupport/lib/active_support/dependencies.rb b/activesupport/lib/active_support/dependencies.rb
index 6be19771f5..59675d744e 100644
--- a/activesupport/lib/active_support/dependencies.rb
+++ b/activesupport/lib/active_support/dependencies.rb
@@ -407,7 +407,8 @@ module ActiveSupport #:nodoc:
end
def load_once_path?(path)
- # to_s works around a ruby1.9 issue where #starts_with?(Pathname) will always return false
+ # to_s works around a ruby1.9 issue where String#starts_with?(Pathname)
+ # will raise a TypeError: no implicit conversion of Pathname into String
autoload_once_paths.any? { |base| path.starts_with? base.to_s }
end
@@ -665,6 +666,14 @@ module ActiveSupport #:nodoc:
constants = normalized.split('::')
to_remove = constants.pop
+ # Remove the file path from the loaded list.
+ file_path = search_for_file(const.underscore)
+ if file_path
+ expanded = File.expand_path(file_path)
+ expanded.sub!(/\.rb\z/, '')
+ self.loaded.delete(expanded)
+ end
+
if constants.empty?
parent = Object
else
diff --git a/activesupport/lib/active_support/inflections.rb b/activesupport/lib/active_support/inflections.rb
index 4ea6abfa12..2ca1124e76 100644
--- a/activesupport/lib/active_support/inflections.rb
+++ b/activesupport/lib/active_support/inflections.rb
@@ -1,5 +1,11 @@
require 'active_support/inflector/inflections'
+#--
+# Defines the standard inflection rules. These are the starting point for
+# new projects and are not considered complete. The current set of inflection
+# rules is frozen. This means, we do not change them to become more complete.
+# This is a safety measure to keep existing applications from breaking.
+#++
module ActiveSupport
Inflector.inflections(:en) do |inflect|
inflect.plural(/$/, 's')
diff --git a/activesupport/lib/active_support/inflector/methods.rb b/activesupport/lib/active_support/inflector/methods.rb
index cdee4c2ca5..b642d87d76 100644
--- a/activesupport/lib/active_support/inflector/methods.rb
+++ b/activesupport/lib/active_support/inflector/methods.rb
@@ -117,7 +117,7 @@ module ActiveSupport
result.gsub!(/([a-z\d]*)/i) { |match|
"#{inflections.acronyms[match] || match.downcase}"
}
- result.gsub!(/^\w/) { $&.upcase } if options.fetch(:capitalize, true)
+ result.gsub!(/^\w/) { |match| match.upcase } if options.fetch(:capitalize, true)
result
end
diff --git a/activesupport/lib/active_support/json/encoding.rb b/activesupport/lib/active_support/json/encoding.rb
index 2859075e10..f29d42276d 100644
--- a/activesupport/lib/active_support/json/encoding.rb
+++ b/activesupport/lib/active_support/json/encoding.rb
@@ -4,6 +4,7 @@ require 'active_support/core_ext/module/delegation'
module ActiveSupport
class << self
delegate :use_standard_json_time_format, :use_standard_json_time_format=,
+ :time_precision, :time_precision=,
:escape_html_entities_in_json, :escape_html_entities_in_json=,
:encode_big_decimal_as_string, :encode_big_decimal_as_string=,
:json_encoder, :json_encoder=,
@@ -60,7 +61,7 @@ module ActiveSupport
end
# Mark these as private so we don't leak encoding-specific constructs
- private_constant :ESCAPED_CHARS, :ESCAPE_REGEX_WITH_HTML_ENTITIES,
+ private_constant :ESCAPED_CHARS, :ESCAPE_REGEX_WITH_HTML_ENTITIES,
:ESCAPE_REGEX_WITHOUT_HTML_ENTITIES, :EscapedString
# Convert an object into a "JSON-ready" representation composed of
@@ -105,6 +106,10 @@ module ActiveSupport
# as a safety measure.
attr_accessor :escape_html_entities_in_json
+ # Sets the precision of encoded time values.
+ # Defaults to 3 (equivalent to millisecond precision)
+ attr_accessor :time_precision
+
# Sets the encoder used by Rails to encode Ruby objects into JSON strings
# in +Object#to_json+ and +ActiveSupport::JSON.encode+.
attr_accessor :json_encoder
@@ -161,6 +166,7 @@ module ActiveSupport
self.use_standard_json_time_format = true
self.escape_html_entities_in_json = true
self.json_encoder = JSONGemEncoder
+ self.time_precision = 3
end
end
end
diff --git a/activesupport/lib/active_support/key_generator.rb b/activesupport/lib/active_support/key_generator.rb
index 598c46bce5..51d2da3a79 100644
--- a/activesupport/lib/active_support/key_generator.rb
+++ b/activesupport/lib/active_support/key_generator.rb
@@ -57,18 +57,16 @@ module ActiveSupport
# secret they've provided is at least 30 characters in length.
def ensure_secret_secure(secret)
if secret.blank?
- raise ArgumentError, "A secret is required to generate an " +
- "integrity hash for cookie session data. Use " +
- "config.secret_key_base = \"some secret phrase of at " +
- "least #{SECRET_MIN_LENGTH} characters\"" +
- "in config/initializers/secret_token.rb"
+ raise ArgumentError, "A secret is required to generate an integrity hash " \
+ "for cookie session data. Set a secret_key_base of at least " \
+ "#{SECRET_MIN_LENGTH} characters in config/secrets.yml."
end
if secret.length < SECRET_MIN_LENGTH
- raise ArgumentError, "Secret should be something secure, " +
- "like \"#{SecureRandom.hex(16)}\". The value you " +
- "provided, \"#{secret}\", is shorter than the minimum length " +
- "of #{SECRET_MIN_LENGTH} characters"
+ raise ArgumentError, "Secret should be something secure, " \
+ "like \"#{SecureRandom.hex(16)}\". The value you " \
+ "provided, \"#{secret}\", is shorter than the minimum length " \
+ "of #{SECRET_MIN_LENGTH} characters."
end
end
end
diff --git a/activesupport/lib/active_support/message_encryptor.rb b/activesupport/lib/active_support/message_encryptor.rb
index 7773611e11..b019ad0dec 100644
--- a/activesupport/lib/active_support/message_encryptor.rb
+++ b/activesupport/lib/active_support/message_encryptor.rb
@@ -12,7 +12,7 @@ module ActiveSupport
# This can be used in situations similar to the <tt>MessageVerifier</tt>, but
# where you don't want users to be able to determine the value of the payload.
#
- # salt = SecureRandom.random_bytes(64)
+ # salt = SecureRandom.random_bytes(64)
# key = ActiveSupport::KeyGenerator.new('password').generate_key(salt) # => "\x89\xE0\x156\xAC..."
# crypt = ActiveSupport::MessageEncryptor.new(key) # => #<ActiveSupport::MessageEncryptor ...>
# encrypted_data = crypt.encrypt_and_sign('my secret data') # => "NlFBTTMwOUV5UlA1QlNEN2xkY2d6eThYWWh..."
diff --git a/activesupport/lib/active_support/multibyte/unicode.rb b/activesupport/lib/active_support/multibyte/unicode.rb
index 84799c2399..ea3cdcd024 100644
--- a/activesupport/lib/active_support/multibyte/unicode.rb
+++ b/activesupport/lib/active_support/multibyte/unicode.rb
@@ -213,7 +213,7 @@ module ActiveSupport
end
# Ruby >= 2.1 has String#scrub, which is faster than the workaround used for < 2.1.
- if RUBY_VERSION >= '2.1'
+ if '<3'.respond_to?(:scrub)
# Replaces all ISO-8859-1 or CP1252 characters by their UTF-8 equivalent
# resulting in a valid UTF-8 string.
#
@@ -233,16 +233,16 @@ module ActiveSupport
# We're going to 'transcode' bytes from UTF-8 when possible, then fall back to
# CP1252 when we get errors. The final string will be 'converted' back to UTF-8
# before returning.
- reader = Encoding::Converter.new(Encoding::UTF_8, Encoding::UTF_8_MAC)
+ reader = Encoding::Converter.new(Encoding::UTF_8, Encoding::UTF_16LE)
source = string.dup
- out = ''.force_encoding(Encoding::UTF_8_MAC)
+ out = ''.force_encoding(Encoding::UTF_16LE)
loop do
reader.primitive_convert(source, out)
_, _, _, error_bytes, _ = reader.primitive_errinfo
break if error_bytes.nil?
- out << error_bytes.encode(Encoding::UTF_8_MAC, Encoding::Windows_1252, invalid: :replace, undef: :replace)
+ out << error_bytes.encode(Encoding::UTF_16LE, Encoding::Windows_1252, invalid: :replace, undef: :replace)
end
reader.finish
diff --git a/activesupport/lib/active_support/testing/isolation.rb b/activesupport/lib/active_support/testing/isolation.rb
index 75ead48376..908af176be 100644
--- a/activesupport/lib/active_support/testing/isolation.rb
+++ b/activesupport/lib/active_support/testing/isolation.rb
@@ -37,6 +37,8 @@ module ActiveSupport
module Forking
def run_in_isolation(&blk)
read, write = IO.pipe
+ read.binmode
+ write.binmode
pid = fork do
read.close
diff --git a/activesupport/lib/active_support/testing/time_helpers.rb b/activesupport/lib/active_support/testing/time_helpers.rb
index 94230e56ba..9e0a3d6345 100644
--- a/activesupport/lib/active_support/testing/time_helpers.rb
+++ b/activesupport/lib/active_support/testing/time_helpers.rb
@@ -1,10 +1,48 @@
module ActiveSupport
module Testing
+ class SimpleStubs # :nodoc:
+ Stub = Struct.new(:object, :method_name, :original_method)
+
+ def initialize
+ @stubs = {}
+ end
+
+ def stub_object(object, method_name, return_value)
+ key = [object.object_id, method_name]
+
+ if (stub = @stubs[key])
+ unstub_object(stub)
+ end
+
+ new_name = "__simple_stub__#{method_name}"
+
+ @stubs[key] = Stub.new(object, method_name, new_name)
+
+ object.singleton_class.send :alias_method, new_name, method_name
+ object.define_singleton_method(method_name) { return_value }
+ end
+
+ def unstub_all!
+ @stubs.each_value do |stub|
+ unstub_object(stub)
+ end
+ @stubs = {}
+ end
+
+ private
+
+ def unstub_object(stub)
+ singleton_class = stub.object.singleton_class
+ singleton_class.send :undef_method, stub.method_name
+ singleton_class.send :alias_method, stub.method_name, stub.original_method
+ singleton_class.send :undef_method, stub.original_method
+ end
+ end
+
# Containing helpers that helps you test passage of time.
module TimeHelpers
- # Change current time to the time in the future or in the past by a given time difference by
- # stubbing +Time.now+ and +Date.today+. Note that the stubs are automatically removed
- # at the end of each test.
+ # Changes current time to the time in the future or in the past by a given time difference by
+ # stubbing +Time.now+ and +Date.today+.
#
# Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
# travel 1.day
@@ -23,9 +61,8 @@ module ActiveSupport
travel_to Time.now + duration, &block
end
- # Change current time to the given time by stubbing +Time.now+ and +Date.today+ to return the
- # time or date passed into this method. Note that the stubs are automatically removed
- # at the end of each test.
+ # Changes current time to the given time by stubbing +Time.now+ and +Date.today+ to return the
+ # time or date passed into this method.
#
# Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
# travel_to Time.new(2004, 11, 24, 01, 04, 44)
@@ -37,19 +74,36 @@ module ActiveSupport
#
# Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
# travel_to Time.new(2004, 11, 24, 01, 04, 44) do
- # User.create.created_at # => Wed, 24 Nov 2004 01:04:44 EST -05:00
+ # Time.current # => Wed, 24 Nov 2004 01:04:44 EST -05:00
# end
# Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
def travel_to(date_or_time, &block)
- Time.stubs now: date_or_time.to_time
- Date.stubs today: date_or_time.to_date
+ simple_stubs.stub_object(Time, :now, date_or_time.to_time)
+ simple_stubs.stub_object(Date, :today, date_or_time.to_date)
if block_given?
block.call
- Time.unstub :now
- Date.unstub :today
+ travel_back
end
end
+
+ # Returns the current time back to its original state, by removing the stubs added by
+ # `travel` and `travel_to`.
+ #
+ # Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
+ # travel_to Time.new(2004, 11, 24, 01, 04, 44)
+ # Time.current # => Wed, 24 Nov 2004 01:04:44 EST -05:00
+ # travel_back
+ # Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
+ def travel_back
+ simple_stubs.unstub_all!
+ end
+
+ private
+
+ def simple_stubs
+ @simple_stubs ||= SimpleStubs.new
+ end
end
end
end
diff --git a/activesupport/lib/active_support/time_with_zone.rb b/activesupport/lib/active_support/time_with_zone.rb
index 50db7da9d9..c25c97cfa8 100644
--- a/activesupport/lib/active_support/time_with_zone.rb
+++ b/activesupport/lib/active_support/time_with_zone.rb
@@ -45,7 +45,7 @@ module ActiveSupport
def initialize(utc_time, time_zone, local_time = nil, period = nil)
@utc, @time_zone, @time = utc_time, time_zone, local_time
- @period = @utc ? period : get_period_and_ensure_valid_local_time
+ @period = @utc ? period : get_period_and_ensure_valid_local_time(period)
end
# Returns a Time or DateTime instance that represents the time in +time_zone+.
@@ -132,8 +132,8 @@ module ActiveSupport
end
def xmlschema(fraction_digits = 0)
- fraction = if fraction_digits > 0
- (".%06i" % time.usec)[0, fraction_digits + 1]
+ fraction = if fraction_digits.to_i > 0
+ (".%06i" % time.usec)[0, fraction_digits.to_i + 1]
end
"#{time.strftime("%Y-%m-%dT%H:%M:%S")}#{fraction}#{formatted_offset(true, 'Z')}"
@@ -154,7 +154,7 @@ module ActiveSupport
# # => "2005/02/01 05:15:10 -1000"
def as_json(options = nil)
if ActiveSupport::JSON::Encoding.use_standard_json_time_format
- xmlschema(3)
+ xmlschema(ActiveSupport::JSON::Encoding.time_precision)
else
%(#{time.strftime("%Y/%m/%d %H:%M:%S")} #{formatted_offset(false)})
end
@@ -367,12 +367,12 @@ module ActiveSupport
end
private
- def get_period_and_ensure_valid_local_time
+ def get_period_and_ensure_valid_local_time(period)
# 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
@time = transfer_time_values_to_utc_constructor(@time) unless @time.utc?
begin
- @time_zone.period_for_local(@time)
+ period || @time_zone.period_for_local(@time)
rescue ::TZInfo::PeriodNotFound
# time is in the "spring forward" hour gap, so we're moving the time forward one hour and trying again
@time += 1.hour
@@ -390,7 +390,8 @@ module ActiveSupport
def wrap_with_time_zone(time)
if time.acts_like?(:time)
- self.class.new(nil, time_zone, time)
+ periods = time_zone.periods_for_local(time)
+ self.class.new(nil, time_zone, time, periods.include?(period) ? period : nil)
elsif time.is_a?(Range)
wrap_with_time_zone(time.begin)..wrap_with_time_zone(time.end)
else
diff --git a/activesupport/lib/active_support/values/time_zone.rb b/activesupport/lib/active_support/values/time_zone.rb
index beaac42fa1..eb785d46ce 100644
--- a/activesupport/lib/active_support/values/time_zone.rb
+++ b/activesupport/lib/active_support/values/time_zone.rb
@@ -352,6 +352,10 @@ module ActiveSupport
tzinfo.period_for_local(time, dst)
end
+ def periods_for_local(time) #:nodoc:
+ tzinfo.periods_for_local(time)
+ end
+
def self.find_tzinfo(name)
TZInfo::TimezoneProxy.new(MAPPING[name] || name)
end
diff --git a/activesupport/lib/active_support/xml_mini.rb b/activesupport/lib/active_support/xml_mini.rb
index d082a0a499..009ee4db90 100644
--- a/activesupport/lib/active_support/xml_mini.rb
+++ b/activesupport/lib/active_support/xml_mini.rb
@@ -1,7 +1,9 @@
require 'time'
require 'base64'
+require 'bigdecimal'
require 'active_support/core_ext/module/delegation'
require 'active_support/core_ext/string/inflections'
+require 'active_support/core_ext/date_time/calculations'
module ActiveSupport
# = XmlMini
@@ -56,13 +58,13 @@ module ActiveSupport
# TODO use regexp instead of Date.parse
unless defined?(PARSING)
PARSING = {
- "symbol" => Proc.new { |symbol| symbol.to_sym },
+ "symbol" => Proc.new { |symbol| symbol.to_s.to_sym },
"date" => Proc.new { |date| ::Date.parse(date) },
"datetime" => Proc.new { |time| Time.xmlschema(time).utc rescue ::DateTime.parse(time).utc },
"integer" => Proc.new { |integer| integer.to_i },
"float" => Proc.new { |float| float.to_f },
"decimal" => Proc.new { |number| BigDecimal(number) },
- "boolean" => Proc.new { |boolean| %w(1 true).include?(boolean.strip) },
+ "boolean" => Proc.new { |boolean| %w(1 true).include?(boolean.to_s.strip) },
"string" => Proc.new { |string| string.to_s },
"yaml" => Proc.new { |yaml| YAML::load(yaml) rescue yaml },
"base64Binary" => Proc.new { |bin| ::Base64.decode64(bin) },