activeobject 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (80) hide show
  1. data/CHANGE +10 -0
  2. data/Interface_desc +21 -0
  3. data/MIT-LICENSE +20 -0
  4. data/README +72 -0
  5. data/Rakefile.rb +9 -0
  6. data/active-object.gemspec +50 -0
  7. data/examples/account.rb +69 -0
  8. data/examples/data.tch +0 -0
  9. data/examples/light_cloud.yml +18 -0
  10. data/examples/test.rb +3 -0
  11. data/examples/user.rb +112 -0
  12. data/init.rb +4 -0
  13. data/lib/active-object.rb +23 -0
  14. data/lib/active_object/adapters/light_cloud.rb +40 -0
  15. data/lib/active_object/adapters/tokyo_cabinet.rb +48 -0
  16. data/lib/active_object/adapters/tokyo_tyrant.rb +14 -0
  17. data/lib/active_object/associations.rb +200 -0
  18. data/lib/active_object/base.rb +415 -0
  19. data/lib/active_object/callbacks.rb +180 -0
  20. data/lib/active_object/observer.rb +180 -0
  21. data/lib/active_object/serialization.rb +99 -0
  22. data/lib/active_object/serializers/json_serializer.rb +75 -0
  23. data/lib/active_object/serializers/xml_serializer.rb +325 -0
  24. data/lib/active_object/validations.rb +687 -0
  25. data/lib/active_support/callbacks.rb +303 -0
  26. data/lib/active_support/core_ext/array/access.rb +53 -0
  27. data/lib/active_support/core_ext/array/conversions.rb +183 -0
  28. data/lib/active_support/core_ext/array/extract_options.rb +20 -0
  29. data/lib/active_support/core_ext/array/grouping.rb +106 -0
  30. data/lib/active_support/core_ext/array/random_access.rb +12 -0
  31. data/lib/active_support/core_ext/array.rb +13 -0
  32. data/lib/active_support/core_ext/blank.rb +58 -0
  33. data/lib/active_support/core_ext/class/attribute_accessors.rb +54 -0
  34. data/lib/active_support/core_ext/class/inheritable_attributes.rb +140 -0
  35. data/lib/active_support/core_ext/class/removal.rb +50 -0
  36. data/lib/active_support/core_ext/class.rb +3 -0
  37. data/lib/active_support/core_ext/duplicable.rb +43 -0
  38. data/lib/active_support/core_ext/enumerable.rb +72 -0
  39. data/lib/active_support/core_ext/hash/conversions.rb +259 -0
  40. data/lib/active_support/core_ext/hash/keys.rb +52 -0
  41. data/lib/active_support/core_ext/hash.rb +8 -0
  42. data/lib/active_support/core_ext/module/aliasing.rb +74 -0
  43. data/lib/active_support/core_ext/module/attr_accessor_with_default.rb +31 -0
  44. data/lib/active_support/core_ext/module/attribute_accessors.rb +58 -0
  45. data/lib/active_support/core_ext/module.rb +16 -0
  46. data/lib/active_support/core_ext/object/conversions.rb +14 -0
  47. data/lib/active_support/core_ext/object/extending.rb +80 -0
  48. data/lib/active_support/core_ext/object/instance_variables.rb +74 -0
  49. data/lib/active_support/core_ext/object/metaclass.rb +13 -0
  50. data/lib/active_support/core_ext/object/misc.rb +43 -0
  51. data/lib/active_support/core_ext/object.rb +5 -0
  52. data/lib/active_support/core_ext/string/inflections.rb +167 -0
  53. data/lib/active_support/core_ext/string.rb +7 -0
  54. data/lib/active_support/core_ext.rb +4 -0
  55. data/lib/active_support/inflections.rb +55 -0
  56. data/lib/active_support/inflector.rb +348 -0
  57. data/lib/active_support/vendor/builder-2.1.2/blankslate.rb +113 -0
  58. data/lib/active_support/vendor/builder-2.1.2/builder/blankslate.rb +20 -0
  59. data/lib/active_support/vendor/builder-2.1.2/builder/css.rb +250 -0
  60. data/lib/active_support/vendor/builder-2.1.2/builder/xchar.rb +115 -0
  61. data/lib/active_support/vendor/builder-2.1.2/builder/xmlbase.rb +139 -0
  62. data/lib/active_support/vendor/builder-2.1.2/builder/xmlevents.rb +63 -0
  63. data/lib/active_support/vendor/builder-2.1.2/builder/xmlmarkup.rb +328 -0
  64. data/lib/active_support/vendor/builder-2.1.2/builder.rb +13 -0
  65. data/lib/active_support/vendor/xml-simple-1.0.11/xmlsimple.rb +1021 -0
  66. data/lib/active_support/vendor.rb +14 -0
  67. data/lib/active_support.rb +6 -0
  68. data/spec/case/association_test.rb +97 -0
  69. data/spec/case/base_test.rb +74 -0
  70. data/spec/case/callbacks_observers_test.rb +38 -0
  71. data/spec/case/callbacks_test.rb +424 -0
  72. data/spec/case/serialization_test.rb +87 -0
  73. data/spec/case/validations_test.rb +1482 -0
  74. data/spec/data.tch +0 -0
  75. data/spec/helper.rb +15 -0
  76. data/spec/light_cloud.yml +18 -0
  77. data/spec/model/account.rb +4 -0
  78. data/spec/model/topic.rb +26 -0
  79. data/spec/model/user.rb +8 -0
  80. metadata +173 -0
@@ -0,0 +1,14 @@
1
+ # Prefer gems to the bundled libs.
2
+ require 'rubygems'
3
+
4
+ begin
5
+ gem 'builder', '~> 2.1.2'
6
+ rescue Gem::LoadError
7
+ $:.unshift "#{File.dirname(__FILE__)}/vendor/builder-2.1.2"
8
+ end
9
+
10
+ begin
11
+ gem 'xml-simple', '~> 1.0.11'
12
+ rescue Gem::LoadError
13
+ $:.unshift "#{File.dirname(__FILE__)}/vendor/xml-simple-1.0.11"
14
+ end
@@ -0,0 +1,6 @@
1
+ require File.join(File.dirname(__FILE__),'active_support','vendor')
2
+
3
+ Dir[File.dirname(__FILE__) + "/active_support/*.rb"].sort.each do |path|
4
+ filename = File.basename(path)
5
+ require "active_support/#{filename}"
6
+ end
@@ -0,0 +1,97 @@
1
+ require File.join(File.dirname(__FILE__),'..','helper')
2
+ require File.join(File.dirname(__FILE__),'..','model','user')
3
+
4
+ class Icon < ActiveObject::Base
5
+ attribute :path
6
+ end
7
+
8
+ class Friend < ActiveObject::Base
9
+ attribute :name
10
+ end
11
+
12
+
13
+ User.instance_eval{
14
+ has_one :icon
15
+ has_many :friends
16
+ }
17
+
18
+
19
+ class CreateObjectTest < Test::Unit::TestCase
20
+ def setup
21
+ @attributes = {:name=>'aaron',:email=>'aaron@nonobo.com',:password=>'123456'}
22
+ @path = '/home/Aaron'
23
+ @friends = ['kame','jim']
24
+ end
25
+
26
+ def test_has_one
27
+ @icon = Icon.create(:path=> @path)
28
+ @u = User.new(@attributes)
29
+ @u.icon = @icon
30
+ @u.save
31
+
32
+ @read_user = User.find(@u.id)
33
+
34
+ assert_equal @read_user.icon.id, @icon.id
35
+ assert_equal @read_user.icon.path,@path
36
+ end
37
+
38
+ def test_has_one_change
39
+ @icon = Icon.create(:path=> @path)
40
+ @u = User.new(@attributes)
41
+ @u.icon = @icon
42
+ @u.save
43
+ @u = User.find(@u.id)
44
+ old_icon = @u.icon
45
+
46
+ @icon = Icon.create(:path=> 'valid path')
47
+ @u.icon = @icon
48
+ @u.save
49
+ @u = User.find(@u.id)
50
+
51
+ assert_not_equal old_icon.id, @u.icon.id
52
+ assert_equal @u.icon.path,'valid path'
53
+
54
+ end
55
+
56
+ def test_has_many
57
+ @friend = Friend.create(:name=>@friends[0])
58
+
59
+ @u = User.new(@attributes)
60
+ @u.friends.append @friend
61
+
62
+ assert_equal @u.friends.size,1
63
+
64
+ @friend = Friend.create(:name=>@friends[1])
65
+
66
+ @u.friends.append @friend
67
+
68
+ @u.save
69
+
70
+ @u = User.find(@u.id)
71
+
72
+ @u.friends.each_with_index do |friend,index|
73
+ assert_equal friend.name,@friends[index]
74
+ end
75
+
76
+ @friend = Friend.create(:name=>'nancy')
77
+ @friends.insert(1,'nancy')
78
+
79
+ @u.friends.insert(1,@friend)
80
+
81
+ @u.friends.each_with_index do |friend,index|
82
+ assert_equal friend.name,@friends[index]
83
+ end
84
+
85
+ assert_equal @u.friends.size,@friends.size
86
+
87
+ @u.friends.clear
88
+
89
+ @u.save
90
+
91
+ @u = User.find(@u.id)
92
+
93
+ assert_equal @u.friends.object_ids,[]
94
+
95
+ end
96
+
97
+ end
@@ -0,0 +1,74 @@
1
+ require File.join(File.dirname(__FILE__),'..','helper')
2
+ require File.join(File.dirname(__FILE__),'..','model','user')
3
+ require File.join(File.dirname(__FILE__),'..','model','account')
4
+
5
+ class BaseTest < Test::Unit::TestCase
6
+ def setup
7
+ @attributes = {:name=>'Aaron',:email=>'aaron@nonobo.com',:password=>'123456'}
8
+ ActiveObject::Base.adb.clear
9
+ end
10
+
11
+ def test_new_object
12
+ @u = User.new
13
+ assert_equal true,@u.new_record?
14
+ User.attributes.each do |attribute|
15
+ assert_equal true,@u.respond_to?(attribute)
16
+ end
17
+ end
18
+
19
+ def test_new_object_with_attributes
20
+ @u = User.new(@attributes)
21
+ @attributes.each do |key,value|
22
+ assert_equal value,@u.send(key)
23
+ end
24
+ end
25
+
26
+ def test_create_object
27
+ @u = User.create(@attributes)
28
+ assert_equal false,@u.new_record?
29
+ @u.destroy
30
+ end
31
+
32
+ def test_find_object
33
+ User.create(@attributes)
34
+ @u = User.find(@attributes[:email])
35
+ @attributes.each do |key,value|
36
+ assert_equal value,@u.send(key)
37
+ end
38
+ assert_equal false,@u.new_record?
39
+ end
40
+
41
+ def test_all
42
+ @users = []
43
+ @users << User.create(@attributes)
44
+ @users << User.create(@attributes.merge(:email=>'kame@nonobo.com'))
45
+ @users << User.create(@attributes.merge(:email=>'jim@nonobo.com'))
46
+ Account.create(@attributes.merge(:email=>'nancy@nonobo.com'))
47
+
48
+ @users = User.all
49
+
50
+ assert_equal @users.size,3
51
+
52
+ @users.each do |user|
53
+ assert_equal ['kame@nonobo.com','jim@nonobo.com','aaron@nonobo.com'].include?(user.email),true
54
+ end
55
+ end
56
+
57
+ def test_delete_object
58
+ User.create(@attributes)
59
+ User.delete(@attributes[:email])
60
+ assert_raise ActiveObject::ObjectNotFound do
61
+ User.find(@attributes[:email])
62
+ end
63
+ end
64
+
65
+ def test_create_multiple_object
66
+ @objects = [{:name=>'aaron',:email=>'aaron@nonobo.com'},{:name=>'yalong',:email=>'yalong@nonobo.com'}]
67
+ User.create(@objects)
68
+ @objects.each do |object|
69
+ @u = User.find(object[:email])
70
+ assert_equal object[:email],@u.email
71
+ @u.destroy
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,38 @@
1
+ require File.join(File.dirname(__FILE__),"..","helper")
2
+
3
+ class Comment < ActiveObject::Base
4
+ attr_accessor :callers
5
+
6
+ before_validation :record_callers
7
+
8
+ def after_validation
9
+ record_callers
10
+ end
11
+
12
+ def record_callers
13
+ callers << self.class if callers
14
+ end
15
+ end
16
+
17
+ class CommentObserver < ActiveObject::Observer
18
+ attr_accessor :callers
19
+
20
+ def after_validation(model)
21
+ callers << self.class if callers
22
+ end
23
+ end
24
+
25
+ class CallbacksObserversTest < Test::Unit::TestCase
26
+ def test_model_callbacks_fire_before_observers_are_notified
27
+ callers = []
28
+
29
+ comment = Comment.new
30
+ comment.callers = callers
31
+
32
+ CommentObserver.instance.callers = callers
33
+
34
+ comment.valid?
35
+
36
+ assert_equal [Comment, Comment, CommentObserver], callers, "model callbacks did not fire before observers were notified"
37
+ end
38
+ end
@@ -0,0 +1,424 @@
1
+ require File.join(File.dirname(__FILE__),"..","helper")
2
+
3
+ class User < ActiveObject::Base
4
+ primary_key :email
5
+ attribute :name,:email,:password,:salary
6
+ end
7
+
8
+ class CallbackDeveloper < ActiveObject::Base
9
+ primary_key :email
10
+ attribute :name,:email,:password,:salary
11
+
12
+ class << self
13
+ def callback_string(callback_method)
14
+ "history << [#{callback_method.to_sym.inspect}, :string]"
15
+ end
16
+
17
+ def callback_proc(callback_method)
18
+ Proc.new { |model| model.history << [callback_method, :proc] }
19
+ end
20
+
21
+ def define_callback_method(callback_method)
22
+ define_method("#{callback_method}_method") do |model|
23
+ model.history << [callback_method, :method]
24
+ end
25
+ end
26
+
27
+ def callback_object(callback_method)
28
+ klass = Class.new
29
+ klass.send(:define_method, callback_method) do |model|
30
+ model.history << [callback_method, :object]
31
+ end
32
+ klass.new
33
+ end
34
+ end
35
+
36
+ ActiveObject::Callbacks::CALLBACKS.each do |callback_method|
37
+ callback_method_sym = callback_method.to_sym
38
+ define_callback_method(callback_method_sym)
39
+ send(callback_method, callback_method_sym)
40
+ send(callback_method, callback_string(callback_method_sym))
41
+ send(callback_method, callback_proc(callback_method_sym))
42
+ send(callback_method, callback_object(callback_method_sym))
43
+ send(callback_method) { |model| model.history << [callback_method_sym, :block] }
44
+ end
45
+
46
+ def history
47
+ @history ||= []
48
+ end
49
+
50
+ # after_initialize and after_find are invoked only if instance methods have been defined.
51
+ def after_initialize
52
+
53
+ end
54
+
55
+ def after_find
56
+ end
57
+ end
58
+
59
+ class ParentDeveloper < ActiveObject::Base
60
+ primary_key :email
61
+ attribute :name,:email,:password,:salary
62
+
63
+ attr_accessor :after_save_called
64
+ before_validation {|record| record.after_save_called = true}
65
+ end
66
+
67
+ class ChildDeveloper < ParentDeveloper
68
+ primary_key :email
69
+ attribute :name,:email,:password,:salary
70
+ end
71
+
72
+ class RecursiveCallbackDeveloper < ActiveObject::Base
73
+ primary_key :email
74
+ attribute :name,:email,:password,:salary
75
+
76
+ before_save :on_before_save
77
+ after_save :on_after_save
78
+
79
+ attr_reader :on_before_save_called, :on_after_save_called
80
+
81
+ def on_before_save
82
+ @on_before_save_called ||= 0
83
+ @on_before_save_called += 1
84
+ save unless @on_before_save_called > 1
85
+ end
86
+
87
+ def on_after_save
88
+ @on_after_save_called ||= 0
89
+ @on_after_save_called += 1
90
+ save unless @on_after_save_called > 1
91
+ end
92
+ end
93
+
94
+ class ImmutableDestroyDeveloper < ActiveObject::Base
95
+ primary_key :email
96
+ attribute :name,:email,:password,:salary
97
+
98
+ validates_inclusion_of :salary, :in => 50000..200000
99
+
100
+ before_destroy :cancel
101
+
102
+ def cancelled?
103
+ @cancelled == true
104
+ end
105
+
106
+ private
107
+ def cancel
108
+ @cancelled = true
109
+ false
110
+ end
111
+ end
112
+
113
+ class ImmutableSaveDeveloper < ActiveObject::Base
114
+ primary_key :email
115
+ attribute :name,:email,:password,:salary
116
+
117
+ validates_inclusion_of :salary, :in => 50000..200000
118
+
119
+ before_save :cancel
120
+
121
+ def cancelled?
122
+ @cancelled == true
123
+ end
124
+
125
+ private
126
+ def cancel
127
+ @cancelled = true
128
+ false
129
+ end
130
+ end
131
+
132
+ class ImmutableMethodDeveloper < ActiveObject::Base
133
+ primary_key :email
134
+ attribute :name,:email,:password,:salary
135
+
136
+ validates_inclusion_of :salary, :in => 50000..200000
137
+
138
+ def cancelled?
139
+ @cancelled == true
140
+ end
141
+
142
+ def before_save
143
+ @cancelled = true
144
+ false
145
+ end
146
+
147
+ def before_destroy
148
+ @cancelled = true
149
+ false
150
+ end
151
+ end
152
+
153
+ class CallbackCancellationDeveloper < ActiveObject::Base
154
+ primary_key :email
155
+ attribute :name,:email,:password,:salary
156
+
157
+ def before_create
158
+ false
159
+ end
160
+ end
161
+
162
+ class CallbacksTest < Test::Unit::TestCase
163
+ def setup
164
+ @attributes={:name=>'aaron',:email=>'aaron@nonobo.com',:password=>'123456',:salary=>100000}
165
+ end
166
+
167
+ def test_initialize
168
+ david = CallbackDeveloper.new
169
+ assert_equal [
170
+ [ :after_initialize, :string ],
171
+ [ :after_initialize, :proc ],
172
+ [ :after_initialize, :object ],
173
+ [ :after_initialize, :block ],
174
+ ], david.history
175
+ end
176
+
177
+ def test_find
178
+ CallbackDeveloper.create(@attributes)
179
+ david = CallbackDeveloper.find(@attributes[:email])
180
+ assert_equal [
181
+ [ :after_initialize, :string ],
182
+ [ :after_initialize, :proc ],
183
+ [ :after_initialize, :object ],
184
+ [ :after_initialize, :block ],
185
+ ], david.history
186
+ david.destroy
187
+ end
188
+
189
+ def test_new_valid?
190
+ david = CallbackDeveloper.new
191
+ david.valid?
192
+ assert_equal [
193
+ [ :after_initialize, :string ],
194
+ [ :after_initialize, :proc ],
195
+ [ :after_initialize, :object ],
196
+ [ :after_initialize, :block ],
197
+ [ :before_validation, :string ],
198
+ [ :before_validation, :proc ],
199
+ [ :before_validation, :object ],
200
+ [ :before_validation, :block ],
201
+ [ :before_validation_on_create, :string ],
202
+ [ :before_validation_on_create, :proc ],
203
+ [ :before_validation_on_create, :object ],
204
+ [ :before_validation_on_create, :block ],
205
+ [ :after_validation, :string ],
206
+ [ :after_validation, :proc ],
207
+ [ :after_validation, :object ],
208
+ [ :after_validation, :block ],
209
+ [ :after_validation_on_create, :string ],
210
+ [ :after_validation_on_create, :proc ],
211
+ [ :after_validation_on_create, :object ],
212
+ [ :after_validation_on_create, :block ]
213
+ ], david.history
214
+ end
215
+
216
+ def test_existing_valid?
217
+ CallbackDeveloper.create(@attributes)
218
+ david = CallbackDeveloper.find(@attributes[:email])
219
+ david.valid?
220
+ assert_equal [
221
+ [ :after_initialize, :string ],
222
+ [ :after_initialize, :proc ],
223
+ [ :after_initialize, :object ],
224
+ [ :after_initialize, :block ],
225
+ [ :before_validation, :string ],
226
+ [ :before_validation, :proc ],
227
+ [ :before_validation, :object ],
228
+ [ :before_validation, :block ],
229
+ [ :before_validation_on_update, :string ],
230
+ [ :before_validation_on_update, :proc ],
231
+ [ :before_validation_on_update, :object ],
232
+ [ :before_validation_on_update, :block ],
233
+ [ :after_validation, :string ],
234
+ [ :after_validation, :proc ],
235
+ [ :after_validation, :object ],
236
+ [ :after_validation, :block ],
237
+ [ :after_validation_on_update, :string ],
238
+ [ :after_validation_on_update, :proc ],
239
+ [ :after_validation_on_update, :object ],
240
+ [ :after_validation_on_update, :block ]
241
+ ], david.history
242
+ david.destroy
243
+ end
244
+
245
+ def test_create
246
+ david = CallbackDeveloper.create(@attributes)
247
+ assert_equal [
248
+ [ :after_initialize, :string ],
249
+ [ :after_initialize, :proc ],
250
+ [ :after_initialize, :object ],
251
+ [ :after_initialize, :block ],
252
+ [ :before_validation, :string ],
253
+ [ :before_validation, :proc ],
254
+ [ :before_validation, :object ],
255
+ [ :before_validation, :block ],
256
+ [ :before_validation_on_create, :string ],
257
+ [ :before_validation_on_create, :proc ],
258
+ [ :before_validation_on_create, :object ],
259
+ [ :before_validation_on_create, :block ],
260
+ [ :after_validation, :string ],
261
+ [ :after_validation, :proc ],
262
+ [ :after_validation, :object ],
263
+ [ :after_validation, :block ],
264
+ [ :after_validation_on_create, :string ],
265
+ [ :after_validation_on_create, :proc ],
266
+ [ :after_validation_on_create, :object ],
267
+ [ :after_validation_on_create, :block ],
268
+ [ :before_save, :string ],
269
+ [ :before_save, :proc ],
270
+ [ :before_save, :object ],
271
+ [ :before_save, :block ],
272
+ [ :before_create, :string ],
273
+ [ :before_create, :proc ],
274
+ [ :before_create, :object ],
275
+ [ :before_create, :block ],
276
+ [ :after_create, :string ],
277
+ [ :after_create, :proc ],
278
+ [ :after_create, :object ],
279
+ [ :after_create, :block ],
280
+ [ :after_save, :string ],
281
+ [ :after_save, :proc ],
282
+ [ :after_save, :object ],
283
+ [ :after_save, :block ]
284
+ ], david.history
285
+ david.destroy
286
+ end
287
+
288
+ def test_save
289
+ CallbackDeveloper.create(@attributes)
290
+ david = CallbackDeveloper.find(@attributes[:email])
291
+ david.save
292
+ assert_equal [
293
+ [ :after_initialize, :string ],
294
+ [ :after_initialize, :proc ],
295
+ [ :after_initialize, :object ],
296
+ [ :after_initialize, :block ],
297
+ [ :before_validation, :string ],
298
+ [ :before_validation, :proc ],
299
+ [ :before_validation, :object ],
300
+ [ :before_validation, :block ],
301
+ [ :before_validation_on_update, :string ],
302
+ [ :before_validation_on_update, :proc ],
303
+ [ :before_validation_on_update, :object ],
304
+ [ :before_validation_on_update, :block ],
305
+ [ :after_validation, :string ],
306
+ [ :after_validation, :proc ],
307
+ [ :after_validation, :object ],
308
+ [ :after_validation, :block ],
309
+ [ :after_validation_on_update, :string ],
310
+ [ :after_validation_on_update, :proc ],
311
+ [ :after_validation_on_update, :object ],
312
+ [ :after_validation_on_update, :block ],
313
+ [ :before_save, :string ],
314
+ [ :before_save, :proc ],
315
+ [ :before_save, :object ],
316
+ [ :before_save, :block ],
317
+ [ :before_update, :string ],
318
+ [ :before_update, :proc ],
319
+ [ :before_update, :object ],
320
+ [ :before_update, :block ],
321
+ [ :after_update, :string ],
322
+ [ :after_update, :proc ],
323
+ [ :after_update, :object ],
324
+ [ :after_update, :block ],
325
+ [ :after_save, :string ],
326
+ [ :after_save, :proc ],
327
+ [ :after_save, :object ],
328
+ [ :after_save, :block ]
329
+ ], david.history
330
+ david.destroy
331
+ end
332
+
333
+ def test_destroy
334
+ CallbackDeveloper.create(@attributes)
335
+ david = CallbackDeveloper.find(@attributes[:email])
336
+ david.destroy
337
+ assert_equal [
338
+ [ :after_initialize, :string ],
339
+ [ :after_initialize, :proc ],
340
+ [ :after_initialize, :object ],
341
+ [ :after_initialize, :block ],
342
+ [ :before_destroy, :string ],
343
+ [ :before_destroy, :proc ],
344
+ [ :before_destroy, :object ],
345
+ [ :before_destroy, :block ],
346
+ [ :after_destroy, :string ],
347
+ [ :after_destroy, :proc ],
348
+ [ :after_destroy, :object ],
349
+ [ :after_destroy, :block ]
350
+ ], david.history
351
+ end
352
+
353
+ def test_delete
354
+ CallbackDeveloper.create(@attributes)
355
+ david = CallbackDeveloper.find(@attributes[:email])
356
+ CallbackDeveloper.delete(david.id)
357
+ assert_equal [
358
+ [ :after_initialize, :string ],
359
+ [ :after_initialize, :proc ],
360
+ [ :after_initialize, :object ],
361
+ [ :after_initialize, :block ],
362
+ ], david.history
363
+ end
364
+
365
+ def test_before_save_returning_false
366
+ david = ImmutableSaveDeveloper.create(@attributes)
367
+
368
+
369
+ assert david.valid?
370
+ assert !david.save
371
+ assert_raises(ActiveObject::ObjectNotSaved) { david.save! }
372
+
373
+ david.salary = 10_000_000
374
+ assert !david.valid?
375
+ assert !david.save
376
+ assert_raises(ActiveObject::ObjectInvalid) { david.save! }
377
+ end
378
+
379
+ def test_before_create_returning_false
380
+ someone = CallbackCancellationDeveloper.new
381
+ assert someone.valid?
382
+ assert !someone.save
383
+ end
384
+
385
+ def test_before_destroy_returning_false
386
+ david = ImmutableDestroyDeveloper.create(@attributes)
387
+
388
+ assert !david.destroy
389
+ assert_not_nil ImmutableDestroyDeveloper.find(@attributes[:email])
390
+ end
391
+
392
+ def test_zzz_callback_returning_false # must be run last since we modify CallbackDeveloper
393
+ CallbackDeveloper.create(@attributes)
394
+ david = CallbackDeveloper.find(@attributes[:email])
395
+ CallbackDeveloper.before_validation proc { |model| model.history << [:before_validation, :returning_false]; return false }
396
+ CallbackDeveloper.before_validation proc { |model| model.history << [:before_validation, :should_never_get_here] }
397
+ david.save
398
+ assert_equal [
399
+ [ :after_initialize, :string ],
400
+ [ :after_initialize, :proc ],
401
+ [ :after_initialize, :object ],
402
+ [ :after_initialize, :block ],
403
+ [ :before_validation, :string ],
404
+ [ :before_validation, :proc ],
405
+ [ :before_validation, :object ],
406
+ [ :before_validation, :block ],
407
+ [ :before_validation, :returning_false ]
408
+ ], david.history
409
+ david.destroy
410
+ end
411
+
412
+ def test_inheritence_of_callbacks
413
+ parent = ParentDeveloper.new
414
+ assert !parent.after_save_called
415
+ parent.save
416
+ assert parent.after_save_called
417
+
418
+ child = ChildDeveloper.new
419
+ assert !child.after_save_called
420
+ child.save
421
+ assert child.after_save_called
422
+ end
423
+
424
+ end