From 743cafb7f4a54d162a432c43974a5e5be55fd0b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Tue, 12 Jan 2010 20:00:53 +0100 Subject: Create Rails::Subscriber::TestHelper and use it to make ActiveRecord subscriber tests run in both sync and async scenarios. --- railties/lib/rails/subscriber/test_helper.rb | 106 +++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 railties/lib/rails/subscriber/test_helper.rb (limited to 'railties/lib') diff --git a/railties/lib/rails/subscriber/test_helper.rb b/railties/lib/rails/subscriber/test_helper.rb new file mode 100644 index 0000000000..d8a8551a45 --- /dev/null +++ b/railties/lib/rails/subscriber/test_helper.rb @@ -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 \ No newline at end of file -- cgit v1.2.3