rails-observers 0.1.2 → 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,249 +0,0 @@
1
- require 'helper'
2
-
3
- class SpecialDeveloper < Developer; end
4
-
5
- class DeveloperObserver < ActiveRecord::Observer
6
- def calls
7
- @calls ||= []
8
- end
9
-
10
- def before_save(developer)
11
- calls << developer
12
- end
13
- end
14
-
15
- class SalaryChecker < ActiveRecord::Observer
16
- observe :special_developer
17
- attr_accessor :last_saved
18
-
19
- def before_save(developer)
20
- return developer.salary > 80000
21
- end
22
-
23
- module Implementation
24
- def after_save(developer)
25
- self.last_saved = developer
26
- end
27
- end
28
- include Implementation
29
- end
30
-
31
- class TopicaAuditor < ActiveRecord::Observer
32
- observe :topic
33
-
34
- attr_reader :topic
35
-
36
- def after_find(topic)
37
- @topic = topic
38
- end
39
- end
40
-
41
- class TopicObserver < ActiveRecord::Observer
42
- attr_reader :topic
43
-
44
- def after_find(topic)
45
- @topic = topic
46
- end
47
-
48
- # Create an after_save callback, so a notify_observer hook is created
49
- # on :topic.
50
- def after_save(nothing)
51
- end
52
- end
53
-
54
- class MinimalisticObserver < ActiveRecord::Observer
55
- attr_reader :minimalistic
56
-
57
- def after_find(minimalistic)
58
- @minimalistic = minimalistic
59
- end
60
- end
61
-
62
- class MultiObserver < ActiveRecord::Observer
63
- attr_reader :record
64
-
65
- def self.observed_class() [ Topic, Developer ] end
66
-
67
- cattr_reader :last_inherited
68
- @@last_inherited = nil
69
-
70
- def observed_class_inherited_with_testing(subclass)
71
- observed_class_inherited_without_testing(subclass)
72
- @@last_inherited = subclass
73
- end
74
-
75
- alias_method_chain :observed_class_inherited, :testing
76
-
77
- def after_find(record)
78
- @record = record
79
- end
80
- end
81
-
82
- class ValidatedComment < Comment
83
- attr_accessor :callers
84
-
85
- before_validation :record_callers
86
-
87
- after_validation do
88
- record_callers
89
- end
90
-
91
- def record_callers
92
- callers << self.class if callers
93
- end
94
- end
95
-
96
- class ValidatedCommentObserver < ActiveRecord::Observer
97
- attr_accessor :callers
98
-
99
- def after_validation(model)
100
- callers << self.class if callers
101
- end
102
- end
103
-
104
-
105
- class AroundTopic < Topic
106
- end
107
-
108
- class AroundTopicObserver < ActiveRecord::Observer
109
- observe :around_topic
110
- def topic_ids
111
- @topic_ids ||= []
112
- end
113
-
114
- def around_save(topic)
115
- topic_ids << topic.id
116
- yield(topic)
117
- topic_ids << topic.id
118
- end
119
- end
120
-
121
- class LifecycleTest < ActiveRecord::TestCase
122
- fixtures :topics, :developers, :minimalistics
123
-
124
- def test_before_destroy
125
- topic = Topic.find(1)
126
- assert_difference 'Topic.count', -(1 + topic.replies.size) do
127
- topic.destroy
128
- end
129
- end
130
-
131
- def test_auto_observer
132
- topic_observer = TopicaAuditor.instance
133
- assert_nil TopicaAuditor.observed_class
134
- assert_equal [Topic], TopicaAuditor.observed_classes.to_a
135
-
136
- topic = Topic.find(1)
137
- assert_equal topic.title, topic_observer.topic.title
138
- end
139
-
140
- def test_inferred_auto_observer
141
- topic_observer = TopicObserver.instance
142
- assert_equal Topic, TopicObserver.observed_class
143
-
144
- topic = Topic.find(1)
145
- assert_equal topic.title, topic_observer.topic.title
146
- end
147
-
148
- def test_observing_two_classes
149
- multi_observer = MultiObserver.instance
150
-
151
- topic = Topic.find(1)
152
- assert_equal topic.title, multi_observer.record.title
153
-
154
- developer = Developer.find(1)
155
- assert_equal developer.name, multi_observer.record.name
156
- end
157
-
158
- def test_observing_subclasses
159
- multi_observer = MultiObserver.instance
160
-
161
- developer = SpecialDeveloper.find(1)
162
- assert_equal developer.name, multi_observer.record.name
163
-
164
- klass = Class.new(Developer)
165
- assert_equal klass, multi_observer.last_inherited
166
-
167
- developer = klass.find(1)
168
- assert_equal developer.name, multi_observer.record.name
169
- end
170
-
171
- def test_after_find_can_be_observed_when_its_not_defined_on_the_model
172
- observer = MinimalisticObserver.instance
173
- assert_equal Minimalistic, MinimalisticObserver.observed_class
174
-
175
- minimalistic = Minimalistic.find(1)
176
- assert_equal minimalistic, observer.minimalistic
177
- end
178
-
179
- def test_after_find_can_be_observed_when_its_defined_on_the_model
180
- observer = TopicObserver.instance
181
- assert_equal Topic, TopicObserver.observed_class
182
-
183
- topic = Topic.find(1)
184
- assert_equal topic, observer.topic
185
- end
186
-
187
- def test_invalid_observer
188
- assert_raise(ArgumentError) { Topic.observers = Object.new; Topic.instantiate_observers }
189
- end
190
-
191
- test "model callbacks fire before observers are notified" do
192
- callers = []
193
-
194
- comment = ValidatedComment.new
195
- comment.callers = ValidatedCommentObserver.instance.callers = callers
196
-
197
- comment.valid?
198
- assert_equal [ValidatedComment, ValidatedComment, ValidatedCommentObserver], callers,
199
- "model callbacks did not fire before observers were notified"
200
- end
201
-
202
- test "able to save developer" do
203
- SalaryChecker.instance # activate
204
- developer = SpecialDeveloper.new :name => 'Roger', :salary => 100000
205
- assert developer.save, "developer with normal salary failed to save"
206
- end
207
-
208
- test "unable to save developer with low salary" do
209
- SalaryChecker.instance # activate
210
- developer = SpecialDeveloper.new :name => 'Rookie', :salary => 50000
211
- assert !developer.save, "allowed to save a developer with too low salary"
212
- end
213
-
214
- test "able to call methods defined with included module" do # https://rails.lighthouseapp.com/projects/8994/tickets/6065-activerecordobserver-is-not-aware-of-method-added-by-including-modules
215
- SalaryChecker.instance # activate
216
- developer = SpecialDeveloper.create! :name => 'Roger', :salary => 100000
217
- assert_equal developer, SalaryChecker.instance.last_saved
218
- end
219
-
220
- test "around filter from observer should accept block" do
221
- observer = AroundTopicObserver.instance
222
- topic = AroundTopic.new
223
- topic.save
224
- assert_nil observer.topic_ids.first
225
- assert_not_nil observer.topic_ids.last
226
- end
227
-
228
- test "able to disable observers" do
229
- observer = DeveloperObserver.instance # activate
230
- observer.calls.clear
231
-
232
- ActiveRecord::Base.observers.disable DeveloperObserver do
233
- Developer.create! :name => 'Ancestor', :salary => 100000
234
- SpecialDeveloper.create! :name => 'Descendent', :salary => 100000
235
- end
236
-
237
- assert_equal [], observer.calls
238
- end
239
-
240
- def test_observer_is_called_once
241
- observer = DeveloperObserver.instance # activate
242
- observer.calls.clear
243
-
244
- developer = Developer.create! :name => 'Ancestor', :salary => 100000
245
- special_developer = SpecialDeveloper.create! :name => 'Descendent', :salary => 100000
246
-
247
- assert_equal [developer, special_developer], observer.calls
248
- end
249
- end
@@ -1,27 +0,0 @@
1
- class ORM
2
- include ActiveModel::Observing
3
-
4
- def save
5
- notify_observers :before_save
6
- end
7
-
8
- class Observer < ActiveModel::Observer
9
- def before_save_invocations
10
- @before_save_invocations ||= []
11
- end
12
-
13
- def before_save(record)
14
- before_save_invocations << record
15
- end
16
- end
17
- end
18
-
19
- class Widget < ORM; end
20
- class Budget < ORM; end
21
- class WidgetObserver < ORM::Observer; end
22
- class BudgetObserver < ORM::Observer; end
23
- class AuditTrail < ORM::Observer
24
- observe :widget, :budget
25
- end
26
-
27
- ORM.instantiate_observers
@@ -1,222 +0,0 @@
1
- require 'minitest/autorun'
2
- require 'active_model'
3
- require 'rails/observers/active_model/active_model'
4
- require 'models/observers'
5
-
6
- class ObserverArrayTest < ActiveModel::TestCase
7
- def teardown
8
- ORM.observers.enable :all
9
- Budget.observers.enable :all
10
- Widget.observers.enable :all
11
- end
12
-
13
- def assert_observer_notified(model_class, observer_class)
14
- observer_class.instance.before_save_invocations.clear
15
- model_instance = model_class.new
16
- model_instance.save
17
- assert_equal [model_instance], observer_class.instance.before_save_invocations
18
- end
19
-
20
- def assert_observer_not_notified(model_class, observer_class)
21
- observer_class.instance.before_save_invocations.clear
22
- model_instance = model_class.new
23
- model_instance.save
24
- assert_equal [], observer_class.instance.before_save_invocations
25
- end
26
-
27
- test "all observers are enabled by default" do
28
- assert_observer_notified Widget, WidgetObserver
29
- assert_observer_notified Budget, BudgetObserver
30
- assert_observer_notified Widget, AuditTrail
31
- assert_observer_notified Budget, AuditTrail
32
- end
33
-
34
- test "can disable individual observers using a class constant" do
35
- ORM.observers.disable WidgetObserver
36
-
37
- assert_observer_not_notified Widget, WidgetObserver
38
- assert_observer_notified Budget, BudgetObserver
39
- assert_observer_notified Widget, AuditTrail
40
- assert_observer_notified Budget, AuditTrail
41
- end
42
-
43
- test "can enable individual observers using a class constant" do
44
- ORM.observers.disable :all
45
- ORM.observers.enable AuditTrail
46
-
47
- assert_observer_not_notified Widget, WidgetObserver
48
- assert_observer_not_notified Budget, BudgetObserver
49
- assert_observer_notified Widget, AuditTrail
50
- assert_observer_notified Budget, AuditTrail
51
- end
52
-
53
- test "can disable individual observers using a symbol" do
54
- ORM.observers.disable :budget_observer
55
-
56
- assert_observer_notified Widget, WidgetObserver
57
- assert_observer_not_notified Budget, BudgetObserver
58
- assert_observer_notified Widget, AuditTrail
59
- assert_observer_notified Budget, AuditTrail
60
- end
61
-
62
- test "can enable individual observers using a symbol" do
63
- ORM.observers.disable :all
64
- ORM.observers.enable :audit_trail
65
-
66
- assert_observer_not_notified Widget, WidgetObserver
67
- assert_observer_not_notified Budget, BudgetObserver
68
- assert_observer_notified Widget, AuditTrail
69
- assert_observer_notified Budget, AuditTrail
70
- end
71
-
72
- test "can disable multiple observers at a time" do
73
- ORM.observers.disable :widget_observer, :budget_observer
74
-
75
- assert_observer_not_notified Widget, WidgetObserver
76
- assert_observer_not_notified Budget, BudgetObserver
77
- assert_observer_notified Widget, AuditTrail
78
- assert_observer_notified Budget, AuditTrail
79
- end
80
-
81
- test "can enable multiple observers at a time" do
82
- ORM.observers.disable :all
83
- ORM.observers.enable :widget_observer, :budget_observer
84
-
85
- assert_observer_notified Widget, WidgetObserver
86
- assert_observer_notified Budget, BudgetObserver
87
- assert_observer_not_notified Widget, AuditTrail
88
- assert_observer_not_notified Budget, AuditTrail
89
- end
90
-
91
- test "can disable all observers using :all" do
92
- ORM.observers.disable :all
93
-
94
- assert_observer_not_notified Widget, WidgetObserver
95
- assert_observer_not_notified Budget, BudgetObserver
96
- assert_observer_not_notified Widget, AuditTrail
97
- assert_observer_not_notified Budget, AuditTrail
98
- end
99
-
100
- test "can enable all observers using :all" do
101
- ORM.observers.disable :all
102
- ORM.observers.enable :all
103
-
104
- assert_observer_notified Widget, WidgetObserver
105
- assert_observer_notified Budget, BudgetObserver
106
- assert_observer_notified Widget, AuditTrail
107
- assert_observer_notified Budget, AuditTrail
108
- end
109
-
110
- test "can disable observers on individual models without affecting those observers on other models" do
111
- Widget.observers.disable :all
112
-
113
- assert_observer_not_notified Widget, WidgetObserver
114
- assert_observer_notified Budget, BudgetObserver
115
- assert_observer_not_notified Widget, AuditTrail
116
- assert_observer_notified Budget, AuditTrail
117
- end
118
-
119
- test "can enable observers on individual models without affecting those observers on other models" do
120
- ORM.observers.disable :all
121
- Budget.observers.enable AuditTrail
122
-
123
- assert_observer_not_notified Widget, WidgetObserver
124
- assert_observer_not_notified Budget, BudgetObserver
125
- assert_observer_not_notified Widget, AuditTrail
126
- assert_observer_notified Budget, AuditTrail
127
- end
128
-
129
- test "can disable observers for the duration of a block" do
130
- yielded = false
131
- ORM.observers.disable :budget_observer do
132
- yielded = true
133
- assert_observer_notified Widget, WidgetObserver
134
- assert_observer_not_notified Budget, BudgetObserver
135
- assert_observer_notified Widget, AuditTrail
136
- assert_observer_notified Budget, AuditTrail
137
- end
138
-
139
- assert yielded
140
- assert_observer_notified Widget, WidgetObserver
141
- assert_observer_notified Budget, BudgetObserver
142
- assert_observer_notified Widget, AuditTrail
143
- assert_observer_notified Budget, AuditTrail
144
- end
145
-
146
- test "can enable observers for the duration of a block" do
147
- yielded = false
148
- Widget.observers.disable :all
149
-
150
- Widget.observers.enable :all do
151
- yielded = true
152
- assert_observer_notified Widget, WidgetObserver
153
- assert_observer_notified Budget, BudgetObserver
154
- assert_observer_notified Widget, AuditTrail
155
- assert_observer_notified Budget, AuditTrail
156
- end
157
-
158
- assert yielded
159
- assert_observer_not_notified Widget, WidgetObserver
160
- assert_observer_notified Budget, BudgetObserver
161
- assert_observer_not_notified Widget, AuditTrail
162
- assert_observer_notified Budget, AuditTrail
163
- end
164
-
165
- test "raises an appropriate error when a developer accidentally enables or disables the wrong class (i.e. Widget instead of WidgetObserver)" do
166
- assert_raise ArgumentError do
167
- ORM.observers.enable :widget
168
- end
169
-
170
- assert_raise ArgumentError do
171
- ORM.observers.enable Widget
172
- end
173
-
174
- assert_raise ArgumentError do
175
- ORM.observers.disable :widget
176
- end
177
-
178
- assert_raise ArgumentError do
179
- ORM.observers.disable Widget
180
- end
181
- end
182
-
183
- test "allows #enable at the superclass level to override #disable at the subclass level when called last" do
184
- Widget.observers.disable :all
185
- ORM.observers.enable :all
186
-
187
- assert_observer_notified Widget, WidgetObserver
188
- assert_observer_notified Budget, BudgetObserver
189
- assert_observer_notified Widget, AuditTrail
190
- assert_observer_notified Budget, AuditTrail
191
- end
192
-
193
- test "allows #disable at the superclass level to override #enable at the subclass level when called last" do
194
- Budget.observers.enable :audit_trail
195
- ORM.observers.disable :audit_trail
196
-
197
- assert_observer_notified Widget, WidgetObserver
198
- assert_observer_notified Budget, BudgetObserver
199
- assert_observer_not_notified Widget, AuditTrail
200
- assert_observer_not_notified Budget, AuditTrail
201
- end
202
-
203
- test "can use the block form at different levels of the hierarchy" do
204
- yielded = false
205
- Widget.observers.disable :all
206
-
207
- ORM.observers.enable :all do
208
- yielded = true
209
- assert_observer_notified Widget, WidgetObserver
210
- assert_observer_notified Budget, BudgetObserver
211
- assert_observer_notified Widget, AuditTrail
212
- assert_observer_notified Budget, AuditTrail
213
- end
214
-
215
- assert yielded
216
- assert_observer_not_notified Widget, WidgetObserver
217
- assert_observer_notified Budget, BudgetObserver
218
- assert_observer_not_notified Widget, AuditTrail
219
- assert_observer_notified Budget, AuditTrail
220
- end
221
- end
222
-