aboutsummaryrefslogtreecommitdiffstats
path: root/activemodel/test/cases/observing_test.rb
blob: 421ac4b4f88b8316f46319eed38f899adff4ebba (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
require 'cases/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