aboutsummaryrefslogtreecommitdiffstats
path: root/activesupport
diff options
context:
space:
mode:
Diffstat (limited to 'activesupport')
-rw-r--r--activesupport/CHANGELOG.md11
-rw-r--r--activesupport/lib/active_support/core_ext/time/calculations.rb12
-rw-r--r--activesupport/lib/active_support/json/encoding.rb8
-rw-r--r--activesupport/test/core_ext/time_ext_test.rb22
-rw-r--r--activesupport/test/json/encoding_test.rb29
5 files changed, 67 insertions, 15 deletions
diff --git a/activesupport/CHANGELOG.md b/activesupport/CHANGELOG.md
index 649766cc9b..d612c644af 100644
--- a/activesupport/CHANGELOG.md
+++ b/activesupport/CHANGELOG.md
@@ -1,5 +1,16 @@
## unreleased ##
+* Override `Time.at` to support the passing of Time-like values when called with a single argument.
+
+ *Andrew White*
+
+* Revert the changes on unicode character encoding from `ActiveSupport::JSON.encode`.
+ This was causing a regression where the resulting string is always returning UTF-8.
+ Also it changes the behavior of this method on a stable release.
+ Fixes #9498.
+
+ *Rafael Mendonça França*
+
* Fix `ActiveSupport::TimeZone.parse` when time is at a local DST jump.
Fixes #9678.
diff --git a/activesupport/lib/active_support/core_ext/time/calculations.rb b/activesupport/lib/active_support/core_ext/time/calculations.rb
index 9146d82bd8..7524063efb 100644
--- a/activesupport/lib/active_support/core_ext/time/calculations.rb
+++ b/activesupport/lib/active_support/core_ext/time/calculations.rb
@@ -45,6 +45,18 @@ class Time
def current
::Time.zone ? ::Time.zone.now : ::Time.now
end
+
+ # Layers additional behavior on Time.at so that ActiveSupport::TimeWithZone and DateTime
+ # instances can be used when called with a single argument
+ def at_with_coercion(*args)
+ if args.size == 1 && args.first.acts_like?(:time)
+ at_without_coercion(args.first.to_i)
+ else
+ at_without_coercion(*args)
+ end
+ end
+ alias_method :at_without_coercion, :at
+ alias_method :at, :at_with_coercion
end
# Tells whether the Time object's time lies in the past
diff --git a/activesupport/lib/active_support/json/encoding.rb b/activesupport/lib/active_support/json/encoding.rb
index a50e6524c6..bd2f909ca9 100644
--- a/activesupport/lib/active_support/json/encoding.rb
+++ b/activesupport/lib/active_support/json/encoding.rb
@@ -122,7 +122,13 @@ module ActiveSupport
if string.respond_to?(:force_encoding)
string = string.encode(::Encoding::UTF_8, :undef => :replace).force_encoding(::Encoding::BINARY)
end
- json = string.gsub(escape_regex) { |s| ESCAPED_CHARS[s] }
+ 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}/n, '\\\\u\&')
+ }
json = %("#{json}")
json.force_encoding(::Encoding::UTF_8) if json.respond_to?(:force_encoding)
json
diff --git a/activesupport/test/core_ext/time_ext_test.rb b/activesupport/test/core_ext/time_ext_test.rb
index 0d680832ef..a22e161279 100644
--- a/activesupport/test/core_ext/time_ext_test.rb
+++ b/activesupport/test/core_ext/time_ext_test.rb
@@ -774,6 +774,28 @@ class TimeExtCalculationsTest < ActiveSupport::TestCase
assert_equal(-1, Time.utc(2000) <=> ActiveSupport::TimeWithZone.new( Time.utc(2000, 1, 1, 0, 0, 1), ActiveSupport::TimeZone['UTC'] ))
end
+ def test_at_with_datetime
+ assert_equal Time.utc(2000, 1, 1, 0, 0, 0), Time.at(DateTime.civil(2000, 1, 1, 0, 0, 0))
+
+ # Only test this if the underlying Time.at raises a TypeError
+ begin
+ Time.at_without_coercion(Time.now, 0)
+ rescue TypeError
+ assert_raise(TypeError) { assert_equal(Time.utc(2000, 1, 1, 0, 0, 0), Time.at(DateTime.civil(2000, 1, 1, 0, 0, 0), 0)) }
+ end
+ end
+
+ def test_at_with_time_with_zone
+ assert_equal Time.utc(2000, 1, 1, 0, 0, 0), Time.at(ActiveSupport::TimeWithZone.new(Time.utc(2000, 1, 1, 0, 0, 0), ActiveSupport::TimeZone['UTC']))
+
+ # Only test this if the underlying Time.at raises a TypeError
+ begin
+ Time.at_without_coercion(Time.now, 0)
+ rescue TypeError
+ assert_raise(TypeError) { assert_equal(Time.utc(2000, 1, 1, 0, 0, 0), Time.at(ActiveSupport::TimeWithZone.new(Time.utc(2000, 1, 1, 0, 0, 0), ActiveSupport::TimeZone['UTC']), 0)) }
+ end
+ end
+
def test_eql?
assert_equal true, Time.utc(2000).eql?( ActiveSupport::TimeWithZone.new(Time.utc(2000), ActiveSupport::TimeZone['UTC']) )
assert_equal true, Time.utc(2000).eql?( ActiveSupport::TimeWithZone.new(Time.utc(2000), ActiveSupport::TimeZone["Hawaii"]) )
diff --git a/activesupport/test/json/encoding_test.rb b/activesupport/test/json/encoding_test.rb
index e4e13c3f25..72366f9ab4 100644
--- a/activesupport/test/json/encoding_test.rb
+++ b/activesupport/test/json/encoding_test.rb
@@ -100,11 +100,11 @@ class TestJSONEncoding < Test::Unit::TestCase
def test_utf8_string_encoded_properly_when_kcode_is_utf8
with_kcode 'UTF8' do
result = ActiveSupport::JSON.encode('€2.99')
- assert_equal '"€2.99"', result
+ assert_equal '"\\u20ac2.99"', result
assert_equal(Encoding::UTF_8, result.encoding) if result.respond_to?(:encoding)
result = ActiveSupport::JSON.encode('✎☺')
- assert_equal '"✎☺"', result
+ assert_equal '"\\u270e\\u263a"', result
assert_equal(Encoding::UTF_8, result.encoding) if result.respond_to?(:encoding)
end
end
@@ -113,22 +113,23 @@ class TestJSONEncoding < Test::Unit::TestCase
def test_non_utf8_string_transcodes
s = '二'.encode('Shift_JIS')
result = ActiveSupport::JSON.encode(s)
- assert_equal '"二"', result
+ assert_equal '"\\u4e8c"', result
assert_equal Encoding::UTF_8, result.encoding
end
- end
- def test_wide_utf8_chars
- w = '𠜎'
- result = ActiveSupport::JSON.encode(w)
- assert_equal '"𠜎"', result
- end
+ def test_utf8_hash_key_does_not_change_the_encoding
+ w = { '𠜎' => 'a' }
+ result = ActiveSupport::JSON.encode(w)
+ assert_equal '{"\\u070e":"a"}', result
- def test_wide_utf8_roundtrip
- hash = { :string => "𐒑" }
- json = ActiveSupport::JSON.encode(hash)
- decoded_hash = ActiveSupport::JSON.decode(json)
- assert_equal "𐒑", decoded_hash['string']
+ if RUBY_VERSION >= '2.0'
+ expected_encoding = Encoding::UTF_8
+ else
+ expected_encoding = Encoding::US_ASCII
+ end
+
+ assert_equal expected_encoding, result.encoding
+ end
end
def test_exception_raised_when_encoding_circular_reference_in_array