aboutsummaryrefslogtreecommitdiffstats
path: root/activesupport
diff options
context:
space:
mode:
Diffstat (limited to 'activesupport')
-rw-r--r--activesupport/CHANGELOG.md38
-rw-r--r--activesupport/lib/active_support/callbacks.rb6
-rw-r--r--activesupport/lib/active_support/configurable.rb1
-rw-r--r--activesupport/lib/active_support/core_ext/module/attribute_accessors.rb1
-rw-r--r--activesupport/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb1
-rw-r--r--activesupport/lib/active_support/core_ext/module/delegation.rb1
-rw-r--r--activesupport/lib/active_support/core_ext/object/blank.rb1
-rw-r--r--activesupport/lib/active_support/core_ext/object/to_query.rb7
-rw-r--r--activesupport/lib/active_support/core_ext/object/with_options.rb2
-rw-r--r--activesupport/lib/active_support/dependencies.rb4
-rw-r--r--activesupport/lib/active_support/deprecation/proxy_wrappers.rb2
-rw-r--r--activesupport/lib/active_support/duration/iso8601_parser.rb1
-rw-r--r--activesupport/lib/active_support/inflector/inflections.rb1
-rw-r--r--activesupport/lib/active_support/inflector/methods.rb1
-rw-r--r--activesupport/lib/active_support/key_generator.rb2
-rw-r--r--activesupport/lib/active_support/message_encryptor.rb4
-rw-r--r--activesupport/lib/active_support/multibyte/chars.rb1
-rw-r--r--activesupport/lib/active_support/notifications/fanout.rb42
-rw-r--r--activesupport/lib/active_support/notifications/instrumenter.rb61
-rw-r--r--activesupport/lib/active_support/subscriber.rb9
-rw-r--r--activesupport/lib/active_support/testing/deprecation.rb1
-rw-r--r--activesupport/lib/active_support/testing/parallelization.rb16
-rw-r--r--activesupport/lib/active_support/values/time_zone.rb4
-rw-r--r--activesupport/test/cache/stores/redis_cache_store_test.rb4
-rw-r--r--activesupport/test/core_ext/object/to_query_test.rb14
-rw-r--r--activesupport/test/json/encoding_test.rb1
-rw-r--r--activesupport/test/log_subscriber_test.rb16
-rw-r--r--activesupport/test/notifications_test.rb36
28 files changed, 230 insertions, 48 deletions
diff --git a/activesupport/CHANGELOG.md b/activesupport/CHANGELOG.md
index 24ad72c45d..8808b38aac 100644
--- a/activesupport/CHANGELOG.md
+++ b/activesupport/CHANGELOG.md
@@ -1,3 +1,41 @@
+* Add "event object" support to the notification system.
+ Before this change, end users were forced to create hand made artisanal
+ event objects on their own, like this:
+
+ ActiveSupport::Notifications.subscribe('wait') do |*args|
+ @event = ActiveSupport::Notifications::Event.new(*args)
+ end
+
+ ActiveSupport::Notifications.instrument('wait') do
+ sleep 1
+ end
+
+ @event.duration # => 1000.138
+
+ After this change, if the block passed to `subscribe` only takes one
+ parameter, the framework will yield an event object to the block. Now
+ end users are no longer required to make their own:
+
+ ActiveSupport::Notifications.subscribe('wait') do |event|
+ @event = event
+ end
+
+ ActiveSupport::Notifications.instrument('wait') do
+ sleep 1
+ end
+
+ p @event.allocations # => 7
+ p @event.cpu_time # => 0.256
+ p @event.idle_time # => 1003.2399
+
+ Now you can enjoy event objects without making them yourself. Neat!
+
+ *Aaron "t.lo" Patterson*
+
+* Add cpu_time, idle_time, and allocations to Event
+
+ *Eileen M. Uchitelle*, *Aaron Patterson*
+
* RedisCacheStore: support key expiry in increment/decrement.
Pass `:expires_in` to `#increment` and `#decrement` to set a Redis EXPIRE on the key.
diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb
index a1b841ec3d..c266b432c0 100644
--- a/activesupport/lib/active_support/callbacks.rb
+++ b/activesupport/lib/active_support/callbacks.rb
@@ -497,9 +497,7 @@ module ActiveSupport
arg.halted || !@user_conditions.all? { |c| c.call(arg.target, arg.value) }
end
- def nested
- @nested
- end
+ attr_reader :nested
def final?
!@call_template
@@ -578,7 +576,7 @@ module ActiveSupport
end
protected
- def chain; @chain; end
+ attr_reader :chain
private
diff --git a/activesupport/lib/active_support/configurable.rb b/activesupport/lib/active_support/configurable.rb
index 4d6f7819bb..2610114d8f 100644
--- a/activesupport/lib/active_support/configurable.rb
+++ b/activesupport/lib/active_support/configurable.rb
@@ -3,7 +3,6 @@
require "active_support/concern"
require "active_support/ordered_options"
require "active_support/core_ext/array/extract_options"
-require "active_support/core_ext/regexp"
module ActiveSupport
# Configurable provides a <tt>config</tt> method to store and retrieve
diff --git a/activesupport/lib/active_support/core_ext/module/attribute_accessors.rb b/activesupport/lib/active_support/core_ext/module/attribute_accessors.rb
index 01fee0fb74..281eaa7d5f 100644
--- a/activesupport/lib/active_support/core_ext/module/attribute_accessors.rb
+++ b/activesupport/lib/active_support/core_ext/module/attribute_accessors.rb
@@ -1,7 +1,6 @@
# frozen_string_literal: true
require "active_support/core_ext/array/extract_options"
-require "active_support/core_ext/regexp"
# Extends the module object with class/module and instance accessors for
# class/module attributes, just like the native attr* accessors for instance
diff --git a/activesupport/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb b/activesupport/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb
index 4b9b6ea9bd..e777f02cb6 100644
--- a/activesupport/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb
+++ b/activesupport/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb
@@ -1,7 +1,6 @@
# frozen_string_literal: true
require "active_support/core_ext/array/extract_options"
-require "active_support/core_ext/regexp"
# Extends the module object with class/module and instance accessors for
# class/module attributes, just like the native attr* accessors for instance
diff --git a/activesupport/lib/active_support/core_ext/module/delegation.rb b/activesupport/lib/active_support/core_ext/module/delegation.rb
index 7f42f44efb..3128539112 100644
--- a/activesupport/lib/active_support/core_ext/module/delegation.rb
+++ b/activesupport/lib/active_support/core_ext/module/delegation.rb
@@ -1,7 +1,6 @@
# frozen_string_literal: true
require "set"
-require "active_support/core_ext/regexp"
class Module
# Error generated by +delegate+ when a method is called on +nil+ and +allow_nil+
diff --git a/activesupport/lib/active_support/core_ext/object/blank.rb b/activesupport/lib/active_support/core_ext/object/blank.rb
index 2ca431ab10..ad6a9c6146 100644
--- a/activesupport/lib/active_support/core_ext/object/blank.rb
+++ b/activesupport/lib/active_support/core_ext/object/blank.rb
@@ -1,6 +1,5 @@
# frozen_string_literal: true
-require "active_support/core_ext/regexp"
require "concurrent/map"
class Object
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 abb461966a..bac6ff9c97 100644
--- a/activesupport/lib/active_support/core_ext/object/to_query.rb
+++ b/activesupport/lib/active_support/core_ext/object/to_query.rb
@@ -75,11 +75,14 @@ class Hash
#
# This method is also aliased as +to_param+.
def to_query(namespace = nil)
- collect do |key, value|
+ query = collect do |key, value|
unless (value.is_a?(Hash) || value.is_a?(Array)) && value.empty?
value.to_query(namespace ? "#{namespace}[#{key}]" : key)
end
- end.compact.sort! * "&"
+ end.compact
+
+ query.sort! unless namespace.to_s.include?("[]")
+ query.join("&")
end
alias_method :to_param, :to_query
diff --git a/activesupport/lib/active_support/core_ext/object/with_options.rb b/activesupport/lib/active_support/core_ext/object/with_options.rb
index 2838fd76be..1d46add6e0 100644
--- a/activesupport/lib/active_support/core_ext/object/with_options.rb
+++ b/activesupport/lib/active_support/core_ext/object/with_options.rb
@@ -68,7 +68,7 @@ class Object
# You can access these methods using the class name instead:
#
# class Phone < ActiveRecord::Base
- # enum phone_number_type: [home: 0, office: 1, mobile: 2]
+ # enum phone_number_type: { home: 0, office: 1, mobile: 2 }
#
# with_options presence: true do
# validates :phone_number_type, inclusion: { in: Phone.phone_number_types.keys }
diff --git a/activesupport/lib/active_support/dependencies.rb b/activesupport/lib/active_support/dependencies.rb
index a02cefc78e..9dc2c46880 100644
--- a/activesupport/lib/active_support/dependencies.rb
+++ b/activesupport/lib/active_support/dependencies.rb
@@ -345,7 +345,7 @@ module ActiveSupport #:nodoc:
end
def require_or_load(file_name, const_path = nil)
- file_name = $` if file_name =~ /\.rb\z/
+ file_name = file_name.chomp(".rb")
expanded = File.expand_path(file_name)
return if loaded.include?(expanded)
@@ -395,7 +395,7 @@ module ActiveSupport #:nodoc:
# constant paths which would cause Dependencies to attempt to load this
# file.
def loadable_constants_for_path(path, bases = autoload_paths)
- path = $` if path =~ /\.rb\z/
+ path = path.chomp(".rb")
expanded_path = File.expand_path(path)
paths = []
diff --git a/activesupport/lib/active_support/deprecation/proxy_wrappers.rb b/activesupport/lib/active_support/deprecation/proxy_wrappers.rb
index 896c0d2d8e..56f1e23136 100644
--- a/activesupport/lib/active_support/deprecation/proxy_wrappers.rb
+++ b/activesupport/lib/active_support/deprecation/proxy_wrappers.rb
@@ -1,7 +1,5 @@
# frozen_string_literal: true
-require "active_support/core_ext/regexp"
-
module ActiveSupport
class Deprecation
class DeprecationProxy #:nodoc:
diff --git a/activesupport/lib/active_support/duration/iso8601_parser.rb b/activesupport/lib/active_support/duration/iso8601_parser.rb
index 1847eeaa86..414f727705 100644
--- a/activesupport/lib/active_support/duration/iso8601_parser.rb
+++ b/activesupport/lib/active_support/duration/iso8601_parser.rb
@@ -1,7 +1,6 @@
# frozen_string_literal: true
require "strscan"
-require "active_support/core_ext/regexp"
module ActiveSupport
class Duration
diff --git a/activesupport/lib/active_support/inflector/inflections.rb b/activesupport/lib/active_support/inflector/inflections.rb
index 7e5dff1d6d..2b86d233e5 100644
--- a/activesupport/lib/active_support/inflector/inflections.rb
+++ b/activesupport/lib/active_support/inflector/inflections.rb
@@ -2,7 +2,6 @@
require "concurrent/map"
require "active_support/core_ext/array/prepend_and_append"
-require "active_support/core_ext/regexp"
require "active_support/i18n"
require "active_support/deprecation"
diff --git a/activesupport/lib/active_support/inflector/methods.rb b/activesupport/lib/active_support/inflector/methods.rb
index 339b93b8da..7359de762a 100644
--- a/activesupport/lib/active_support/inflector/methods.rb
+++ b/activesupport/lib/active_support/inflector/methods.rb
@@ -1,7 +1,6 @@
# frozen_string_literal: true
require "active_support/inflections"
-require "active_support/core_ext/regexp"
module ActiveSupport
# The Inflector transforms words from singular to plural, class names to table
diff --git a/activesupport/lib/active_support/key_generator.rb b/activesupport/lib/active_support/key_generator.rb
index 78f7d7ca8d..00edcdd05a 100644
--- a/activesupport/lib/active_support/key_generator.rb
+++ b/activesupport/lib/active_support/key_generator.rb
@@ -59,7 +59,7 @@ module ActiveSupport
if secret.blank?
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 via `bin/rails credentials:edit`."
+ "#{SECRET_MIN_LENGTH} characters by running `rails credentials:edit`."
end
if secret.length < SECRET_MIN_LENGTH
diff --git a/activesupport/lib/active_support/message_encryptor.rb b/activesupport/lib/active_support/message_encryptor.rb
index 8b73270894..404404cad1 100644
--- a/activesupport/lib/active_support/message_encryptor.rb
+++ b/activesupport/lib/active_support/message_encryptor.rb
@@ -210,9 +210,7 @@ module ActiveSupport
OpenSSL::Cipher.new(@cipher)
end
- def verifier
- @verifier
- end
+ attr_reader :verifier
def aead_mode?
@aead_mode ||= new_cipher.authenticated?
diff --git a/activesupport/lib/active_support/multibyte/chars.rb b/activesupport/lib/active_support/multibyte/chars.rb
index 8152b8fd22..499a206f49 100644
--- a/activesupport/lib/active_support/multibyte/chars.rb
+++ b/activesupport/lib/active_support/multibyte/chars.rb
@@ -4,7 +4,6 @@ require "active_support/json"
require "active_support/core_ext/string/access"
require "active_support/core_ext/string/behavior"
require "active_support/core_ext/module/delegation"
-require "active_support/core_ext/regexp"
module ActiveSupport #:nodoc:
module Multibyte #:nodoc:
diff --git a/activesupport/lib/active_support/notifications/fanout.rb b/activesupport/lib/active_support/notifications/fanout.rb
index 25aab175b4..4e4ca70942 100644
--- a/activesupport/lib/active_support/notifications/fanout.rb
+++ b/activesupport/lib/active_support/notifications/fanout.rb
@@ -70,12 +70,29 @@ module ActiveSupport
module Subscribers # :nodoc:
def self.new(pattern, listener)
+ subscriber_class = Timed
+
if listener.respond_to?(:start) && listener.respond_to?(:finish)
- subscriber = Evented.new pattern, listener
+ subscriber_class = Evented
else
- subscriber = Timed.new pattern, listener
+ # Doing all this to detect a block like `proc { |x| }` vs
+ # `proc { |*x| }` or `proc { |**x| }`
+ if listener.respond_to?(:parameters)
+ params = listener.parameters
+ if params.length == 1 && params.first.first == :opt
+ subscriber_class = EventObject
+ end
+ end
end
+ wrap_all pattern, subscriber_class.new(pattern, listener)
+ end
+
+ def self.event_object_subscriber(pattern, block)
+ wrap_all pattern, EventObject.new(pattern, block)
+ end
+
+ def self.wrap_all(pattern, subscriber)
unless pattern
AllMessages.new(subscriber)
else
@@ -130,6 +147,27 @@ module ActiveSupport
end
end
+ class EventObject < Evented
+ def start(name, id, payload)
+ stack = Thread.current[:_event_stack] ||= []
+ event = build_event name, id, payload
+ event.start!
+ stack.push event
+ end
+
+ def finish(name, id, payload)
+ stack = Thread.current[:_event_stack]
+ event = stack.pop
+ event.finish!
+ @delegate.call event
+ end
+
+ private
+ def build_event(name, id, payload)
+ ActiveSupport::Notifications::Event.new name, nil, nil, id, payload
+ end
+ end
+
class AllMessages # :nodoc:
def initialize(delegate)
@delegate = delegate
diff --git a/activesupport/lib/active_support/notifications/instrumenter.rb b/activesupport/lib/active_support/notifications/instrumenter.rb
index e99f5ee688..f8344912bb 100644
--- a/activesupport/lib/active_support/notifications/instrumenter.rb
+++ b/activesupport/lib/active_support/notifications/instrumenter.rb
@@ -63,6 +63,42 @@ module ActiveSupport
@end = ending
@children = []
@duration = nil
+ @cpu_time_start = nil
+ @cpu_time_finish = nil
+ @allocation_count_start = 0
+ @allocation_count_finish = 0
+ end
+
+ # Record information at the time this event starts
+ def start!
+ @time = now
+ @cpu_time_start = now_cpu
+ @allocation_count_start = now_allocations
+ end
+
+ # Record information at the time this event finishes
+ def finish!
+ @cpu_time_finish = now_cpu
+ @end = now
+ @allocation_count_finish = now_allocations
+ end
+
+ # Returns the CPU time (in milliseconds) passed since the call to
+ # +start!+ and the call to +finish!+
+ def cpu_time
+ (@cpu_time_finish - @cpu_time_start) * 1000
+ end
+
+ # Returns the idle time time (in milliseconds) passed since the call to
+ # +start!+ and the call to +finish!+
+ def idle_time
+ duration - cpu_time
+ end
+
+ # Returns the number of allocations made since the call to +start!+ and
+ # the call to +finish!+
+ def allocations
+ @allocation_count_finish - @allocation_count_start
end
# Returns the difference in milliseconds between when the execution of the
@@ -88,6 +124,31 @@ module ActiveSupport
def parent_of?(event)
@children.include? event
end
+
+ private
+ def now
+ Process.clock_gettime(Process::CLOCK_MONOTONIC)
+ end
+
+ if defined?(Process::CLOCK_PROCESS_CPUTIME_ID)
+ def now_cpu
+ Process.clock_gettime(Process::CLOCK_PROCESS_CPUTIME_ID)
+ end
+ else
+ def now_cpu
+ 0
+ end
+ end
+
+ if defined?(JRUBY_VERSION)
+ def now_allocations
+ 0
+ end
+ else
+ def now_allocations
+ GC.stat :total_allocated_objects
+ end
+ end
end
end
end
diff --git a/activesupport/lib/active_support/subscriber.rb b/activesupport/lib/active_support/subscriber.rb
index 8ad39f7a05..5a4c3d74af 100644
--- a/activesupport/lib/active_support/subscriber.rb
+++ b/activesupport/lib/active_support/subscriber.rb
@@ -79,7 +79,8 @@ module ActiveSupport
end
def start(name, id, payload)
- e = ActiveSupport::Notifications::Event.new(name, Time.now, nil, id, payload)
+ e = ActiveSupport::Notifications::Event.new(name, nil, nil, id, payload)
+ e.start!
parent = event_stack.last
parent << e if parent
@@ -87,9 +88,8 @@ module ActiveSupport
end
def finish(name, id, payload)
- finished = Time.now
- event = event_stack.pop
- event.end = finished
+ event = event_stack.pop
+ event.finish!
event.payload.merge!(payload)
method = name.split(".".freeze).first
@@ -97,7 +97,6 @@ module ActiveSupport
end
private
-
def event_stack
SubscriberQueueRegistry.instance.get_queue(@queue_key)
end
diff --git a/activesupport/lib/active_support/testing/deprecation.rb b/activesupport/lib/active_support/testing/deprecation.rb
index f655435729..18d63d2780 100644
--- a/activesupport/lib/active_support/testing/deprecation.rb
+++ b/activesupport/lib/active_support/testing/deprecation.rb
@@ -1,7 +1,6 @@
# frozen_string_literal: true
require "active_support/deprecation"
-require "active_support/core_ext/regexp"
module ActiveSupport
module Testing
diff --git a/activesupport/lib/active_support/testing/parallelization.rb b/activesupport/lib/active_support/testing/parallelization.rb
index 59c8486f41..1caac1feb3 100644
--- a/activesupport/lib/active_support/testing/parallelization.rb
+++ b/activesupport/lib/active_support/testing/parallelization.rb
@@ -26,25 +26,21 @@ module ActiveSupport
def pop; @queue.pop; end
end
- @after_fork_hooks = []
+ @@after_fork_hooks = []
def self.after_fork_hook(&blk)
- @after_fork_hooks << blk
+ @@after_fork_hooks << blk
end
- def self.after_fork_hooks
- @after_fork_hooks
- end
+ cattr_reader :after_fork_hooks
- @run_cleanup_hooks = []
+ @@run_cleanup_hooks = []
def self.run_cleanup_hook(&blk)
- @run_cleanup_hooks << blk
+ @@run_cleanup_hooks << blk
end
- def self.run_cleanup_hooks
- @run_cleanup_hooks
- end
+ cattr_reader :run_cleanup_hooks
def initialize(queue_size)
@queue_size = queue_size
diff --git a/activesupport/lib/active_support/values/time_zone.rb b/activesupport/lib/active_support/values/time_zone.rb
index 792c88415c..fd07a3a6a2 100644
--- a/activesupport/lib/active_support/values/time_zone.rb
+++ b/activesupport/lib/active_support/values/time_zone.rb
@@ -265,7 +265,7 @@ module ActiveSupport
private
def load_country_zones(code)
country = TZInfo::Country.get(code)
- country.zone_identifiers.map do |tz_id|
+ country.zone_identifiers.flat_map do |tz_id|
if MAPPING.value?(tz_id)
MAPPING.inject([]) do |memo, (key, value)|
memo << self[key] if value == tz_id
@@ -274,7 +274,7 @@ module ActiveSupport
else
create(tz_id, nil, TZInfo::Timezone.new(tz_id))
end
- end.flatten(1).sort!
+ end.sort!
end
def zones_map
diff --git a/activesupport/test/cache/stores/redis_cache_store_test.rb b/activesupport/test/cache/stores/redis_cache_store_test.rb
index 3b873de383..305a2c184d 100644
--- a/activesupport/test/cache/stores/redis_cache_store_test.rb
+++ b/activesupport/test/cache/stores/redis_cache_store_test.rb
@@ -103,9 +103,7 @@ module ActiveSupport::Cache::RedisCacheStoreTests
private
def build(**kwargs)
- ActiveSupport::Cache::RedisCacheStore.new(driver: DRIVER, **kwargs).tap do |cache|
- cache.redis
- end
+ ActiveSupport::Cache::RedisCacheStore.new(driver: DRIVER, **kwargs).tap(&:redis)
end
end
diff --git a/activesupport/test/core_ext/object/to_query_test.rb b/activesupport/test/core_ext/object/to_query_test.rb
index 7593bcfa4d..b0b7ef0913 100644
--- a/activesupport/test/core_ext/object/to_query_test.rb
+++ b/activesupport/test/core_ext/object/to_query_test.rb
@@ -77,6 +77,20 @@ class ToQueryTest < ActiveSupport::TestCase
assert_equal "name=Nakshay&type=human", hash.to_query
end
+ def test_hash_not_sorted_lexicographically_for_nested_structure
+ params = {
+ "foo" => {
+ "contents" => [
+ { "name" => "gorby", "id" => "123" },
+ { "name" => "puff", "d" => "true" }
+ ]
+ }
+ }
+ expected = "foo[contents][][name]=gorby&foo[contents][][id]=123&foo[contents][][name]=puff&foo[contents][][d]=true"
+
+ assert_equal expected, URI.decode(params.to_query)
+ end
+
private
def assert_query_equal(expected, actual)
assert_equal expected.split("&"), actual.to_query.split("&")
diff --git a/activesupport/test/json/encoding_test.rb b/activesupport/test/json/encoding_test.rb
index 340a2abf75..ebc5df14dd 100644
--- a/activesupport/test/json/encoding_test.rb
+++ b/activesupport/test/json/encoding_test.rb
@@ -3,7 +3,6 @@
require "securerandom"
require "abstract_unit"
require "active_support/core_ext/string/inflections"
-require "active_support/core_ext/regexp"
require "active_support/json"
require "active_support/time"
require "time_zone_test_helpers"
diff --git a/activesupport/test/log_subscriber_test.rb b/activesupport/test/log_subscriber_test.rb
index 2af9b1de30..7f05459493 100644
--- a/activesupport/test/log_subscriber_test.rb
+++ b/activesupport/test/log_subscriber_test.rb
@@ -75,6 +75,22 @@ class SyncLogSubscriberTest < ActiveSupport::TestCase
assert_kind_of ActiveSupport::Notifications::Event, @log_subscriber.event
end
+ def test_event_attributes
+ ActiveSupport::LogSubscriber.attach_to :my_log_subscriber, @log_subscriber
+ instrument "some_event.my_log_subscriber"
+ wait
+ event = @log_subscriber.event
+ if defined?(JRUBY_VERSION)
+ assert_equal 0, event.cpu_time
+ assert_equal 0, event.allocations
+ else
+ assert_operator event.cpu_time, :>, 0
+ assert_operator event.allocations, :>, 0
+ end
+ assert_operator event.duration, :>, 0
+ assert_operator event.idle_time, :>, 0
+ end
+
def test_does_not_send_the_event_if_it_doesnt_match_the_class
ActiveSupport::LogSubscriber.attach_to :my_log_subscriber, @log_subscriber
instrument "unknown_event.my_log_subscriber"
diff --git a/activesupport/test/notifications_test.rb b/activesupport/test/notifications_test.rb
index d035f993f7..62817a839a 100644
--- a/activesupport/test/notifications_test.rb
+++ b/activesupport/test/notifications_test.rb
@@ -26,6 +26,42 @@ module Notifications
end
end
+ class SubscribeEventObjects < TestCase
+ def test_subscribe_events
+ events = []
+ @notifier.subscribe do |event|
+ events << event
+ end
+
+ ActiveSupport::Notifications.instrument("foo")
+ event = events.first
+ assert event, "should have an event"
+ assert_operator event.allocations, :>, 0
+ assert_operator event.cpu_time, :>, 0
+ assert_operator event.idle_time, :>, 0
+ assert_operator event.duration, :>, 0
+ end
+
+ def test_subscribe_via_top_level_api
+ old_notifier = ActiveSupport::Notifications.notifier
+ ActiveSupport::Notifications.notifier = ActiveSupport::Notifications::Fanout.new
+
+ event = nil
+ ActiveSupport::Notifications.subscribe("foo") do |e|
+ event = e
+ end
+
+ ActiveSupport::Notifications.instrument("foo") do
+ 100.times { Object.new } # allocate at least 100 objects
+ end
+
+ assert event
+ assert_operator event.allocations, :>=, 100
+ ensure
+ ActiveSupport::Notifications.notifier = old_notifier
+ end
+ end
+
class SubscribedTest < TestCase
def test_subscribed
name = "foo"