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.
@@ -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
- should_eventually "work with << then save" do
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(MongoID.new) }.should raise_error(MongoMapper::DocumentNotFound)
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 == @doc3
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 == @doc3
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(MongoID.new).should be(nil)
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