massive_record 0.2.2.rc1 → 0.2.2.rc2

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.md CHANGED
@@ -1,7 +1,10 @@
1
1
  # v0.2.2 (git develop)
2
2
 
3
3
 
4
- # v0.2.2.rc1 (git master)
4
+ # v0.2.2.rc2 (git master)
5
+ - Fixed some issues related to callbacks on embedded records.
6
+
7
+ # v0.2.2.rc1
5
8
 
6
9
  - ProxyCollection destroy_all and delete_all returns removed records.
7
10
  - Changes are better detected on new records. user = User.new :email => "me@gmail.com"; user.email_changed?
@@ -1,9 +1,11 @@
1
1
  require 'massive_record/orm/schema/embedded_interface'
2
+ require 'massive_record/orm/in_the_middle_of_saving_tracker'
2
3
 
3
4
  module MassiveRecord
4
5
  module ORM
5
6
  class Embedded < Base
6
7
  include Schema::EmbeddedInterface
8
+ include InTheMiddleOfSavingTracker
7
9
 
8
10
  DATABASE_ID_SEPARATOR = '|'
9
11
 
@@ -0,0 +1,75 @@
1
+ module MassiveRecord
2
+ module ORM
3
+
4
+ #
5
+ # Tracks if we are in the middle of being saved or not, and if
6
+ # we are asked valid? in the middle of a save, we'll return the
7
+ # last answer we gave to that question, instead of running
8
+ # validations again.
9
+ #
10
+ #
11
+ # Main reason for doing so is when used in conjunction with
12
+ # Embedded records, in the following situations:
13
+ #
14
+ # 1. Calling save on an embedded record when the owner
15
+ # is not persisted will call save on the same
16
+ # record again when owner is saved and informs
17
+ # embeds many proxy that it is being about to be
18
+ # saved. Resulting in all callbacks fire again
19
+ # on the record which issued the save in the first
20
+ # place.
21
+ #
22
+ # We can query each embedded record inside of
23
+ # embeds_many#parent_will_be_saved! if we are to call save
24
+ # on it (to make each embedded record update it's persisted state),
25
+ # or if we should not do it, if the embedded record was the one
26
+ # triggered the save in the first place.
27
+ #
28
+ # 2. Calling save on an embedded record when the owner
29
+ # is not persisted will first validate the embedded
30
+ # record, then the owner will validate all associated
31
+ # records, including the one record which issued
32
+ # the save and therefor is validated.
33
+ #
34
+ # We can controll if we are to run validations on a record
35
+ # or not, based if we are in the middle of a save on current
36
+ # record, thus callbacks (like before_validations etc) will
37
+ # not run twice.
38
+ #
39
+ module InTheMiddleOfSavingTracker
40
+ attr_reader :in_the_middle_of_saving
41
+ alias in_the_middle_of_saving? in_the_middle_of_saving
42
+
43
+ def save(options = {})
44
+ with_in_the_middle_of_saving_tracker { super }
45
+ end
46
+
47
+ def save!(options = {})
48
+ with_in_the_middle_of_saving_tracker { super }
49
+ end
50
+
51
+ def valid?(*)
52
+ if in_the_middle_of_saving?
53
+ if @last_valid_value_inside_of_current_save.nil?
54
+ @last_valid_value_inside_of_current_save = super
55
+ else
56
+ @last_valid_value_inside_of_current_save
57
+ end
58
+ else
59
+ super
60
+ end
61
+ end
62
+
63
+
64
+ private
65
+
66
+ def with_in_the_middle_of_saving_tracker
67
+ @in_the_middle_of_saving = true
68
+ yield
69
+ ensure
70
+ @in_the_middle_of_saving = false
71
+ @last_valid_value_inside_of_current_save = nil
72
+ end
73
+ end
74
+ end
75
+ end
@@ -32,10 +32,17 @@ module MassiveRecord
32
32
  module Operations
33
33
  class << self
34
34
  def suppress
35
- @suppressed = true
35
+ suppressed_was, @suppressed = @suppressed, true
36
36
  yield
37
37
  ensure
38
- @suppressed = false
38
+ @suppressed = suppressed_was
39
+ end
40
+
41
+ def force
42
+ suppressed_was, @suppressed = @suppressed, false
43
+ yield
44
+ ensure
45
+ @suppressed = suppressed_was
39
46
  end
40
47
 
41
48
  def suppressed?
@@ -93,7 +93,7 @@ module MassiveRecord
93
93
  if record.destroyed?
94
94
  proxy_targets_update_hash[record.database_id] = nil
95
95
  elsif record.new_record? || record.changed?
96
- record.save
96
+ record.save(:validate => false) unless record.in_the_middle_of_saving?
97
97
  proxy_targets_update_hash[record.database_id] = Base.coder.dump(record.attributes_db_raw_data_hash)
98
98
  end
99
99
  end
@@ -1,3 +1,3 @@
1
1
  module MassiveRecord
2
- VERSION = "0.2.2.rc1"
2
+ VERSION = "0.2.2.rc2"
3
3
  end
@@ -1,309 +1,153 @@
1
1
  require 'spec_helper'
2
+ require 'orm/models/callback_testable'
2
3
  require 'orm/models/person'
3
4
  require 'orm/models/address'
4
5
 
5
- #
6
- # Some basic tests
7
- #
8
- shared_examples_for "Massive Record with callbacks" do
9
- it "should include ActiveModel::Callbacks" do
10
- @model.class.should respond_to :define_model_callbacks
11
- end
12
-
13
- it "should include ActiveModell::Validations::Callback" do
14
- @model.class.included_modules.should include(ActiveModel::Validations::Callbacks)
15
- end
16
- end
17
-
18
- {
19
- "MassiveRecord::Base::Table" => Person,
20
- "MassiveRecord::Base::Column" => Address
21
- }.each do |orm_class, inherited_by_test_class|
22
- describe orm_class do
23
- before do
24
- @model = inherited_by_test_class.new
25
- end
26
-
27
- it_should_behave_like "Massive Record with callbacks"
28
- end
29
- end
30
-
31
-
32
- #
33
- # Some real life object tests
34
- #
35
- class CallbackDeveloper < MassiveRecord::ORM::Table
36
- class << self
37
- def callback_string(callback_method)
38
- "history << [#{callback_method.to_sym.inspect}, :string]"
39
- end
6
+ describe "callbacks on" do
7
+ include SetUpHbaseConnectionBeforeAll
8
+ include SetTableNamesToTestTable
40
9
 
41
- def callback_proc(callback_method)
42
- Proc.new { |model| model.history << [callback_method, :proc] }
43
- end
10
+ class CallbackDeveloperTable < MassiveRecord::ORM::Table
11
+ include CallbackTestable
44
12
 
45
- def define_callback_method(callback_method)
46
- define_method(callback_method) do
47
- self.history << [callback_method, :method]
48
- end
49
- send(callback_method, :"#{callback_method}")
50
- end
13
+ embeds_many :callback_developer_embeddeds, :store_in => :base
51
14
 
52
- def callback_object(callback_method)
53
- klass = Class.new
54
- klass.send(:define_method, callback_method) do |model|
55
- model.history << [callback_method, :object]
56
- end
57
- klass.new
15
+ column_family :base do
16
+ field :name, :default => "Thorbjorn"
58
17
  end
59
18
  end
60
19
 
61
- MassiveRecord::ORM::Callbacks::CALLBACKS.each do |callback_method|
62
- next if callback_method.to_s =~ /^around_/
63
- define_callback_method(callback_method)
64
- send(callback_method, callback_string(callback_method))
65
- send(callback_method, callback_proc(callback_method))
66
- send(callback_method, callback_object(callback_method))
67
- send(callback_method) { |model| model.history << [callback_method, :block] }
68
- end
20
+ describe CallbackDeveloperTable do
21
+ let(:new_record) { described_class.new "1" }
22
+ let(:created_record) { described_class.create "dummy" }
23
+ let(:persisted_record) do
24
+ described_class.create! "1"
25
+ described_class.find "1"
26
+ end
69
27
 
70
- def history
71
- @history ||= []
28
+ it_should_behave_like "a model with callbacks"
72
29
  end
73
- end
74
30
 
75
31
 
76
- describe "callbacks for" do
77
- include MockMassiveRecordConnection
78
32
 
79
- it "initialize should run in correct order" do
80
- thorbjorn = CallbackDeveloper.new
81
- thorbjorn.history.should == [
82
- [:after_initialize, :method],
83
- [:after_initialize, :string],
84
- [:after_initialize, :proc],
85
- [:after_initialize, :object],
86
- [:after_initialize, :block]
87
- ]
88
- end
89
33
 
90
- it "find should run in correct order" do
91
- thorbjorn = CallbackDeveloper.find(1)
92
- thorbjorn.history.should == [
93
- [:after_find, :method],
94
- [:after_find, :string],
95
- [:after_find, :proc],
96
- [:after_find, :object],
97
- [:after_find, :block],
98
- [:after_initialize, :method],
99
- [:after_initialize, :string],
100
- [:after_initialize, :proc],
101
- [:after_initialize, :object],
102
- [:after_initialize, :block]
103
- ]
104
- end
34
+ class CallbackDeveloperEmbedded < MassiveRecord::ORM::Embedded
35
+ include CallbackTestable
105
36
 
106
- it "touch should run in correct order" do
107
- thorbjorn = CallbackDeveloper.find(1)
108
- thorbjorn.touch
109
- thorbjorn.history.should == [
110
- [:after_find, :method],
111
- [:after_find, :string],
112
- [:after_find, :proc],
113
- [:after_find, :object],
114
- [:after_find, :block],
115
- [:after_initialize, :method],
116
- [:after_initialize, :string],
117
- [:after_initialize, :proc],
118
- [:after_initialize, :object],
119
- [:after_initialize, :block],
120
- [:after_touch, :method],
121
- [:after_touch, :string],
122
- [:after_touch, :proc],
123
- [:after_touch, :object],
124
- [:after_touch, :block]
125
- ]
126
- end
127
-
128
- it "valid for new record should run in correct order" do
129
- thorbjorn = CallbackDeveloper.new
130
- thorbjorn.valid?
131
- thorbjorn.history.should == [
132
- [:after_initialize, :method],
133
- [:after_initialize, :string],
134
- [:after_initialize, :proc],
135
- [:after_initialize, :object],
136
- [:after_initialize, :block],
137
- [:before_validation, :method],
138
- [:before_validation, :string],
139
- [:before_validation, :proc],
140
- [:before_validation, :object],
141
- [:before_validation, :block],
142
- [:after_validation, :method],
143
- [:after_validation, :string],
144
- [:after_validation, :proc],
145
- [:after_validation, :object],
146
- [:after_validation, :block]
147
- ]
148
- end
37
+ embedded_in :callback_developer_table
149
38
 
150
- it "valid for exiting record should run in correct order" do
151
- thorbjorn = CallbackDeveloper.find(1)
152
- thorbjorn.valid?
153
- thorbjorn.history.should == [
154
- [:after_find, :method],
155
- [:after_find, :string],
156
- [:after_find, :proc],
157
- [:after_find, :object],
158
- [:after_find, :block],
159
- [:after_initialize, :method],
160
- [:after_initialize, :string],
161
- [:after_initialize, :proc],
162
- [:after_initialize, :object],
163
- [:after_initialize, :block],
164
- [:before_validation, :method],
165
- [:before_validation, :string],
166
- [:before_validation, :proc],
167
- [:before_validation, :object],
168
- [:before_validation, :block],
169
- [:after_validation, :method],
170
- [:after_validation, :string],
171
- [:after_validation, :proc],
172
- [:after_validation, :object],
173
- [:after_validation, :block]
174
- ]
39
+ field :name, :default => "Trym"
175
40
  end
176
41
 
177
- it "create should run in correct order" do
178
- thorbjorn = CallbackDeveloper.create "dummy"
179
- thorbjorn.history.should == [
180
- [:after_initialize, :method],
181
- [:after_initialize, :string],
182
- [:after_initialize, :proc ],
183
- [:after_initialize, :object],
184
- [:after_initialize, :block ],
185
- [:before_validation, :method],
186
- [:before_validation, :string],
187
- [:before_validation, :proc ],
188
- [:before_validation, :object],
189
- [:before_validation, :block ],
190
- [:after_validation, :method],
191
- [:after_validation, :string],
192
- [:after_validation, :proc ],
193
- [:after_validation, :object],
194
- [:after_validation, :block ],
195
- [:before_save, :method],
196
- [:before_save, :string],
197
- [:before_save, :proc ],
198
- [:before_save, :object],
199
- [:before_save, :block ],
200
- [:before_create, :method],
201
- [:before_create, :string],
202
- [:before_create, :proc ],
203
- [:before_create, :object],
204
- [:before_create, :block ],
205
- [:after_create, :method],
206
- [:after_create, :string],
207
- [:after_create, :proc ],
208
- [:after_create, :object],
209
- [:after_create, :block ],
210
- [:after_save, :method],
211
- [:after_save, :string],
212
- [:after_save, :proc ],
213
- [:after_save, :object],
214
- [:after_save, :block ]
215
- ]
216
- end
42
+ describe CallbackDeveloperEmbedded do
43
+ let(:owner_new_record) { CallbackDeveloperTable.new "1" }
44
+ let(:owner) { owner_new_record.save! ; owner_new_record }
217
45
 
218
- it "update should run in correct order" do
219
- thorbjorn = CallbackDeveloper.find(1)
220
- thorbjorn.save
221
- thorbjorn.history.should == [
222
- [:after_find, :method],
223
- [:after_find, :string],
224
- [:after_find, :proc],
225
- [:after_find, :object],
226
- [:after_find, :block],
227
- [:after_initialize, :method],
228
- [:after_initialize, :string],
229
- [:after_initialize, :proc ],
230
- [:after_initialize, :object],
231
- [:after_initialize, :block ],
232
- [:before_validation, :method],
233
- [:before_validation, :string],
234
- [:before_validation, :proc ],
235
- [:before_validation, :object],
236
- [:before_validation, :block ],
237
- [:after_validation, :method],
238
- [:after_validation, :string],
239
- [:after_validation, :proc ],
240
- [:after_validation, :object],
241
- [:after_validation, :block ],
242
- [:before_save, :method],
243
- [:before_save, :string],
244
- [:before_save, :proc ],
245
- [:before_save, :object],
246
- [:before_save, :block ],
247
- [:before_update, :method],
248
- [:before_update, :string],
249
- [:before_update, :proc ],
250
- [:before_update, :object],
251
- [:before_update, :block ],
252
- [:after_update, :method],
253
- [:after_update, :string],
254
- [:after_update, :proc ],
255
- [:after_update, :object],
256
- [:after_update, :block ],
257
- [:after_save, :method],
258
- [:after_save, :string],
259
- [:after_save, :proc ],
260
- [:after_save, :object],
261
- [:after_save, :block ]
262
- ]
263
- end
46
+ let(:new_record) { described_class.new "1", :callback_developer_table => owner_new_record }
47
+ let(:created_record) { described_class.create "dummy", :callback_developer_table => owner_new_record }
48
+ let(:persisted_record) do
49
+ owner.callback_developer_embeddeds << described_class.new("1-1")
50
+ owner.callback_developer_embeddeds.reset # Resets to drop all proxy cached records, force reload from DB
51
+ owner.callback_developer_embeddeds.find("1-1")
52
+ end
264
53
 
265
- it "destroy should run in correct order" do
266
- thorbjorn = CallbackDeveloper.find(1)
267
- thorbjorn.destroy
268
- thorbjorn.history.should == [
269
- [:after_find, :method],
270
- [:after_find, :string],
271
- [:after_find, :proc],
272
- [:after_find, :object],
273
- [:after_find, :block],
274
- [:after_initialize, :method],
275
- [:after_initialize, :string],
276
- [:after_initialize, :proc ],
277
- [:after_initialize, :object],
278
- [:after_initialize, :block ],
279
- [:before_destroy, :method],
280
- [:before_destroy, :string],
281
- [:before_destroy, :proc ],
282
- [:before_destroy, :object],
283
- [:before_destroy, :block ],
284
- [:after_destroy, :method],
285
- [:after_destroy, :string],
286
- [:after_destroy, :proc ],
287
- [:after_destroy, :object],
288
- [:after_destroy, :block ]
289
- ]
290
- end
54
+ it_should_behave_like "a model with callbacks"
55
+
56
+
57
+ describe "saved via owner" do
58
+ context "when owner is new record" do
59
+ subject { new_record }
60
+ before { subject } # Tap to initialize
61
+
62
+ describe "save callbacks" do
63
+ it "runs in correct order" do
64
+ owner_new_record.save
65
+ subject.history.should eq [
66
+ [:after_initialize, :method],
67
+ [:after_initialize, :string],
68
+ [:after_initialize, :proc ],
69
+ [:after_initialize, :object],
70
+ [:after_initialize, :block ],
71
+ [:before_validation, :method],
72
+ [:before_validation, :string],
73
+ [:before_validation, :proc ],
74
+ [:before_validation, :object],
75
+ [:before_validation, :block ],
76
+ [:after_validation, :method],
77
+ [:after_validation, :string],
78
+ [:after_validation, :proc ],
79
+ [:after_validation, :object],
80
+ [:after_validation, :block ],
81
+ [:before_save, :method],
82
+ [:before_save, :string],
83
+ [:before_save, :proc ],
84
+ [:before_save, :object],
85
+ [:before_save, :block ],
86
+ [:before_create, :method],
87
+ [:before_create, :string],
88
+ [:before_create, :proc ],
89
+ [:before_create, :object],
90
+ [:before_create, :block ],
91
+ [:after_create, :method],
92
+ [:after_create, :string],
93
+ [:after_create, :proc ],
94
+ [:after_create, :object],
95
+ [:after_create, :block ],
96
+ [:after_save, :method],
97
+ [:after_save, :string],
98
+ [:after_save, :proc ],
99
+ [:after_save, :object],
100
+ [:after_save, :block ]
101
+ ]
102
+ end
103
+ end
104
+ end
291
105
 
292
- it "should not run callbacks for destroy on delete" do
293
- thorbjorn = CallbackDeveloper.find(1)
294
- thorbjorn.delete
295
- thorbjorn.should be_destroyed
296
- thorbjorn.history.should == [
297
- [:after_find, :method],
298
- [:after_find, :string],
299
- [:after_find, :proc],
300
- [:after_find, :object],
301
- [:after_find, :block],
302
- [:after_initialize, :method],
303
- [:after_initialize, :string],
304
- [:after_initialize, :proc ],
305
- [:after_initialize, :object],
306
- [:after_initialize, :block ]
307
- ]
106
+ context "when owner is persisted" do
107
+ subject { persisted_record; owner.callback_developer_embeddeds.first }
108
+ before { subject } # Tap to initialize
109
+
110
+ describe "update callbacks" do
111
+ it "is run in correct order" do
112
+ subject.name += "_NEW"
113
+ subject.history.clear
114
+ owner.save
115
+ subject.history.should eq [
116
+ [:before_validation, :method],
117
+ [:before_validation, :string],
118
+ [:before_validation, :proc ],
119
+ [:before_validation, :object],
120
+ [:before_validation, :block ],
121
+ [:after_validation, :method],
122
+ [:after_validation, :string],
123
+ [:after_validation, :proc ],
124
+ [:after_validation, :object],
125
+ [:after_validation, :block ],
126
+ [:before_save, :method],
127
+ [:before_save, :string],
128
+ [:before_save, :proc ],
129
+ [:before_save, :object],
130
+ [:before_save, :block ],
131
+ [:before_update, :method],
132
+ [:before_update, :string],
133
+ [:before_update, :proc ],
134
+ [:before_update, :object],
135
+ [:before_update, :block ],
136
+ [:after_update, :method],
137
+ [:after_update, :string],
138
+ [:after_update, :proc ],
139
+ [:after_update, :object],
140
+ [:after_update, :block ],
141
+ [:after_save, :method],
142
+ [:after_save, :string],
143
+ [:after_save, :proc ],
144
+ [:after_save, :object],
145
+ [:after_save, :block ]
146
+ ]
147
+ end
148
+ end
149
+ end
150
+ end
308
151
  end
309
152
  end
153
+
@@ -0,0 +1,44 @@
1
+ module CallbackTestable
2
+ extend ActiveSupport::Concern
3
+
4
+ included do
5
+ MassiveRecord::ORM::Callbacks::CALLBACKS.each do |callback_method|
6
+ next if callback_method.to_s =~ /^around_/
7
+ define_callback_method(callback_method)
8
+ send(callback_method, callback_string(callback_method))
9
+ send(callback_method, callback_proc(callback_method))
10
+ send(callback_method, callback_object(callback_method))
11
+ send(callback_method) { |model| model.history << [callback_method, :block] }
12
+ end
13
+ end
14
+
15
+ module ClassMethods
16
+ def callback_string(callback_method)
17
+ "history << [#{callback_method.to_sym.inspect}, :string]"
18
+ end
19
+
20
+ def callback_proc(callback_method)
21
+ Proc.new { |model| model.history << [callback_method, :proc] }
22
+ end
23
+
24
+ def define_callback_method(callback_method)
25
+ define_method(callback_method) do
26
+ self.history << [callback_method, :method]
27
+ end
28
+ send(callback_method, :"#{callback_method}")
29
+ end
30
+
31
+ def callback_object(callback_method)
32
+ klass = Class.new
33
+ klass.send(:define_method, callback_method) do |model|
34
+ model.history << [callback_method, :object]
35
+ end
36
+ klass.new
37
+ end
38
+ end
39
+
40
+
41
+ def history
42
+ @history ||= []
43
+ end
44
+ end
@@ -26,6 +26,15 @@ describe MassiveRecord::ORM::Persistence::Operations do
26
26
  subject.should be_instance_of MassiveRecord::ORM::Persistence::Operations::Suppress
27
27
  end
28
28
  end
29
+
30
+ it "is possible to force" do
31
+ MassiveRecord::ORM::Persistence::Operations.suppress do
32
+ MassiveRecord::ORM::Persistence::Operations.force do
33
+ klass = "MassiveRecord::ORM::Persistence::Operations::#{method.to_s.classify}".constantize
34
+ should be_instance_of klass
35
+ end
36
+ end
37
+ end
29
38
  end
30
39
  end
31
40
  end
@@ -51,6 +60,15 @@ describe MassiveRecord::ORM::Persistence::Operations do
51
60
  subject.should be_instance_of MassiveRecord::ORM::Persistence::Operations::Suppress
52
61
  end
53
62
  end
63
+
64
+ it "is possible to force" do
65
+ MassiveRecord::ORM::Persistence::Operations.suppress do
66
+ MassiveRecord::ORM::Persistence::Operations.force do
67
+ klass = "MassiveRecord::ORM::Persistence::Operations::Embedded::#{method.to_s.classify}".constantize
68
+ should be_instance_of klass
69
+ end
70
+ end
71
+ end
54
72
  end
55
73
  end
56
74
  end
@@ -0,0 +1,316 @@
1
+ require 'spec_helper'
2
+
3
+ shared_examples_for "a model with callbacks" do
4
+ it "should include ActiveModel::Callbacks" do
5
+ described_class.should respond_to :define_model_callbacks
6
+ end
7
+
8
+ it "should include ActiveModell::Validations::Callback" do
9
+ described_class.included_modules.should include(ActiveModel::Validations::Callbacks)
10
+ end
11
+
12
+
13
+
14
+ context "new record" do
15
+ describe "initialize callbacks" do
16
+ it "runs in correct order" do
17
+ subject.history.should eq [
18
+ [:after_initialize, :method],
19
+ [:after_initialize, :string],
20
+ [:after_initialize, :proc],
21
+ [:after_initialize, :object],
22
+ [:after_initialize, :block]
23
+ ]
24
+ end
25
+ end
26
+
27
+ describe "validations callback" do
28
+ it "runs in correct order for new records" do
29
+ subject.valid?
30
+ subject.history.should eq [
31
+ [:after_initialize, :method],
32
+ [:after_initialize, :string],
33
+ [:after_initialize, :proc],
34
+ [:after_initialize, :object],
35
+ [:after_initialize, :block],
36
+ [:before_validation, :method],
37
+ [:before_validation, :string],
38
+ [:before_validation, :proc],
39
+ [:before_validation, :object],
40
+ [:before_validation, :block],
41
+ [:after_validation, :method],
42
+ [:after_validation, :string],
43
+ [:after_validation, :proc],
44
+ [:after_validation, :object],
45
+ [:after_validation, :block]
46
+ ]
47
+ end
48
+ end
49
+
50
+ describe "create callbacks" do
51
+ subject { created_record }
52
+
53
+ it "runs in correct order" do
54
+ subject.history.should eq [
55
+ [:after_initialize, :method],
56
+ [:after_initialize, :string],
57
+ [:after_initialize, :proc ],
58
+ [:after_initialize, :object],
59
+ [:after_initialize, :block ],
60
+ [:before_validation, :method],
61
+ [:before_validation, :string],
62
+ [:before_validation, :proc ],
63
+ [:before_validation, :object],
64
+ [:before_validation, :block ],
65
+ [:after_validation, :method],
66
+ [:after_validation, :string],
67
+ [:after_validation, :proc ],
68
+ [:after_validation, :object],
69
+ [:after_validation, :block ],
70
+ [:before_save, :method],
71
+ [:before_save, :string],
72
+ [:before_save, :proc ],
73
+ [:before_save, :object],
74
+ [:before_save, :block ],
75
+ [:before_create, :method],
76
+ [:before_create, :string],
77
+ [:before_create, :proc ],
78
+ [:before_create, :object],
79
+ [:before_create, :block ],
80
+ [:after_create, :method],
81
+ [:after_create, :string],
82
+ [:after_create, :proc ],
83
+ [:after_create, :object],
84
+ [:after_create, :block ],
85
+ [:after_save, :method],
86
+ [:after_save, :string],
87
+ [:after_save, :proc ],
88
+ [:after_save, :object],
89
+ [:after_save, :block ]
90
+ ]
91
+ end
92
+ end
93
+
94
+ describe "save callbacks" do
95
+ subject { new_record }
96
+
97
+ it "runs in correct order" do
98
+ subject.save
99
+ subject.history.should eq [
100
+ [:after_initialize, :method],
101
+ [:after_initialize, :string],
102
+ [:after_initialize, :proc ],
103
+ [:after_initialize, :object],
104
+ [:after_initialize, :block ],
105
+ [:before_validation, :method],
106
+ [:before_validation, :string],
107
+ [:before_validation, :proc ],
108
+ [:before_validation, :object],
109
+ [:before_validation, :block ],
110
+ [:after_validation, :method],
111
+ [:after_validation, :string],
112
+ [:after_validation, :proc ],
113
+ [:after_validation, :object],
114
+ [:after_validation, :block ],
115
+ [:before_save, :method],
116
+ [:before_save, :string],
117
+ [:before_save, :proc ],
118
+ [:before_save, :object],
119
+ [:before_save, :block ],
120
+ [:before_create, :method],
121
+ [:before_create, :string],
122
+ [:before_create, :proc ],
123
+ [:before_create, :object],
124
+ [:before_create, :block ],
125
+ [:after_create, :method],
126
+ [:after_create, :string],
127
+ [:after_create, :proc ],
128
+ [:after_create, :object],
129
+ [:after_create, :block ],
130
+ [:after_save, :method],
131
+ [:after_save, :string],
132
+ [:after_save, :proc ],
133
+ [:after_save, :object],
134
+ [:after_save, :block ]
135
+ ]
136
+ end
137
+ end
138
+ end
139
+
140
+
141
+ context "persisted record" do
142
+ subject { persisted_record }
143
+
144
+ describe "find callbacks" do
145
+ it "runs in correct order" do
146
+ subject.history.should eq [
147
+ [:after_find, :method],
148
+ [:after_find, :string],
149
+ [:after_find, :proc],
150
+ [:after_find, :object],
151
+ [:after_find, :block],
152
+ [:after_initialize, :method],
153
+ [:after_initialize, :string],
154
+ [:after_initialize, :proc],
155
+ [:after_initialize, :object],
156
+ [:after_initialize, :block]
157
+ ]
158
+ end
159
+ end
160
+
161
+
162
+ describe "touch callbacks" do
163
+ it "runs in correct order" do
164
+ subject.touch
165
+ subject.history.should eq [
166
+ [:after_find, :method],
167
+ [:after_find, :string],
168
+ [:after_find, :proc],
169
+ [:after_find, :object],
170
+ [:after_find, :block],
171
+ [:after_initialize, :method],
172
+ [:after_initialize, :string],
173
+ [:after_initialize, :proc],
174
+ [:after_initialize, :object],
175
+ [:after_initialize, :block],
176
+ [:after_touch, :method],
177
+ [:after_touch, :string],
178
+ [:after_touch, :proc],
179
+ [:after_touch, :object],
180
+ [:after_touch, :block]
181
+ ]
182
+ end
183
+ end
184
+
185
+
186
+
187
+ describe "validations callback" do
188
+ it "runs in correct order for persisted records" do
189
+ subject.valid?
190
+ subject.history.should eq [
191
+ [:after_find, :method],
192
+ [:after_find, :string],
193
+ [:after_find, :proc],
194
+ [:after_find, :object],
195
+ [:after_find, :block],
196
+ [:after_initialize, :method],
197
+ [:after_initialize, :string],
198
+ [:after_initialize, :proc],
199
+ [:after_initialize, :object],
200
+ [:after_initialize, :block],
201
+ [:before_validation, :method],
202
+ [:before_validation, :string],
203
+ [:before_validation, :proc],
204
+ [:before_validation, :object],
205
+ [:before_validation, :block],
206
+ [:after_validation, :method],
207
+ [:after_validation, :string],
208
+ [:after_validation, :proc],
209
+ [:after_validation, :object],
210
+ [:after_validation, :block]
211
+ ]
212
+ end
213
+ end
214
+
215
+
216
+
217
+
218
+ describe "update callbacks" do
219
+ it "runs in the correct order" do
220
+ subject.save
221
+ subject.history.should eq [
222
+ [:after_find, :method],
223
+ [:after_find, :string],
224
+ [:after_find, :proc],
225
+ [:after_find, :object],
226
+ [:after_find, :block],
227
+ [:after_initialize, :method],
228
+ [:after_initialize, :string],
229
+ [:after_initialize, :proc ],
230
+ [:after_initialize, :object],
231
+ [:after_initialize, :block ],
232
+ [:before_validation, :method],
233
+ [:before_validation, :string],
234
+ [:before_validation, :proc ],
235
+ [:before_validation, :object],
236
+ [:before_validation, :block ],
237
+ [:after_validation, :method],
238
+ [:after_validation, :string],
239
+ [:after_validation, :proc ],
240
+ [:after_validation, :object],
241
+ [:after_validation, :block ],
242
+ [:before_save, :method],
243
+ [:before_save, :string],
244
+ [:before_save, :proc ],
245
+ [:before_save, :object],
246
+ [:before_save, :block ],
247
+ [:before_update, :method],
248
+ [:before_update, :string],
249
+ [:before_update, :proc ],
250
+ [:before_update, :object],
251
+ [:before_update, :block ],
252
+ [:after_update, :method],
253
+ [:after_update, :string],
254
+ [:after_update, :proc ],
255
+ [:after_update, :object],
256
+ [:after_update, :block ],
257
+ [:after_save, :method],
258
+ [:after_save, :string],
259
+ [:after_save, :proc ],
260
+ [:after_save, :object],
261
+ [:after_save, :block ]
262
+ ]
263
+ end
264
+ end
265
+
266
+
267
+ describe "destroy callbacks" do
268
+ it "runs in correct order" do
269
+ subject.destroy
270
+ subject.history.should eq [
271
+ [:after_find, :method],
272
+ [:after_find, :string],
273
+ [:after_find, :proc],
274
+ [:after_find, :object],
275
+ [:after_find, :block],
276
+ [:after_initialize, :method],
277
+ [:after_initialize, :string],
278
+ [:after_initialize, :proc ],
279
+ [:after_initialize, :object],
280
+ [:after_initialize, :block ],
281
+ [:before_destroy, :method],
282
+ [:before_destroy, :string],
283
+ [:before_destroy, :proc ],
284
+ [:before_destroy, :object],
285
+ [:before_destroy, :block ],
286
+ [:after_destroy, :method],
287
+ [:after_destroy, :string],
288
+ [:after_destroy, :proc ],
289
+ [:after_destroy, :object],
290
+ [:after_destroy, :block ]
291
+ ]
292
+ end
293
+ end
294
+
295
+
296
+
297
+ describe "delete callbacks" do
298
+ it "does not run callbacks for destroy" do
299
+ subject.delete
300
+ subject.should be_destroyed
301
+ subject.history.should eq [
302
+ [:after_find, :method],
303
+ [:after_find, :string],
304
+ [:after_find, :proc],
305
+ [:after_find, :object],
306
+ [:after_find, :block],
307
+ [:after_initialize, :method],
308
+ [:after_initialize, :string],
309
+ [:after_initialize, :proc ],
310
+ [:after_initialize, :object],
311
+ [:after_initialize, :block ]
312
+ ]
313
+ end
314
+ end
315
+ end
316
+ end
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: massive_record
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease: 6
5
- version: 0.2.2.rc1
5
+ version: 0.2.2.rc2
6
6
  platform: ruby
7
7
  authors:
8
8
  - Companybook
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2011-10-07 00:00:00 +02:00
13
+ date: 2011-10-24 00:00:00 +02:00
14
14
  default_executable:
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
@@ -122,6 +122,7 @@ files:
122
122
  - lib/massive_record/orm/id_factory/atomic_incrementation.rb
123
123
  - lib/massive_record/orm/id_factory/timestamp.rb
124
124
  - lib/massive_record/orm/identity_map.rb
125
+ - lib/massive_record/orm/in_the_middle_of_saving_tracker.rb
125
126
  - lib/massive_record/orm/log_subscriber.rb
126
127
  - lib/massive_record/orm/observer.rb
127
128
  - lib/massive_record/orm/persistence.rb
@@ -217,6 +218,7 @@ files:
217
218
  - spec/orm/models/address.rb
218
219
  - spec/orm/models/address_with_timestamp.rb
219
220
  - spec/orm/models/best_friend.rb
221
+ - spec/orm/models/callback_testable.rb
220
222
  - spec/orm/models/car.rb
221
223
  - spec/orm/models/friend.rb
222
224
  - spec/orm/models/model_without_default_id.rb
@@ -251,6 +253,7 @@ files:
251
253
  - spec/orm/schema/field_spec.rb
252
254
  - spec/orm/schema/fields_spec.rb
253
255
  - spec/orm/schema/table_interface_spec.rb
256
+ - spec/shared/orm/callbacks.rb
254
257
  - spec/shared/orm/coders/an_orm_coder.rb
255
258
  - spec/shared/orm/id_factories.rb
256
259
  - spec/shared/orm/model_with_timestamps.rb
@@ -335,6 +338,7 @@ test_files:
335
338
  - spec/orm/models/address.rb
336
339
  - spec/orm/models/address_with_timestamp.rb
337
340
  - spec/orm/models/best_friend.rb
341
+ - spec/orm/models/callback_testable.rb
338
342
  - spec/orm/models/car.rb
339
343
  - spec/orm/models/friend.rb
340
344
  - spec/orm/models/model_without_default_id.rb
@@ -369,6 +373,7 @@ test_files:
369
373
  - spec/orm/schema/field_spec.rb
370
374
  - spec/orm/schema/fields_spec.rb
371
375
  - spec/orm/schema/table_interface_spec.rb
376
+ - spec/shared/orm/callbacks.rb
372
377
  - spec/shared/orm/coders/an_orm_coder.rb
373
378
  - spec/shared/orm/id_factories.rb
374
379
  - spec/shared/orm/model_with_timestamps.rb