mongo_mapper 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +7 -0
- data/LICENSE +20 -0
- data/README.rdoc +39 -0
- data/Rakefile +87 -0
- data/VERSION +1 -0
- data/bin/mmconsole +55 -0
- data/lib/mongo_mapper.rb +92 -0
- data/lib/mongo_mapper/associations.rb +86 -0
- data/lib/mongo_mapper/associations/base.rb +83 -0
- data/lib/mongo_mapper/associations/belongs_to_polymorphic_proxy.rb +34 -0
- data/lib/mongo_mapper/associations/belongs_to_proxy.rb +22 -0
- data/lib/mongo_mapper/associations/many_documents_as_proxy.rb +27 -0
- data/lib/mongo_mapper/associations/many_documents_proxy.rb +116 -0
- data/lib/mongo_mapper/associations/many_embedded_polymorphic_proxy.rb +33 -0
- data/lib/mongo_mapper/associations/many_embedded_proxy.rb +67 -0
- data/lib/mongo_mapper/associations/many_polymorphic_proxy.rb +11 -0
- data/lib/mongo_mapper/associations/many_proxy.rb +6 -0
- data/lib/mongo_mapper/associations/proxy.rb +64 -0
- data/lib/mongo_mapper/callbacks.rb +106 -0
- data/lib/mongo_mapper/document.rb +317 -0
- data/lib/mongo_mapper/dynamic_finder.rb +35 -0
- data/lib/mongo_mapper/embedded_document.rb +354 -0
- data/lib/mongo_mapper/finder_options.rb +94 -0
- data/lib/mongo_mapper/key.rb +32 -0
- data/lib/mongo_mapper/observing.rb +50 -0
- data/lib/mongo_mapper/pagination.rb +51 -0
- data/lib/mongo_mapper/rails_compatibility/document.rb +15 -0
- data/lib/mongo_mapper/rails_compatibility/embedded_document.rb +27 -0
- data/lib/mongo_mapper/save_with_validation.rb +19 -0
- data/lib/mongo_mapper/serialization.rb +55 -0
- data/lib/mongo_mapper/serializers/json_serializer.rb +92 -0
- data/lib/mongo_mapper/support.rb +157 -0
- data/lib/mongo_mapper/validations.rb +69 -0
- data/mongo_mapper.gemspec +156 -0
- data/test/NOTE_ON_TESTING +1 -0
- data/test/custom_matchers.rb +48 -0
- data/test/functional/associations/test_belongs_to_polymorphic_proxy.rb +54 -0
- data/test/functional/associations/test_belongs_to_proxy.rb +46 -0
- data/test/functional/associations/test_many_documents_as_proxy.rb +244 -0
- data/test/functional/associations/test_many_embedded_polymorphic_proxy.rb +132 -0
- data/test/functional/associations/test_many_embedded_proxy.rb +174 -0
- data/test/functional/associations/test_many_polymorphic_proxy.rb +297 -0
- data/test/functional/associations/test_many_proxy.rb +331 -0
- data/test/functional/test_associations.rb +48 -0
- data/test/functional/test_binary.rb +18 -0
- data/test/functional/test_callbacks.rb +85 -0
- data/test/functional/test_document.rb +951 -0
- data/test/functional/test_embedded_document.rb +97 -0
- data/test/functional/test_pagination.rb +87 -0
- data/test/functional/test_rails_compatibility.rb +30 -0
- data/test/functional/test_validations.rb +279 -0
- data/test/models.rb +169 -0
- data/test/test_helper.rb +29 -0
- data/test/unit/serializers/test_json_serializer.rb +189 -0
- data/test/unit/test_association_base.rb +144 -0
- data/test/unit/test_document.rb +165 -0
- data/test/unit/test_dynamic_finder.rb +125 -0
- data/test/unit/test_embedded_document.rb +645 -0
- data/test/unit/test_finder_options.rb +193 -0
- data/test/unit/test_key.rb +163 -0
- data/test/unit/test_mongomapper.rb +28 -0
- data/test/unit/test_observing.rb +101 -0
- data/test/unit/test_pagination.rb +109 -0
- data/test/unit/test_rails_compatibility.rb +39 -0
- data/test/unit/test_serializations.rb +52 -0
- data/test/unit/test_support.rb +272 -0
- data/test/unit/test_time_zones.rb +40 -0
- data/test/unit/test_validations.rb +503 -0
- metadata +204 -0
@@ -0,0 +1,331 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'models'
|
3
|
+
|
4
|
+
class ManyProxyTest < Test::Unit::TestCase
|
5
|
+
def setup
|
6
|
+
Project.collection.clear
|
7
|
+
Status.collection.clear
|
8
|
+
end
|
9
|
+
|
10
|
+
should "default reader to empty array" do
|
11
|
+
project = Project.new
|
12
|
+
project.statuses.should == []
|
13
|
+
end
|
14
|
+
|
15
|
+
should "allow adding to association like it was an array" do
|
16
|
+
project = Project.new
|
17
|
+
project.statuses << Status.new
|
18
|
+
project.statuses.push Status.new
|
19
|
+
project.statuses.concat Status.new
|
20
|
+
project.statuses.size.should == 3
|
21
|
+
end
|
22
|
+
|
23
|
+
should "be able to replace the association" do
|
24
|
+
project = Project.new
|
25
|
+
project.statuses = [Status.new("name" => "ready")]
|
26
|
+
project.save.should be_true
|
27
|
+
|
28
|
+
from_db = Project.find(project.id)
|
29
|
+
from_db.statuses.size.should == 1
|
30
|
+
from_db.statuses[0].name.should == "ready"
|
31
|
+
end
|
32
|
+
|
33
|
+
should "correctly assign foreign key when using <<, push and concat" do
|
34
|
+
project = Project.new
|
35
|
+
project.statuses << Status.new(:name => '<<')
|
36
|
+
project.statuses.push Status.new(:name => 'push')
|
37
|
+
project.statuses.concat Status.new(:name => 'concat')
|
38
|
+
|
39
|
+
from_db = Project.find(project.id)
|
40
|
+
from_db.statuses[0].project_id.should == project.id
|
41
|
+
from_db.statuses[1].project_id.should == project.id
|
42
|
+
from_db.statuses[2].project_id.should == project.id
|
43
|
+
end
|
44
|
+
|
45
|
+
context "build" do
|
46
|
+
should "assign foreign key" do
|
47
|
+
project = Project.create
|
48
|
+
status = project.statuses.build
|
49
|
+
status.project_id.should == project.id
|
50
|
+
end
|
51
|
+
|
52
|
+
should "allow assigning attributes" do
|
53
|
+
project = Project.create
|
54
|
+
status = project.statuses.build(:name => 'Foo')
|
55
|
+
status.name.should == 'Foo'
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
context "create" do
|
60
|
+
should "assign foreign key" do
|
61
|
+
project = Project.create
|
62
|
+
status = project.statuses.create
|
63
|
+
status.project_id.should == project.id
|
64
|
+
end
|
65
|
+
|
66
|
+
should "save record" do
|
67
|
+
project = Project.create
|
68
|
+
lambda {
|
69
|
+
project.statuses.create
|
70
|
+
}.should change { Status.count }
|
71
|
+
end
|
72
|
+
|
73
|
+
should "allow passing attributes" do
|
74
|
+
project = Project.create
|
75
|
+
status = project.statuses.create(:name => 'Foo!')
|
76
|
+
status.name.should == 'Foo!'
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
context "count" do
|
81
|
+
should "work scoped to association" do
|
82
|
+
project = Project.create
|
83
|
+
3.times { project.statuses.create }
|
84
|
+
|
85
|
+
other_project = Project.create
|
86
|
+
2.times { other_project.statuses.create }
|
87
|
+
|
88
|
+
project.statuses.count.should == 3
|
89
|
+
other_project.statuses.count.should == 2
|
90
|
+
end
|
91
|
+
|
92
|
+
should "work with conditions" do
|
93
|
+
project = Project.create
|
94
|
+
project.statuses.create(:name => 'Foo')
|
95
|
+
project.statuses.create(:name => 'Other 1')
|
96
|
+
project.statuses.create(:name => 'Other 2')
|
97
|
+
|
98
|
+
project.statuses.count(:name => 'Foo').should == 1
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
context "Unassociating documents" do
|
103
|
+
setup do
|
104
|
+
@project = Project.create
|
105
|
+
@project.statuses << Status.create(:name => '1')
|
106
|
+
@project.statuses << Status.create(:name => '2')
|
107
|
+
|
108
|
+
@project2 = Project.create
|
109
|
+
@project2.statuses << Status.create(:name => '1')
|
110
|
+
@project2.statuses << Status.create(:name => '2')
|
111
|
+
end
|
112
|
+
|
113
|
+
should "work with destroy all" do
|
114
|
+
@project.statuses.count.should == 2
|
115
|
+
@project.statuses.destroy_all
|
116
|
+
@project.statuses.count.should == 0
|
117
|
+
|
118
|
+
@project2.statuses.count.should == 2
|
119
|
+
Status.count.should == 2
|
120
|
+
end
|
121
|
+
|
122
|
+
should "work with destroy all and conditions" do
|
123
|
+
@project.statuses.count.should == 2
|
124
|
+
@project.statuses.destroy_all(:name => '1')
|
125
|
+
@project.statuses.count.should == 1
|
126
|
+
|
127
|
+
@project2.statuses.count.should == 2
|
128
|
+
Status.count.should == 3
|
129
|
+
end
|
130
|
+
|
131
|
+
should "work with delete all" do
|
132
|
+
@project.statuses.count.should == 2
|
133
|
+
@project.statuses.delete_all
|
134
|
+
@project.statuses.count.should == 0
|
135
|
+
|
136
|
+
@project2.statuses.count.should == 2
|
137
|
+
Status.count.should == 2
|
138
|
+
end
|
139
|
+
|
140
|
+
should "work with delete all and conditions" do
|
141
|
+
@project.statuses.count.should == 2
|
142
|
+
@project.statuses.delete_all(:name => '1')
|
143
|
+
@project.statuses.count.should == 1
|
144
|
+
|
145
|
+
@project2.statuses.count.should == 2
|
146
|
+
Status.count.should == 3
|
147
|
+
end
|
148
|
+
|
149
|
+
should "work with nullify" do
|
150
|
+
@project.statuses.count.should == 2
|
151
|
+
@project.statuses.nullify
|
152
|
+
@project.statuses.count.should == 0
|
153
|
+
|
154
|
+
@project2.statuses.count.should == 2
|
155
|
+
Status.count.should == 4
|
156
|
+
Status.count(:name => '1').should == 2
|
157
|
+
Status.count(:name => '2').should == 2
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
context "Finding scoped to association" do
|
162
|
+
setup do
|
163
|
+
@project1 = Project.new(:name => 'Project 1')
|
164
|
+
@brand_new = Status.create(:name => 'New', :position => 1 )
|
165
|
+
@complete = Status.create(:name => 'Complete', :position => 2)
|
166
|
+
@project1.statuses = [@brand_new, @complete]
|
167
|
+
@project1.save
|
168
|
+
|
169
|
+
@project2 = Project.create(:name => 'Project 2')
|
170
|
+
@in_progress = Status.create(:name => 'In Progress')
|
171
|
+
@archived = Status.create(:name => 'Archived')
|
172
|
+
@another_complete = Status.create(:name => 'Complete')
|
173
|
+
@project2.statuses = [@in_progress, @archived, @another_complete]
|
174
|
+
@project2.save
|
175
|
+
end
|
176
|
+
|
177
|
+
context "dynamic finders" do
|
178
|
+
should "work with single key" do
|
179
|
+
@project1.statuses.find_by_name('New').should == @brand_new
|
180
|
+
@project2.statuses.find_by_name('In Progress').should == @in_progress
|
181
|
+
end
|
182
|
+
|
183
|
+
should "work with multiple keys" do
|
184
|
+
@project1.statuses.find_by_name_and_position('New', 1).should == @brand_new
|
185
|
+
@project1.statuses.find_by_name_and_position('New', 2).should be_nil
|
186
|
+
end
|
187
|
+
|
188
|
+
should "raise error when using !" do
|
189
|
+
lambda {
|
190
|
+
@project1.statuses.find_by_name!('Fake')
|
191
|
+
}.should raise_error(MongoMapper::DocumentNotFound)
|
192
|
+
end
|
193
|
+
|
194
|
+
context "find_or_create_by" do
|
195
|
+
should "not create document if found" do
|
196
|
+
lambda {
|
197
|
+
status = @project1.statuses.find_or_create_by_name('New')
|
198
|
+
status.project.should == @project1
|
199
|
+
status.should == @brand_new
|
200
|
+
}.should_not change { Status.count }
|
201
|
+
end
|
202
|
+
|
203
|
+
should "create document if not found" do
|
204
|
+
lambda {
|
205
|
+
status = @project1.statuses.find_or_create_by_name('Delivered')
|
206
|
+
status.project.should == @project1
|
207
|
+
}.should change { Status.count }.by(1)
|
208
|
+
end
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
context "with :all" do
|
213
|
+
should "work" do
|
214
|
+
@project1.statuses.find(:all, :order => "position asc").should == [@brand_new, @complete]
|
215
|
+
end
|
216
|
+
|
217
|
+
should "work with conditions" do
|
218
|
+
statuses = @project1.statuses.find(:all, :conditions => {'name' => 'Complete'})
|
219
|
+
statuses.should == [@complete]
|
220
|
+
end
|
221
|
+
|
222
|
+
should "work with order" do
|
223
|
+
statuses = @project1.statuses.find(:all, :order => 'name asc')
|
224
|
+
statuses.should == [@complete, @brand_new]
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
context "with #all" do
|
229
|
+
should "work" do
|
230
|
+
@project1.statuses.all(:order => "position asc").should == [@brand_new, @complete]
|
231
|
+
end
|
232
|
+
|
233
|
+
should "work with conditions" do
|
234
|
+
statuses = @project1.statuses.all(:conditions => {'name' => 'Complete'})
|
235
|
+
statuses.should == [@complete]
|
236
|
+
end
|
237
|
+
|
238
|
+
should "work with order" do
|
239
|
+
statuses = @project1.statuses.all(:order => 'name asc')
|
240
|
+
statuses.should == [@complete, @brand_new]
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
244
|
+
context "with :first" do
|
245
|
+
should "work" do
|
246
|
+
@project1.statuses.find(:first, :order => 'name').should == @complete
|
247
|
+
end
|
248
|
+
|
249
|
+
should "work with conditions" do
|
250
|
+
status = @project1.statuses.find(:first, :conditions => {:name => 'Complete'})
|
251
|
+
status.should == @complete
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
255
|
+
context "with #first" do
|
256
|
+
should "work" do
|
257
|
+
@project1.statuses.first(:order => 'name').should == @complete
|
258
|
+
end
|
259
|
+
|
260
|
+
should "work with conditions" do
|
261
|
+
status = @project1.statuses.first(:conditions => {:name => 'Complete'})
|
262
|
+
status.should == @complete
|
263
|
+
end
|
264
|
+
end
|
265
|
+
|
266
|
+
context "with :last" do
|
267
|
+
should "work" do
|
268
|
+
@project1.statuses.find(:last, :order => "position asc").should == @complete
|
269
|
+
end
|
270
|
+
|
271
|
+
should "work with conditions" do
|
272
|
+
status = @project1.statuses.find(:last, :conditions => {:name => 'New'})
|
273
|
+
status.should == @brand_new
|
274
|
+
end
|
275
|
+
end
|
276
|
+
|
277
|
+
context "with #last" do
|
278
|
+
should "work" do
|
279
|
+
@project1.statuses.last(:order => "position asc").should == @complete
|
280
|
+
end
|
281
|
+
|
282
|
+
should "work with conditions" do
|
283
|
+
status = @project1.statuses.last(:conditions => {:name => 'New'})
|
284
|
+
status.should == @brand_new
|
285
|
+
end
|
286
|
+
end
|
287
|
+
|
288
|
+
context "with one id" do
|
289
|
+
should "work for id in association" do
|
290
|
+
@project1.statuses.find(@complete.id).should == @complete
|
291
|
+
end
|
292
|
+
|
293
|
+
should "not work for id not in association" do
|
294
|
+
lambda {
|
295
|
+
@project1.statuses.find(@archived.id)
|
296
|
+
}.should raise_error(MongoMapper::DocumentNotFound)
|
297
|
+
end
|
298
|
+
end
|
299
|
+
|
300
|
+
context "with multiple ids" do
|
301
|
+
should "work for ids in association" do
|
302
|
+
statuses = @project1.statuses.find(@brand_new.id, @complete.id)
|
303
|
+
statuses.should == [@brand_new, @complete]
|
304
|
+
end
|
305
|
+
|
306
|
+
should "not work for ids not in association" do
|
307
|
+
lambda {
|
308
|
+
@project1.statuses.find(@brand_new.id, @complete.id, @archived.id)
|
309
|
+
}.should raise_error(MongoMapper::DocumentNotFound)
|
310
|
+
end
|
311
|
+
end
|
312
|
+
|
313
|
+
context "with #paginate" do
|
314
|
+
setup do
|
315
|
+
@statuses = @project2.statuses.paginate(:per_page => 2, :page => 1, :order => 'name asc')
|
316
|
+
end
|
317
|
+
|
318
|
+
should "return total pages" do
|
319
|
+
@statuses.total_pages.should == 2
|
320
|
+
end
|
321
|
+
|
322
|
+
should "return total entries" do
|
323
|
+
@statuses.total_entries.should == 3
|
324
|
+
end
|
325
|
+
|
326
|
+
should "return the subject" do
|
327
|
+
@statuses.collect(&:name).should == %w(Archived Complete)
|
328
|
+
end
|
329
|
+
end
|
330
|
+
end
|
331
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'models'
|
3
|
+
|
4
|
+
class AssociationsTest < Test::Unit::TestCase
|
5
|
+
def setup
|
6
|
+
clear_all_collections
|
7
|
+
end
|
8
|
+
|
9
|
+
should "allow changing class names" do
|
10
|
+
class AwesomeUser
|
11
|
+
include MongoMapper::Document
|
12
|
+
|
13
|
+
many :posts, :class_name => 'AssociationsTest::AwesomePost', :foreign_key => :creator_id
|
14
|
+
end
|
15
|
+
AwesomeUser.collection.clear
|
16
|
+
|
17
|
+
class AwesomeTag
|
18
|
+
include MongoMapper::EmbeddedDocument
|
19
|
+
|
20
|
+
key :name, String
|
21
|
+
key :post_id, String
|
22
|
+
|
23
|
+
belongs_to :post, :class_name => 'AssociationsTest::AwesomeUser'
|
24
|
+
end
|
25
|
+
|
26
|
+
class AwesomePost
|
27
|
+
include MongoMapper::Document
|
28
|
+
|
29
|
+
key :creator_id, String
|
30
|
+
|
31
|
+
belongs_to :creator, :class_name => 'AssociationsTest::AwesomeUser'
|
32
|
+
many :tags, :class_name => 'AssociationsTest::AwesomeTag', :foreign_key => :post_id
|
33
|
+
end
|
34
|
+
|
35
|
+
AwesomeUser.collection.clear
|
36
|
+
AwesomePost.collection.clear
|
37
|
+
|
38
|
+
user = AwesomeUser.create
|
39
|
+
tag1 = AwesomeTag.new(:name => 'awesome')
|
40
|
+
tag2 = AwesomeTag.new(:name => 'grand')
|
41
|
+
post1 = AwesomePost.create(:creator => user, :tags => [tag1])
|
42
|
+
post2 = AwesomePost.create(:creator => user, :tags => [tag2])
|
43
|
+
user.posts.should == [post1, post2]
|
44
|
+
|
45
|
+
post1_from_db = AwesomePost.find(post1.id)
|
46
|
+
post1_from_db.tags.should == [tag1]
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class BinaryTest < Test::Unit::TestCase
|
4
|
+
should "serialize and deserialize correctly" do
|
5
|
+
klass = Class.new do
|
6
|
+
include MongoMapper::Document
|
7
|
+
set_collection_name 'test'
|
8
|
+
key :contents, Binary
|
9
|
+
end
|
10
|
+
klass.collection.clear
|
11
|
+
|
12
|
+
doc = klass.new(:contents => '010101')
|
13
|
+
doc.save
|
14
|
+
|
15
|
+
doc = klass.find(doc.id)
|
16
|
+
doc.contents.to_s.should == ByteBuffer.new('010101').to_s
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class CallbacksTest < Test::Unit::TestCase
|
4
|
+
context "Defining and running callbacks" do
|
5
|
+
setup do
|
6
|
+
@document = Class.new do
|
7
|
+
include MongoMapper::Document
|
8
|
+
set_collection_name 'test'
|
9
|
+
|
10
|
+
key :name, String
|
11
|
+
|
12
|
+
[ :before_validation_on_create, :before_validation_on_update,
|
13
|
+
:before_validation, :after_validation,
|
14
|
+
:before_create, :after_create,
|
15
|
+
:before_update, :after_update,
|
16
|
+
:before_save, :after_save,
|
17
|
+
:before_destroy, :after_destroy].each do |callback|
|
18
|
+
callback_method = "#{callback}_callback"
|
19
|
+
send(callback, callback_method)
|
20
|
+
define_method(callback_method) do
|
21
|
+
history << callback.to_sym
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def history
|
26
|
+
@history ||= []
|
27
|
+
end
|
28
|
+
|
29
|
+
def clear_history
|
30
|
+
@history = nil
|
31
|
+
end
|
32
|
+
end
|
33
|
+
@document.collection.clear
|
34
|
+
end
|
35
|
+
|
36
|
+
should "get the order right for creating documents" do
|
37
|
+
doc = @document.create(:name => 'John Nunemaker')
|
38
|
+
doc.history.should == [:before_validation, :before_validation_on_create, :after_validation, :before_save, :before_create, :after_create, :after_save]
|
39
|
+
end
|
40
|
+
|
41
|
+
should "get the order right for updating documents" do
|
42
|
+
doc = @document.create(:name => 'John Nunemaker')
|
43
|
+
doc.clear_history
|
44
|
+
doc.name = 'John'
|
45
|
+
doc.save
|
46
|
+
doc.history.should == [:before_validation, :before_validation_on_update, :after_validation, :before_save, :before_update, :after_update, :after_save]
|
47
|
+
end
|
48
|
+
|
49
|
+
should "work for before and after validation" do
|
50
|
+
doc = @document.new(:name => 'John Nunemaker')
|
51
|
+
doc.valid?
|
52
|
+
doc.history.should include(:before_validation)
|
53
|
+
doc.history.should include(:after_validation)
|
54
|
+
end
|
55
|
+
|
56
|
+
should "work for before and after create" do
|
57
|
+
doc = @document.create(:name => 'John Nunemaker')
|
58
|
+
doc.history.should include(:before_create)
|
59
|
+
doc.history.should include(:after_create)
|
60
|
+
end
|
61
|
+
|
62
|
+
should "work for before and after update" do
|
63
|
+
doc = @document.create(:name => 'John Nunemaker')
|
64
|
+
doc.name = 'John Doe'
|
65
|
+
doc.save
|
66
|
+
doc.history.should include(:before_update)
|
67
|
+
doc.history.should include(:after_update)
|
68
|
+
end
|
69
|
+
|
70
|
+
should "work for before and after save" do
|
71
|
+
doc = @document.new
|
72
|
+
doc.name = 'John Doe'
|
73
|
+
doc.save
|
74
|
+
doc.history.should include(:before_save)
|
75
|
+
doc.history.should include(:after_save)
|
76
|
+
end
|
77
|
+
|
78
|
+
should "work for before and after destroy" do
|
79
|
+
doc = @document.create(:name => 'John Nunemaker')
|
80
|
+
doc.destroy
|
81
|
+
doc.history.should include(:before_destroy)
|
82
|
+
doc.history.should include(:after_destroy)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|