aboutsummaryrefslogtreecommitdiffstats
path: root/activesupport
diff options
context:
space:
mode:
Diffstat (limited to 'activesupport')
-rw-r--r--activesupport/CHANGELOG.md4
-rw-r--r--activesupport/lib/active_support/core_ext/date/conversions.rb3
-rw-r--r--activesupport/lib/active_support/core_ext/enumerable.rb68
-rw-r--r--activesupport/lib/active_support/deprecation.rb2
-rw-r--r--activesupport/lib/active_support/deprecation/behaviors.rb29
-rw-r--r--activesupport/lib/active_support/deprecation/reporting.rb2
-rw-r--r--activesupport/lib/active_support/testing/time_helpers.rb1
-rw-r--r--activesupport/lib/active_support/values/time_zone.rb3
-rw-r--r--activesupport/test/deprecation_test.rb35
9 files changed, 107 insertions, 40 deletions
diff --git a/activesupport/CHANGELOG.md b/activesupport/CHANGELOG.md
index 6146dd989f..a4fc1e34eb 100644
--- a/activesupport/CHANGELOG.md
+++ b/activesupport/CHANGELOG.md
@@ -1,3 +1,7 @@
+* Pass gem name and deprecation horizon to deprecation notifications.
+
+ *Willem van Bergen*
+
* Add support for `:offset` and `:zone` to `ActiveSupport::TimeWithZone#change`
*Andrew White*
diff --git a/activesupport/lib/active_support/core_ext/date/conversions.rb b/activesupport/lib/active_support/core_ext/date/conversions.rb
index d553406dff..0f59c754fe 100644
--- a/activesupport/lib/active_support/core_ext/date/conversions.rb
+++ b/activesupport/lib/active_support/core_ext/date/conversions.rb
@@ -79,6 +79,9 @@ class Date
# date.to_time(:local) # => 2007-11-10 00:00:00 0800
#
# date.to_time(:utc) # => 2007-11-10 00:00:00 UTC
+ #
+ # NOTE: The :local timezone is Ruby's *process* timezone, i.e. ENV['TZ'].
+ # If the *application's* timezone is needed, then use +in_time_zone+ instead.
def to_time(form = :local)
raise ArgumentError, "Expected :local or :utc, got #{form.inspect}." unless [:local, :utc].include?(form)
::Time.send(form, year, month, day)
diff --git a/activesupport/lib/active_support/core_ext/enumerable.rb b/activesupport/lib/active_support/core_ext/enumerable.rb
index 90d7d2947f..4f120d4b45 100644
--- a/activesupport/lib/active_support/core_ext/enumerable.rb
+++ b/activesupport/lib/active_support/core_ext/enumerable.rb
@@ -1,28 +1,50 @@
module Enumerable
- # Calculates a sum from the elements.
+ # Enumerable#sum was added in Ruby 2.4 but it only works with Numeric elements
+ # when we omit an identity.
#
- # payments.sum { |p| p.price * p.tax_rate }
- # payments.sum(&:price)
- #
- # The latter is a shortcut for:
- #
- # payments.inject(0) { |sum, p| sum + p.price }
- #
- # It can also calculate the sum without the use of a block.
- #
- # [5, 15, 10].sum # => 30
- # ['foo', 'bar'].sum # => "foobar"
- # [[1, 2], [3, 1, 5]].sum # => [1, 2, 3, 1, 5]
- #
- # The default sum of an empty list is zero. You can override this default:
- #
- # [].sum(Payment.new(0)) { |i| i.amount } # => Payment.new(0)
- def sum(identity = nil, &block)
- if block_given?
- map(&block).sum(identity)
- else
- sum = identity ? inject(identity, :+) : inject(:+)
- sum || identity || 0
+ # We tried shimming it to attempt the fast native method, rescue TypeError,
+ # and fall back to the compatible implementation, but that's much slower than
+ # just calling the compat method in the first place.
+ if Enumerable.instance_methods(false).include?(:sum) && !((?a..?b).sum rescue false)
+ # We can't use Refinements here because Refinements with Module which will be prepended
+ # doesn't work well https://bugs.ruby-lang.org/issues/13446
+ alias :_original_sum_with_required_identity :sum
+ private :_original_sum_with_required_identity
+ # Calculates a sum from the elements.
+ #
+ # payments.sum { |p| p.price * p.tax_rate }
+ # payments.sum(&:price)
+ #
+ # The latter is a shortcut for:
+ #
+ # payments.inject(0) { |sum, p| sum + p.price }
+ #
+ # It can also calculate the sum without the use of a block.
+ #
+ # [5, 15, 10].sum # => 30
+ # ['foo', 'bar'].sum # => "foobar"
+ # [[1, 2], [3, 1, 5]].sum # => [1, 2, 3, 1, 5]
+ #
+ # The default sum of an empty list is zero. You can override this default:
+ #
+ # [].sum(Payment.new(0)) { |i| i.amount } # => Payment.new(0)
+ def sum(identity = nil, &block)
+ if identity
+ _original_sum_with_required_identity(identity, &block)
+ elsif block_given?
+ map(&block).sum(identity)
+ else
+ inject(:+) || 0
+ end
+ end
+ else
+ def sum(identity = nil, &block)
+ if block_given?
+ map(&block).sum(identity)
+ else
+ sum = identity ? inject(identity, :+) : inject(:+)
+ sum || identity || 0
+ end
end
end
diff --git a/activesupport/lib/active_support/deprecation.rb b/activesupport/lib/active_support/deprecation.rb
index 72c74e966a..35cddcfde6 100644
--- a/activesupport/lib/active_support/deprecation.rb
+++ b/activesupport/lib/active_support/deprecation.rb
@@ -30,7 +30,7 @@ module ActiveSupport
attr_accessor :deprecation_horizon
# It accepts two parameters on initialization. The first is a version of library
- # and the second is a library name
+ # and the second is a library name.
#
# ActiveSupport::Deprecation.new('2.0', 'MyLibrary')
def initialize(deprecation_horizon = "5.3", gem_name = "Rails")
diff --git a/activesupport/lib/active_support/deprecation/behaviors.rb b/activesupport/lib/active_support/deprecation/behaviors.rb
index 1d1354c23e..a9a182f212 100644
--- a/activesupport/lib/active_support/deprecation/behaviors.rb
+++ b/activesupport/lib/active_support/deprecation/behaviors.rb
@@ -9,18 +9,18 @@ module ActiveSupport
class Deprecation
# Default warning behaviors per Rails.env.
DEFAULT_BEHAVIORS = {
- raise: ->(message, callstack) {
+ raise: ->(message, callstack, deprecation_horizon, gem_name) {
e = DeprecationException.new(message)
e.set_backtrace(callstack.map(&:to_s))
raise e
},
- stderr: ->(message, callstack) {
+ stderr: ->(message, callstack, deprecation_horizon, gem_name) {
$stderr.puts(message)
$stderr.puts callstack.join("\n ") if debug
},
- log: ->(message, callstack) {
+ log: ->(message, callstack, deprecation_horizon, gem_name) {
logger =
if defined?(Rails.logger) && Rails.logger
Rails.logger
@@ -32,12 +32,16 @@ module ActiveSupport
logger.debug callstack.join("\n ") if debug
},
- notify: ->(message, callstack) {
- ActiveSupport::Notifications.instrument("deprecation.rails",
- message: message, callstack: callstack)
+ notify: ->(message, callstack, deprecation_horizon, gem_name) {
+ notification_name = "deprecation.#{gem_name.underscore.tr('/', '_')}"
+ ActiveSupport::Notifications.instrument(notification_name,
+ message: message,
+ callstack: callstack,
+ gem_name: gem_name,
+ deprecation_horizon: deprecation_horizon)
},
- silence: ->(message, callstack) {},
+ silence: ->(message, callstack, deprecation_horizon, gem_name) {},
}
# Behavior module allows to determine how to display deprecation messages.
@@ -83,8 +87,17 @@ module ActiveSupport
# # custom stuff
# }
def behavior=(behavior)
- @behavior = Array(behavior).map { |b| DEFAULT_BEHAVIORS[b] || b }
+ @behavior = Array(behavior).map { |b| DEFAULT_BEHAVIORS[b] || arity_coerce(b) }
end
+
+ private
+ def arity_coerce(behavior)
+ if behavior.arity == 4 || behavior.arity == -1
+ behavior
+ else
+ -> message, callstack, _, _ { behavior.call(message, callstack) }
+ end
+ end
end
end
end
diff --git a/activesupport/lib/active_support/deprecation/reporting.rb b/activesupport/lib/active_support/deprecation/reporting.rb
index 58c5c50e30..851d8eeda1 100644
--- a/activesupport/lib/active_support/deprecation/reporting.rb
+++ b/activesupport/lib/active_support/deprecation/reporting.rb
@@ -18,7 +18,7 @@ module ActiveSupport
callstack ||= caller_locations(2)
deprecation_message(callstack, message).tap do |m|
- behavior.each { |b| b.call(m, callstack) }
+ behavior.each { |b| b.call(m, callstack, deprecation_horizon, gem_name) }
end
end
diff --git a/activesupport/lib/active_support/testing/time_helpers.rb b/activesupport/lib/active_support/testing/time_helpers.rb
index 07c9be0604..3d9ff99729 100644
--- a/activesupport/lib/active_support/testing/time_helpers.rb
+++ b/activesupport/lib/active_support/testing/time_helpers.rb
@@ -1,4 +1,5 @@
require "active_support/core_ext/string/strip" # for strip_heredoc
+require "active_support/core_ext/time/calculations"
require "concurrent/map"
module ActiveSupport
diff --git a/activesupport/lib/active_support/values/time_zone.rb b/activesupport/lib/active_support/values/time_zone.rb
index ce5207546d..96a541a4ef 100644
--- a/activesupport/lib/active_support/values/time_zone.rb
+++ b/activesupport/lib/active_support/values/time_zone.rb
@@ -6,7 +6,7 @@ module ActiveSupport
# The TimeZone class serves as a wrapper around TZInfo::Timezone instances.
# It allows us to do the following:
#
- # * Limit the set of zones provided by TZInfo to a meaningful subset of 146
+ # * Limit the set of zones provided by TZInfo to a meaningful subset of 134
# zones.
# * Retrieve and display zones with a friendlier name
# (e.g., "Eastern Time (US & Canada)" instead of "America/New_York").
@@ -59,6 +59,7 @@ module ActiveSupport
"Buenos Aires" => "America/Argentina/Buenos_Aires",
"Montevideo" => "America/Montevideo",
"Georgetown" => "America/Guyana",
+ "Puerto Rico" => "America/Puerto_Rico",
"Greenland" => "America/Godthab",
"Mid-Atlantic" => "Atlantic/South_Georgia",
"Azores" => "Atlantic/Azores",
diff --git a/activesupport/test/deprecation_test.rb b/activesupport/test/deprecation_test.rb
index 36d1ef0849..257cb50fb2 100644
--- a/activesupport/test/deprecation_test.rb
+++ b/activesupport/test/deprecation_test.rb
@@ -100,16 +100,18 @@ class DeprecationTest < ActiveSupport::TestCase
end
def test_several_behaviors
- @a, @b = nil, nil
+ @a, @b, @c = nil, nil, nil
ActiveSupport::Deprecation.behavior = [
- Proc.new { |msg, callstack| @a = msg },
- Proc.new { |msg, callstack| @b = msg }
+ lambda { |msg, callstack, horizon, gem| @a = msg },
+ lambda { |msg, callstack| @b = msg },
+ lambda { |*args| @c = args },
]
@dtc.partially
assert_match(/foo=nil/, @a)
assert_match(/foo=nil/, @b)
+ assert_equal 4, @c.size
end
def test_raise_behaviour
@@ -119,7 +121,7 @@ class DeprecationTest < ActiveSupport::TestCase
callstack = caller_locations
e = assert_raise ActiveSupport::DeprecationException do
- ActiveSupport::Deprecation.behavior.first.call(message, callstack)
+ ActiveSupport::Deprecation.behavior.first.call(message, callstack, "horizon", "gem")
end
assert_equal message, e.message
assert_equal callstack.map(&:to_s), e.backtrace.map(&:to_s)
@@ -130,7 +132,7 @@ class DeprecationTest < ActiveSupport::TestCase
behavior = ActiveSupport::Deprecation.behavior.first
content = capture(:stderr) {
- assert_nil behavior.call("Some error!", ["call stack!"])
+ assert_nil behavior.call("Some error!", ["call stack!"], "horizon", "gem")
}
assert_match(/Some error!/, content)
assert_match(/call stack!/, content)
@@ -152,11 +154,32 @@ class DeprecationTest < ActiveSupport::TestCase
behavior = ActiveSupport::Deprecation.behavior.first
stderr_output = capture(:stderr) {
- assert_nil behavior.call("Some error!", ["call stack!"])
+ assert_nil behavior.call("Some error!", ["call stack!"], "horizon", "gem")
}
assert stderr_output.empty?
end
+ def test_default_notify_behavior
+ ActiveSupport::Deprecation.behavior = :notify
+ behavior = ActiveSupport::Deprecation.behavior.first
+
+ begin
+ events = []
+ ActiveSupport::Notifications.subscribe("deprecation.my_gem_custom") { |_, **args|
+ events << args
+ }
+
+ assert_nil behavior.call("Some error!", ["call stack!"], "horizon", "MyGem::Custom")
+ assert_equal 1, events.size
+ assert_equal "Some error!", events.first[:message]
+ assert_equal ["call stack!"], events.first[:callstack]
+ assert_equal "horizon", events.first[:deprecation_horizon]
+ assert_equal "MyGem::Custom", events.first[:gem_name]
+ ensure
+ ActiveSupport::Notifications.unsubscribe("deprecation.my_gem_custom")
+ end
+ end
+
def test_deprecated_instance_variable_proxy
assert_not_deprecated { @dtc.request.size }