jnunemaker-mongomapper 0.3.2 → 0.3.3
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/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
|