3 require 'models/developer'
5 require 'models/minimalistic'
7 class Topic
; def after_find() end end
8 class Developer
; def after_find() end end
9 class SpecialDeveloper
< Developer
; end
11 class TopicManualObserver
14 attr_reader
:action, :object, :callbacks
17 Topic
.add_observer(self)
21 def update(callback_method
, object
)
22 @callbacks << { "callback_method" => callback_method
, "object" => object
}
25 def has_been_notified
?
30 class TopicaAuditor
< ActiveRecord
::Observer
40 class TopicObserver
< ActiveRecord
::Observer
48 class MinimalisticObserver
< ActiveRecord
::Observer
49 attr_reader
:minimalistic
51 def after_find(minimalistic
)
52 @minimalistic = minimalistic
56 class MultiObserver
< ActiveRecord
::Observer
59 def self.observed_class() [ Topic
, Developer
] end
61 cattr_reader
:last_inherited
62 @
@last_inherited = nil
64 def observed_class_inherited_with_testing(subclass
)
65 observed_class_inherited_without_testing(subclass
)
66 @
@last_inherited = subclass
69 alias_method_chain
:observed_class_inherited, :testing
71 def after_find(record
)
76 class LifecycleTest
< ActiveRecord
::TestCase
77 fixtures
:topics, :developers, :minimalistics
79 def test_before_destroy
80 original_count
= Topic
.count
81 (topic_to_be_destroyed
= Topic
.find(1)).destroy
82 assert_equal original_count
- (1 + topic_to_be_destroyed
.replies
.size
), Topic
.count
86 ActiveRecord
::Base.observers
= :topic_manual_observer
87 ActiveRecord
::Base.instantiate_observers
93 assert TopicManualObserver
.instance
.has_been_notified
?
94 assert_equal
:after_save, TopicManualObserver
.instance
.callbacks
.last
["callback_method"]
97 def test_observer_update_on_save
98 ActiveRecord
::Base.observers
= TopicManualObserver
99 ActiveRecord
::Base.instantiate_observers
101 topic
= Topic
.find(1)
102 assert TopicManualObserver
.instance
.has_been_notified
?
103 assert_equal
:after_find, TopicManualObserver
.instance
.callbacks
.first
["callback_method"]
106 def test_auto_observer
107 topic_observer
= TopicaAuditor
.instance
108 assert_nil TopicaAuditor
.observed_class
109 assert_equal
[Topic
], TopicaAuditor
.instance
.observed_classes
.to_a
111 topic
= Topic
.find(1)
112 assert_equal topic
.title
, topic_observer
.topic
.title
115 def test_inferred_auto_observer
116 topic_observer
= TopicObserver
.instance
117 assert_equal Topic
, TopicObserver
.observed_class
119 topic
= Topic
.find(1)
120 assert_equal topic
.title
, topic_observer
.topic
.title
123 def test_observing_two_classes
124 multi_observer
= MultiObserver
.instance
126 topic
= Topic
.find(1)
127 assert_equal topic
.title
, multi_observer
.record
.title
129 developer
= Developer
.find(1)
130 assert_equal developer
.name
, multi_observer
.record
.name
133 def test_observing_subclasses
134 multi_observer
= MultiObserver
.instance
136 developer
= SpecialDeveloper
.find(1)
137 assert_equal developer
.name
, multi_observer
.record
.name
139 klass
= Class
.new(Developer
)
140 assert_equal klass
, multi_observer
.last_inherited
142 developer
= klass
.find(1)
143 assert_equal developer
.name
, multi_observer
.record
.name
146 def test_after_find_can_be_observed_when_its_not_defined_on_the_model
147 observer
= MinimalisticObserver
.instance
148 assert_equal Minimalistic
, MinimalisticObserver
.observed_class
150 minimalistic
= Minimalistic
.find(1)
151 assert_equal minimalistic
, observer
.minimalistic
154 def test_after_find_can_be_observed_when_its_defined_on_the_model
155 observer
= TopicObserver
.instance
156 assert_equal Topic
, TopicObserver
.observed_class
158 topic
= Topic
.find(1)
159 assert_equal topic
, observer
.topic
162 def test_after_find_is_not_created_if_its_not_used
163 # use a fresh class so an observer can't have defined an
165 model_class
= Class
.new(ActiveRecord
::Base)
166 observer_class
= Class
.new(ActiveRecord
::Observer)
167 observer_class
.observe(model_class
)
169 observer
= observer_class
.instance
171 assert
!model_class
.method_defined
?(:after_find)
174 def test_after_find_is_not_clobbered_if_it_already_exists
175 # use a fresh observer class so we can instantiate it (Observer is
177 model_class
= Class
.new(ActiveRecord
::Base) do
180 original_method
= model_class
.instance_method(:after_find)
181 observer_class
= Class
.new(ActiveRecord
::Observer) do
184 observer_class
.observe(model_class
)
186 observer
= observer_class
.instance
187 assert_equal original_method
, model_class
.instance_method(:after_find)
190 def test_invalid_observer
191 assert_raise(ArgumentError
) { Topic
.observers
= Object
.new
; Topic
.instantiate_observers
}