1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Create Rails::Subscriber::TestHelper and use it to make ActiveRecord subscriber tests run in both sync and async scenarios.

This commit is contained in:
José Valim 2010-01-12 20:00:53 +01:00
parent dc2e291a93
commit 743cafb7f4
4 changed files with 174 additions and 33 deletions

View file

@ -191,6 +191,7 @@ module ActiveRecord
end end
protected protected
def log(sql, name) def log(sql, name)
name ||= "SQL" name ||= "SQL"
result = nil result = nil

View file

@ -0,0 +1,51 @@
require "cases/helper"
require "models/developer"
require "rails/subscriber/test_helper"
require "active_record/railties/subscriber"
module SubscriberTest
Rails::Subscriber.add(:active_record, ActiveRecord::Railties::Subscriber.new)
def super
@old_logger = ActiveRecord::Base.logger
super
end
def teardown
super
ActiveRecord::Base.logger = @old_logger
end
def set_logger(logger)
ActiveRecord::Base.logger = @logger
end
def test_basic_query_logging
Developer.all
wait
assert_equal 1, @logger.logged(:debug).size
assert_match /Developer Load/, @logger.logged(:debug).last
assert_match /SELECT \* FROM "developers"/, @logger.logged(:debug).last
end
def test_cached_queries
ActiveRecord::Base.cache do
Developer.all
Developer.all
end
wait
assert_equal 2, @logger.logged(:debug).size
assert_match /CACHE/, @logger.logged(:debug).last
assert_match /SELECT \* FROM "developers"/, @logger.logged(:debug).last
end
class SyncSubscriberTest < ActiveSupport::TestCase
include Rails::Subscriber::SyncTestHelper
include SubscriberTest
end
class AsyncSubscriberTest < ActiveSupport::TestCase
include Rails::Subscriber::AsyncTestHelper
include SubscriberTest
end
end

View file

@ -0,0 +1,106 @@
require 'rails'
require 'rails/subscriber'
module Rails
class Subscriber
# Provides some helpers to deal with testing subscribers by setting up
# notifications. Take for instance ActiveRecord subscriber tests:
#
# module SubscriberTest
# Rails::Subscriber.add(:active_record, ActiveRecord::Railties::Subscriber.new)
#
# def test_basic_query_logging
# Developer.all
# wait
# assert_equal 1, @logger.logged(:debug).size
# assert_match /Developer Load/, @logger.logged(:debug).last
# assert_match /SELECT \* FROM "developers"/, @logger.logged(:debug).last
# end
#
# class SyncSubscriberTest < ActiveSupport::TestCase
# include Rails::Subscriber::SyncTestHelper
# include SubscriberTest
# end
#
# class AsyncSubscriberTest < ActiveSupport::TestCase
# include Rails::Subscriber::AsyncTestHelper
# include SubscriberTest
# end
# end
#
# All you need to do is to ensure that your subscriber is added to Rails::Subscriber,
# as in the second line of the code above. The test helpers is reponsible for setting
# up the queue, subscriptions and turning colors in logs off.
#
# The messages are available in the @logger instance, which is a logger with limited
# powers (it actually do not send anything to your output), and you can collect them
# doing @logger.logged(level), where level is the level used in logging, like info,
# debug, warn and so on.
#
module TestHelper
def setup
Thread.abort_on_exception = true
@logger = MockLogger.new
@notifier = ActiveSupport::Notifications::Notifier.new(queue)
Rails::Subscriber.colorize_logging = false
@notifier.subscribe { |*args| Rails::Subscriber.dispatch(args) }
set_logger(@logger)
ActiveSupport::Notifications.notifier = @notifier
end
def teardown
set_logger(nil)
ActiveSupport::Notifications.notifier = nil
Thread.abort_on_exception = false
end
class MockLogger
def initialize
@logged = Hash.new { |h,k| h[k] = [] }
end
def method_missing(level, message)
@logged[level] << message
end
def logged(level)
@logged[level].compact.map { |l| l.to_s.strip }
end
end
# Wait notifications to be published.
def wait
@notifier.wait
end
# Overwrite if you use another logger in your subscriber:
#
# def logger
# ActiveRecord::Base.logger = @logger
# end
#
def set_logger(logger)
Rails.logger = logger
end
end
module SyncTestHelper
include TestHelper
def queue
ActiveSupport::Notifications::Fanout.new(true)
end
end
module AsyncTestHelper
include TestHelper
def queue
ActiveSupport::Notifications::Fanout.new(false)
end
end
end
end

View file

@ -1,25 +1,5 @@
require 'abstract_unit' require 'abstract_unit'
require 'rails/subscriber' require 'rails/subscriber/test_helper'
Thread.abort_on_exception = true
class MockLogger
def initialize
@logged = Hash.new { |h,k| h[k] = [] }
end
def method_missing(level, message)
@logged[level] << message
end
def logged(level)
@logged[level].compact.map { |l| l.to_s.strip }
end
end
ActiveSupport::Notifications.subscribe do |*args|
Rails::Subscriber.dispatch(args)
end
class MySubscriber < Rails::Subscriber class MySubscriber < Rails::Subscriber
attr_reader :event attr_reader :event
@ -40,16 +20,14 @@ class MySubscriber < Rails::Subscriber
end end
end end
class SubscriberTest < ActiveSupport::TestCase module SubscriberTest
def setup def setup
@logger = MockLogger.new super
@previous_logger, Rails.logger = Rails.logger, @logger
@subscriber = MySubscriber.new @subscriber = MySubscriber.new
wait
end end
def teardown def teardown
Rails.logger = @previous_logger super
Rails::Subscriber.subscribers.clear Rails::Subscriber.subscribers.clear
end end
@ -57,10 +35,6 @@ class SubscriberTest < ActiveSupport::TestCase
ActiveSupport::Notifications.instrument(*args, &block) ActiveSupport::Notifications.instrument(*args, &block)
end end
def wait
ActiveSupport::Notifications.notifier.wait
end
def test_proxies_method_to_rails_logger def test_proxies_method_to_rails_logger
@subscriber.foo(nil) @subscriber.foo(nil)
assert_equal %w(debug), @logger.logged(:debug) assert_equal %w(debug), @logger.logged(:debug)
@ -69,16 +43,14 @@ class SubscriberTest < ActiveSupport::TestCase
end end
def test_set_color_for_messages def test_set_color_for_messages
Rails::Subscriber.colorize_logging = true
@subscriber.bar(nil) @subscriber.bar(nil)
assert_equal "\e[31mcool\e[0m, \e[1m\e[34misn't it?\e[0m", @logger.logged(:info).last assert_equal "\e[31mcool\e[0m, \e[1m\e[34misn't it?\e[0m", @logger.logged(:info).last
end end
def test_does_not_set_color_if_colorize_logging_is_set_to_false def test_does_not_set_color_if_colorize_logging_is_set_to_false
Rails::Subscriber.colorize_logging = false
@subscriber.bar(nil) @subscriber.bar(nil)
assert_equal "cool, isn't it?", @logger.logged(:info).last assert_equal "cool, isn't it?", @logger.logged(:info).last
ensure
Rails::Subscriber.colorize_logging = true
end end
def test_event_is_sent_to_the_registered_class def test_event_is_sent_to_the_registered_class
@ -109,4 +81,15 @@ class SubscriberTest < ActiveSupport::TestCase
wait wait
assert_equal [], @logger.logged(:info) assert_equal [], @logger.logged(:info)
end end
class SyncSubscriberTest < ActiveSupport::TestCase
include Rails::Subscriber::SyncTestHelper
include SubscriberTest
end
class AsyncSubscriberTest < ActiveSupport::TestCase
include Rails::Subscriber::AsyncTestHelper
include SubscriberTest
end
end end