aboutsummaryrefslogtreecommitdiffstats
path: root/activemodel/test
diff options
context:
space:
mode:
authorMyron Marston <myron.marston@gmail.com>2011-04-28 02:07:42 +0800
committerDavid Heinemeier Hansson <david@loudthinking.com>2011-04-28 10:23:49 +0800
commit1f8cc446d9a7ab751a2def65309ac4bc71e85cd3 (patch)
treeeb537f50bf74ca362dada1b52800d42259d65d2f /activemodel/test
parent5d20c0a64aafa4d35f5aa0613cc16170c2a2ec03 (diff)
downloadrails-1f8cc446d9a7ab751a2def65309ac4bc71e85cd3.tar.gz
rails-1f8cc446d9a7ab751a2def65309ac4bc71e85cd3.tar.bz2
rails-1f8cc446d9a7ab751a2def65309ac4bc71e85cd3.zip
Allow observers to be enabled and disabled.
This is useful in situations like model unit tests and the occasional rake task to backfill old data.
Diffstat (limited to 'activemodel/test')
-rw-r--r--activemodel/test/cases/observer_array_test.rb122
-rw-r--r--activemodel/test/cases/observing_test.rb5
-rw-r--r--activemodel/test/models/observers.rb27
3 files changed, 154 insertions, 0 deletions
diff --git a/activemodel/test/cases/observer_array_test.rb b/activemodel/test/cases/observer_array_test.rb
new file mode 100644
index 0000000000..215ca80bb4
--- /dev/null
+++ b/activemodel/test/cases/observer_array_test.rb
@@ -0,0 +1,122 @@
+require 'cases/helper'
+require 'models/observers'
+
+class ObserverArrayTest < ActiveModel::TestCase
+ def teardown
+ ORM.observers.enable :all
+ Budget.observers.enable :all
+ Widget.observers.enable :all
+ end
+
+ def assert_observer_notified(model_class, observer_class)
+ observer_class.instance.before_save_invocations.clear
+ model_instance = model_class.new
+ model_instance.save
+ assert_equal [model_instance], observer_class.instance.before_save_invocations
+ end
+
+ def assert_observer_not_notified(model_class, observer_class)
+ observer_class.instance.before_save_invocations.clear
+ model_instance = model_class.new
+ model_instance.save
+ assert_equal [], observer_class.instance.before_save_invocations
+ end
+
+ test "all observers are enabled by default" do
+ assert_observer_notified Widget, WidgetObserver
+ assert_observer_notified Budget, BudgetObserver
+ assert_observer_notified Widget, AuditTrail
+ assert_observer_notified Budget, AuditTrail
+ end
+
+ test "can disable individual observers using a class constant" do
+ ORM.observers.disable WidgetObserver
+
+ assert_observer_not_notified Widget, WidgetObserver
+ assert_observer_notified Budget, BudgetObserver
+ assert_observer_notified Widget, AuditTrail
+ assert_observer_notified Budget, AuditTrail
+ end
+
+ test "can disable individual observers using a symbol" do
+ ORM.observers.disable :budget_observer
+
+ assert_observer_notified Widget, WidgetObserver
+ assert_observer_not_notified Budget, BudgetObserver
+ assert_observer_notified Widget, AuditTrail
+ assert_observer_notified Budget, AuditTrail
+ end
+
+ test "can disable all observers using :all" do
+ ORM.observers.disable :all
+
+ assert_observer_not_notified Widget, WidgetObserver
+ assert_observer_not_notified Budget, BudgetObserver
+ assert_observer_not_notified Widget, AuditTrail
+ assert_observer_not_notified Budget, AuditTrail
+ end
+
+ test "can disable observers on individual models without affecting observers on other models" do
+ Widget.observers.disable :all
+
+ assert_observer_not_notified Widget, WidgetObserver
+ assert_observer_notified Budget, BudgetObserver
+ assert_observer_not_notified Widget, AuditTrail
+ assert_observer_notified Budget, AuditTrail
+ end
+
+ test "can disable observers for the duration of a block" do
+ yielded = false
+ ORM.observers.disable :budget_observer do
+ yielded = true
+ assert_observer_notified Widget, WidgetObserver
+ assert_observer_not_notified Budget, BudgetObserver
+ assert_observer_notified Widget, AuditTrail
+ assert_observer_notified Budget, AuditTrail
+ end
+
+ assert yielded
+ assert_observer_notified Widget, WidgetObserver
+ assert_observer_notified Budget, BudgetObserver
+ assert_observer_notified Widget, AuditTrail
+ assert_observer_notified Budget, AuditTrail
+ end
+
+ test "can enable observers for the duration of a block" do
+ yielded = false
+ Widget.observers.disable :all
+
+ Widget.observers.enable :all do
+ yielded = true
+ assert_observer_notified Widget, WidgetObserver
+ assert_observer_notified Budget, BudgetObserver
+ assert_observer_notified Widget, AuditTrail
+ assert_observer_notified Budget, AuditTrail
+ end
+
+ assert yielded
+ assert_observer_not_notified Widget, WidgetObserver
+ assert_observer_notified Budget, BudgetObserver
+ assert_observer_not_notified Widget, AuditTrail
+ assert_observer_notified Budget, AuditTrail
+ end
+
+ test "raises an appropriate error when a developer accidentally enables or disables the wrong class (i.e. Widget instead of WidgetObserver)" do
+ assert_raise ArgumentError do
+ ORM.observers.enable :widget
+ end
+
+ assert_raise ArgumentError do
+ ORM.observers.enable Widget
+ end
+
+ assert_raise ArgumentError do
+ ORM.observers.disable :widget
+ end
+
+ assert_raise ArgumentError do
+ ORM.observers.disable Widget
+ end
+ end
+end
+
diff --git a/activemodel/test/cases/observing_test.rb b/activemodel/test/cases/observing_test.rb
index 63686843b6..99b1f407ae 100644
--- a/activemodel/test/cases/observing_test.rb
+++ b/activemodel/test/cases/observing_test.rb
@@ -43,6 +43,11 @@ class ObservingTest < ActiveModel::TestCase
assert ObservedModel.observers.include?(:bar), ":bar not in #{ObservedModel.observers.inspect}"
end
+ test "uses an ObserverArray so observers can be disabled" do
+ ObservedModel.observers = [:foo, :bar]
+ assert ObservedModel.observers.is_a?(ActiveModel::ObserverArray)
+ end
+
test "instantiates observer names passed as strings" do
ObservedModel.observers << 'foo_observer'
FooObserver.expects(:instance)
diff --git a/activemodel/test/models/observers.rb b/activemodel/test/models/observers.rb
new file mode 100644
index 0000000000..3729b3435e
--- /dev/null
+++ b/activemodel/test/models/observers.rb
@@ -0,0 +1,27 @@
+class ORM
+ include ActiveModel::Observing
+
+ def save
+ notify_observers :before_save
+ end
+
+ class Observer < ActiveModel::Observer
+ def before_save_invocations
+ @before_save_invocations ||= []
+ end
+
+ def before_save(record)
+ before_save_invocations << record
+ end
+ end
+end
+
+class Widget < ORM; end
+class Budget < ORM; end
+class WidgetObserver < ORM::Observer; end
+class BudgetObserver < ORM::Observer; end
+class AuditTrail < ORM::Observer
+ observe :widget, :budget
+end
+
+ORM.instantiate_observers