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.
@@ -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