mongodoc 0.2.1 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. data/README.textile +42 -12
  2. data/Rakefile +4 -4
  3. data/TODO +26 -0
  4. data/VERSION +1 -1
  5. data/examples/simple_document.rb +1 -1
  6. data/examples/simple_object.rb +0 -2
  7. data/features/mongodb.yml +6 -5
  8. data/features/removing_documents.feature +68 -0
  9. data/features/step_definitions/collection_steps.rb +3 -3
  10. data/features/step_definitions/document_steps.rb +2 -2
  11. data/features/step_definitions/removing_documents_steps.rb +14 -0
  12. data/features/support/support.rb +2 -2
  13. data/lib/mongodoc.rb +4 -7
  14. data/lib/mongodoc/associations/collection_proxy.rb +103 -0
  15. data/lib/mongodoc/associations/document_proxy.rb +53 -0
  16. data/lib/mongodoc/associations/hash_proxy.rb +96 -0
  17. data/lib/mongodoc/associations/proxy_base.rb +51 -0
  18. data/lib/mongodoc/attributes.rb +49 -17
  19. data/lib/mongodoc/collection.rb +15 -5
  20. data/lib/mongodoc/connection.rb +83 -20
  21. data/lib/mongodoc/criteria.rb +9 -4
  22. data/lib/mongodoc/cursor.rb +9 -3
  23. data/lib/mongodoc/document.rb +37 -24
  24. data/lib/mongodoc/validations/macros.rb +11 -0
  25. data/lib/mongodoc/validations/validates_embedded.rb +13 -0
  26. data/mongodb.example.yml +13 -5
  27. data/mongodoc.gemspec +33 -23
  28. data/spec/associations/collection_proxy_spec.rb +200 -0
  29. data/spec/associations/document_proxy_spec.rb +42 -0
  30. data/spec/associations/hash_proxy_spec.rb +163 -0
  31. data/spec/attributes_spec.rb +113 -47
  32. data/spec/bson_spec.rb +24 -24
  33. data/spec/collection_spec.rb +67 -86
  34. data/spec/connection_spec.rb +98 -150
  35. data/spec/criteria_spec.rb +4 -3
  36. data/spec/cursor_spec.rb +33 -27
  37. data/spec/document_spec.rb +173 -156
  38. data/spec/embedded_save_spec.rb +8 -3
  39. data/spec/new_record_spec.rb +33 -121
  40. metadata +80 -39
  41. data/lib/mongodoc/parent_proxy.rb +0 -44
  42. data/lib/mongodoc/proxy.rb +0 -83
  43. data/spec/parent_proxy_spec.rb +0 -44
  44. data/spec/proxy_spec.rb +0 -80
@@ -121,6 +121,7 @@ describe MongoDoc::Criteria do
121
121
 
122
122
  before do
123
123
  @count = 27
124
+ @collection = mock
124
125
  @cursor = stub('cursor', :count => @count)
125
126
  Person.stub(:collection).and_return(@collection)
126
127
  end
@@ -339,9 +340,9 @@ describe MongoDoc::Criteria do
339
340
  @criteria.selector.should == { :_id => id }
340
341
  end
341
342
 
342
- it "adds the string as the _id query to the selector" do
343
- id = Mongo::ObjectID.new.to_s
344
- @criteria.id(id)
343
+ it "when a string adds ObjectID as the _id query to the selector" do
344
+ id = Mongo::ObjectID.new
345
+ @criteria.id(id.to_s)
345
346
  @criteria.selector.should == { :_id => id }
346
347
  end
347
348
 
@@ -1,85 +1,91 @@
1
1
  require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
2
 
3
3
  describe "MongoDoc::Cursor" do
4
- before do
5
- @mongo_cursor = stub('cursor')
6
- @cursor = MongoDoc::Cursor.new(@mongo_cursor)
7
- end
4
+ let(:mongo_cursor) { stub('cursor') }
5
+
6
+ let(:collection) { stub('collection') }
7
+
8
+ let(:cursor) { MongoDoc::Cursor.new(collection, mongo_cursor) }
8
9
 
9
10
  it "is Enumerable" do
10
- Enumerable.should === @cursor
11
+ Enumerable.should === cursor
11
12
  end
12
13
 
13
14
  it ".new wraps a Mongo::Cursor" do
14
- @cursor._cursor.should == @mongo_cursor
15
+ cursor._cursor.should == mongo_cursor
16
+ end
17
+
18
+ it "#collection returns the MongoDoc::Collection for this cursor" do
19
+ cursor.collection.should == collection
20
+ cursor._collection.should == collection
15
21
  end
16
22
 
17
23
  context "with the underlying cursor" do
18
- %w(close closed? count explain limit query_options_hash query_opts skip sort).each do |delegated_method|
24
+ %w(admin close closed? count explain fields full_collection_name hint limit order query_options_hash query_opts selector skip snapshot sort timeout).each do |delegated_method|
19
25
  it "delegates #{delegated_method} to the Mongo::Cursor" do
20
- @mongo_cursor.should_receive(delegated_method)
21
- @cursor.send(delegated_method)
26
+ mongo_cursor.should_receive(delegated_method)
27
+ cursor.send(delegated_method)
22
28
  end
23
29
  end
24
30
  end
25
31
 
26
32
  context "#each" do
27
33
  it "delegates to the cursor" do
28
- @mongo_cursor.should_receive(:each)
29
- @cursor.each
34
+ mongo_cursor.should_receive(:each)
35
+ cursor.each
30
36
  end
31
37
 
32
38
  it "decodes the return from the delegate" do
33
39
  bson = stub('bson')
34
- @cursor.stub(:_cursor).and_return([bson])
40
+ cursor.stub(:_cursor).and_return([bson])
35
41
  MongoDoc::BSON.should_receive(:decode).with(bson)
36
- @cursor.each {}
42
+ cursor.each {}
37
43
  end
38
44
 
39
45
  it "calls the block with the decoded return" do
40
46
  result = stub('bson')
41
- @cursor.stub(:_cursor).and_return([result])
47
+ cursor.stub(:_cursor).and_return([result])
42
48
  MongoDoc::BSON.stub(:decode).and_return(result)
43
- @cursor.each {|obj| @obj = obj}
49
+ cursor.each {|obj| @obj = obj}
44
50
  @obj.should == result
45
51
  end
46
52
  end
47
53
 
48
54
  context "#next_document" do
49
55
  it "delegates to the cursor" do
50
- @mongo_cursor.should_receive(:next_document)
51
- @cursor.next_document
56
+ mongo_cursor.should_receive(:next_document)
57
+ cursor.next_document
52
58
  end
53
59
 
54
60
  it "decodes the return from the delegate" do
55
61
  bson = stub('bson')
56
- @mongo_cursor.stub(:next_document).and_return(bson)
62
+ mongo_cursor.stub(:next_document).and_return(bson)
57
63
  MongoDoc::BSON.should_receive(:decode).with(bson)
58
- @cursor.next_document
64
+ cursor.next_document
59
65
  end
60
66
 
61
67
  it "returns nil if the delegate returns nil" do
62
- @mongo_cursor.stub(:next_document)
63
- @cursor.next_document.should be_nil
68
+ mongo_cursor.stub(:next_document)
69
+ cursor.next_document.should be_nil
64
70
  end
65
71
  end
66
72
 
67
73
  context "#to_a" do
68
74
  it "delegates to the cursor" do
69
- @mongo_cursor.should_receive(:to_a)
70
- @cursor.to_a
75
+ mongo_cursor.should_receive(:to_a)
76
+ cursor.to_a
71
77
  end
72
78
 
73
79
  it "decodes the return from the delegate" do
74
80
  array = stub('array')
75
- @mongo_cursor.stub(:to_a).and_return(array)
81
+ mongo_cursor.stub(:to_a).and_return(array)
76
82
  MongoDoc::BSON.should_receive(:decode).with(array)
77
- @cursor.to_a
83
+ cursor.to_a
78
84
  end
79
85
 
80
86
  it "returns [] if the delegate returns []" do
81
- @mongo_cursor.stub(:to_a).and_return([])
82
- @cursor.to_a.should == []
87
+ mongo_cursor.stub(:to_a).and_return([])
88
+ cursor.to_a.should == []
83
89
  end
84
90
  end
85
91
  end
@@ -18,8 +18,8 @@ describe "MongoDoc::Document" do
18
18
  @doc.id.should == @doc._id
19
19
  end
20
20
 
21
- it "#to_param returns the _id" do
22
- @doc.to_param.should == @doc._id
21
+ it "#to_param returns the string of the _id" do
22
+ @doc.to_param.should == @doc._id.to_s
23
23
  end
24
24
 
25
25
  context "#new_record?" do
@@ -219,109 +219,64 @@ describe "MongoDoc::Document" do
219
219
  validates_presence_of :data
220
220
  end
221
221
 
222
+ let(:data) { 'data' }
223
+ let(:instance) { CreateTest.new(:data => data) }
224
+
222
225
  before do
223
- @value = 'value'
224
- CreateTest.stub(:_create).and_return(true)
226
+ instance.stub(:save)
227
+ instance.stub(:save!)
225
228
  end
226
229
 
227
230
  context ".create" do
228
- it "creates a new document" do
229
- obj = CreateTest.new
230
- CreateTest.should_receive(:new).and_return(obj)
231
- CreateTest.create
232
- end
233
-
234
- it "delegates to _create with safe => false" do
235
- obj = CreateTest.new(:data => @value)
236
- CreateTest.stub(:new).and_return(obj)
237
- CreateTest.should_receive(:_create).with(obj, false).and_return(true)
238
- CreateTest.create(:data => @value)
239
- end
240
-
241
- it "sets the passed attributes" do
242
- CreateTest.create(:data => @value).data.should == @value
231
+ it "creates a new document with the attributes" do
232
+ CreateTest.should_receive(:new).with(:data => data).and_return(instance)
233
+ CreateTest.create(:data => data)
243
234
  end
244
235
 
245
- it "returns a valid document" do
246
- CreateTest.should === CreateTest.create(:data => @value)
247
- end
236
+ context "with the new document" do
237
+ before do
238
+ CreateTest.stub(:new).and_return(instance)
239
+ end
248
240
 
249
- it "validates" do
250
- CreateTest.create.errors.should_not be_empty
251
- end
241
+ it "calls save on the instance with safe => false" do
242
+ instance.should_receive(:save).with(false)
243
+ CreateTest.create(:data => data)
244
+ end
252
245
 
253
- it "returns an invalid document" do
254
- CreateTest.should === CreateTest.create
246
+ it "returns the new object" do
247
+ CreateTest.create(:data => data).should == instance
248
+ end
255
249
  end
256
250
  end
257
251
 
258
252
  context ".create!" do
259
- it "creates a new document" do
260
- obj = CreateTest.new
261
- CreateTest.should_receive(:new).and_return(obj)
262
- CreateTest.create! rescue nil
253
+ it "creates a new document with the attributes" do
254
+ CreateTest.should_receive(:new).with(:data => data).and_return(instance)
255
+ CreateTest.create!(:data => data)
263
256
  end
264
257
 
265
- it "delegates to _create with safe => true" do
266
- obj = CreateTest.new(:data => @value)
267
- CreateTest.stub(:new).and_return(obj)
268
- CreateTest.should_receive(:_create).with(obj, true).and_return(true)
269
- CreateTest.create!(:data => @value)
270
- end
271
-
272
- it "sets the passed attributes" do
273
- CreateTest.create!(:data => @value).data.should == @value
274
- end
258
+ context "with the new document" do
259
+ before do
260
+ CreateTest.stub(:new).and_return(instance)
261
+ end
275
262
 
276
- it "returns a valid document" do
277
- CreateTest.should === CreateTest.create!(:data => @value)
278
- end
263
+ it "calls save! on the instance" do
264
+ instance.should_receive(:save!)
265
+ CreateTest.create!(:data => data)
266
+ end
279
267
 
280
- it "raises when invalid" do
281
- expect do
282
- CreateTest.create!
283
- end.should raise_error(MongoDoc::DocumentInvalidError)
268
+ it "returns the new object" do
269
+ CreateTest.create!(:data => data).should == instance
270
+ end
284
271
  end
285
272
  end
286
273
  end
287
274
 
288
- context "#_create" do
289
- class CreateTest
290
- include MongoDoc::Document
291
- end
292
-
293
- before do
294
- @collection = stub('collection')
295
- @collection.stub(:insert)
296
- @doc = CreateTest.new
297
- CreateTest.stub(:collection).and_return(@collection)
298
- end
299
-
300
- it "delegates to the collection insert with safe" do
301
- safe = true
302
- @collection.should_receive(:insert).with(@doc, hash_including(:safe => safe))
303
- CreateTest.send(:_create, @doc, safe)
304
- end
305
-
306
- it "sets the _id of the document" do
307
- id = 'id'
308
- @collection.stub(:insert).and_return(id)
309
- CreateTest.send(:_create, @doc, false)
310
- @doc._id.should == id
311
- end
312
-
313
- it "returns the _id" do
314
- id = 'id'
315
- @collection.stub(:insert).and_return(id)
316
- CreateTest.send(:_create, @doc, false).should == id
317
- end
318
- end
319
-
320
275
  context "updating attributes" do
321
276
  class UpdateAttributesRoot
322
277
  include MongoDoc::Document
323
278
 
324
- has_one :update_attribute_child
279
+ has_one :update_attributes_child
325
280
  end
326
281
 
327
282
  class UpdateAttributesChild
@@ -330,104 +285,127 @@ describe "MongoDoc::Document" do
330
285
  key :data
331
286
  end
332
287
 
288
+ let(:data) {'data'}
289
+
290
+ let(:attrs) {{:data => data}}
291
+
292
+ let(:path_attrs) {{'update_attributes_child.data' => data}}
293
+
294
+ let(:doc) do
295
+ doc = UpdateAttributesChild.new
296
+ doc._id = 'id'
297
+ doc.stub(:_naive_update_attributes)
298
+ doc
299
+ end
300
+
333
301
  before do
334
- @data = 'data'
335
- @doc = UpdateAttributesChild.new
336
- UpdateAttributesRoot.new.update_attribute_child = @doc
337
- @attrs = {:data => @data}
338
- @path_attrs = {'update_attribute_child.data' => @data}
339
- @doc.stub(:_naive_update_attributes)
302
+ root = UpdateAttributesRoot.new
303
+ root.update_attributes_child = doc
304
+ root._id = 'id'
340
305
  end
341
306
 
342
307
  context "#update_attributes" do
308
+ it "delegates to save if the object is a new record" do
309
+ check = 'check'
310
+ doc.stub(:new_record?).and_return(true)
311
+ doc.should_receive(:save).and_return(check)
312
+ doc.update_attributes(attrs).should == check
313
+ end
343
314
 
344
315
  it "sets the attributes" do
345
- @doc.update_attributes(@attrs)
346
- @doc.data.should == @data
316
+ doc.update_attributes(attrs)
317
+ doc.data.should == data
347
318
  end
348
319
 
349
320
  it "normalizes the attributes to the parent" do
350
- @doc.should_receive(:_path_to_root)
351
- @doc.update_attributes(@attrs)
321
+ doc.should_receive(:_path_to_root)
322
+ doc.update_attributes(attrs)
352
323
  end
353
324
 
354
325
  it "validates" do
355
- @doc.should_receive(:valid?)
356
- @doc.update_attributes(@attrs)
326
+ doc.should_receive(:valid?)
327
+ doc.update_attributes(attrs)
357
328
  end
358
329
 
359
330
  it "returns false if the object is not valid" do
360
- @doc.stub(:valid?).and_return(false)
361
- @doc.update_attributes(@attrs).should be_false
331
+ doc.stub(:valid?).and_return(false)
332
+ doc.update_attributes(attrs).should be_false
362
333
  end
363
334
 
364
335
  context "if valid" do
365
336
  context "and strict" do
366
337
  it "delegates to _strict_update_attributes" do
367
- strict_attrs = @attrs.merge(:__strict__ => true)
368
- @doc.should_receive(:_strict_update_attributes).with(@path_attrs, false)
369
- @doc.update_attributes(strict_attrs)
338
+ strict_attrs = attrs.merge(:__strict__ => true)
339
+ doc.should_receive(:_strict_update_attributes).with(path_attrs, false)
340
+ doc.update_attributes(strict_attrs)
370
341
  end
371
342
  end
372
343
 
373
344
  context "and naive" do
374
345
  it "delegates to _naive_update_attributes" do
375
- @doc.should_receive(:_naive_update_attributes).with(@path_attrs, false)
376
- @doc.update_attributes(@attrs)
346
+ doc.should_receive(:_naive_update_attributes).with(path_attrs, false)
347
+ doc.update_attributes(attrs)
377
348
  end
378
349
  end
379
350
 
380
351
  it "returns the result of _naive_update_attributes" do
381
352
  result = 'check'
382
- @doc.stub(:_naive_update_attributes).and_return(result)
383
- @doc.update_attributes(@attrs).should == result
353
+ doc.stub(:_naive_update_attributes).and_return(result)
354
+ doc.update_attributes(attrs).should == result
384
355
  end
385
356
  end
386
357
  end
387
358
 
388
359
  context "#update_attributes!" do
360
+ it "delegates to save! if the object is a new record" do
361
+ check = 'check'
362
+ doc.stub(:new_record?).and_return(true)
363
+ doc.should_receive(:save!).and_return(check)
364
+ doc.update_attributes!(attrs).should == check
365
+ end
366
+
389
367
  it "sets the attributes" do
390
- @doc.update_attributes!(@attrs)
391
- @doc.data.should == @data
368
+ doc.update_attributes!(attrs)
369
+ doc.data.should == data
392
370
  end
393
371
 
394
372
  it "normalizes the attributes to the parent" do
395
- @doc.should_receive(:_path_to_root)
396
- @doc.update_attributes!(@attrs)
373
+ doc.should_receive(:_path_to_root)
374
+ doc.update_attributes!(attrs)
397
375
  end
398
376
 
399
377
  it "validates" do
400
- @doc.should_receive(:valid?).and_return(true)
401
- @doc.update_attributes!(@attrs)
378
+ doc.should_receive(:valid?).and_return(true)
379
+ doc.update_attributes!(attrs)
402
380
  end
403
381
 
404
382
  it "raises if not valid" do
405
- @doc.stub(:valid?).and_return(false)
383
+ doc.stub(:valid?).and_return(false)
406
384
  expect do
407
- @doc.update_attributes!(@attrs)
385
+ doc.update_attributes!(attrs)
408
386
  end.should raise_error(MongoDoc::DocumentInvalidError)
409
387
  end
410
388
 
411
389
  context "if valid" do
412
390
  context "and strict" do
413
391
  it "delegates to _strict_update_attributes with safe == true" do
414
- strict_attrs = @attrs.merge(:__strict__ => true)
415
- @doc.should_receive(:_strict_update_attributes).with(@path_attrs, true)
416
- @doc.update_attributes!(strict_attrs)
392
+ strict_attrs = attrs.merge(:__strict__ => true)
393
+ doc.should_receive(:_strict_update_attributes).with(path_attrs, true)
394
+ doc.update_attributes!(strict_attrs)
417
395
  end
418
396
  end
419
397
 
420
398
  context "and naive" do
421
399
  it "delegates to _naive_update_attributes with safe == true" do
422
- @doc.should_receive(:_naive_update_attributes).with(@path_attrs, true)
423
- @doc.update_attributes!(@attrs)
400
+ doc.should_receive(:_naive_update_attributes).with(path_attrs, true)
401
+ doc.update_attributes!(attrs)
424
402
  end
425
403
  end
426
404
 
427
405
  it "returns the result of _naive_update_attributes" do
428
406
  result = 'check'
429
- @doc.stub(:_naive_update_attributes).and_return(result)
430
- @doc.update_attributes!(@attrs).should == result
407
+ doc.stub(:_naive_update_attributes).and_return(result)
408
+ doc.update_attributes!(attrs).should == result
431
409
  end
432
410
  end
433
411
  end
@@ -438,27 +416,29 @@ describe "MongoDoc::Document" do
438
416
  include MongoDoc::Document
439
417
  end
440
418
 
441
- before do
442
- @id = 'id'
443
- @attrs = {:data => 'data'}
444
- @safe = false
445
- @doc = NaiveUpdateAttributes.new
446
- @doc.stub(:_id).and_return(@id)
447
- @collection = stub('collection')
448
- @collection.stub(:update)
449
- @doc.stub(:_collection).and_return(@collection)
419
+
420
+ let(:id) { 'id' }
421
+
422
+ let(:attrs) { {:data => 'data'} }
423
+
424
+ let(:safe) { false }
425
+
426
+ let(:doc) do
427
+ doc = NaiveUpdateAttributes.new
428
+ doc.stub(:_id).and_return(id)
429
+ doc
450
430
  end
451
431
 
452
- it "calls update on the collection without a root" do
453
- @collection.should_receive(:update).with({'_id' => @id}, MongoDoc::Query.set_modifier(@attrs), {:safe => @safe})
454
- @doc.send(:_naive_update_attributes, @attrs, @safe)
432
+ it "without a root delegates to _update" do
433
+ doc.should_receive(:_update).with({}, attrs, safe)
434
+ doc.send(:_naive_update_attributes, attrs, safe)
455
435
  end
456
436
 
457
437
  it "with a root, calls _naive_update_attributes on the root" do
458
438
  root = NaiveUpdateAttributes.new
459
- @doc.stub(:_root).and_return(root)
460
- root.should_receive(:_naive_update_attributes).with(@attrs, @safe)
461
- @doc.send(:_naive_update_attributes, @attrs, @safe)
439
+ doc.stub(:_root).and_return(root)
440
+ root.should_receive(:_naive_update_attributes).with(attrs, safe)
441
+ doc.send(:_naive_update_attributes, attrs, safe)
462
442
  end
463
443
  end
464
444
 
@@ -467,41 +447,45 @@ describe "MongoDoc::Document" do
467
447
  include MongoDoc::Document
468
448
  end
469
449
 
470
- before do
471
- @id = 'id'
472
- @attrs = {:data => 'data'}
473
- @selector = {'selector' => 'selector'}
474
- @safe = false
475
- @doc = StrictUpdateAttributes.new
476
- @doc.stub(:_id).and_return(@id)
477
- @collection = stub('collection')
478
- @collection.stub(:update)
479
- @doc.stub(:_collection).and_return(@collection)
450
+ let(:id) { 'id' }
451
+
452
+ let(:attrs) { {:data => 'data'} }
453
+
454
+ let(:selector) { {:selector => 'selector'} }
455
+
456
+ let(:safe) { false }
457
+
458
+ let(:doc) do
459
+ doc = StrictUpdateAttributes.new
460
+ doc.stub(:_id).and_return(id)
461
+ doc
480
462
  end
481
463
 
482
464
  context "without a root" do
483
- it "calls update on the collection" do
484
- @collection.should_receive(:update).with({'_id' => @id}.merge(@selector), MongoDoc::Query.set_modifier(@attrs), :safe => @safe)
485
- @doc.send(:_strict_update_attributes, @attrs, @safe, @selector)
465
+ it "without a root delegates to _update" do
466
+ doc.should_receive(:_update).with(selector, attrs, safe)
467
+ doc.send(:_strict_update_attributes, attrs, safe, selector)
486
468
  end
487
469
  end
488
470
 
489
471
  context "with a root" do
472
+ let(:root) { StrictUpdateAttributes.new }
473
+
490
474
  before do
491
- @root = StrictUpdateAttributes.new
492
- @root.stub(:_collection).and_return(@collection)
493
- @doc.stub(:_root).and_return(@root)
494
- @doc.stub(:_selector_path_to_root).and_return({'path._id' => @id})
475
+ doc.stub(:_root).and_return(root)
495
476
  end
496
477
 
497
- it "calls _selector_path_to_root on our id" do
498
- @doc.should_receive(:_selector_path_to_root).with('_id' => @id).and_return({'path._id' => @id})
499
- @doc.send(:_strict_update_attributes, @attrs, @safe)
478
+ it "calls _path_to_root on our id" do
479
+ root.stub(:_strict_update_attributes)
480
+ doc.should_receive(:_path_to_root).with(doc, '_id' => id)
481
+ doc.send(:_strict_update_attributes, attrs, safe)
500
482
  end
501
483
 
502
484
  it "calls _strict_update_attributes on the root with our selector" do
503
- @root.should_receive(:_strict_update_attributes).with(@attrs, @safe, 'path._id' => @id)
504
- @doc.send(:_strict_update_attributes, @attrs, @safe)
485
+ selector = {'path._id' => id}
486
+ doc.stub(:_path_to_root).with(doc, '_id' => id).and_return(selector)
487
+ root.should_receive(:_strict_update_attributes).with(attrs, safe, selector)
488
+ doc.send(:_strict_update_attributes, attrs, safe)
505
489
  end
506
490
  end
507
491
  end
@@ -622,12 +606,45 @@ describe "MongoDoc::Document" do
622
606
 
623
607
  it "roundtrips the proxy" do
624
608
  doc = TestHasManyBsonDoc.new(:subdoc => SubHasManyBsonDoc.new(:attr => "value"))
625
- MongoDoc::Proxy.should === MongoDoc::BSON.decode(doc.to_bson).subdoc
609
+ MongoDoc::Associations::CollectionProxy.should === MongoDoc::BSON.decode(doc.to_bson).subdoc
626
610
  end
627
611
  end
628
612
  end
629
613
  end
630
614
 
615
+ context "removing documents" do
616
+ class RemoveDocument
617
+ include MongoDoc::Document
618
+ end
619
+
620
+ let(:doc) { RemoveDocument.new }
621
+
622
+ context "#remove" do
623
+ it "when called on a embedded document with a _root raises UnsupportedOperation" do
624
+ doc._root = RemoveDocument.new
625
+ expect { doc.remove }.to raise_error(MongoDoc::UnsupportedOperation)
626
+ end
627
+
628
+ it "delegates to remove document" do
629
+ doc.should_receive(:remove_document)
630
+ doc.remove
631
+ end
632
+ end
633
+
634
+ context "#remove_document" do
635
+ it "when the document is the root, removes the document" do
636
+ doc.should_receive(:_remove)
637
+ doc.remove_document
638
+ end
639
+
640
+ it "when the document is not the root, calls remove_document on the root" do
641
+ doc._root = root = RemoveDocument.new
642
+ root.should_receive(:remove_document)
643
+ doc.remove_document
644
+ end
645
+ end
646
+ end
647
+
631
648
  context "misc class methods" do
632
649
  class ClassMethods
633
650
  include MongoDoc::Document
@@ -640,7 +657,7 @@ describe "MongoDoc::Document" do
640
657
  it ".collection returns a wrapped MongoDoc::Collection" do
641
658
  db = stub('db')
642
659
  db.should_receive(:collection).with(ClassMethods.to_s.tableize.gsub('/', '.'))
643
- MongoDoc.should_receive(:database).and_return(db)
660
+ MongoDoc::Connection.should_receive(:database).and_return(db)
644
661
  MongoDoc::Collection.should === ClassMethods.collection
645
662
  end
646
663
  end