Froze rails gems
[depot.git] / vendor / rails / activerecord / test / cases / callbacks_test.rb
1 require "cases/helper"
2
3 class CallbackDeveloper < ActiveRecord::Base
4 set_table_name 'developers'
5
6 class << self
7 def callback_string(callback_method)
8 "history << [#{callback_method.to_sym.inspect}, :string]"
9 end
10
11 def callback_proc(callback_method)
12 Proc.new { |model| model.history << [callback_method, :proc] }
13 end
14
15 def define_callback_method(callback_method)
16 define_method("#{callback_method}_method") do |model|
17 model.history << [callback_method, :method]
18 end
19 end
20
21 def callback_object(callback_method)
22 klass = Class.new
23 klass.send(:define_method, callback_method) do |model|
24 model.history << [callback_method, :object]
25 end
26 klass.new
27 end
28 end
29
30 ActiveRecord::Callbacks::CALLBACKS.each do |callback_method|
31 callback_method_sym = callback_method.to_sym
32 define_callback_method(callback_method_sym)
33 send(callback_method, callback_method_sym)
34 send(callback_method, callback_string(callback_method_sym))
35 send(callback_method, callback_proc(callback_method_sym))
36 send(callback_method, callback_object(callback_method_sym))
37 send(callback_method) { |model| model.history << [callback_method_sym, :block] }
38 end
39
40 def history
41 @history ||= []
42 end
43
44 # after_initialize and after_find are invoked only if instance methods have been defined.
45 def after_initialize
46 end
47
48 def after_find
49 end
50 end
51
52 class ParentDeveloper < ActiveRecord::Base
53 set_table_name 'developers'
54 attr_accessor :after_save_called
55 before_validation {|record| record.after_save_called = true}
56 end
57
58 class ChildDeveloper < ParentDeveloper
59
60 end
61
62 class RecursiveCallbackDeveloper < ActiveRecord::Base
63 set_table_name 'developers'
64
65 before_save :on_before_save
66 after_save :on_after_save
67
68 attr_reader :on_before_save_called, :on_after_save_called
69
70 def on_before_save
71 @on_before_save_called ||= 0
72 @on_before_save_called += 1
73 save unless @on_before_save_called > 1
74 end
75
76 def on_after_save
77 @on_after_save_called ||= 0
78 @on_after_save_called += 1
79 save unless @on_after_save_called > 1
80 end
81 end
82
83 class ImmutableDeveloper < ActiveRecord::Base
84 set_table_name 'developers'
85
86 validates_inclusion_of :salary, :in => 50000..200000
87
88 before_save :cancel
89 before_destroy :cancel
90
91 def cancelled?
92 @cancelled == true
93 end
94
95 private
96 def cancel
97 @cancelled = true
98 false
99 end
100 end
101
102 class ImmutableMethodDeveloper < ActiveRecord::Base
103 set_table_name 'developers'
104
105 validates_inclusion_of :salary, :in => 50000..200000
106
107 def cancelled?
108 @cancelled == true
109 end
110
111 def before_save
112 @cancelled = true
113 false
114 end
115
116 def before_destroy
117 @cancelled = true
118 false
119 end
120 end
121
122 class CallbackCancellationDeveloper < ActiveRecord::Base
123 set_table_name 'developers'
124 def before_create
125 false
126 end
127 end
128
129 class CallbacksTest < ActiveRecord::TestCase
130 fixtures :developers
131
132 def test_initialize
133 david = CallbackDeveloper.new
134 assert_equal [
135 [ :after_initialize, :string ],
136 [ :after_initialize, :proc ],
137 [ :after_initialize, :object ],
138 [ :after_initialize, :block ],
139 ], david.history
140 end
141
142 def test_find
143 david = CallbackDeveloper.find(1)
144 assert_equal [
145 [ :after_find, :string ],
146 [ :after_find, :proc ],
147 [ :after_find, :object ],
148 [ :after_find, :block ],
149 [ :after_initialize, :string ],
150 [ :after_initialize, :proc ],
151 [ :after_initialize, :object ],
152 [ :after_initialize, :block ],
153 ], david.history
154 end
155
156 def test_new_valid?
157 david = CallbackDeveloper.new
158 david.valid?
159 assert_equal [
160 [ :after_initialize, :string ],
161 [ :after_initialize, :proc ],
162 [ :after_initialize, :object ],
163 [ :after_initialize, :block ],
164 [ :before_validation, :string ],
165 [ :before_validation, :proc ],
166 [ :before_validation, :object ],
167 [ :before_validation, :block ],
168 [ :before_validation_on_create, :string ],
169 [ :before_validation_on_create, :proc ],
170 [ :before_validation_on_create, :object ],
171 [ :before_validation_on_create, :block ],
172 [ :after_validation, :string ],
173 [ :after_validation, :proc ],
174 [ :after_validation, :object ],
175 [ :after_validation, :block ],
176 [ :after_validation_on_create, :string ],
177 [ :after_validation_on_create, :proc ],
178 [ :after_validation_on_create, :object ],
179 [ :after_validation_on_create, :block ]
180 ], david.history
181 end
182
183 def test_existing_valid?
184 david = CallbackDeveloper.find(1)
185 david.valid?
186 assert_equal [
187 [ :after_find, :string ],
188 [ :after_find, :proc ],
189 [ :after_find, :object ],
190 [ :after_find, :block ],
191 [ :after_initialize, :string ],
192 [ :after_initialize, :proc ],
193 [ :after_initialize, :object ],
194 [ :after_initialize, :block ],
195 [ :before_validation, :string ],
196 [ :before_validation, :proc ],
197 [ :before_validation, :object ],
198 [ :before_validation, :block ],
199 [ :before_validation_on_update, :string ],
200 [ :before_validation_on_update, :proc ],
201 [ :before_validation_on_update, :object ],
202 [ :before_validation_on_update, :block ],
203 [ :after_validation, :string ],
204 [ :after_validation, :proc ],
205 [ :after_validation, :object ],
206 [ :after_validation, :block ],
207 [ :after_validation_on_update, :string ],
208 [ :after_validation_on_update, :proc ],
209 [ :after_validation_on_update, :object ],
210 [ :after_validation_on_update, :block ]
211 ], david.history
212 end
213
214 def test_create
215 david = CallbackDeveloper.create('name' => 'David', 'salary' => 1000000)
216 assert_equal [
217 [ :after_initialize, :string ],
218 [ :after_initialize, :proc ],
219 [ :after_initialize, :object ],
220 [ :after_initialize, :block ],
221 [ :before_validation, :string ],
222 [ :before_validation, :proc ],
223 [ :before_validation, :object ],
224 [ :before_validation, :block ],
225 [ :before_validation_on_create, :string ],
226 [ :before_validation_on_create, :proc ],
227 [ :before_validation_on_create, :object ],
228 [ :before_validation_on_create, :block ],
229 [ :after_validation, :string ],
230 [ :after_validation, :proc ],
231 [ :after_validation, :object ],
232 [ :after_validation, :block ],
233 [ :after_validation_on_create, :string ],
234 [ :after_validation_on_create, :proc ],
235 [ :after_validation_on_create, :object ],
236 [ :after_validation_on_create, :block ],
237 [ :before_save, :string ],
238 [ :before_save, :proc ],
239 [ :before_save, :object ],
240 [ :before_save, :block ],
241 [ :before_create, :string ],
242 [ :before_create, :proc ],
243 [ :before_create, :object ],
244 [ :before_create, :block ],
245 [ :after_create, :string ],
246 [ :after_create, :proc ],
247 [ :after_create, :object ],
248 [ :after_create, :block ],
249 [ :after_save, :string ],
250 [ :after_save, :proc ],
251 [ :after_save, :object ],
252 [ :after_save, :block ]
253 ], david.history
254 end
255
256 def test_save
257 david = CallbackDeveloper.find(1)
258 david.save
259 assert_equal [
260 [ :after_find, :string ],
261 [ :after_find, :proc ],
262 [ :after_find, :object ],
263 [ :after_find, :block ],
264 [ :after_initialize, :string ],
265 [ :after_initialize, :proc ],
266 [ :after_initialize, :object ],
267 [ :after_initialize, :block ],
268 [ :before_validation, :string ],
269 [ :before_validation, :proc ],
270 [ :before_validation, :object ],
271 [ :before_validation, :block ],
272 [ :before_validation_on_update, :string ],
273 [ :before_validation_on_update, :proc ],
274 [ :before_validation_on_update, :object ],
275 [ :before_validation_on_update, :block ],
276 [ :after_validation, :string ],
277 [ :after_validation, :proc ],
278 [ :after_validation, :object ],
279 [ :after_validation, :block ],
280 [ :after_validation_on_update, :string ],
281 [ :after_validation_on_update, :proc ],
282 [ :after_validation_on_update, :object ],
283 [ :after_validation_on_update, :block ],
284 [ :before_save, :string ],
285 [ :before_save, :proc ],
286 [ :before_save, :object ],
287 [ :before_save, :block ],
288 [ :before_update, :string ],
289 [ :before_update, :proc ],
290 [ :before_update, :object ],
291 [ :before_update, :block ],
292 [ :after_update, :string ],
293 [ :after_update, :proc ],
294 [ :after_update, :object ],
295 [ :after_update, :block ],
296 [ :after_save, :string ],
297 [ :after_save, :proc ],
298 [ :after_save, :object ],
299 [ :after_save, :block ]
300 ], david.history
301 end
302
303 def test_destroy
304 david = CallbackDeveloper.find(1)
305 david.destroy
306 assert_equal [
307 [ :after_find, :string ],
308 [ :after_find, :proc ],
309 [ :after_find, :object ],
310 [ :after_find, :block ],
311 [ :after_initialize, :string ],
312 [ :after_initialize, :proc ],
313 [ :after_initialize, :object ],
314 [ :after_initialize, :block ],
315 [ :before_destroy, :string ],
316 [ :before_destroy, :proc ],
317 [ :before_destroy, :object ],
318 [ :before_destroy, :block ],
319 [ :after_destroy, :string ],
320 [ :after_destroy, :proc ],
321 [ :after_destroy, :object ],
322 [ :after_destroy, :block ]
323 ], david.history
324 end
325
326 def test_delete
327 david = CallbackDeveloper.find(1)
328 CallbackDeveloper.delete(david.id)
329 assert_equal [
330 [ :after_find, :string ],
331 [ :after_find, :proc ],
332 [ :after_find, :object ],
333 [ :after_find, :block ],
334 [ :after_initialize, :string ],
335 [ :after_initialize, :proc ],
336 [ :after_initialize, :object ],
337 [ :after_initialize, :block ],
338 ], david.history
339 end
340
341 def test_before_save_returning_false
342 david = ImmutableDeveloper.find(1)
343 assert david.valid?
344 assert !david.save
345 assert_raises(ActiveRecord::RecordNotSaved) { david.save! }
346
347 david = ImmutableDeveloper.find(1)
348 david.salary = 10_000_000
349 assert !david.valid?
350 assert !david.save
351 assert_raises(ActiveRecord::RecordInvalid) { david.save! }
352 end
353
354 def test_before_create_returning_false
355 someone = CallbackCancellationDeveloper.new
356 assert someone.valid?
357 assert !someone.save
358 end
359
360 def test_before_destroy_returning_false
361 david = ImmutableDeveloper.find(1)
362 assert !david.destroy
363 assert_not_nil ImmutableDeveloper.find_by_id(1)
364 end
365
366 def test_zzz_callback_returning_false # must be run last since we modify CallbackDeveloper
367 david = CallbackDeveloper.find(1)
368 CallbackDeveloper.before_validation proc { |model| model.history << [:before_validation, :returning_false]; return false }
369 CallbackDeveloper.before_validation proc { |model| model.history << [:before_validation, :should_never_get_here] }
370 david.save
371 assert_equal [
372 [ :after_find, :string ],
373 [ :after_find, :proc ],
374 [ :after_find, :object ],
375 [ :after_find, :block ],
376 [ :after_initialize, :string ],
377 [ :after_initialize, :proc ],
378 [ :after_initialize, :object ],
379 [ :after_initialize, :block ],
380 [ :before_validation, :string ],
381 [ :before_validation, :proc ],
382 [ :before_validation, :object ],
383 [ :before_validation, :block ],
384 [ :before_validation, :returning_false ]
385 ], david.history
386 end
387
388 def test_inheritence_of_callbacks
389 parent = ParentDeveloper.new
390 assert !parent.after_save_called
391 parent.save
392 assert parent.after_save_called
393
394 child = ChildDeveloper.new
395 assert !child.after_save_called
396 child.save
397 assert child.after_save_called
398 end
399
400 end