aboutsummaryrefslogtreecommitdiffstats
path: root/activesupport
diff options
context:
space:
mode:
Diffstat (limited to 'activesupport')
-rw-r--r--activesupport/CHANGELOG.md62
-rw-r--r--activesupport/activesupport.gemspec2
-rw-r--r--activesupport/lib/active_support/all.rb1
-rw-r--r--activesupport/lib/active_support/cache/strategy/local_cache.rb3
-rw-r--r--activesupport/lib/active_support/core_ext/array/grouping.rb12
-rw-r--r--activesupport/lib/active_support/core_ext/class/attribute_accessors.rb11
-rw-r--r--activesupport/lib/active_support/core_ext/hash/conversions.rb9
-rw-r--r--activesupport/lib/active_support/core_ext/hash/deep_merge.rb10
-rw-r--r--activesupport/lib/active_support/core_ext/hash/indifferent_access.rb1
-rw-r--r--activesupport/lib/active_support/core_ext/hash/keys.rb12
-rw-r--r--activesupport/lib/active_support/core_ext/integer/multiple.rb6
-rw-r--r--activesupport/lib/active_support/core_ext/kernel/reporting.rb3
-rw-r--r--activesupport/lib/active_support/core_ext/module/deprecation.rb2
-rw-r--r--activesupport/lib/active_support/core_ext/object/json.rb62
-rw-r--r--activesupport/lib/active_support/core_ext/string/inflections.rb16
-rw-r--r--activesupport/lib/active_support/inflector/methods.rb24
-rw-r--r--activesupport/lib/active_support/json/decoding.rb3
-rw-r--r--activesupport/lib/active_support/json/encoding.rb72
-rw-r--r--activesupport/lib/active_support/notifications.rb2
-rw-r--r--activesupport/lib/active_support/per_thread_registry.rb12
-rw-r--r--activesupport/lib/active_support/subscriber.rb2
-rw-r--r--activesupport/lib/active_support/test_case.rb6
-rw-r--r--activesupport/lib/active_support/time_with_zone.rb8
-rw-r--r--activesupport/test/core_ext/array_ext_test.rb18
-rw-r--r--activesupport/test/core_ext/class/attribute_accessor_test.rb9
-rw-r--r--activesupport/test/core_ext/string_ext_test.rb8
-rw-r--r--activesupport/test/inflector_test.rb6
-rw-r--r--activesupport/test/inflector_test_cases.rb6
-rw-r--r--activesupport/test/json/encoding_test.rb100
-rw-r--r--activesupport/test/message_encryptor_test.rb2
-rw-r--r--activesupport/test/message_verifier_test.rb2
31 files changed, 334 insertions, 158 deletions
diff --git a/activesupport/CHANGELOG.md b/activesupport/CHANGELOG.md
index e718e79877..95253567c0 100644
--- a/activesupport/CHANGELOG.md
+++ b/activesupport/CHANGELOG.md
@@ -1,12 +1,64 @@
-* Added Numeric#in_milliseconds, like 1.hour.in_milliseconds, so we can feed them to JavaScript functions like getTime().
+* Unify `cattr_*` interface: allow to pass a block to `cattr_reader`.
- *DHH*
+ Example:
+
+ class A
+ cattr_reader(:defr) { 'default_reader_value' }
+ end
+ A.defr # => 'default_reader_value'
+
+ *Alexey Chernenkov*
+
+* Improved compatibility with the stdlib JSON gem.
+
+ Previously, calling `::JSON.{generate,dump}` sometimes causes unexpected
+ failures such as intridea/multi_json#86.
+
+ `::JSON.{generate,dump}` now bypasses the ActiveSupport JSON encoder
+ completely and yields the same result with or without ActiveSupport. This
+ means that it will **not** call `as_json` and will ignore any options that
+ the JSON gem does not natively understand. To invoke ActiveSupport's JSON
+ encoder instead, use `obj.to_json(options)` or
+ `ActiveSupport::JSON.encode(obj, options)`.
+
+ *Godfrey Chan*
+
+* Fix Active Support `Time#to_json` and `DateTime#to_json` to return 3 decimal
+ places worth of fractional seconds, similar to `TimeWithZone`.
+
+ *Ryan Glover*
+
+* Removed circular reference protection in JSON encoder, deprecated
+ `ActiveSupport::JSON::Encoding::CircularReferenceError`.
+
+ *Godfrey Chan*, *Sergio Campamá*
+
+* Add `capitalize` option to `Inflector.humanize`, so strings can be humanized without being capitalized:
+
+ 'employee_salary'.humanize # => "Employee salary"
+ 'employee_salary'.humanize(capitalize: false) # => "employee salary"
+
+ *claudiob*
+
+* Fixed `Object#as_json` and `Struct#as_json` not working properly with options. They now take
+ the same options as `Hash#as_json`:
+
+ struct = Struct.new(:foo, :bar).new
+ struct.foo = "hello"
+ struct.bar = "world"
+ json = struct.as_json(only: [:foo]) # => {foo: "hello"}
+
+ *Sergio Campamá*, *Godfrey Chan*
+
+* Added `Numeric#in_milliseconds`, like `1.hour.in_milliseconds`, so we can feed them to JavaScript functions like `getTime()`.
+
+ *DHH*
-* Calling ActiveSupport::JSON.decode with unsupported options now raises an error.
+* Calling `ActiveSupport::JSON.decode` with unsupported options now raises an error.
*Godfrey Chan*
-* Support :unless_exist in FileStore
+* Support `:unless_exist` in `FileStore`.
*Michael Grosser*
@@ -19,7 +71,7 @@
*Benjamin Fleischer*
-* Disable the ability to iterate over Range of AS::TimeWithZone
+* Disable the ability to iterate over Range of AS::TimeWithZone
due to significant performance issues.
*Bogdan Gusiev*
diff --git a/activesupport/activesupport.gemspec b/activesupport/activesupport.gemspec
index ffc2c2074e..c27c50e47b 100644
--- a/activesupport/activesupport.gemspec
+++ b/activesupport/activesupport.gemspec
@@ -22,7 +22,7 @@ Gem::Specification.new do |s|
s.add_dependency('i18n', '~> 0.6', '>= 0.6.4')
s.add_dependency 'json', '~> 1.7'
- s.add_dependency 'tzinfo', '~> 0.3.37'
+ s.add_dependency 'tzinfo', '~> 1.1'
s.add_dependency 'minitest', '~> 5.0'
s.add_dependency 'thread_safe','~> 0.1'
end
diff --git a/activesupport/lib/active_support/all.rb b/activesupport/lib/active_support/all.rb
index 151008bbaa..f537818300 100644
--- a/activesupport/lib/active_support/all.rb
+++ b/activesupport/lib/active_support/all.rb
@@ -1,4 +1,3 @@
require 'active_support'
-require 'active_support/deprecation'
require 'active_support/time'
require 'active_support/core_ext'
diff --git a/activesupport/lib/active_support/cache/strategy/local_cache.rb b/activesupport/lib/active_support/cache/strategy/local_cache.rb
index fb42c4a41e..cea7eee924 100644
--- a/activesupport/lib/active_support/cache/strategy/local_cache.rb
+++ b/activesupport/lib/active_support/cache/strategy/local_cache.rb
@@ -23,6 +23,9 @@ module ActiveSupport
def set_cache_for(local_cache_key, value)
@registry[local_cache_key] = value
end
+
+ def self.set_cache_for(l, v); instance.set_cache_for l, v; end
+ def self.cache_for(l); instance.cache_for l; end
end
# Simple memory backed cache. This cache is not thread safe and is intended only
diff --git a/activesupport/lib/active_support/core_ext/array/grouping.rb b/activesupport/lib/active_support/core_ext/array/grouping.rb
index 37f007c751..3529d57174 100644
--- a/activesupport/lib/active_support/core_ext/array/grouping.rb
+++ b/activesupport/lib/active_support/core_ext/array/grouping.rb
@@ -53,7 +53,7 @@ class Array
# ["4", "5"]
# ["6", "7"]
def in_groups(number, fill_with = nil)
- # size / number gives minor group size;
+ # size.div number gives minor group size;
# size % number gives how many objects need extra accommodation;
# each group hold either division or division + 1 items.
division = size.div number
@@ -83,10 +83,10 @@ class Array
#
# [1, 2, 3, 4, 5].split(3) # => [[1, 2], [4, 5]]
# (1..10).to_a.split { |i| i % 3 == 0 } # => [[1, 2], [4, 5], [7, 8], [10]]
- def split(value = nil, &block)
- if block
+ def split(value = nil)
+ if block_given?
inject([[]]) do |results, element|
- if block.call(element)
+ if yield(element)
results << []
else
results.last << element
@@ -95,9 +95,9 @@ class Array
results
end
else
- results, arr = [[]], self
+ results, arr = [[]], self.dup
until arr.empty?
- if (idx = index(value))
+ if (idx = arr.index(value))
results.last.concat(arr.shift(idx))
arr.shift
results << []
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 34859617c9..6daa828b24 100644
--- a/activesupport/lib/active_support/core_ext/class/attribute_accessors.rb
+++ b/activesupport/lib/active_support/core_ext/class/attribute_accessors.rb
@@ -29,6 +29,16 @@ class Class
# end
#
# Person.new.hair_colors # => NoMethodError
+ #
+ # Also, you can pass a block to set up the attribute with a default value.
+ #
+ # class Person
+ # cattr_reader :hair_colors do
+ # [:brown, :black, :blonde, :red]
+ # end
+ # end
+ #
+ # Person.hair_colors # => [:brown, :black, :blonde, :red]
def cattr_reader(*syms)
options = syms.extract_options!
syms.each do |sym|
@@ -50,6 +60,7 @@ class Class
end
EOS
end
+ class_variable_set("@@#{sym}", yield) if block_given?
end
end
diff --git a/activesupport/lib/active_support/core_ext/hash/conversions.rb b/activesupport/lib/active_support/core_ext/hash/conversions.rb
index 8930376ac8..2684c772ea 100644
--- a/activesupport/lib/active_support/core_ext/hash/conversions.rb
+++ b/activesupport/lib/active_support/core_ext/hash/conversions.rb
@@ -10,7 +10,7 @@ require 'active_support/core_ext/string/inflections'
class Hash
# Returns a string containing an XML representation of its receiver:
#
- # {'foo' => 1, 'bar' => 2}.to_xml
+ # { foo: 1, bar: 2 }.to_xml
# # =>
# # <?xml version="1.0" encoding="UTF-8"?>
# # <hash>
@@ -43,7 +43,10 @@ class Hash
# end
#
# { foo: Foo.new }.to_xml(skip_instruct: true)
- # # => "<hash><bar>fooing!</bar></hash>"
+ # # =>
+ # # <hash>
+ # # <bar>fooing!</bar>
+ # # </hash>
#
# * Otherwise, a node with +key+ as tag is created with a string representation of
# +value+ as text node. If +value+ is +nil+ an attribute "nil" set to "true" is added.
@@ -201,7 +204,7 @@ module ActiveSupport
end
def become_empty_string?(value)
- # {"string" => true}
+ # { "string" => true }
# No tests fail when the second term is removed.
value['type'] == 'string' && value['nil'] != 'true'
end
diff --git a/activesupport/lib/active_support/core_ext/hash/deep_merge.rb b/activesupport/lib/active_support/core_ext/hash/deep_merge.rb
index e07db50b77..42fece6c28 100644
--- a/activesupport/lib/active_support/core_ext/hash/deep_merge.rb
+++ b/activesupport/lib/active_support/core_ext/hash/deep_merge.rb
@@ -1,13 +1,13 @@
class Hash
# Returns a new hash with +self+ and +other_hash+ merged recursively.
#
- # h1 = { x: { y: [4,5,6] }, z: [7,8,9] }
- # h2 = { x: { y: [7,8,9] }, z: 'xyz' }
+ # h1 = { x: { y: [4, 5, 6] }, z: [7, 8, 9] }
+ # h2 = { x: { y: [7, 8, 9] }, z: 'xyz' }
#
- # h1.deep_merge(h2) #=> {x: {y: [7, 8, 9]}, z: "xyz"}
- # h2.deep_merge(h1) #=> {x: {y: [4, 5, 6]}, z: [7, 8, 9]}
+ # h1.deep_merge(h2) # => {:x=>{:y=>[7, 8, 9]}, :z=>"xyz"}
+ # h2.deep_merge(h1) # => {:x=>{:y=>[4, 5, 6]}, :z=>[7, 8, 9]}
# h1.deep_merge(h2) { |key, old, new| Array.wrap(old) + Array.wrap(new) }
- # #=> {:x=>{:y=>[4, 5, 6, 7, 8, 9]}, :z=>[7, 8, 9, "xyz"]}
+ # # => {:x=>{:y=>[4, 5, 6, 7, 8, 9]}, :z=>[7, 8, 9, "xyz"]}
def deep_merge(other_hash, &block)
dup.deep_merge!(other_hash, &block)
end
diff --git a/activesupport/lib/active_support/core_ext/hash/indifferent_access.rb b/activesupport/lib/active_support/core_ext/hash/indifferent_access.rb
index 981e8436bf..970d6faa1d 100644
--- a/activesupport/lib/active_support/core_ext/hash/indifferent_access.rb
+++ b/activesupport/lib/active_support/core_ext/hash/indifferent_access.rb
@@ -18,5 +18,6 @@ class Hash
#
# b = { b: 1 }
# { a: b }.with_indifferent_access['a'] # calls b.nested_under_indifferent_access
+ # # => {"b"=>32}
alias nested_under_indifferent_access with_indifferent_access
end
diff --git a/activesupport/lib/active_support/core_ext/hash/keys.rb b/activesupport/lib/active_support/core_ext/hash/keys.rb
index b4c451ace4..1845e74c45 100644
--- a/activesupport/lib/active_support/core_ext/hash/keys.rb
+++ b/activesupport/lib/active_support/core_ext/hash/keys.rb
@@ -4,7 +4,7 @@ class Hash
# hash = { name: 'Rob', age: '28' }
#
# hash.transform_keys{ |key| key.to_s.upcase }
- # # => { "NAME" => "Rob", "AGE" => "28" }
+ # # => {"NAME"=>"Rob", "AGE"=>"28"}
def transform_keys
result = {}
each_key do |key|
@@ -27,7 +27,7 @@ class Hash
# hash = { name: 'Rob', age: '28' }
#
# hash.stringify_keys
- # #=> { "name" => "Rob", "age" => "28" }
+ # # => {"name"=>"Rob", "age"=>"28"}
def stringify_keys
transform_keys{ |key| key.to_s }
end
@@ -44,7 +44,7 @@ class Hash
# hash = { 'name' => 'Rob', 'age' => '28' }
#
# hash.symbolize_keys
- # #=> { name: "Rob", age: "28" }
+ # # => {"name"=>"Rob", "age"=>"28"}
def symbolize_keys
transform_keys{ |key| key.to_sym rescue key }
end
@@ -78,7 +78,7 @@ class Hash
# hash = { person: { name: 'Rob', age: '28' } }
#
# hash.deep_transform_keys{ |key| key.to_s.upcase }
- # # => { "PERSON" => { "NAME" => "Rob", "AGE" => "28" } }
+ # # => {"PERSON"=>{"NAME"=>"Rob", "AGE"=>"28"}}
def deep_transform_keys(&block)
result = {}
each do |key, value|
@@ -105,7 +105,7 @@ class Hash
# hash = { person: { name: 'Rob', age: '28' } }
#
# hash.deep_stringify_keys
- # # => { "person" => { "name" => "Rob", "age" => "28" } }
+ # # => {"person"=>{"name"=>"Rob", "age"=>"28"}}
def deep_stringify_keys
deep_transform_keys{ |key| key.to_s }
end
@@ -124,7 +124,7 @@ class Hash
# hash = { 'person' => { 'name' => 'Rob', 'age' => '28' } }
#
# hash.deep_symbolize_keys
- # # => { person: { name: "Rob", age: "28" } }
+ # # => {:person=>{:name=>"Rob", :age=>"28"}}
def deep_symbolize_keys
deep_transform_keys{ |key| key.to_sym rescue key }
end
diff --git a/activesupport/lib/active_support/core_ext/integer/multiple.rb b/activesupport/lib/active_support/core_ext/integer/multiple.rb
index 7c6c2f1ca7..c668c7c2eb 100644
--- a/activesupport/lib/active_support/core_ext/integer/multiple.rb
+++ b/activesupport/lib/active_support/core_ext/integer/multiple.rb
@@ -1,9 +1,9 @@
class Integer
# Check whether the integer is evenly divisible by the argument.
#
- # 0.multiple_of?(0) #=> true
- # 6.multiple_of?(5) #=> false
- # 10.multiple_of?(2) #=> true
+ # 0.multiple_of?(0) # => true
+ # 6.multiple_of?(5) # => false
+ # 10.multiple_of?(2) # => true
def multiple_of?(number)
number != 0 ? self % number == 0 : zero?
end
diff --git a/activesupport/lib/active_support/core_ext/kernel/reporting.rb b/activesupport/lib/active_support/core_ext/kernel/reporting.rb
index 36ab836457..df11737a6b 100644
--- a/activesupport/lib/active_support/core_ext/kernel/reporting.rb
+++ b/activesupport/lib/active_support/core_ext/kernel/reporting.rb
@@ -60,8 +60,7 @@ module Kernel
# puts 'This code gets executed and nothing related to ZeroDivisionError was seen'
def suppress(*exception_classes)
yield
- rescue Exception => e
- raise unless exception_classes.any? { |cls| e.kind_of?(cls) }
+ rescue *exception_classes
end
# Captures the given stream and returns it:
diff --git a/activesupport/lib/active_support/core_ext/module/deprecation.rb b/activesupport/lib/active_support/core_ext/module/deprecation.rb
index d873de197f..56d670fbe8 100644
--- a/activesupport/lib/active_support/core_ext/module/deprecation.rb
+++ b/activesupport/lib/active_support/core_ext/module/deprecation.rb
@@ -1,5 +1,3 @@
-require 'active_support/deprecation/method_wrappers'
-
class Module
# deprecate :foo
# deprecate bar: 'message'
diff --git a/activesupport/lib/active_support/core_ext/object/json.rb b/activesupport/lib/active_support/core_ext/object/json.rb
index 554da1a2aa..5157b0402f 100644
--- a/activesupport/lib/active_support/core_ext/object/json.rb
+++ b/activesupport/lib/active_support/core_ext/object/json.rb
@@ -1,35 +1,60 @@
# Hack to load json gem first so we can overwrite its to_json.
require 'json'
require 'bigdecimal'
+require 'active_support/core_ext/big_decimal/conversions' # for #to_s
+require 'active_support/core_ext/hash/except'
+require 'active_support/core_ext/hash/slice'
+require 'active_support/core_ext/object/instance_variables'
require 'time'
+require 'active_support/core_ext/time/conversions'
+require 'active_support/core_ext/date_time/conversions'
+require 'active_support/core_ext/date/conversions'
+require 'active_support/core_ext/module/aliasing'
# The JSON gem adds a few modules to Ruby core classes containing :to_json definition, overwriting
# their default behavior. That said, we need to define the basic to_json method in all of them,
# 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}
+# should give exactly the same results with or without active support.
[Object, Array, FalseClass, Float, Hash, Integer, NilClass, String, TrueClass].each do |klass|
klass.class_eval do
- # Dumps object in JSON (JavaScript Object Notation). See www.json.org for more info.
- def to_json(options = nil)
- ActiveSupport::JSON.encode(self, options)
+ def to_json_with_active_support_encoder(options = nil)
+ if options.is_a?(::JSON::State)
+ # Called from JSON.{generate,dump}, forward it to JSON gem's to_json
+ self.to_json_without_active_support_encoder(options)
+ else
+ # to_json is being invoked directly, use ActiveSupport's encoder
+ ActiveSupport::JSON.encode(self, options)
+ end
end
+
+ alias_method_chain :to_json, :active_support_encoder
end
end
class Object
def as_json(options = nil) #:nodoc:
if respond_to?(:to_hash)
- to_hash
+ to_hash.as_json(options)
else
- instance_values
+ instance_values.as_json(options)
end
end
end
class Struct #:nodoc:
def as_json(options = nil)
- Hash[members.zip(values)]
+ Hash[members.zip(values)].as_json(options)
end
end
@@ -91,7 +116,7 @@ end
class Float
# Encoding Infinity or NaN to JSON should return "null". The default returns
- # "Infinity" or "NaN" which breaks parsing the JSON. E.g. JSON.parse('[NaN]').
+ # "Infinity" or "NaN" which are not valid JSON.
def as_json(options = nil) #:nodoc:
finite? ? self : nil
end
@@ -139,14 +164,11 @@ end
class Array
def as_json(options = nil) #:nodoc:
- # use encoder as a proxy to call as_json on all elements, to protect from circular references
- encoder = options && options[:encoder] || ActiveSupport::JSON::Encoding::Encoder.new(options)
- map { |v| encoder.as_json(v, options) }
+ map { |v| v.as_json(options && options.dup) }
end
def encode_json(encoder) #:nodoc:
- # we assume here that the encoder has already run as_json on self and the elements, so we run encode_json directly
- "[#{map { |v| v.encode_json(encoder) } * ','}]"
+ "[#{map { |v| v.as_json.encode_json(encoder) } * ','}]"
end
end
@@ -165,26 +187,18 @@ class Hash
self
end
- # use encoder as a proxy to call as_json on all values in the subset, to protect from circular references
- encoder = options && options[:encoder] || ActiveSupport::JSON::Encoding::Encoder.new(options)
- Hash[subset.map { |k, v| [k.to_s, encoder.as_json(v, options)] }]
+ Hash[subset.map { |k, v| [k.to_s, v.as_json(options && options.dup)] }]
end
def encode_json(encoder) #:nodoc:
- # values are encoded with use_options = false, because we don't want hash representations from ActiveModel to be
- # processed once again with as_json with options, as this could cause unexpected results (i.e. missing fields);
-
- # on the other hand, we need to run as_json on the elements, because the model representation may contain fields
- # like Time/Date in their original (not jsonified) form, etc.
-
- "{#{map { |k,v| "#{encoder.encode(k.to_s)}:#{encoder.encode(v, false)}" } * ','}}"
+ "{#{map { |k,v| "#{k.as_json.encode_json(encoder)}:#{v.as_json.encode_json(encoder)}" } * ','}}"
end
end
class Time
def as_json(options = nil) #:nodoc:
if ActiveSupport.use_standard_json_time_format
- xmlschema
+ xmlschema(3)
else
%(#{strftime("%Y/%m/%d %H:%M:%S")} #{formatted_offset(false)})
end
@@ -204,7 +218,7 @@ end
class DateTime
def as_json(options = nil) #:nodoc:
if ActiveSupport.use_standard_json_time_format
- xmlschema
+ xmlschema(3)
else
strftime('%Y/%m/%d %H:%M:%S %z')
end
diff --git a/activesupport/lib/active_support/core_ext/string/inflections.rb b/activesupport/lib/active_support/core_ext/string/inflections.rb
index 56e8a5f98d..b7b750c77b 100644
--- a/activesupport/lib/active_support/core_ext/string/inflections.rb
+++ b/activesupport/lib/active_support/core_ext/string/inflections.rb
@@ -190,13 +190,19 @@ class String
ActiveSupport::Inflector.classify(self)
end
- # Capitalizes the first word, turns underscores into spaces, and strips '_id'.
+ # Capitalizes the first word, turns underscores into spaces, and strips a
+ # trailing '_id' if present.
# Like +titleize+, this is meant for creating pretty output.
#
- # 'employee_salary'.humanize # => "Employee salary"
- # 'author_id'.humanize # => "Author"
- def humanize
- ActiveSupport::Inflector.humanize(self)
+ # The capitalization of the first word can be turned off by setting the
+ # optional parameter +capitalize+ to false.
+ # By default, this parameter is true.
+ #
+ # 'employee_salary'.humanize # => "Employee salary"
+ # 'author_id'.humanize # => "Author"
+ # 'author_id'.humanize(capitalize: false) # => "author"
+ def humanize(options = {})
+ ActiveSupport::Inflector.humanize(self, options)
end
# Creates a foreign key name from a class name.
diff --git a/activesupport/lib/active_support/inflector/methods.rb b/activesupport/lib/active_support/inflector/methods.rb
index ffdb7b53c4..0f7ae98a8a 100644
--- a/activesupport/lib/active_support/inflector/methods.rb
+++ b/activesupport/lib/active_support/inflector/methods.rb
@@ -98,20 +98,26 @@ module ActiveSupport
word
end
- # Capitalizes the first word and turns underscores into spaces and strips a
- # trailing "_id", if any. Like +titleize+, this is meant for creating pretty
- # output.
- #
- # 'employee_salary'.humanize # => "Employee salary"
- # 'author_id'.humanize # => "Author"
- def humanize(lower_case_and_underscored_word)
+ # Capitalizes the first word, turns underscores into spaces, and strips a
+ # trailing '_id' if present.
+ # Like +titleize+, this is meant for creating pretty output.
+ #
+ # The capitalization of the first word can be turned off by setting the
+ # optional parameter +capitalize+ to false.
+ # By default, this parameter is true.
+ #
+ # humanize('employee_salary') # => "Employee salary"
+ # humanize('author_id') # => "Author"
+ # humanize('author_id', capitalize: false) # => "author"
+ def humanize(lower_case_and_underscored_word, options = {})
result = lower_case_and_underscored_word.to_s.dup
inflections.humans.each { |(rule, replacement)| break if result.sub!(rule, replacement) }
result.gsub!(/_id$/, "")
result.tr!('_', ' ')
- result.gsub(/([a-z\d]*)/i) { |match|
+ result.gsub!(/([a-z\d]*)/i) { |match|
"#{inflections.acronyms[match] || match.downcase}"
- }.gsub(/^\w/) { $&.upcase }
+ }
+ options.fetch(:capitalize, true) ? result.gsub(/^\w/) { $&.upcase } : result
end
# Capitalizes all the words and replaces some characters in the string to
diff --git a/activesupport/lib/active_support/json/decoding.rb b/activesupport/lib/active_support/json/decoding.rb
index 315c76199a..8b5fc70dee 100644
--- a/activesupport/lib/active_support/json/decoding.rb
+++ b/activesupport/lib/active_support/json/decoding.rb
@@ -7,6 +7,9 @@ module ActiveSupport
mattr_accessor :parse_json_times
module JSON
+ # matches YAML-formatted dates
+ DATE_REGEX = /^(?:\d{4}-\d{2}-\d{2}|\d{4}-\d{1,2}-\d{1,2}[T \t]+\d{1,2}:\d{2}:\d{2}(\.[0-9]*)?(([ \t]*)Z|[-+]\d{2}?(:\d{2})?))$/
+
class << self
# Parses a JSON string (JavaScript Object Notation) into a hash.
# See www.json.org for more info.
diff --git a/activesupport/lib/active_support/json/encoding.rb b/activesupport/lib/active_support/json/encoding.rb
index 4d73672047..0e1c379b5b 100644
--- a/activesupport/lib/active_support/json/encoding.rb
+++ b/activesupport/lib/active_support/json/encoding.rb
@@ -3,15 +3,6 @@
require 'active_support/core_ext/object/json'
require 'active_support/core_ext/module/delegation'
-require 'active_support/core_ext/big_decimal/conversions' # for #to_s
-require 'active_support/core_ext/hash/except'
-require 'active_support/core_ext/hash/slice'
-require 'active_support/core_ext/object/instance_variables'
-require 'active_support/core_ext/time/conversions'
-require 'active_support/core_ext/date_time/conversions'
-require 'active_support/core_ext/date/conversions'
-require 'set'
-
module ActiveSupport
class << self
delegate :use_standard_json_time_format, :use_standard_json_time_format=,
@@ -21,9 +12,6 @@ module ActiveSupport
end
module JSON
- # matches YAML-formatted dates
- DATE_REGEX = /^(?:\d{4}-\d{2}-\d{2}|\d{4}-\d{1,2}-\d{1,2}[T \t]+\d{1,2}:\d{2}:\d{2}(\.[0-9]*)?(([ \t]*)Z|[-+]\d{2}?(:\d{2})?))$/
-
# Dumps objects in JSON (JavaScript Object Notation).
# See www.json.org for more info.
#
@@ -34,56 +22,22 @@ module ActiveSupport
end
module Encoding #:nodoc:
- class CircularReferenceError < StandardError; end
-
class Encoder
attr_reader :options
def initialize(options = nil)
@options = options || {}
- @seen = Set.new
- end
-
- def encode(value, use_options = true)
- check_for_circular_references(value) do
- jsonified = use_options ? value.as_json(options_for(value)) : value.as_json
- jsonified.encode_json(self)
- end
end
- # like encode, but only calls as_json, without encoding to string.
- def as_json(value, use_options = true)
- check_for_circular_references(value) do
- use_options ? value.as_json(options_for(value)) : value.as_json
- end
- end
-
- def options_for(value)
- if value.is_a?(Array) || value.is_a?(Hash)
- # hashes and arrays need to get encoder in the options, so that
- # they can detect circular references.
- options.merge(:encoder => self)
- else
- options.dup
- end
+ def encode(value)
+ value.as_json(options.dup).encode_json(self)
end
def escape(string)
Encoding.escape(string)
end
-
- private
- def check_for_circular_references(value)
- unless @seen.add?(value.__id__)
- raise CircularReferenceError, 'object references itself'
- end
- yield
- ensure
- @seen.delete(value.__id__)
- end
end
-
ESCAPED_CHARS = {
"\x00" => '\u0000', "\x01" => '\u0001', "\x02" => '\u0002',
"\x03" => '\u0003', "\x04" => '\u0004', "\x05" => '\u0005',
@@ -138,6 +92,28 @@ module ActiveSupport
json.force_encoding(::Encoding::UTF_8)
json
end
+
+ # Deprecate CircularReferenceError
+ def const_missing(name)
+ if name == :CircularReferenceError
+ message = "The JSON encoder in Rails 4.1 no longer offers protection from circular references. " \
+ "You are seeing this warning because you are rescuing from (or otherwise referencing) " \
+ "ActiveSupport::Encoding::CircularReferenceError. In the future, this error will be " \
+ "removed from Rails. You should remove these rescue blocks from your code and ensure " \
+ "that your data structures are free of circular references so they can be properly " \
+ "serialized into JSON.\n\n" \
+ "For example, the following Hash contains a circular reference to itself:\n" \
+ " h = {}\n" \
+ " h['circular'] = h\n" \
+ "In this case, calling h.to_json would not work properly."
+
+ ActiveSupport::Deprecation.warn message
+
+ SystemStackError
+ else
+ super
+ end
+ end
end
self.use_standard_json_time_format = true
diff --git a/activesupport/lib/active_support/notifications.rb b/activesupport/lib/active_support/notifications.rb
index b32aa75e59..7a96c66626 100644
--- a/activesupport/lib/active_support/notifications.rb
+++ b/activesupport/lib/active_support/notifications.rb
@@ -178,7 +178,7 @@ module ActiveSupport
end
def instrumenter
- InstrumentationRegistry.instrumenter_for(notifier)
+ InstrumentationRegistry.instance.instrumenter_for(notifier)
end
end
diff --git a/activesupport/lib/active_support/per_thread_registry.rb b/activesupport/lib/active_support/per_thread_registry.rb
index aa682fb36c..a5e7389d16 100644
--- a/activesupport/lib/active_support/per_thread_registry.rb
+++ b/activesupport/lib/active_support/per_thread_registry.rb
@@ -32,21 +32,19 @@ module ActiveSupport
#
# If the class has an initializer, it must accept no arguments.
module PerThreadRegistry
+ def instance
+ Thread.current[name] ||= new
+ end
+
protected
def method_missing(name, *args, &block) # :nodoc:
# Caches the method definition as a singleton method of the receiver.
define_singleton_method(name) do |*a, &b|
- per_thread_registry_instance.public_send(name, *a, &b)
+ instance.public_send(name, *a, &b)
end
send(name, *args, &block)
end
-
- private
-
- def per_thread_registry_instance
- Thread.current[name] ||= new
- end
end
end
diff --git a/activesupport/lib/active_support/subscriber.rb b/activesupport/lib/active_support/subscriber.rb
index f2966f23fc..4b9b48539f 100644
--- a/activesupport/lib/active_support/subscriber.rb
+++ b/activesupport/lib/active_support/subscriber.rb
@@ -94,7 +94,7 @@ module ActiveSupport
private
def event_stack
- SubscriberQueueRegistry.get_queue(@queue_key)
+ SubscriberQueueRegistry.instance.get_queue(@queue_key)
end
end
diff --git a/activesupport/lib/active_support/test_case.rb b/activesupport/lib/active_support/test_case.rb
index 5e24118d34..d687d69603 100644
--- a/activesupport/lib/active_support/test_case.rb
+++ b/activesupport/lib/active_support/test_case.rb
@@ -44,10 +44,8 @@ module ActiveSupport
end
# FIXME: we have tests that depend on run order, we should fix that and
- # remove this method.
- def self.test_order # :nodoc:
- :sorted
- end
+ # remove this method call.
+ self.i_suck_and_my_tests_are_order_dependent!
include ActiveSupport::Testing::TaggedLogging
include ActiveSupport::Testing::SetupAndTeardown
diff --git a/activesupport/lib/active_support/time_with_zone.rb b/activesupport/lib/active_support/time_with_zone.rb
index 95b9b8e5ae..50db7da9d9 100644
--- a/activesupport/lib/active_support/time_with_zone.rb
+++ b/activesupport/lib/active_support/time_with_zone.rb
@@ -146,12 +146,12 @@ module ActiveSupport
# to +false+.
#
# # With ActiveSupport::JSON::Encoding.use_standard_json_time_format = true
- # Time.utc(2005,2,1,15,15,10).in_time_zone.to_json
- # # => "2005-02-01T15:15:10Z"
+ # Time.utc(2005,2,1,15,15,10).in_time_zone("Hawaii").to_json
+ # # => "2005-02-01T05:15:10.000-10:00"
#
# # With ActiveSupport::JSON::Encoding.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"
+ # Time.utc(2005,2,1,15,15,10).in_time_zone("Hawaii").to_json
+ # # => "2005/02/01 05:15:10 -1000"
def as_json(options = nil)
if ActiveSupport::JSON::Encoding.use_standard_json_time_format
xmlschema(3)
diff --git a/activesupport/test/core_ext/array_ext_test.rb b/activesupport/test/core_ext/array_ext_test.rb
index 6cd0eb39b7..57722fd52a 100644
--- a/activesupport/test/core_ext/array_ext_test.rb
+++ b/activesupport/test/core_ext/array_ext_test.rb
@@ -212,18 +212,24 @@ class ArraySplitTests < ActiveSupport::TestCase
end
def test_split_with_argument
- assert_equal [[1, 2], [4, 5]], [1, 2, 3, 4, 5].split(3)
- assert_equal [[1, 2, 3, 4, 5]], [1, 2, 3, 4, 5].split(0)
+ a = [1, 2, 3, 4, 5]
+ assert_equal [[1, 2], [4, 5]], a.split(3)
+ assert_equal [[1, 2, 3, 4, 5]], a.split(0)
+ assert_equal [1, 2, 3, 4, 5], a
end
def test_split_with_block
- assert_equal [[1, 2], [4, 5], [7, 8], [10]], (1..10).to_a.split { |i| i % 3 == 0 }
+ a = (1..10).to_a
+ assert_equal [[1, 2], [4, 5], [7, 8], [10]], a.split { |i| i % 3 == 0 }
+ assert_equal [1, 2, 3, 4, 5, 6, 7, 8, 9 ,10], a
end
def test_split_with_edge_values
- assert_equal [[], [2, 3, 4, 5]], [1, 2, 3, 4, 5].split(1)
- assert_equal [[1, 2, 3, 4], []], [1, 2, 3, 4, 5].split(5)
- assert_equal [[], [2, 3, 4], []], [1, 2, 3, 4, 5].split { |i| i == 1 || i == 5 }
+ a = [1, 2, 3, 4, 5]
+ assert_equal [[], [2, 3, 4, 5]], a.split(1)
+ assert_equal [[1, 2, 3, 4], []], a.split(5)
+ assert_equal [[], [2, 3, 4], []], a.split { |i| i == 1 || i == 5 }
+ assert_equal [1, 2, 3, 4, 5], a
end
end
diff --git a/activesupport/test/core_ext/class/attribute_accessor_test.rb b/activesupport/test/core_ext/class/attribute_accessor_test.rb
index 0d5f39a72b..3bc948f3a6 100644
--- a/activesupport/test/core_ext/class/attribute_accessor_test.rb
+++ b/activesupport/test/core_ext/class/attribute_accessor_test.rb
@@ -8,6 +8,9 @@ class ClassAttributeAccessorTest < ActiveSupport::TestCase
cattr_accessor :bar, :instance_writer => false
cattr_reader :shaq, :instance_reader => false
cattr_accessor :camp, :instance_accessor => false
+ cattr_accessor(:defa) { 'default_accessor_value' }
+ cattr_reader(:defr) { 'default_reader_value' }
+ cattr_writer(:defw) { 'default_writer_value' }
end
@object = @class.new
end
@@ -58,4 +61,10 @@ class ClassAttributeAccessorTest < ActiveSupport::TestCase
end
assert_equal "invalid class attribute name: 1nvalid", exception.message
end
+
+ def test_should_use_default_value_if_block_passed
+ assert_equal 'default_accessor_value', @class.defa
+ assert_equal 'default_reader_value', @class.defr
+ assert_equal 'default_writer_value', @class.class_variable_get('@@defw')
+ end
end
diff --git a/activesupport/test/core_ext/string_ext_test.rb b/activesupport/test/core_ext/string_ext_test.rb
index 3cb66d4eec..20e3d4802e 100644
--- a/activesupport/test/core_ext/string_ext_test.rb
+++ b/activesupport/test/core_ext/string_ext_test.rb
@@ -155,6 +155,12 @@ class StringInflectionsTest < ActiveSupport::TestCase
end
end
+ def test_humanize_without_capitalize
+ UnderscoreToHumanWithoutCapitalize.each do |underscore, human|
+ assert_equal(human, underscore.humanize(capitalize: false))
+ end
+ end
+
def test_ord
assert_equal 97, 'a'.ord
assert_equal 97, 'abc'.ord
@@ -270,7 +276,7 @@ class StringInflectionsTest < ActiveSupport::TestCase
def test_truncate_should_not_be_html_safe
assert !"Hello World!".truncate(12).html_safe?
end
-
+
def test_remove
assert_equal "Summer", "Fast Summer".remove(/Fast /)
assert_equal "Summer", "Fast Summer".remove!(/Fast /)
diff --git a/activesupport/test/inflector_test.rb b/activesupport/test/inflector_test.rb
index 32739d45a9..6184df481f 100644
--- a/activesupport/test/inflector_test.rb
+++ b/activesupport/test/inflector_test.rb
@@ -287,6 +287,12 @@ class InflectorTest < ActiveSupport::TestCase
end
end
+ def test_humanize_without_capitalize
+ UnderscoreToHumanWithoutCapitalize.each do |underscore, human|
+ assert_equal(human, ActiveSupport::Inflector.humanize(underscore, capitalize: false))
+ end
+ end
+
def test_humanize_by_rule
ActiveSupport::Inflector.inflections do |inflect|
inflect.human(/_cnt$/i, '\1_count')
diff --git a/activesupport/test/inflector_test_cases.rb b/activesupport/test/inflector_test_cases.rb
index cc36d62138..b34a946baf 100644
--- a/activesupport/test/inflector_test_cases.rb
+++ b/activesupport/test/inflector_test_cases.rb
@@ -212,6 +212,12 @@ module InflectorTestCases
"underground" => "Underground"
}
+ UnderscoreToHumanWithoutCapitalize = {
+ "employee_salary" => "employee salary",
+ "employee_id" => "employee",
+ "underground" => "underground"
+ }
+
MixtureToTitleCase = {
'active_record' => 'Active Record',
'ActiveRecord' => 'Active Record',
diff --git a/activesupport/test/json/encoding_test.rb b/activesupport/test/json/encoding_test.rb
index d549113ff4..39da760bf2 100644
--- a/activesupport/test/json/encoding_test.rb
+++ b/activesupport/test/json/encoding_test.rb
@@ -13,7 +13,7 @@ class TestJSONEncoding < ActiveSupport::TestCase
class Hashlike
def to_hash
- { :a => 1 }
+ { :foo => "hello", :bar => "world" }
end
end
@@ -32,6 +32,19 @@ class TestJSONEncoding < ActiveSupport::TestCase
end
end
+ class HashWithAsJson < Hash
+ attr_accessor :as_json_called
+
+ def initialize(*)
+ super
+ end
+
+ def as_json(options={})
+ @as_json_called = true
+ super
+ end
+ end
+
TrueTests = [[ true, %(true) ]]
FalseTests = [[ false, %(false) ]]
NilTests = [[ nil, %(null) ]]
@@ -61,7 +74,7 @@ class TestJSONEncoding < ActiveSupport::TestCase
[ :"a b", %("a b") ]]
ObjectTests = [[ Foo.new(1, 2), %({\"a\":1,\"b\":2}) ]]
- HashlikeTests = [[ Hashlike.new, %({\"a\":1}) ]]
+ HashlikeTests = [[ Hashlike.new, %({\"bar\":\"world\",\"foo\":\"hello\"}) ]]
CustomTests = [[ Custom.new, '"custom"' ]]
RegexpTests = [[ /^a/, '"(?-mix:^a)"' ], [/^\w{1,2}[a-z]+/ix, '"(?ix-m:^\\\\w{1,2}[a-z]+)"']]
@@ -71,8 +84,8 @@ class TestJSONEncoding < ActiveSupport::TestCase
DateTimeTests = [[ DateTime.civil(2005,2,1,15,15,10), %("2005/02/01 15:15:10 +0000") ]]
StandardDateTests = [[ Date.new(2005,2,1), %("2005-02-01") ]]
- StandardTimeTests = [[ Time.utc(2005,2,1,15,15,10), %("2005-02-01T15:15:10Z") ]]
- StandardDateTimeTests = [[ DateTime.civil(2005,2,1,15,15,10), %("2005-02-01T15:15:10+00:00") ]]
+ StandardTimeTests = [[ Time.utc(2005,2,1,15,15,10), %("2005-02-01T15:15:10.000Z") ]]
+ StandardDateTimeTests = [[ DateTime.civil(2005,2,1,15,15,10), %("2005-02-01T15:15:10.000+00:00") ]]
StandardStringTests = [[ 'this is the <string>', %("this is the <string>")]]
def sorted_json(json)
@@ -146,19 +159,25 @@ class TestJSONEncoding < ActiveSupport::TestCase
def test_exception_raised_when_encoding_circular_reference_in_array
a = [1]
a << a
- assert_raise(ActiveSupport::JSON::Encoding::CircularReferenceError) { ActiveSupport::JSON.encode(a) }
+ assert_deprecated do
+ assert_raise(ActiveSupport::JSON::Encoding::CircularReferenceError) { ActiveSupport::JSON.encode(a) }
+ end
end
def test_exception_raised_when_encoding_circular_reference_in_hash
a = { :name => 'foo' }
a[:next] = a
- assert_raise(ActiveSupport::JSON::Encoding::CircularReferenceError) { ActiveSupport::JSON.encode(a) }
+ assert_deprecated do
+ assert_raise(ActiveSupport::JSON::Encoding::CircularReferenceError) { ActiveSupport::JSON.encode(a) }
+ end
end
def test_exception_raised_when_encoding_circular_reference_in_hash_inside_array
a = { :name => 'foo', :sub => [] }
a[:sub] << a
- assert_raise(ActiveSupport::JSON::Encoding::CircularReferenceError) { ActiveSupport::JSON.encode(a) }
+ assert_deprecated do
+ assert_raise(ActiveSupport::JSON::Encoding::CircularReferenceError) { ActiveSupport::JSON.encode(a) }
+ end
end
def test_hash_key_identifiers_are_always_quoted
@@ -178,7 +197,7 @@ class TestJSONEncoding < ActiveSupport::TestCase
prev = ActiveSupport.use_standard_json_time_format
ActiveSupport.use_standard_json_time_format = true
with_env_tz 'US/Eastern' do
- assert_equal %("2005-02-01T15:15:10-05:00"), ActiveSupport::JSON.encode(Time.local(2005,2,1,15,15,10))
+ assert_equal %("2005-02-01T15:15:10.000-05:00"), ActiveSupport::JSON.encode(Time.local(2005,2,1,15,15,10))
end
ensure
ActiveSupport.use_standard_json_time_format = prev
@@ -204,6 +223,31 @@ class TestJSONEncoding < ActiveSupport::TestCase
end
end
+ def test_hash_like_with_options
+ h = Hashlike.new
+ json = h.to_json :only => [:foo]
+
+ assert_equal({"foo"=>"hello"}, JSON.parse(json))
+ end
+
+ def test_object_to_json_with_options
+ obj = Object.new
+ obj.instance_variable_set :@foo, "hello"
+ obj.instance_variable_set :@bar, "world"
+ json = obj.to_json :only => ["foo"]
+
+ assert_equal({"foo"=>"hello"}, JSON.parse(json))
+ end
+
+ def test_struct_to_json_with_options
+ struct = Struct.new(:foo, :bar).new
+ struct.foo = "hello"
+ struct.bar = "world"
+ json = struct.to_json :only => [:foo]
+
+ assert_equal({"foo"=>"hello"}, JSON.parse(json))
+ end
+
def test_hash_should_pass_encoding_options_to_children_in_as_json
person = {
:name => 'John',
@@ -285,7 +329,7 @@ class TestJSONEncoding < ActiveSupport::TestCase
hash = {"foo" => f, "other_hash" => {"foo" => "other_foo", "test" => "other_test"}}
assert_equal({"foo"=>{"foo"=>"hello","bar"=>"world"},
- "other_hash" => {"foo"=>"other_foo","test"=>"other_test"}}, JSON.parse(hash.to_json))
+ "other_hash" => {"foo"=>"other_foo","test"=>"other_test"}}, ActiveSupport::JSON.decode(hash.to_json))
end
def test_struct_encoding
@@ -310,13 +354,13 @@ class TestJSONEncoding < ActiveSupport::TestCase
assert_equal({"name" => "David",
"sub" => {
"name" => "David",
- "date" => "2010-01-01" }}, JSON.parse(json_custom))
+ "date" => "2010-01-01" }}, ActiveSupport::JSON.decode(json_custom))
assert_equal({"name" => "David", "email" => "sample@example.com"},
- JSON.parse(json_strings))
+ ActiveSupport::JSON.decode(json_strings))
assert_equal({"name" => "David", "date" => "2010-01-01"},
- JSON.parse(json_string_and_date))
+ ActiveSupport::JSON.decode(json_string_and_date))
end
def test_opt_out_big_decimal_string_serialization
@@ -336,6 +380,38 @@ class TestJSONEncoding < ActiveSupport::TestCase
assert_equal false, false.as_json
end
+ def test_json_gem_dump_by_passing_active_support_encoder
+ h = HashWithAsJson.new
+ h[:foo] = "hello"
+ h[:bar] = "world"
+
+ assert_equal %({"foo":"hello","bar":"world"}), JSON.dump(h)
+ assert_nil h.as_json_called
+ end
+
+ def test_json_gem_generate_by_passing_active_support_encoder
+ h = HashWithAsJson.new
+ h[:foo] = "hello"
+ h[:bar] = "world"
+
+ assert_equal %({"foo":"hello","bar":"world"}), JSON.generate(h)
+ assert_nil h.as_json_called
+ end
+
+ def test_json_gem_pretty_generate_by_passing_active_support_encoder
+ h = HashWithAsJson.new
+ h[:foo] = "hello"
+ h[:bar] = "world"
+
+ assert_equal <<EXPECTED.chomp, JSON.pretty_generate(h)
+{
+ "foo": "hello",
+ "bar": "world"
+}
+EXPECTED
+ assert_nil h.as_json_called
+ end
+
protected
def object_keys(json_object)
diff --git a/activesupport/test/message_encryptor_test.rb b/activesupport/test/message_encryptor_test.rb
index 509c453b5c..203156baa1 100644
--- a/activesupport/test/message_encryptor_test.rb
+++ b/activesupport/test/message_encryptor_test.rb
@@ -60,7 +60,7 @@ class MessageEncryptorTest < ActiveSupport::TestCase
ActiveSupport.use_standard_json_time_format = true
encryptor = ActiveSupport::MessageEncryptor.new(SecureRandom.hex(64), SecureRandom.hex(64), :serializer => JSONSerializer.new)
message = encryptor.encrypt_and_sign({ :foo => 123, 'bar' => Time.utc(2010) })
- exp = { "foo" => 123, "bar" => "2010-01-01T00:00:00Z" }
+ exp = { "foo" => 123, "bar" => "2010-01-01T00:00:00.000Z" }
assert_equal exp, encryptor.decrypt_and_verify(message)
ensure
ActiveSupport.use_standard_json_time_format = prev
diff --git a/activesupport/test/message_verifier_test.rb b/activesupport/test/message_verifier_test.rb
index a8633f7299..f0f261d710 100644
--- a/activesupport/test/message_verifier_test.rb
+++ b/activesupport/test/message_verifier_test.rb
@@ -49,7 +49,7 @@ class MessageVerifierTest < ActiveSupport::TestCase
ActiveSupport.use_standard_json_time_format = true
verifier = ActiveSupport::MessageVerifier.new("Hey, I'm a secret!", :serializer => JSONSerializer.new)
message = verifier.generate({ :foo => 123, 'bar' => Time.utc(2010) })
- exp = { "foo" => 123, "bar" => "2010-01-01T00:00:00Z" }
+ exp = { "foo" => 123, "bar" => "2010-01-01T00:00:00.000Z" }
assert_equal exp, verifier.verify(message)
ensure
ActiveSupport.use_standard_json_time_format = prev