~michaelforrest/use-case-mapper/trunk

« back to all changes in this revision

Viewing changes to vendor/rails/activerecord/test/cases/callbacks_test.rb

  • Committer: Michael Forrest
  • Date: 2010-10-15 16:28:50 UTC
  • Revision ID: michael.forrest@canonical.com-20101015162850-tj2vchanv0kr0dun
refrozeĀ gems

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 
 
125
  attr_reader   :after_save_called, :after_create_called, :after_update_called, :after_destroy_called
 
126
  attr_accessor :cancel_before_save, :cancel_before_create, :cancel_before_update, :cancel_before_destroy
 
127
 
 
128
  def before_save;    !@cancel_before_save;    end
 
129
  def before_create;  !@cancel_before_create;  end
 
130
  def before_update;  !@cancel_before_update;  end
 
131
  def before_destroy; !@cancel_before_destroy; end
 
132
 
 
133
  def after_save;      @after_save_called    = true; end
 
134
  def after_update;    @after_update_called  = true; end
 
135
  def after_create;    @after_create_called  = true; end
 
136
  def after_destroy;   @after_destroy_called = true; end
 
137
end
 
138
 
 
139
class CallbacksTest < ActiveRecord::TestCase
 
140
  fixtures :developers
 
141
 
 
142
  def test_initialize
 
143
    david = CallbackDeveloper.new
 
144
    assert_equal [
 
145
      [ :after_initialize,            :string ],
 
146
      [ :after_initialize,            :proc   ],
 
147
      [ :after_initialize,            :object ],
 
148
      [ :after_initialize,            :block  ],
 
149
    ], david.history
 
150
  end
 
151
 
 
152
  def test_find
 
153
    david = CallbackDeveloper.find(1)
 
154
    assert_equal [
 
155
      [ :after_find,            :string ],
 
156
      [ :after_find,            :proc   ],
 
157
      [ :after_find,            :object ],
 
158
      [ :after_find,            :block  ],
 
159
      [ :after_initialize,            :string ],
 
160
      [ :after_initialize,            :proc   ],
 
161
      [ :after_initialize,            :object ],
 
162
      [ :after_initialize,            :block  ],
 
163
    ], david.history
 
164
  end
 
165
 
 
166
  def test_new_valid?
 
167
    david = CallbackDeveloper.new
 
168
    david.valid?
 
169
    assert_equal [
 
170
      [ :after_initialize,            :string ],
 
171
      [ :after_initialize,            :proc   ],
 
172
      [ :after_initialize,            :object ],
 
173
      [ :after_initialize,            :block  ],
 
174
      [ :before_validation,           :string ],
 
175
      [ :before_validation,           :proc   ],
 
176
      [ :before_validation,           :object ],
 
177
      [ :before_validation,           :block  ],
 
178
      [ :before_validation_on_create, :string ],
 
179
      [ :before_validation_on_create, :proc   ],
 
180
      [ :before_validation_on_create, :object ],
 
181
      [ :before_validation_on_create, :block  ],
 
182
      [ :after_validation,            :string ],
 
183
      [ :after_validation,            :proc   ],
 
184
      [ :after_validation,            :object ],
 
185
      [ :after_validation,            :block  ],
 
186
      [ :after_validation_on_create,  :string ],
 
187
      [ :after_validation_on_create,  :proc   ],
 
188
      [ :after_validation_on_create,  :object ],
 
189
      [ :after_validation_on_create,  :block  ]
 
190
    ], david.history
 
191
  end
 
192
 
 
193
  def test_existing_valid?
 
194
    david = CallbackDeveloper.find(1)
 
195
    david.valid?
 
196
    assert_equal [
 
197
      [ :after_find,            :string ],
 
198
      [ :after_find,            :proc   ],
 
199
      [ :after_find,            :object ],
 
200
      [ :after_find,            :block  ],
 
201
      [ :after_initialize,            :string ],
 
202
      [ :after_initialize,            :proc   ],
 
203
      [ :after_initialize,            :object ],
 
204
      [ :after_initialize,            :block  ],
 
205
      [ :before_validation,           :string ],
 
206
      [ :before_validation,           :proc   ],
 
207
      [ :before_validation,           :object ],
 
208
      [ :before_validation,           :block  ],
 
209
      [ :before_validation_on_update, :string ],
 
210
      [ :before_validation_on_update, :proc   ],
 
211
      [ :before_validation_on_update, :object ],
 
212
      [ :before_validation_on_update, :block  ],
 
213
      [ :after_validation,            :string ],
 
214
      [ :after_validation,            :proc   ],
 
215
      [ :after_validation,            :object ],
 
216
      [ :after_validation,            :block  ],
 
217
      [ :after_validation_on_update,  :string ],
 
218
      [ :after_validation_on_update,  :proc   ],
 
219
      [ :after_validation_on_update,  :object ],
 
220
      [ :after_validation_on_update,  :block  ]
 
221
    ], david.history
 
222
  end
 
223
 
 
224
  def test_create
 
225
    david = CallbackDeveloper.create('name' => 'David', 'salary' => 1000000)
 
226
    assert_equal [
 
227
      [ :after_initialize,            :string ],
 
228
      [ :after_initialize,            :proc   ],
 
229
      [ :after_initialize,            :object ],
 
230
      [ :after_initialize,            :block  ],
 
231
      [ :before_validation,           :string ],
 
232
      [ :before_validation,           :proc   ],
 
233
      [ :before_validation,           :object ],
 
234
      [ :before_validation,           :block  ],
 
235
      [ :before_validation_on_create, :string ],
 
236
      [ :before_validation_on_create, :proc   ],
 
237
      [ :before_validation_on_create, :object ],
 
238
      [ :before_validation_on_create, :block  ],
 
239
      [ :after_validation,            :string ],
 
240
      [ :after_validation,            :proc   ],
 
241
      [ :after_validation,            :object ],
 
242
      [ :after_validation,            :block  ],
 
243
      [ :after_validation_on_create,  :string ],
 
244
      [ :after_validation_on_create,  :proc   ],
 
245
      [ :after_validation_on_create,  :object ],
 
246
      [ :after_validation_on_create,  :block  ],
 
247
      [ :before_save,                 :string ],
 
248
      [ :before_save,                 :proc   ],
 
249
      [ :before_save,                 :object ],
 
250
      [ :before_save,                 :block  ],
 
251
      [ :before_create,               :string ],
 
252
      [ :before_create,               :proc   ],
 
253
      [ :before_create,               :object ],
 
254
      [ :before_create,               :block  ],
 
255
      [ :after_create,                :string ],
 
256
      [ :after_create,                :proc   ],
 
257
      [ :after_create,                :object ],
 
258
      [ :after_create,                :block  ],
 
259
      [ :after_save,                  :string ],
 
260
      [ :after_save,                  :proc   ],
 
261
      [ :after_save,                  :object ],
 
262
      [ :after_save,                  :block  ]
 
263
    ], david.history
 
264
  end
 
265
 
 
266
  def test_save
 
267
    david = CallbackDeveloper.find(1)
 
268
    david.save
 
269
    assert_equal [
 
270
      [ :after_find,            :string ],
 
271
      [ :after_find,            :proc   ],
 
272
      [ :after_find,            :object ],
 
273
      [ :after_find,            :block  ],
 
274
      [ :after_initialize,            :string ],
 
275
      [ :after_initialize,            :proc   ],
 
276
      [ :after_initialize,            :object ],
 
277
      [ :after_initialize,            :block  ],
 
278
      [ :before_validation,           :string ],
 
279
      [ :before_validation,           :proc   ],
 
280
      [ :before_validation,           :object ],
 
281
      [ :before_validation,           :block  ],
 
282
      [ :before_validation_on_update, :string ],
 
283
      [ :before_validation_on_update, :proc   ],
 
284
      [ :before_validation_on_update, :object ],
 
285
      [ :before_validation_on_update, :block  ],
 
286
      [ :after_validation,            :string ],
 
287
      [ :after_validation,            :proc   ],
 
288
      [ :after_validation,            :object ],
 
289
      [ :after_validation,            :block  ],
 
290
      [ :after_validation_on_update,  :string ],
 
291
      [ :after_validation_on_update,  :proc   ],
 
292
      [ :after_validation_on_update,  :object ],
 
293
      [ :after_validation_on_update,  :block  ],
 
294
      [ :before_save,                 :string ],
 
295
      [ :before_save,                 :proc   ],
 
296
      [ :before_save,                 :object ],
 
297
      [ :before_save,                 :block  ],
 
298
      [ :before_update,               :string ],
 
299
      [ :before_update,               :proc   ],
 
300
      [ :before_update,               :object ],
 
301
      [ :before_update,               :block  ],
 
302
      [ :after_update,                :string ],
 
303
      [ :after_update,                :proc   ],
 
304
      [ :after_update,                :object ],
 
305
      [ :after_update,                :block  ],
 
306
      [ :after_save,                  :string ],
 
307
      [ :after_save,                  :proc   ],
 
308
      [ :after_save,                  :object ],
 
309
      [ :after_save,                  :block  ]
 
310
    ], david.history
 
311
  end
 
312
 
 
313
  def test_destroy
 
314
    david = CallbackDeveloper.find(1)
 
315
    david.destroy
 
316
    assert_equal [
 
317
      [ :after_find,            :string ],
 
318
      [ :after_find,            :proc   ],
 
319
      [ :after_find,            :object ],
 
320
      [ :after_find,            :block  ],
 
321
      [ :after_initialize,            :string ],
 
322
      [ :after_initialize,            :proc   ],
 
323
      [ :after_initialize,            :object ],
 
324
      [ :after_initialize,            :block  ],
 
325
      [ :before_destroy,              :string ],
 
326
      [ :before_destroy,              :proc   ],
 
327
      [ :before_destroy,              :object ],
 
328
      [ :before_destroy,              :block  ],
 
329
      [ :after_destroy,               :string ],
 
330
      [ :after_destroy,               :proc   ],
 
331
      [ :after_destroy,               :object ],
 
332
      [ :after_destroy,               :block  ]
 
333
    ], david.history
 
334
  end
 
335
 
 
336
  def test_delete
 
337
    david = CallbackDeveloper.find(1)
 
338
    CallbackDeveloper.delete(david.id)
 
339
    assert_equal [
 
340
      [ :after_find,            :string ],
 
341
      [ :after_find,            :proc   ],
 
342
      [ :after_find,            :object ],
 
343
      [ :after_find,            :block  ],
 
344
      [ :after_initialize,            :string ],
 
345
      [ :after_initialize,            :proc   ],
 
346
      [ :after_initialize,            :object ],
 
347
      [ :after_initialize,            :block  ],
 
348
    ], david.history
 
349
  end
 
350
 
 
351
  def test_before_save_returning_false
 
352
    david = ImmutableDeveloper.find(1)
 
353
    assert david.valid?
 
354
    assert !david.save
 
355
    assert_raise(ActiveRecord::RecordNotSaved) { david.save! }
 
356
 
 
357
    david = ImmutableDeveloper.find(1)
 
358
    david.salary = 10_000_000
 
359
    assert !david.valid?
 
360
    assert !david.save
 
361
    assert_raise(ActiveRecord::RecordInvalid) { david.save! }
 
362
 
 
363
    someone = CallbackCancellationDeveloper.find(1)
 
364
    someone.cancel_before_save = true
 
365
    assert someone.valid?
 
366
    assert !someone.save
 
367
    assert_save_callbacks_not_called(someone)
 
368
  end
 
369
 
 
370
  def test_before_create_returning_false
 
371
    someone = CallbackCancellationDeveloper.new
 
372
    someone.cancel_before_create = true
 
373
    assert someone.valid?
 
374
    assert !someone.save
 
375
    assert_save_callbacks_not_called(someone)
 
376
  end
 
377
 
 
378
  def test_before_update_returning_false
 
379
    someone = CallbackCancellationDeveloper.find(1)
 
380
    someone.cancel_before_update = true
 
381
    assert someone.valid?
 
382
    assert !someone.save
 
383
    assert_save_callbacks_not_called(someone)
 
384
  end
 
385
 
 
386
  def test_before_destroy_returning_false
 
387
    david = ImmutableDeveloper.find(1)
 
388
    assert !david.destroy
 
389
    assert_not_nil ImmutableDeveloper.find_by_id(1)
 
390
 
 
391
    someone = CallbackCancellationDeveloper.find(1)
 
392
    someone.cancel_before_destroy = true
 
393
    assert !someone.destroy
 
394
    assert !someone.after_destroy_called
 
395
  end
 
396
 
 
397
  def assert_save_callbacks_not_called(someone)
 
398
    assert !someone.after_save_called
 
399
    assert !someone.after_create_called
 
400
    assert !someone.after_update_called
 
401
  end
 
402
  private :assert_save_callbacks_not_called
 
403
 
 
404
  def test_zzz_callback_returning_false # must be run last since we modify CallbackDeveloper
 
405
    david = CallbackDeveloper.find(1)
 
406
    CallbackDeveloper.before_validation proc { |model| model.history << [:before_validation, :returning_false]; return false }
 
407
    CallbackDeveloper.before_validation proc { |model| model.history << [:before_validation, :should_never_get_here] }
 
408
    david.save
 
409
    assert_equal [
 
410
      [ :after_find,            :string ],
 
411
      [ :after_find,            :proc   ],
 
412
      [ :after_find,            :object ],
 
413
      [ :after_find,            :block  ],
 
414
      [ :after_initialize,            :string ],
 
415
      [ :after_initialize,            :proc   ],
 
416
      [ :after_initialize,            :object ],
 
417
      [ :after_initialize,            :block  ],
 
418
      [ :before_validation,           :string ],
 
419
      [ :before_validation,           :proc   ],
 
420
      [ :before_validation,           :object ],
 
421
      [ :before_validation,           :block  ],
 
422
      [ :before_validation, :returning_false  ]
 
423
    ], david.history
 
424
  end
 
425
 
 
426
  def test_inheritence_of_callbacks
 
427
    parent = ParentDeveloper.new
 
428
    assert !parent.after_save_called
 
429
    parent.save
 
430
    assert parent.after_save_called
 
431
 
 
432
    child = ChildDeveloper.new
 
433
    assert !child.after_save_called
 
434
    child.save
 
435
    assert child.after_save_called
 
436
  end
 
437
 
 
438
end