require 'test_helper' class ObservedModel < ActiveModel::Base class Observer end end class FooObserver < ActiveModel::Observer class << self public :new end attr_accessor :stub def on_spec(record) stub.event_with(record) if stub end end class Foo < ActiveModel::Base end class ObservingTest < ActiveModel::TestCase def setup ObservedModel.observers.clear end test "initializes model with no cached observers" do assert ObservedModel.observers.empty?, "Not empty: #{ObservedModel.observers.inspect}" end test "stores cached observers in an array" do ObservedModel.observers << :foo assert ObservedModel.observers.include?(:foo), ":foo not in #{ObservedModel.observers.inspect}" end test "flattens array of assigned cached observers" do ObservedModel.observers = [[:foo], :bar] assert ObservedModel.observers.include?(:foo), ":foo not in #{ObservedModel.observers.inspect}" assert ObservedModel.observers.include?(:bar), ":bar not in #{ObservedModel.observers.inspect}" end test "instantiates observer names passed as strings" do ObservedModel.observers << 'foo_observer' FooObserver.expects(:instance) ObservedModel.instantiate_observers end test "instantiates observer names passed as symbols" do ObservedModel.observers << :foo_observer FooObserver.expects(:instance) ObservedModel.instantiate_observers end test "instantiates observer classes" do ObservedModel.observers << ObservedModel::Observer ObservedModel::Observer.expects(:instance) ObservedModel.instantiate_observers end test "passes observers to subclasses" do FooObserver.instance bar = Class.new(Foo) assert_equal Foo.count_observers, bar.count_observers end end class ObserverTest < ActiveModel::TestCase def setup ObservedModel.observers = :foo_observer FooObserver.models = nil end test "guesses implicit observable model name" do assert_equal 'Foo', FooObserver.observed_class_name end test "tracks implicit observable models" do instance = FooObserver.new assert instance.send(:observed_classes).include?(Foo), "Foo not in #{instance.send(:observed_classes).inspect}" assert !instance.send(:observed_classes).include?(ObservedModel), "ObservedModel in #{instance.send(:observed_classes).inspect}" end test "tracks explicit observed model class" do old_instance = FooObserver.new assert !old_instance.send(:observed_classes).include?(ObservedModel), "ObservedModel in #{old_instance.send(:observed_classes).inspect}" FooObserver.observe ObservedModel instance = FooObserver.new assert instance.send(:observed_classes).include?(ObservedModel), "ObservedModel not in #{instance.send(:observed_classes).inspect}" end test "tracks explicit observed model as string" do old_instance = FooObserver.new assert !old_instance.send(:observed_classes).include?(ObservedModel), "ObservedModel in #{old_instance.send(:observed_classes).inspect}" FooObserver.observe 'observed_model' instance = FooObserver.new assert instance.send(:observed_classes).include?(ObservedModel), "ObservedModel not in #{instance.send(:observed_classes).inspect}" end test "tracks explicit observed model as symbol" do old_instance = FooObserver.new assert !old_instance.send(:observed_classes).include?(ObservedModel), "ObservedModel in #{old_instance.send(:observed_classes).inspect}" FooObserver.observe :observed_model instance = FooObserver.new assert instance.send(:observed_classes).include?(ObservedModel), "ObservedModel not in #{instance.send(:observed_classes).inspect}" end test "calls existing observer event" do foo = Foo.new FooObserver.instance.stub = stub FooObserver.instance.stub.expects(:event_with).with(foo) Foo.send(:changed) Foo.send(:notify_observers, :on_spec, foo) end test "skips nonexistent observer event" do foo = Foo.new Foo.send(:changed) Foo.send(:notify_observers, :whatever, foo) end end