jnunemaker-mongomapper 0.3.2 → 0.3.3
Sign up to get free protection for your applications and to get access to all the features.
- data/History +10 -0
- data/Rakefile +5 -3
- data/VERSION +1 -1
- data/lib/mongomapper/associations/belongs_to_polymorphic_proxy.rb +3 -1
- data/lib/mongomapper/associations/belongs_to_proxy.rb +2 -2
- data/lib/mongomapper/associations/many_documents_proxy.rb +32 -14
- data/lib/mongomapper/associations/proxy.rb +2 -6
- data/lib/mongomapper/associations.rb +44 -9
- data/lib/mongomapper/document.rb +142 -89
- data/lib/mongomapper/dynamic_finder.rb +38 -0
- data/lib/mongomapper/embedded_document.rb +102 -85
- data/lib/mongomapper/finder_options.rb +3 -14
- data/lib/mongomapper/key.rb +10 -15
- data/lib/mongomapper/support.rb +30 -0
- data/lib/mongomapper.rb +4 -31
- data/mongomapper.gemspec +12 -10
- data/test/functional/associations/test_belongs_to_polymorphic_proxy.rb +14 -0
- data/test/functional/associations/test_belongs_to_proxy.rb +10 -0
- data/test/functional/associations/test_many_proxy.rb +63 -4
- data/test/functional/test_document.rb +371 -120
- data/test/functional/test_rails_compatibility.rb +2 -3
- data/test/models.rb +10 -6
- data/test/unit/serializers/test_json_serializer.rb +1 -1
- data/test/unit/test_document.rb +7 -1
- data/test/unit/test_embedded_document.rb +115 -24
- data/test/unit/test_finder_options.rb +7 -38
- data/test/unit/test_key.rb +46 -23
- metadata +7 -7
- data/test/unit/test_mongo_id.rb +0 -35
@@ -11,16 +11,48 @@ class DocumentTest < Test::Unit::TestCase
|
|
11
11
|
key :last_name, String
|
12
12
|
key :age, Integer
|
13
13
|
end
|
14
|
-
|
14
|
+
|
15
15
|
@document.collection.clear
|
16
16
|
end
|
17
|
+
|
18
|
+
context "Saving a document with a custom id" do
|
19
|
+
should "clear custom id flag when saved" do
|
20
|
+
doc = @document.new(:id => '1234')
|
21
|
+
doc.using_custom_id?.should be_true
|
22
|
+
doc.save.should be_true
|
23
|
+
doc.using_custom_id?.should be_false
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context "Loading a document from the database with keys that are not defined" do
|
28
|
+
setup do
|
29
|
+
@id = XGen::Mongo::Driver::ObjectID.new.to_s
|
30
|
+
@document.collection.insert({
|
31
|
+
:_id => @id,
|
32
|
+
:first_name => 'John',
|
33
|
+
:last_name => 'Nunemaker',
|
34
|
+
:age => 27,
|
35
|
+
:favorite_color => 'red',
|
36
|
+
:skills => ['ruby', 'rails', 'javascript', 'xhtml', 'css']
|
37
|
+
})
|
38
|
+
end
|
39
|
+
|
40
|
+
should "assign all keys from database" do
|
41
|
+
doc = @document.find(@id)
|
42
|
+
doc.first_name.should == 'John'
|
43
|
+
doc.last_name.should == 'Nunemaker'
|
44
|
+
doc.age.should == 27
|
45
|
+
doc.favorite_color.should == 'red'
|
46
|
+
doc.skills.should == ['ruby', 'rails', 'javascript', 'xhtml', 'css']
|
47
|
+
end
|
48
|
+
end
|
17
49
|
|
18
50
|
context "Document Class Methods" do
|
19
51
|
context "Using key with type Array" do
|
20
52
|
setup do
|
21
53
|
@document.key :tags, Array
|
22
54
|
end
|
23
|
-
|
55
|
+
|
24
56
|
should "give correct default" do
|
25
57
|
doc = @document.new
|
26
58
|
doc.tags.should == []
|
@@ -53,7 +85,7 @@ class DocumentTest < Test::Unit::TestCase
|
|
53
85
|
doc.tags.should == ["foo"]
|
54
86
|
end
|
55
87
|
|
56
|
-
|
88
|
+
should "work with << then save" do
|
57
89
|
doc = @document.new
|
58
90
|
doc.tags << "foo"
|
59
91
|
doc.tags << "bar"
|
@@ -62,7 +94,7 @@ class DocumentTest < Test::Unit::TestCase
|
|
62
94
|
@document.find(doc.id).tags.should == %w(foo bar)
|
63
95
|
end
|
64
96
|
end
|
65
|
-
|
97
|
+
|
66
98
|
context "Using key with type Hash" do
|
67
99
|
setup do
|
68
100
|
@document.key :foo, Hash
|
@@ -72,14 +104,14 @@ class DocumentTest < Test::Unit::TestCase
|
|
72
104
|
doc = @document.new
|
73
105
|
doc.foo.should == {}
|
74
106
|
end
|
75
|
-
|
107
|
+
|
76
108
|
should "work with []=" do
|
77
109
|
doc = @document.new
|
78
110
|
doc.foo["quux"] = "bar"
|
79
111
|
doc.foo["quux"].should == "bar"
|
80
112
|
doc.foo.should == { "quux" => "bar" }
|
81
113
|
end
|
82
|
-
|
114
|
+
|
83
115
|
should "work with indifferent access" do
|
84
116
|
doc = @document.new
|
85
117
|
doc.foo = {:baz => 'bar'}
|
@@ -91,47 +123,51 @@ class DocumentTest < Test::Unit::TestCase
|
|
91
123
|
doc = @document.new
|
92
124
|
doc.foo = {:baz => 'bar'}
|
93
125
|
doc.save
|
94
|
-
|
126
|
+
|
95
127
|
doc = @document.find(doc.id)
|
96
128
|
doc.foo[:baz].should == 'bar'
|
97
129
|
doc.foo['baz'].should == 'bar'
|
98
130
|
end
|
99
131
|
end
|
100
|
-
|
132
|
+
|
101
133
|
context "Saving a document with an embedded document" do
|
102
134
|
setup do
|
103
135
|
@document.class_eval do
|
104
136
|
key :foo, Address
|
105
137
|
end
|
106
138
|
end
|
107
|
-
|
139
|
+
|
108
140
|
should "embed embedded document" do
|
109
141
|
address = Address.new(:city => 'South Bend', :state => 'IN')
|
110
142
|
doc = @document.new(:foo => address)
|
111
143
|
doc.save
|
112
144
|
doc.foo.city.should == 'South Bend'
|
113
145
|
doc.foo.state.should == 'IN'
|
114
|
-
|
146
|
+
|
115
147
|
from_db = @document.find(doc.id)
|
116
148
|
from_db.foo.city.should == 'South Bend'
|
117
149
|
from_db.foo.state.should == 'IN'
|
118
150
|
end
|
119
151
|
end
|
120
|
-
|
152
|
+
|
121
153
|
context "Creating a single document" do
|
122
154
|
setup do
|
123
155
|
@doc_instance = @document.create({:first_name => 'John', :last_name => 'Nunemaker', :age => '27'})
|
124
156
|
end
|
125
|
-
|
157
|
+
|
126
158
|
should "create a document in correct collection" do
|
127
159
|
@document.count.should == 1
|
128
160
|
end
|
129
|
-
|
161
|
+
|
130
162
|
should "automatically set id" do
|
131
163
|
@doc_instance.id.should_not be_nil
|
132
164
|
@doc_instance.id.size.should == 24
|
133
165
|
end
|
134
|
-
|
166
|
+
|
167
|
+
should "no longer be new?" do
|
168
|
+
@doc_instance.new?.should be_false
|
169
|
+
end
|
170
|
+
|
135
171
|
should "return instance of document" do
|
136
172
|
@doc_instance.should be_instance_of(@document)
|
137
173
|
@doc_instance.first_name.should == 'John'
|
@@ -139,7 +175,7 @@ class DocumentTest < Test::Unit::TestCase
|
|
139
175
|
@doc_instance.age.should == 27
|
140
176
|
end
|
141
177
|
end
|
142
|
-
|
178
|
+
|
143
179
|
context "Creating a document with no attributes provided" do
|
144
180
|
setup do
|
145
181
|
@document = Class.new do
|
@@ -147,14 +183,14 @@ class DocumentTest < Test::Unit::TestCase
|
|
147
183
|
end
|
148
184
|
@document.collection.clear
|
149
185
|
end
|
150
|
-
|
186
|
+
|
151
187
|
should "create the document" do
|
152
188
|
lambda {
|
153
189
|
@document.create
|
154
190
|
}.should change { @document.count }.by(1)
|
155
191
|
end
|
156
192
|
end
|
157
|
-
|
193
|
+
|
158
194
|
context "Creating multiple documents" do
|
159
195
|
setup do
|
160
196
|
@doc_instances = @document.create([
|
@@ -162,396 +198,579 @@ class DocumentTest < Test::Unit::TestCase
|
|
162
198
|
{:first_name => 'Steve', :last_name => 'Smith', :age => '28'},
|
163
199
|
])
|
164
200
|
end
|
165
|
-
|
201
|
+
|
166
202
|
should "create multiple documents" do
|
167
203
|
@document.count.should == 2
|
168
204
|
end
|
169
|
-
|
205
|
+
|
170
206
|
should "return an array of doc instances" do
|
171
207
|
@doc_instances.map do |doc_instance|
|
172
208
|
doc_instance.should be_instance_of(@document)
|
173
209
|
end
|
174
210
|
end
|
175
211
|
end
|
176
|
-
|
212
|
+
|
177
213
|
context "Updating a document" do
|
178
214
|
setup do
|
179
215
|
doc = @document.create({:first_name => 'John', :last_name => 'Nunemaker', :age => '27'})
|
180
216
|
@doc_instance = @document.update(doc.id, {:age => 40})
|
181
217
|
end
|
182
|
-
|
218
|
+
|
183
219
|
should "update attributes provided" do
|
184
220
|
@doc_instance.age.should == 40
|
185
221
|
end
|
186
|
-
|
222
|
+
|
187
223
|
should "not update existing attributes that were not set to update" do
|
188
224
|
@doc_instance.first_name.should == 'John'
|
189
225
|
@doc_instance.last_name.should == 'Nunemaker'
|
190
226
|
end
|
191
|
-
|
227
|
+
|
192
228
|
should "not create new document" do
|
193
229
|
@document.count.should == 1
|
194
230
|
end
|
195
231
|
end
|
196
|
-
|
232
|
+
|
197
233
|
should "raise error when updating single doc if not provided id and attributes" do
|
198
234
|
doc = @document.create({:first_name => 'John', :last_name => 'Nunemaker', :age => '27'})
|
199
235
|
lambda { @document.update }.should raise_error(ArgumentError)
|
200
236
|
lambda { @document.update(doc.id) }.should raise_error(ArgumentError)
|
201
237
|
lambda { @document.update(doc.id, [1]) }.should raise_error(ArgumentError)
|
202
238
|
end
|
203
|
-
|
239
|
+
|
204
240
|
context "Updating multiple documents" do
|
205
241
|
setup do
|
206
242
|
@doc1 = @document.create({:first_name => 'John', :last_name => 'Nunemaker', :age => '27'})
|
207
243
|
@doc2 = @document.create({:first_name => 'Steve', :last_name => 'Smith', :age => '28'})
|
208
|
-
|
244
|
+
|
209
245
|
@doc_instances = @document.update({
|
210
246
|
@doc1.id => {:age => 30},
|
211
247
|
@doc2.id => {:age => 30},
|
212
248
|
})
|
213
249
|
end
|
214
|
-
|
250
|
+
|
215
251
|
should "not create any new documents" do
|
216
252
|
@document.count.should == 2
|
217
253
|
end
|
218
|
-
|
254
|
+
|
219
255
|
should "should return an array of doc instances" do
|
220
256
|
@doc_instances.map do |doc_instance|
|
221
257
|
doc_instance.should be_instance_of(@document)
|
222
258
|
end
|
223
259
|
end
|
224
|
-
|
260
|
+
|
225
261
|
should "update the documents" do
|
226
262
|
@document.find(@doc1.id).age.should == 30
|
227
263
|
@document.find(@doc2.id).age.should == 30
|
228
264
|
end
|
229
265
|
end
|
230
|
-
|
266
|
+
|
231
267
|
should "raise error when updating multiple documents if not a hash" do
|
232
268
|
lambda { @document.update([1, 2]) }.should raise_error(ArgumentError)
|
233
269
|
end
|
234
|
-
|
270
|
+
|
235
271
|
context "Finding documents" do
|
236
272
|
setup do
|
237
273
|
@doc1 = @document.create({:first_name => 'John', :last_name => 'Nunemaker', :age => '27'})
|
238
274
|
@doc2 = @document.create({:first_name => 'Steve', :last_name => 'Smith', :age => '28'})
|
239
275
|
@doc3 = @document.create({:first_name => 'Steph', :last_name => 'Nunemaker', :age => '26'})
|
240
276
|
end
|
241
|
-
|
277
|
+
|
242
278
|
should "raise document not found if nothing provided" do
|
243
279
|
lambda { @document.find }.should raise_error(MongoMapper::DocumentNotFound)
|
244
280
|
end
|
245
|
-
|
281
|
+
|
246
282
|
context "with a single id" do
|
247
283
|
should "work" do
|
248
284
|
@document.find(@doc1.id).should == @doc1
|
249
285
|
end
|
250
|
-
|
286
|
+
|
251
287
|
should "raise error if document not found" do
|
252
|
-
lambda { @document.find(
|
253
|
-
end
|
254
|
-
|
255
|
-
should "raise error if id is illegal" do
|
256
|
-
lambda { @document.find(1) }.should raise_error(MongoMapper::IllegalID)
|
288
|
+
lambda { @document.find(123) }.should raise_error(MongoMapper::DocumentNotFound)
|
257
289
|
end
|
258
290
|
end
|
259
|
-
|
291
|
+
|
260
292
|
context "with multiple id's" do
|
261
293
|
should "work as arguments" do
|
262
294
|
@document.find(@doc1.id, @doc2.id).should == [@doc1, @doc2]
|
263
295
|
end
|
264
|
-
|
296
|
+
|
265
297
|
should "work as array" do
|
266
298
|
@document.find([@doc1.id, @doc2.id]).should == [@doc1, @doc2]
|
267
299
|
end
|
268
300
|
end
|
269
|
-
|
301
|
+
|
270
302
|
context "with :all" do
|
271
303
|
should "find all documents" do
|
272
304
|
@document.find(:all, :order => 'first_name').should == [@doc1, @doc3, @doc2]
|
273
305
|
end
|
274
|
-
|
306
|
+
|
275
307
|
should "be able to add conditions" do
|
276
308
|
@document.find(:all, :conditions => {:first_name => 'John'}).should == [@doc1]
|
277
309
|
end
|
278
310
|
end
|
279
|
-
|
311
|
+
|
280
312
|
context "with #all" do
|
281
313
|
should "find all documents based on criteria" do
|
282
314
|
@document.all(:order => 'first_name').should == [@doc1, @doc3, @doc2]
|
283
|
-
@document.all(:conditions => {:last_name => 'Nunemaker'}).should == [@doc1, @doc3]
|
315
|
+
@document.all(:conditions => {:last_name => 'Nunemaker'}, :order => 'age desc').should == [@doc1, @doc3]
|
284
316
|
end
|
285
317
|
end
|
286
|
-
|
318
|
+
|
287
319
|
context "with :first" do
|
288
320
|
should "find first document" do
|
289
321
|
@document.find(:first, :order => 'first_name').should == @doc1
|
290
322
|
end
|
291
323
|
end
|
292
|
-
|
324
|
+
|
293
325
|
context "with #first" do
|
294
326
|
should "find first document based on criteria" do
|
295
327
|
@document.first(:order => 'first_name').should == @doc1
|
296
328
|
@document.first(:conditions => {:age => 28}).should == @doc2
|
297
329
|
end
|
298
330
|
end
|
299
|
-
|
331
|
+
|
300
332
|
context "with :last" do
|
301
333
|
should "find last document" do
|
302
|
-
@document.find(:last).should == @
|
334
|
+
@document.find(:last, :order => 'age desc').should == @doc2
|
303
335
|
end
|
304
336
|
end
|
305
|
-
|
337
|
+
|
306
338
|
context "with #last" do
|
307
339
|
should "find last document based on criteria" do
|
308
|
-
@document.last.should == @
|
340
|
+
@document.last(:order => 'age desc').should == @doc2
|
309
341
|
@document.last(:conditions => {:age => 28}).should == @doc2
|
310
342
|
end
|
311
343
|
end
|
344
|
+
|
345
|
+
context "with :find_by" do
|
346
|
+
should "find document based on argument" do
|
347
|
+
@document.find_by_first_name('John').should == @doc1
|
348
|
+
@document.find_by_last_name('Nunemaker', :order => 'age desc').should == @doc1
|
349
|
+
@document.find_by_age(27).should == @doc1
|
350
|
+
end
|
351
|
+
|
352
|
+
should "not raise error" do
|
353
|
+
@document.find_by_first_name('Mongo').should be_nil
|
354
|
+
end
|
355
|
+
|
356
|
+
should "define a method for each key" do
|
357
|
+
@document.methods(false).select { |e| e =~ /^find_by_/ }.size == @document.keys.size
|
358
|
+
end
|
359
|
+
end
|
360
|
+
|
361
|
+
context "with dynamic finders" do
|
362
|
+
should "find document based on all arguments" do
|
363
|
+
@document.find_by_first_name_and_last_name_and_age('John', 'Nunemaker', 27).should == @doc1
|
364
|
+
end
|
365
|
+
|
366
|
+
should "not find the document if an argument is wrong" do
|
367
|
+
@document.find_by_first_name_and_last_name_and_age('John', 'Nunemaker', 28).should be_nil
|
368
|
+
end
|
369
|
+
|
370
|
+
should "find all documents based on arguments" do
|
371
|
+
docs = @document.find_all_by_last_name('Nunemaker')
|
372
|
+
docs.should be_kind_of(Array)
|
373
|
+
docs.should include(@doc1)
|
374
|
+
docs.should include(@doc3)
|
375
|
+
end
|
376
|
+
|
377
|
+
should "find last document based on arguments" do
|
378
|
+
doc = @document.find_last_by_last_name('Nunemaker', :order => 'age desc')
|
379
|
+
doc.should == @doc1
|
380
|
+
end
|
381
|
+
|
382
|
+
should "initialize document with given arguments" do
|
383
|
+
doc = @document.find_or_initialize_by_first_name_and_last_name('David', 'Cuadrado')
|
384
|
+
doc.should be_new
|
385
|
+
doc.first_name.should == 'David'
|
386
|
+
end
|
387
|
+
|
388
|
+
should "not initialize document if document is found" do
|
389
|
+
doc = @document.find_or_initialize_by_first_name('John')
|
390
|
+
doc.should_not be_new
|
391
|
+
end
|
392
|
+
|
393
|
+
should "create document with given arguments" do
|
394
|
+
doc = @document.find_or_create_by_first_name_and_last_name('David', 'Cuadrado')
|
395
|
+
doc.should_not be_new
|
396
|
+
doc.first_name.should == 'David'
|
397
|
+
end
|
398
|
+
|
399
|
+
should "raise error if document is not found" do
|
400
|
+
lambda {@document.find_by_first_name_and_last_name!(1,2)}.should raise_error(MongoMapper::DocumentNotFound)
|
401
|
+
end
|
402
|
+
end
|
312
403
|
end # finding documents
|
313
|
-
|
404
|
+
|
314
405
|
context "Finding document by id" do
|
315
406
|
setup do
|
316
407
|
@doc1 = @document.create({:first_name => 'John', :last_name => 'Nunemaker', :age => '27'})
|
317
408
|
@doc2 = @document.create({:first_name => 'Steve', :last_name => 'Smith', :age => '28'})
|
318
409
|
end
|
319
|
-
|
410
|
+
|
320
411
|
should "be able to find by id" do
|
321
412
|
@document.find_by_id(@doc1.id).should == @doc1
|
322
413
|
@document.find_by_id(@doc2.id).should == @doc2
|
323
414
|
end
|
324
|
-
|
415
|
+
|
325
416
|
should "return nil if document not found" do
|
326
|
-
@document.find_by_id(
|
417
|
+
@document.find_by_id(1234).should be(nil)
|
327
418
|
end
|
328
419
|
end
|
329
|
-
|
420
|
+
|
330
421
|
context "Deleting a document" do
|
331
422
|
setup do
|
332
423
|
@doc1 = @document.create({:first_name => 'John', :last_name => 'Nunemaker', :age => '27'})
|
333
424
|
@doc2 = @document.create({:first_name => 'Steve', :last_name => 'Smith', :age => '28'})
|
334
425
|
@document.delete(@doc1.id)
|
335
426
|
end
|
336
|
-
|
427
|
+
|
337
428
|
should "remove document from collection" do
|
338
429
|
@document.count.should == 1
|
339
430
|
end
|
340
|
-
|
431
|
+
|
341
432
|
should "not remove other documents" do
|
342
433
|
@document.find(@doc2.id).should_not be(nil)
|
343
434
|
end
|
344
435
|
end
|
345
|
-
|
436
|
+
|
346
437
|
context "Deleting multiple documents" do
|
347
438
|
should "work with multiple arguments" do
|
348
439
|
@doc1 = @document.create({:first_name => 'John', :last_name => 'Nunemaker', :age => '27'})
|
349
440
|
@doc2 = @document.create({:first_name => 'Steve', :last_name => 'Smith', :age => '28'})
|
350
441
|
@doc3 = @document.create({:first_name => 'Steph', :last_name => 'Nunemaker', :age => '26'})
|
351
442
|
@document.delete(@doc1.id, @doc2.id)
|
352
|
-
|
443
|
+
|
353
444
|
@document.count.should == 1
|
354
445
|
end
|
355
|
-
|
446
|
+
|
356
447
|
should "work with array as argument" do
|
357
448
|
@doc1 = @document.create({:first_name => 'John', :last_name => 'Nunemaker', :age => '27'})
|
358
449
|
@doc2 = @document.create({:first_name => 'Steve', :last_name => 'Smith', :age => '28'})
|
359
450
|
@doc3 = @document.create({:first_name => 'Steph', :last_name => 'Nunemaker', :age => '26'})
|
360
451
|
@document.delete([@doc1.id, @doc2.id])
|
361
|
-
|
452
|
+
|
362
453
|
@document.count.should == 1
|
363
454
|
end
|
364
455
|
end
|
365
|
-
|
456
|
+
|
366
457
|
context "Deleting all documents" do
|
367
458
|
setup do
|
368
459
|
@doc1 = @document.create({:first_name => 'John', :last_name => 'Nunemaker', :age => '27'})
|
369
460
|
@doc2 = @document.create({:first_name => 'Steve', :last_name => 'Smith', :age => '28'})
|
370
461
|
@doc3 = @document.create({:first_name => 'Steph', :last_name => 'Nunemaker', :age => '26'})
|
371
462
|
end
|
372
|
-
|
463
|
+
|
373
464
|
should "remove all documents when given no conditions" do
|
374
465
|
@document.delete_all
|
375
466
|
@document.count.should == 0
|
376
467
|
end
|
377
|
-
|
468
|
+
|
378
469
|
should "only remove matching documents when given conditions" do
|
379
470
|
@document.delete_all({:first_name => 'John'})
|
380
471
|
@document.count.should == 2
|
381
472
|
end
|
382
|
-
|
473
|
+
|
383
474
|
should "convert the conditions to mongo criteria" do
|
384
475
|
@document.delete_all(:age => [26, 27])
|
385
476
|
@document.count.should == 1
|
386
477
|
end
|
387
478
|
end
|
388
|
-
|
479
|
+
|
389
480
|
context "Destroying a document" do
|
390
481
|
setup do
|
391
482
|
@doc1 = @document.create({:first_name => 'John', :last_name => 'Nunemaker', :age => '27'})
|
392
483
|
@doc2 = @document.create({:first_name => 'Steve', :last_name => 'Smith', :age => '28'})
|
393
484
|
@document.destroy(@doc1.id)
|
394
485
|
end
|
395
|
-
|
486
|
+
|
396
487
|
should "remove document from collection" do
|
397
488
|
@document.count.should == 1
|
398
489
|
end
|
399
|
-
|
490
|
+
|
400
491
|
should "not remove other documents" do
|
401
492
|
@document.find(@doc2.id).should_not be(nil)
|
402
493
|
end
|
403
494
|
end
|
404
|
-
|
495
|
+
|
405
496
|
context "Destroying multiple documents" do
|
406
497
|
should "work with multiple arguments" do
|
407
498
|
@doc1 = @document.create({:first_name => 'John', :last_name => 'Nunemaker', :age => '27'})
|
408
499
|
@doc2 = @document.create({:first_name => 'Steve', :last_name => 'Smith', :age => '28'})
|
409
500
|
@doc3 = @document.create({:first_name => 'Steph', :last_name => 'Nunemaker', :age => '26'})
|
410
501
|
@document.destroy(@doc1.id, @doc2.id)
|
411
|
-
|
502
|
+
|
412
503
|
@document.count.should == 1
|
413
504
|
end
|
414
|
-
|
505
|
+
|
415
506
|
should "work with array as argument" do
|
416
507
|
@doc1 = @document.create({:first_name => 'John', :last_name => 'Nunemaker', :age => '27'})
|
417
508
|
@doc2 = @document.create({:first_name => 'Steve', :last_name => 'Smith', :age => '28'})
|
418
509
|
@doc3 = @document.create({:first_name => 'Steph', :last_name => 'Nunemaker', :age => '26'})
|
419
510
|
@document.destroy([@doc1.id, @doc2.id])
|
420
|
-
|
511
|
+
|
421
512
|
@document.count.should == 1
|
422
513
|
end
|
423
514
|
end
|
424
|
-
|
515
|
+
|
425
516
|
context "Destroying all documents" do
|
426
517
|
setup do
|
427
518
|
@doc1 = @document.create({:first_name => 'John', :last_name => 'Nunemaker', :age => '27'})
|
428
519
|
@doc2 = @document.create({:first_name => 'Steve', :last_name => 'Smith', :age => '28'})
|
429
520
|
@doc3 = @document.create({:first_name => 'Steph', :last_name => 'Nunemaker', :age => '26'})
|
430
521
|
end
|
431
|
-
|
522
|
+
|
432
523
|
should "remove all documents when given no conditions" do
|
433
524
|
@document.destroy_all
|
434
525
|
@document.count.should == 0
|
435
526
|
end
|
436
|
-
|
527
|
+
|
437
528
|
should "only remove matching documents when given conditions" do
|
438
529
|
@document.destroy_all(:first_name => 'John')
|
439
530
|
@document.count.should == 2
|
440
531
|
@document.destroy_all(:age => 26)
|
441
532
|
@document.count.should == 1
|
442
533
|
end
|
443
|
-
|
534
|
+
|
444
535
|
should "convert the conditions to mongo criteria" do
|
445
536
|
@document.destroy_all(:age => [26, 27])
|
446
537
|
@document.count.should == 1
|
447
538
|
end
|
448
539
|
end
|
449
|
-
|
540
|
+
|
541
|
+
context ":dependent" do
|
542
|
+
setup do
|
543
|
+
# FIXME: make use of already defined models
|
544
|
+
class ::Property
|
545
|
+
include MongoMapper::Document
|
546
|
+
end
|
547
|
+
Property.delete_all
|
548
|
+
|
549
|
+
class ::Thing
|
550
|
+
include MongoMapper::Document
|
551
|
+
key :name, String
|
552
|
+
end
|
553
|
+
Thing.delete_all
|
554
|
+
end
|
555
|
+
|
556
|
+
teardown do
|
557
|
+
Object.send :remove_const, 'Property' if defined?(::Property)
|
558
|
+
Object.send :remove_const, 'Thing' if defined?(::Thing)
|
559
|
+
end
|
560
|
+
|
561
|
+
context "many" do
|
562
|
+
context "=> destroy" do
|
563
|
+
setup do
|
564
|
+
Property.belongs_to :thing, :dependent => :destroy
|
565
|
+
Thing.many :properties, :dependent => :destroy
|
566
|
+
|
567
|
+
@thing = Thing.create(:name => "Tree")
|
568
|
+
@property1 = Property.create
|
569
|
+
@property2 = Property.create
|
570
|
+
@property3 = Property.create
|
571
|
+
@thing.properties << @property1
|
572
|
+
@thing.properties << @property2
|
573
|
+
@thing.properties << @property3
|
574
|
+
end
|
575
|
+
|
576
|
+
should "should destroy the associated documents" do
|
577
|
+
@thing.properties.count.should == 3
|
578
|
+
@thing.destroy
|
579
|
+
@thing.properties.count.should == 0
|
580
|
+
Property.count.should == 0
|
581
|
+
end
|
582
|
+
end
|
583
|
+
|
584
|
+
context "=> delete_all" do
|
585
|
+
setup do
|
586
|
+
Property.belongs_to :thing
|
587
|
+
Thing.has_many :properties, :dependent => :delete_all
|
588
|
+
|
589
|
+
@thing = Thing.create(:name => "Tree")
|
590
|
+
@property1 = Property.create
|
591
|
+
@property2 = Property.create
|
592
|
+
@property3 = Property.create
|
593
|
+
@thing.properties << @property1
|
594
|
+
@thing.properties << @property2
|
595
|
+
@thing.properties << @property3
|
596
|
+
end
|
597
|
+
|
598
|
+
should "should delete associated documents" do
|
599
|
+
@thing.properties.count.should == 3
|
600
|
+
@thing.destroy
|
601
|
+
@thing.properties.count.should == 0
|
602
|
+
Property.count.should == 0
|
603
|
+
end
|
604
|
+
end
|
605
|
+
|
606
|
+
context "=> nullify" do
|
607
|
+
setup do
|
608
|
+
Property.belongs_to :thing
|
609
|
+
Thing.has_many :properties, :dependent => :nullify
|
610
|
+
|
611
|
+
@thing = Thing.create(:name => "Tree")
|
612
|
+
@property1 = Property.create
|
613
|
+
@property2 = Property.create
|
614
|
+
@property3 = Property.create
|
615
|
+
@thing.properties << @property1
|
616
|
+
@thing.properties << @property2
|
617
|
+
@thing.properties << @property3
|
618
|
+
end
|
619
|
+
|
620
|
+
should "should nullify relationship but not destroy associated documents" do
|
621
|
+
@thing.properties.count.should == 3
|
622
|
+
@thing.destroy
|
623
|
+
@thing.properties.count.should == 0
|
624
|
+
Property.count.should == 3
|
625
|
+
end
|
626
|
+
end
|
627
|
+
end
|
628
|
+
|
629
|
+
context "belongs_to" do
|
630
|
+
context "=> destroy" do
|
631
|
+
setup do
|
632
|
+
Property.belongs_to :thing, :dependent => :destroy
|
633
|
+
Thing.has_many :properties
|
634
|
+
|
635
|
+
@thing = Thing.create(:name => "Tree")
|
636
|
+
@property1 = Property.create
|
637
|
+
@property2 = Property.create
|
638
|
+
@property3 = Property.create
|
639
|
+
@thing.properties << @property1
|
640
|
+
@thing.properties << @property2
|
641
|
+
@thing.properties << @property3
|
642
|
+
end
|
643
|
+
|
644
|
+
should "destroy the thing" do
|
645
|
+
Thing.count.should == 1
|
646
|
+
@property1.destroy
|
647
|
+
Thing.count.should == 0
|
648
|
+
@property1.thing.should be_frozen
|
649
|
+
end
|
650
|
+
end
|
651
|
+
end
|
652
|
+
end
|
653
|
+
|
450
654
|
context "Counting documents in collection" do
|
451
655
|
setup do
|
452
656
|
@doc1 = @document.create({:first_name => 'John', :last_name => 'Nunemaker', :age => '27'})
|
453
657
|
@doc2 = @document.create({:first_name => 'Steve', :last_name => 'Smith', :age => '28'})
|
454
658
|
@doc3 = @document.create({:first_name => 'Steph', :last_name => 'Nunemaker', :age => '26'})
|
455
659
|
end
|
456
|
-
|
660
|
+
|
457
661
|
should "count all with no arguments" do
|
458
662
|
@document.count.should == 3
|
459
663
|
end
|
460
|
-
|
664
|
+
|
461
665
|
should "return 0 if there are no documents in the collection" do
|
462
666
|
@document.delete_all
|
463
667
|
@document.count.should == 0
|
464
668
|
end
|
465
|
-
|
669
|
+
|
466
670
|
should "return 0 if the collection does not exist" do
|
467
671
|
klass = Class.new do
|
468
672
|
include MongoMapper::Document
|
469
673
|
collection 'foobarbazwickdoesnotexist'
|
470
674
|
end
|
471
|
-
|
675
|
+
|
472
676
|
klass.count.should == 0
|
473
677
|
end
|
474
|
-
|
678
|
+
|
475
679
|
should "return count for matching documents if conditions provided" do
|
476
680
|
@document.count(:age => 27).should == 1
|
477
681
|
end
|
478
|
-
|
682
|
+
|
479
683
|
should "convert the conditions to mongo criteria" do
|
480
684
|
@document.count(:age => [26, 27]).should == 2
|
481
685
|
end
|
482
686
|
end
|
483
|
-
|
687
|
+
|
484
688
|
context "Indexing" do
|
485
689
|
setup do
|
486
690
|
@document.collection.drop_indexes
|
487
691
|
end
|
488
|
-
|
692
|
+
|
489
693
|
should "allow creating index for a key" do
|
490
694
|
index_name = nil
|
491
695
|
lambda {
|
492
696
|
index_name = @document.ensure_index :first_name
|
493
697
|
}.should change { @document.collection.index_information.size }.by(1)
|
494
|
-
|
698
|
+
|
495
699
|
index_name.should == 'first_name_1'
|
496
700
|
index = @document.collection.index_information[index_name]
|
497
701
|
index.should_not be_nil
|
498
702
|
index.should include(['first_name', 1])
|
499
703
|
end
|
500
|
-
|
704
|
+
|
501
705
|
should "allow creating unique index for a key" do
|
502
706
|
@document.collection.expects(:create_index).with(:first_name, true)
|
503
707
|
@document.ensure_index :first_name, :unique => true
|
504
708
|
end
|
505
|
-
|
709
|
+
|
506
710
|
should "allow creating index on multiple keys" do
|
507
711
|
index_name = nil
|
508
712
|
lambda {
|
509
713
|
index_name = @document.ensure_index [[:first_name, 1], [:last_name, -1]]
|
510
714
|
}.should change { @document.collection.index_information.size }.by(1)
|
511
|
-
|
715
|
+
|
512
716
|
index_name.should == 'first_name_1_last_name_-1'
|
513
|
-
|
717
|
+
|
514
718
|
index = @document.collection.index_information[index_name]
|
515
719
|
index.should_not be_nil
|
516
720
|
index.should include(['first_name', 1])
|
517
721
|
index.should include(['last_name', -1])
|
518
722
|
end
|
519
|
-
|
723
|
+
|
520
724
|
should "work with :index shortcut when defining key" do
|
521
725
|
@document.expects(:ensure_index).with('father').returns(nil)
|
522
726
|
@document.key :father, String, :index => true
|
523
727
|
end
|
524
728
|
end
|
525
729
|
end # Document Class Methods
|
526
|
-
|
730
|
+
|
527
731
|
context "Saving a new document" do
|
528
732
|
setup do
|
529
733
|
@doc = @document.new(:first_name => 'John', :age => '27')
|
530
734
|
@doc.save
|
531
735
|
end
|
532
|
-
|
736
|
+
|
533
737
|
should "insert document into the collection" do
|
534
738
|
@document.count.should == 1
|
535
739
|
end
|
536
|
-
|
740
|
+
|
537
741
|
should "assign an id for the document" do
|
538
742
|
@doc.id.should_not be(nil)
|
539
743
|
@doc.id.size.should == 24
|
540
744
|
end
|
541
|
-
|
745
|
+
|
542
746
|
should "save attributes" do
|
543
747
|
@doc.first_name.should == 'John'
|
544
748
|
@doc.age.should == 27
|
545
749
|
end
|
546
|
-
|
750
|
+
|
547
751
|
should "update attributes in the database" do
|
548
752
|
from_db = @document.find(@doc.id)
|
549
753
|
from_db.should == @doc
|
550
754
|
from_db.first_name.should == 'John'
|
551
755
|
from_db.age.should == 27
|
552
756
|
end
|
757
|
+
|
758
|
+
should "allow to add custom attributes to the document" do
|
759
|
+
@doc = @document.new(:first_name => 'David', :age => '26', :gender => 'male', :tags => [1, "2"])
|
760
|
+
@doc.save
|
761
|
+
from_db = @document.find(@doc.id)
|
762
|
+
from_db.gender.should == 'male'
|
763
|
+
from_db.tags.should == [1, "2"]
|
764
|
+
end
|
765
|
+
|
766
|
+
should "allow to use custom methods to assign properties" do
|
767
|
+
person = RealPerson.new(:realname => "David")
|
768
|
+
person.save
|
769
|
+
from_db = RealPerson.find(person.id)
|
770
|
+
from_db.name.should == "David"
|
771
|
+
end
|
553
772
|
end
|
554
|
-
|
773
|
+
|
555
774
|
context "Saving an existing document" do
|
556
775
|
setup do
|
557
776
|
@doc = @document.create(:first_name => 'John', :age => '27')
|
@@ -559,66 +778,80 @@ class DocumentTest < Test::Unit::TestCase
|
|
559
778
|
@doc.age = 30
|
560
779
|
@doc.save
|
561
780
|
end
|
562
|
-
|
781
|
+
|
563
782
|
should "not insert document into collection" do
|
564
783
|
@document.count.should == 1
|
565
784
|
end
|
566
|
-
|
785
|
+
|
567
786
|
should "update attributes" do
|
568
787
|
@doc.first_name.should == 'Johnny'
|
569
788
|
@doc.age.should == 30
|
570
789
|
end
|
571
|
-
|
790
|
+
|
572
791
|
should "update attributes in the database" do
|
573
792
|
from_db = @document.find(@doc.id)
|
574
793
|
from_db.first_name.should == 'Johnny'
|
575
794
|
from_db.age.should == 30
|
576
795
|
end
|
796
|
+
|
797
|
+
should "allow to update custom attributes" do
|
798
|
+
@doc = @document.new(:first_name => 'David', :age => '26', :gender => 'male')
|
799
|
+
@doc.gender = 'Male'
|
800
|
+
@doc.save
|
801
|
+
from_db = @document.find(@doc.id)
|
802
|
+
from_db.gender.should == 'Male'
|
803
|
+
end
|
577
804
|
end
|
578
|
-
|
805
|
+
|
579
806
|
context "Calling update attributes on a new document" do
|
580
807
|
setup do
|
581
808
|
@doc = @document.new(:first_name => 'John', :age => '27')
|
582
809
|
@doc.update_attributes(:first_name => 'Johnny', :age => 30)
|
583
810
|
end
|
584
|
-
|
811
|
+
|
585
812
|
should "insert document into the collection" do
|
586
813
|
@document.count.should == 1
|
587
814
|
end
|
588
|
-
|
815
|
+
|
589
816
|
should "assign an id for the document" do
|
590
817
|
@doc.id.should_not be(nil)
|
591
818
|
@doc.id.size.should == 24
|
592
819
|
end
|
593
|
-
|
820
|
+
|
594
821
|
should "save attributes" do
|
595
822
|
@doc.first_name.should == 'Johnny'
|
596
823
|
@doc.age.should == 30
|
597
824
|
end
|
598
|
-
|
825
|
+
|
599
826
|
should "update attributes in the database" do
|
600
827
|
from_db = @document.find(@doc.id)
|
601
828
|
from_db.should == @doc
|
602
829
|
from_db.first_name.should == 'Johnny'
|
603
830
|
from_db.age.should == 30
|
604
831
|
end
|
832
|
+
|
833
|
+
should "allow to update custom attributes" do
|
834
|
+
@doc.update_attributes(:gender => 'mALe')
|
835
|
+
from_db = @document.find(@doc.id)
|
836
|
+
from_db.gender.should == 'mALe'
|
837
|
+
end
|
605
838
|
end
|
606
|
-
|
839
|
+
|
607
840
|
context "Updating an existing document using update attributes" do
|
608
841
|
setup do
|
609
842
|
@doc = @document.create(:first_name => 'John', :age => '27')
|
610
843
|
@doc.update_attributes(:first_name => 'Johnny', :age => 30)
|
611
844
|
end
|
612
|
-
|
845
|
+
|
613
846
|
should "not insert document into collection" do
|
614
847
|
@document.count.should == 1
|
615
848
|
end
|
616
|
-
|
849
|
+
|
617
850
|
should "update attributes" do
|
618
851
|
@doc.first_name.should == 'Johnny'
|
619
852
|
@doc.age.should == 30
|
620
853
|
end
|
621
|
-
|
854
|
+
|
622
855
|
should "update attributes in the database" do
|
623
856
|
from_db = @document.find(@doc.id)
|
624
857
|
from_db.first_name.should == 'Johnny'
|
@@ -626,38 +859,56 @@ class DocumentTest < Test::Unit::TestCase
|
|
626
859
|
end
|
627
860
|
end
|
628
861
|
|
862
|
+
context "update_attributes" do
|
863
|
+
setup do
|
864
|
+
@document.key :foo, String, :required => true
|
865
|
+
end
|
866
|
+
|
867
|
+
should "return true if document valid" do
|
868
|
+
@document.new.update_attributes(:foo => 'bar').should be_true
|
869
|
+
end
|
870
|
+
|
871
|
+
should "return false if document not valid" do
|
872
|
+
@document.new.update_attributes({}).should be_false
|
873
|
+
end
|
874
|
+
end
|
875
|
+
|
629
876
|
context "Destroying a document that exists" do
|
630
877
|
setup do
|
631
878
|
@doc = @document.create(:first_name => 'John', :age => '27')
|
632
879
|
@doc.destroy
|
633
880
|
end
|
634
|
-
|
881
|
+
|
635
882
|
should "remove the document from the collection" do
|
636
883
|
@document.count.should == 0
|
637
884
|
end
|
638
|
-
|
885
|
+
|
639
886
|
should "raise error if assignment is attempted" do
|
640
887
|
lambda { @doc.first_name = 'Foo' }.should raise_error(TypeError)
|
641
888
|
end
|
889
|
+
|
890
|
+
should "do nothing if destroy is called again" do
|
891
|
+
@doc.destroy.should be_false
|
892
|
+
end
|
642
893
|
end
|
643
|
-
|
894
|
+
|
644
895
|
context "Destroying a document that is a new" do
|
645
896
|
setup do
|
646
897
|
setup do
|
647
898
|
@doc = @document.new(:first_name => 'John Nunemaker', :age => '27')
|
648
899
|
@doc.destroy
|
649
900
|
end
|
650
|
-
|
901
|
+
|
651
902
|
should "not affect collection count" do
|
652
903
|
@document.collection.count.should == 0
|
653
904
|
end
|
654
|
-
|
905
|
+
|
655
906
|
should "raise error if assignment is attempted" do
|
656
907
|
lambda { @doc.first_name = 'Foo' }.should raise_error(TypeError)
|
657
908
|
end
|
658
909
|
end
|
659
910
|
end
|
660
|
-
|
911
|
+
|
661
912
|
context "timestamping" do
|
662
913
|
should "set created_at and updated_at on create" do
|
663
914
|
doc = @document.new(:first_name => 'John', :age => 27)
|
@@ -667,7 +918,7 @@ class DocumentTest < Test::Unit::TestCase
|
|
667
918
|
doc.created_at.should_not be(nil)
|
668
919
|
doc.updated_at.should_not be(nil)
|
669
920
|
end
|
670
|
-
|
921
|
+
|
671
922
|
should "set updated_at on field update but leave created_at alone" do
|
672
923
|
doc = @document.create(:first_name => 'John', :age => 27)
|
673
924
|
old_created_at = doc.created_at
|
@@ -677,17 +928,17 @@ class DocumentTest < Test::Unit::TestCase
|
|
677
928
|
doc.created_at.should == old_created_at
|
678
929
|
doc.updated_at.should_not == old_updated_at
|
679
930
|
end
|
680
|
-
|
931
|
+
|
681
932
|
should "set updated_at on document update but leave created_at alone" do
|
682
933
|
doc = @document.create(:first_name => 'John', :age => 27)
|
683
934
|
old_created_at = doc.created_at
|
684
935
|
old_updated_at = doc.updated_at
|
685
936
|
sleep 1 # this annoys me
|
686
937
|
@document.update(doc._id, { :first_name => 'Johnny' })
|
687
|
-
|
938
|
+
|
688
939
|
from_db = @document.find(doc.id)
|
689
940
|
from_db.created_at.to_i.should == old_created_at.to_i
|
690
941
|
from_db.updated_at.to_i.should_not == old_updated_at.to_i
|
691
942
|
end
|
692
943
|
end
|
693
|
-
end
|
944
|
+
end
|