diff --git a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb index 4a9cc09032..d697cb8d11 100755 --- a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb @@ -191,6 +191,7 @@ module ActiveRecord end protected + def log(sql, name) name ||= "SQL" result = nil diff --git a/activerecord/test/cases/subscriber_test.rb b/activerecord/test/cases/subscriber_test.rb new file mode 100644 index 0000000000..f569d64ee5 --- /dev/null +++ b/activerecord/test/cases/subscriber_test.rb @@ -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 \ No newline at end of file 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 diff --git a/railties/test/subscriber_test.rb b/railties/test/subscriber_test.rb index 0d8793abab..db953bb041 100644 --- a/railties/test/subscriber_test.rb +++ b/railties/test/subscriber_test.rb @@ -1,25 +1,5 @@ require 'abstract_unit' -require 'rails/subscriber' - -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 +require 'rails/subscriber/test_helper' class MySubscriber < Rails::Subscriber attr_reader :event @@ -40,16 +20,14 @@ class MySubscriber < Rails::Subscriber end end -class SubscriberTest < ActiveSupport::TestCase +module SubscriberTest def setup - @logger = MockLogger.new - @previous_logger, Rails.logger = Rails.logger, @logger + super @subscriber = MySubscriber.new - wait end def teardown - Rails.logger = @previous_logger + super Rails::Subscriber.subscribers.clear end @@ -57,10 +35,6 @@ class SubscriberTest < ActiveSupport::TestCase ActiveSupport::Notifications.instrument(*args, &block) end - def wait - ActiveSupport::Notifications.notifier.wait - end - def test_proxies_method_to_rails_logger @subscriber.foo(nil) assert_equal %w(debug), @logger.logged(:debug) @@ -69,16 +43,14 @@ class SubscriberTest < ActiveSupport::TestCase end def test_set_color_for_messages + Rails::Subscriber.colorize_logging = true @subscriber.bar(nil) assert_equal "\e[31mcool\e[0m, \e[1m\e[34misn't it?\e[0m", @logger.logged(:info).last end def test_does_not_set_color_if_colorize_logging_is_set_to_false - Rails::Subscriber.colorize_logging = false @subscriber.bar(nil) assert_equal "cool, isn't it?", @logger.logged(:info).last - ensure - Rails::Subscriber.colorize_logging = true end def test_event_is_sent_to_the_registered_class @@ -109,4 +81,15 @@ class SubscriberTest < ActiveSupport::TestCase wait assert_equal [], @logger.logged(:info) end + + class SyncSubscriberTest < ActiveSupport::TestCase + include Rails::Subscriber::SyncTestHelper + include SubscriberTest + end + + class AsyncSubscriberTest < ActiveSupport::TestCase + include Rails::Subscriber::AsyncTestHelper + include SubscriberTest + end + end \ No newline at end of file