mongodoc 0.0.0 → 0.1.0
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/README.rdoc +44 -3
- data/VERSION +1 -1
- data/features/step_definitions/collection_steps.rb +1 -1
- data/features/step_definitions/criteria_steps.rb +79 -0
- data/features/step_definitions/document_steps.rb +0 -1
- data/features/step_definitions/documents.rb +19 -0
- data/features/step_definitions/json_steps.rb +4 -4
- data/features/step_definitions/object_steps.rb +11 -4
- data/features/step_definitions/objects.rb +24 -0
- data/features/support/support.rb +0 -2
- data/features/using_criteria.feature +146 -0
- data/lib/mongodoc/attributes.rb +69 -71
- data/lib/mongodoc/collection.rb +45 -0
- data/lib/mongodoc/connection.rb +2 -2
- data/lib/mongodoc/criteria.rb +485 -0
- data/lib/mongodoc/cursor.rb +24 -0
- data/lib/mongodoc/document.rb +138 -0
- data/lib/mongodoc/parent_proxy.rb +24 -26
- data/lib/mongodoc/proxy.rb +55 -57
- data/lib/mongodoc.rb +5 -1
- data/mongodoc.gemspec +22 -14
- data/spec/attributes_spec.rb +14 -14
- data/spec/bson_spec.rb +23 -143
- data/spec/collection_spec.rb +180 -0
- data/spec/connection_spec.rb +11 -1
- data/spec/criteria_spec.rb +846 -0
- data/spec/cursor_spec.rb +81 -0
- data/spec/{base_ext.rb → document_ext.rb} +1 -1
- data/spec/document_spec.rb +678 -0
- data/spec/parent_proxy_spec.rb +4 -4
- data/spec/spec_helper.rb +1 -3
- metadata +20 -12
- data/lib/mongodoc/base.rb +0 -163
- data/lib/mongodoc/value_equals.rb +0 -8
- data/spec/base_spec.rb +0 -273
- data/spec/test_classes.rb +0 -19
- data/spec/test_documents.rb +0 -35
@@ -0,0 +1,678 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe "MongoDoc::Document" do
|
4
|
+
|
5
|
+
context "satisfies form_for requirements" do
|
6
|
+
class FormForTest < MongoDoc::Document
|
7
|
+
end
|
8
|
+
|
9
|
+
before do
|
10
|
+
@doc = FormForTest.new
|
11
|
+
@doc._id = '1'
|
12
|
+
end
|
13
|
+
|
14
|
+
it "#id returns the _id" do
|
15
|
+
@doc.id.should == @doc._id
|
16
|
+
end
|
17
|
+
|
18
|
+
it "#to_param returns the _id" do
|
19
|
+
@doc.to_param.should == @doc._id
|
20
|
+
end
|
21
|
+
|
22
|
+
context "#new_record?" do
|
23
|
+
it "is true when the object does not have an _id" do
|
24
|
+
@doc._id = nil
|
25
|
+
@doc.should be_new_record
|
26
|
+
end
|
27
|
+
|
28
|
+
it "is false when the object has an id" do
|
29
|
+
@doc.should_not be_new_record
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
context "validations" do
|
35
|
+
class SimpleValidationTest < MongoDoc::Document
|
36
|
+
key :data
|
37
|
+
validates_presence_of :data
|
38
|
+
end
|
39
|
+
|
40
|
+
it "are part of Base" do
|
41
|
+
Validatable.should === MongoDoc::Document.new
|
42
|
+
end
|
43
|
+
|
44
|
+
it "valid? fails when a document is invalid" do
|
45
|
+
doc = SimpleValidationTest.new
|
46
|
+
doc.should_not be_valid
|
47
|
+
doc.should have(1).error_on(:data)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
context ".criteria" do
|
52
|
+
class CriteriaTest < MongoDoc::Document
|
53
|
+
key :data
|
54
|
+
end
|
55
|
+
|
56
|
+
it "creates a new criteria for the document" do
|
57
|
+
CriteriaTest.criteria.should be_a_kind_of(MongoDoc::Criteria)
|
58
|
+
end
|
59
|
+
|
60
|
+
it "sets the criteria klass" do
|
61
|
+
CriteriaTest.criteria.klass.should == CriteriaTest
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
context "saving" do
|
66
|
+
class SaveRoot < MongoDoc::Document
|
67
|
+
has_many :save_children
|
68
|
+
end
|
69
|
+
|
70
|
+
class SaveChild < MongoDoc::Document
|
71
|
+
key :data
|
72
|
+
end
|
73
|
+
|
74
|
+
before do
|
75
|
+
@root = SaveRoot.new
|
76
|
+
@root.stub(:_save)
|
77
|
+
@child = SaveChild.new
|
78
|
+
@root.save_children << @child
|
79
|
+
end
|
80
|
+
|
81
|
+
context "#save" do
|
82
|
+
it "delegates to the root" do
|
83
|
+
validate = true
|
84
|
+
@root.should_receive(:save).with(validate)
|
85
|
+
@child.save(validate)
|
86
|
+
end
|
87
|
+
|
88
|
+
context "when validating" do
|
89
|
+
it "validates" do
|
90
|
+
@root.should_receive(:valid?)
|
91
|
+
@root.save(true)
|
92
|
+
end
|
93
|
+
|
94
|
+
context "and valid" do
|
95
|
+
it "delegates to _save" do
|
96
|
+
@root.should_receive(:_save).with(false)
|
97
|
+
@root.save(true)
|
98
|
+
end
|
99
|
+
|
100
|
+
it "returns the result of _save if valid" do
|
101
|
+
id = 'id'
|
102
|
+
@root.stub(:valid?).and_return(true)
|
103
|
+
@root.should_receive(:_save).and_return(id)
|
104
|
+
@root.save(true).should == id
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
context "and invalid" do
|
109
|
+
it "does not call _save" do
|
110
|
+
@root.stub(:valid?).and_return(false)
|
111
|
+
@root.should_not_receive(:_save)
|
112
|
+
@root.save(true)
|
113
|
+
end
|
114
|
+
|
115
|
+
it "returns false" do
|
116
|
+
@root.stub(:valid?).and_return(false)
|
117
|
+
@root.save(true).should be_false
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
context "when not validating" do
|
123
|
+
it "does not validate" do
|
124
|
+
@root.should_not_receive(:valid?)
|
125
|
+
@root.save(false)
|
126
|
+
end
|
127
|
+
|
128
|
+
it "delegates to _save" do
|
129
|
+
@root.should_receive(:_save).with(false)
|
130
|
+
@root.save(false)
|
131
|
+
end
|
132
|
+
|
133
|
+
it "returns the result of _save" do
|
134
|
+
id = 'id'
|
135
|
+
@root.stub(:_save).and_return(id)
|
136
|
+
@root.save(false).should == id
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
context "#save!" do
|
142
|
+
it "delegates to the root" do
|
143
|
+
@root.should_receive(:save!)
|
144
|
+
@child.save!
|
145
|
+
end
|
146
|
+
|
147
|
+
it "validates" do
|
148
|
+
@root.should_receive(:valid?).and_return(true)
|
149
|
+
@root.save!
|
150
|
+
end
|
151
|
+
|
152
|
+
it "returns the result of _save if valid" do
|
153
|
+
id = 'id'
|
154
|
+
@root.stub(:valid?).and_return(true)
|
155
|
+
@root.should_receive(:_save).with(true).and_return(id)
|
156
|
+
@root.save!.should == id
|
157
|
+
end
|
158
|
+
|
159
|
+
it "raises if invalid" do
|
160
|
+
@root.stub(:valid?).and_return(false)
|
161
|
+
expect do
|
162
|
+
@root.save!
|
163
|
+
end.should raise_error(MongoDoc::DocumentInvalidError)
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
context "#_save" do
|
169
|
+
class SaveTest < MongoDoc::Document
|
170
|
+
end
|
171
|
+
|
172
|
+
before do
|
173
|
+
@collection = stub('collection')
|
174
|
+
@doc = SaveTest.new
|
175
|
+
@doc.stub(:_collection).and_return(@collection)
|
176
|
+
end
|
177
|
+
|
178
|
+
it "delegates to the collection save" do
|
179
|
+
safe = true
|
180
|
+
@collection.should_receive(:save)
|
181
|
+
@doc.send(:_save, safe)
|
182
|
+
end
|
183
|
+
|
184
|
+
it "sets the _id of the document" do
|
185
|
+
id = 'id'
|
186
|
+
@collection.stub(:save).and_return(id)
|
187
|
+
@doc.send(:_save, true)
|
188
|
+
@doc._id.should == id
|
189
|
+
end
|
190
|
+
|
191
|
+
it "returns the _id" do
|
192
|
+
id = 'id'
|
193
|
+
@collection.stub(:save).and_return(id)
|
194
|
+
@doc.send(:_save, true).should == id
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
context "creating" do
|
199
|
+
class CreateTest < MongoDoc::Document
|
200
|
+
key :data
|
201
|
+
validates_presence_of :data
|
202
|
+
end
|
203
|
+
|
204
|
+
before do
|
205
|
+
@value = 'value'
|
206
|
+
CreateTest.stub(:_create).and_return(true)
|
207
|
+
end
|
208
|
+
|
209
|
+
context ".create" do
|
210
|
+
it "creates a new document" do
|
211
|
+
obj = CreateTest.new
|
212
|
+
CreateTest.should_receive(:new).and_return(obj)
|
213
|
+
CreateTest.create
|
214
|
+
end
|
215
|
+
|
216
|
+
it "delegates to _create with safe => false" do
|
217
|
+
obj = CreateTest.new(:data => @value)
|
218
|
+
CreateTest.stub(:new).and_return(obj)
|
219
|
+
CreateTest.should_receive(:_create).with(obj, false).and_return(true)
|
220
|
+
CreateTest.create(:data => @value)
|
221
|
+
end
|
222
|
+
|
223
|
+
it "sets the passed attributes" do
|
224
|
+
CreateTest.create(:data => @value).data.should == @value
|
225
|
+
end
|
226
|
+
|
227
|
+
it "returns a valid document" do
|
228
|
+
CreateTest.should === CreateTest.create(:data => @value)
|
229
|
+
end
|
230
|
+
|
231
|
+
it "validates" do
|
232
|
+
CreateTest.create.errors.should_not be_empty
|
233
|
+
end
|
234
|
+
|
235
|
+
it "returns an invalid document" do
|
236
|
+
CreateTest.should === CreateTest.create
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
context ".create!" do
|
241
|
+
it "creates a new document" do
|
242
|
+
obj = CreateTest.new
|
243
|
+
CreateTest.should_receive(:new).and_return(obj)
|
244
|
+
CreateTest.create! rescue nil
|
245
|
+
end
|
246
|
+
|
247
|
+
it "delegates to _create with safe => true" do
|
248
|
+
obj = CreateTest.new(:data => @value)
|
249
|
+
CreateTest.stub(:new).and_return(obj)
|
250
|
+
CreateTest.should_receive(:_create).with(obj, true).and_return(true)
|
251
|
+
CreateTest.create!(:data => @value)
|
252
|
+
end
|
253
|
+
|
254
|
+
it "sets the passed attributes" do
|
255
|
+
CreateTest.create!(:data => @value).data.should == @value
|
256
|
+
end
|
257
|
+
|
258
|
+
it "returns a valid document" do
|
259
|
+
CreateTest.should === CreateTest.create!(:data => @value)
|
260
|
+
end
|
261
|
+
|
262
|
+
it "raises when invalid" do
|
263
|
+
expect do
|
264
|
+
CreateTest.create!
|
265
|
+
end.should raise_error(MongoDoc::DocumentInvalidError)
|
266
|
+
end
|
267
|
+
end
|
268
|
+
end
|
269
|
+
|
270
|
+
context "#_create" do
|
271
|
+
class CreateTest < MongoDoc::Document
|
272
|
+
end
|
273
|
+
|
274
|
+
before do
|
275
|
+
@collection = stub('collection')
|
276
|
+
@collection.stub(:insert)
|
277
|
+
@doc = CreateTest.new
|
278
|
+
CreateTest.stub(:collection).and_return(@collection)
|
279
|
+
end
|
280
|
+
|
281
|
+
it "delegates to the collection insert with safe" do
|
282
|
+
safe = true
|
283
|
+
@collection.should_receive(:insert).with(@doc, hash_including(:safe => safe))
|
284
|
+
CreateTest.send(:_create, @doc, safe)
|
285
|
+
end
|
286
|
+
|
287
|
+
it "sets the _id of the document" do
|
288
|
+
id = 'id'
|
289
|
+
@collection.stub(:insert).and_return(id)
|
290
|
+
CreateTest.send(:_create, @doc, false)
|
291
|
+
@doc._id.should == id
|
292
|
+
end
|
293
|
+
|
294
|
+
it "returns the _id" do
|
295
|
+
id = 'id'
|
296
|
+
@collection.stub(:insert).and_return(id)
|
297
|
+
CreateTest.send(:_create, @doc, false).should == id
|
298
|
+
end
|
299
|
+
end
|
300
|
+
|
301
|
+
context "updating attributes" do
|
302
|
+
class UpdateAttributesRoot < MongoDoc::Document
|
303
|
+
has_one :update_attribute_child
|
304
|
+
end
|
305
|
+
|
306
|
+
class UpdateAttributesChild < MongoDoc::Document
|
307
|
+
key :data
|
308
|
+
end
|
309
|
+
|
310
|
+
before do
|
311
|
+
@data = 'data'
|
312
|
+
@doc = UpdateAttributesChild.new
|
313
|
+
UpdateAttributesRoot.new.update_attribute_child = @doc
|
314
|
+
@attrs = {:data => @data}
|
315
|
+
@path_attrs = {'update_attribute_child.data' => @data}
|
316
|
+
@doc.stub(:_propose_update_attributes)
|
317
|
+
end
|
318
|
+
|
319
|
+
context "#update_attributes" do
|
320
|
+
it "sets the attributes" do
|
321
|
+
@doc.update_attributes(@attrs)
|
322
|
+
@doc.data.should == @data
|
323
|
+
end
|
324
|
+
|
325
|
+
it "normalizes the attributes to the parent" do
|
326
|
+
@doc.should_receive(:path_to_root)
|
327
|
+
@doc.update_attributes(@attrs)
|
328
|
+
end
|
329
|
+
|
330
|
+
it "validates" do
|
331
|
+
@doc.should_receive(:valid?)
|
332
|
+
@doc.update_attributes(@attrs)
|
333
|
+
end
|
334
|
+
|
335
|
+
it "returns false if the object is not valid" do
|
336
|
+
@doc.stub(:valid?).and_return(false)
|
337
|
+
@doc.update_attributes(@attrs).should be_false
|
338
|
+
end
|
339
|
+
|
340
|
+
context "if valid" do
|
341
|
+
it "delegates to _propose_update_attributes" do
|
342
|
+
@doc.should_receive(:_propose_update_attributes).with(@doc, @path_attrs, false)
|
343
|
+
@doc.update_attributes(@attrs)
|
344
|
+
end
|
345
|
+
|
346
|
+
it "returns the result of _propose_update_attributes" do
|
347
|
+
result = 'check'
|
348
|
+
@doc.stub(:_propose_update_attributes).and_return(result)
|
349
|
+
@doc.update_attributes(@attrs).should == result
|
350
|
+
end
|
351
|
+
end
|
352
|
+
end
|
353
|
+
|
354
|
+
context "#update_attributes!" do
|
355
|
+
it "sets the attributes" do
|
356
|
+
@doc.update_attributes!(@attrs)
|
357
|
+
@doc.data.should == @data
|
358
|
+
end
|
359
|
+
|
360
|
+
it "normalizes the attributes to the parent" do
|
361
|
+
@doc.should_receive(:path_to_root)
|
362
|
+
@doc.update_attributes!(@attrs)
|
363
|
+
end
|
364
|
+
|
365
|
+
it "validates" do
|
366
|
+
@doc.should_receive(:valid?).and_return(true)
|
367
|
+
@doc.update_attributes!(@attrs)
|
368
|
+
end
|
369
|
+
|
370
|
+
it "raises if not valid" do
|
371
|
+
@doc.stub(:valid?).and_return(false)
|
372
|
+
expect do
|
373
|
+
@doc.update_attributes!(@attrs)
|
374
|
+
end.should raise_error(MongoDoc::DocumentInvalidError)
|
375
|
+
end
|
376
|
+
|
377
|
+
context "if valid" do
|
378
|
+
it "delegates to _propose_update_attributes with safe == true" do
|
379
|
+
@doc.should_receive(:_propose_update_attributes).with(@doc, @path_attrs, true)
|
380
|
+
@doc.update_attributes!(@attrs)
|
381
|
+
end
|
382
|
+
|
383
|
+
it "returns the result of _propose_update_attributes" do
|
384
|
+
result = 'check'
|
385
|
+
@doc.stub(:_propose_update_attributes).and_return(result)
|
386
|
+
@doc.update_attributes!(@attrs).should == result
|
387
|
+
end
|
388
|
+
end
|
389
|
+
end
|
390
|
+
end
|
391
|
+
|
392
|
+
context "#_propose_update_attributes" do
|
393
|
+
class ProposeUpdateAttributes < MongoDoc::Document
|
394
|
+
end
|
395
|
+
|
396
|
+
before do
|
397
|
+
@attrs = {:data => 1}
|
398
|
+
@safe = true
|
399
|
+
end
|
400
|
+
|
401
|
+
context "when not a child" do
|
402
|
+
before do
|
403
|
+
@obj = ProposeUpdateAttributes.new
|
404
|
+
end
|
405
|
+
|
406
|
+
it "delegates to _update_attributes when not a child" do
|
407
|
+
@obj.should_receive(:_update_attributes).with(@attrs, @safe)
|
408
|
+
@obj.send(:_propose_update_attributes, @obj, @attrs, @safe)
|
409
|
+
end
|
410
|
+
|
411
|
+
it "returns the results of _update_attributes" do
|
412
|
+
result = 'check'
|
413
|
+
@obj.stub(:_update_attributes).and_return(result)
|
414
|
+
@obj.send(:_propose_update_attributes, @obj, @attrs, @safe).should == result
|
415
|
+
end
|
416
|
+
end
|
417
|
+
|
418
|
+
context "when a child" do
|
419
|
+
before do
|
420
|
+
@obj = ProposeUpdateAttributes.new
|
421
|
+
@parent = stub('parent')
|
422
|
+
@obj._parent = @parent
|
423
|
+
end
|
424
|
+
|
425
|
+
it "delegates to the parent when a child" do
|
426
|
+
@parent.should_receive(:_propose_update_attributes).with(@obj, @attrs, @safe)
|
427
|
+
@obj.send(:_propose_update_attributes, @obj, @attrs, @safe)
|
428
|
+
end
|
429
|
+
|
430
|
+
it "returns the results of the parent's _propose_update_attributes" do
|
431
|
+
result = 'check'
|
432
|
+
@parent.stub(:_propose_update_attributes).and_return(result)
|
433
|
+
@obj.send(:_propose_update_attributes, @obj, @attrs, @safe).should == result
|
434
|
+
end
|
435
|
+
end
|
436
|
+
end
|
437
|
+
|
438
|
+
context "#_update_attributes" do
|
439
|
+
class UpdateAttributes < MongoDoc::Document
|
440
|
+
end
|
441
|
+
|
442
|
+
before do
|
443
|
+
@collection = stub('collection')
|
444
|
+
@collection.stub(:update)
|
445
|
+
@doc = UpdateAttributes.new
|
446
|
+
@doc.stub(:_id).and_return(@id)
|
447
|
+
UpdateAttributes.stub(:collection).and_return(@collection)
|
448
|
+
@attrs = {:data => 'value'}
|
449
|
+
end
|
450
|
+
|
451
|
+
it "uses the set modifier for the attributes" do
|
452
|
+
safe = true
|
453
|
+
MongoDoc::Query.should_receive(:set_modifier).with(@attrs)
|
454
|
+
@collection.stub(:update)
|
455
|
+
@doc.send(:_update_attributes, @attrs, safe)
|
456
|
+
end
|
457
|
+
|
458
|
+
it "delegates to the collection update with safe" do
|
459
|
+
safe = true
|
460
|
+
@collection.should_receive(:update).with({'_id' => @id}, MongoDoc::Query.set_modifier(@attrs), {:safe => safe})
|
461
|
+
@doc.send(:_update_attributes, @attrs, safe)
|
462
|
+
end
|
463
|
+
|
464
|
+
it "returns the result" do
|
465
|
+
result = 'check'
|
466
|
+
@collection.stub(:update).and_return(result)
|
467
|
+
@doc.send(:_update_attributes, @attrs, true)
|
468
|
+
end
|
469
|
+
end
|
470
|
+
|
471
|
+
context "from a nested document" do
|
472
|
+
class NestedDocsRoot < MongoDoc::Document
|
473
|
+
has_many :nested_children
|
474
|
+
end
|
475
|
+
|
476
|
+
class NestedChild < MongoDoc::Document
|
477
|
+
has_one :leaf
|
478
|
+
end
|
479
|
+
|
480
|
+
class LeafDoc < MongoDoc::Document
|
481
|
+
key :data
|
482
|
+
end
|
483
|
+
|
484
|
+
context "#save" do
|
485
|
+
before do
|
486
|
+
@leaf = LeafDoc.new
|
487
|
+
@root = NestedDocsRoot.new(:nested_children => [NestedChild.new(:leaf => @leaf)])
|
488
|
+
end
|
489
|
+
|
490
|
+
it "calls the root document's save" do
|
491
|
+
@root.should_receive(:save).with(true)
|
492
|
+
@leaf.save
|
493
|
+
end
|
494
|
+
|
495
|
+
it "(with bang!) calls the root documents save!" do
|
496
|
+
@root.should_receive(:save!)
|
497
|
+
@leaf.save!
|
498
|
+
end
|
499
|
+
end
|
500
|
+
|
501
|
+
context "with no has_many, update_attributes" do
|
502
|
+
before do
|
503
|
+
@leaf = LeafDoc.new
|
504
|
+
@root = NestedChild.new(:leaf => @leaf)
|
505
|
+
end
|
506
|
+
|
507
|
+
it "calls the root document's _update_attributes with a full attribute path and not safe" do
|
508
|
+
@root.should_receive(:_update_attributes).with({'leaf.data' => 'data'}, false)
|
509
|
+
@leaf.update_attributes(:data => 'data')
|
510
|
+
end
|
511
|
+
|
512
|
+
it "(with bang!) calls the root document's _update_attributes with a full attribute path and safe" do
|
513
|
+
@root.should_receive(:_update_attributes).with({'leaf.data' => 'data'}, true)
|
514
|
+
@leaf.update_attributes!(:data => 'data')
|
515
|
+
end
|
516
|
+
end
|
517
|
+
|
518
|
+
context "with has_many, update_attributes" do
|
519
|
+
before do
|
520
|
+
@leaf = LeafDoc.new
|
521
|
+
NestedDocsRoot.new(:nested_children => [NestedChild.new(:leaf => @leaf)])
|
522
|
+
end
|
523
|
+
|
524
|
+
it "returns false" do
|
525
|
+
@leaf.update_attributes(:data => 'data').should be_false
|
526
|
+
end
|
527
|
+
|
528
|
+
it "sets an error on base" do
|
529
|
+
@leaf.update_attributes(:data => 'data')
|
530
|
+
@leaf.errors[:base].should_not be_nil
|
531
|
+
end
|
532
|
+
|
533
|
+
it "(with bang!) returns false" do
|
534
|
+
@leaf.update_attributes!(:data => 'data').should be_false
|
535
|
+
end
|
536
|
+
|
537
|
+
it "(with bang!) sets an error on base" do
|
538
|
+
@leaf.update_attributes(:data => 'data')
|
539
|
+
@leaf.errors[:base].should_not be_nil
|
540
|
+
end
|
541
|
+
end
|
542
|
+
|
543
|
+
end
|
544
|
+
|
545
|
+
describe "bson" do
|
546
|
+
class BSONTest < MongoDoc::Document
|
547
|
+
key :other
|
548
|
+
end
|
549
|
+
|
550
|
+
class BSONDerived < BSONTest
|
551
|
+
key :derived
|
552
|
+
end
|
553
|
+
|
554
|
+
class OtherObject
|
555
|
+
attr_accessor :value
|
556
|
+
end
|
557
|
+
|
558
|
+
before do
|
559
|
+
@value = 'value'
|
560
|
+
@other = OtherObject.new
|
561
|
+
@other.value = @value
|
562
|
+
@doc = BSONTest.new(:other => @other)
|
563
|
+
end
|
564
|
+
|
565
|
+
it "encodes the class for the object" do
|
566
|
+
@doc.to_bson[MongoDoc::BSON::CLASS_KEY].should == BSONTest.name
|
567
|
+
end
|
568
|
+
|
569
|
+
it "renders a json representation of the object" do
|
570
|
+
@doc.to_bson.should be_bson_eql({MongoDoc::BSON::CLASS_KEY => BSONTest.name, "other" => {MongoDoc::BSON::CLASS_KEY => OtherObject.name, "value" => @value}})
|
571
|
+
end
|
572
|
+
|
573
|
+
it "includes the _id of the object" do
|
574
|
+
@doc._id = Mongo::ObjectID.new
|
575
|
+
@doc.to_bson.should be_bson_eql({MongoDoc::BSON::CLASS_KEY => BSONTest.name, "_id" => @doc._id.to_bson, "other" => {MongoDoc::BSON::CLASS_KEY => OtherObject.name, "value" => @value}})
|
576
|
+
end
|
577
|
+
|
578
|
+
it "roundtrips the object" do
|
579
|
+
MongoDoc::BSON.decode(@doc.to_bson).should be_kind_of(BSONTest)
|
580
|
+
end
|
581
|
+
|
582
|
+
it "ignores the class hash when the :raw_json option is used" do
|
583
|
+
MongoDoc::BSON.decode(@doc.to_bson.except(MongoDoc::BSON::CLASS_KEY), :raw_json => true)['other'].should == @other.to_bson
|
584
|
+
end
|
585
|
+
|
586
|
+
it "allows for derived classes" do
|
587
|
+
derived = BSONDerived.new(:other => @other, :derived => 'derived')
|
588
|
+
MongoDoc::BSON.decode(derived.to_bson).other.should be_kind_of(OtherObject)
|
589
|
+
end
|
590
|
+
|
591
|
+
it "roundtrips embedded ruby objects" do
|
592
|
+
MongoDoc::BSON.decode(@doc.to_bson).other.should be_kind_of(OtherObject)
|
593
|
+
end
|
594
|
+
|
595
|
+
context "associations" do
|
596
|
+
context "has_one" do
|
597
|
+
class TestHasOneBsonDoc < MongoDoc::Document
|
598
|
+
has_one :subdoc
|
599
|
+
end
|
600
|
+
|
601
|
+
class SubHasOneBsonDoc < MongoDoc::Document
|
602
|
+
key :attr
|
603
|
+
end
|
604
|
+
|
605
|
+
it "#to_bson renders a bson representation of the document" do
|
606
|
+
doc = TestHasOneBsonDoc.new
|
607
|
+
subdoc = SubHasOneBsonDoc.new(:attr => "value")
|
608
|
+
bson = doc.to_bson
|
609
|
+
bson["subdoc"] = subdoc.to_bson
|
610
|
+
doc.subdoc = subdoc
|
611
|
+
doc.to_bson.should == bson
|
612
|
+
end
|
613
|
+
|
614
|
+
it "roundtrips" do
|
615
|
+
doc = TestHasOneBsonDoc.new
|
616
|
+
subdoc = SubHasOneBsonDoc.new(:attr => "value")
|
617
|
+
doc.subdoc = subdoc
|
618
|
+
MongoDoc::BSON.decode(doc.to_bson).should == doc
|
619
|
+
end
|
620
|
+
end
|
621
|
+
|
622
|
+
context "has_many" do
|
623
|
+
|
624
|
+
class SubHasManyBsonDoc < MongoDoc::Document
|
625
|
+
key :attr
|
626
|
+
end
|
627
|
+
|
628
|
+
class TestHasManyBsonDoc < MongoDoc::Document
|
629
|
+
has_many :subdoc, :class_name => 'SubHasManyBsonDoc'
|
630
|
+
end
|
631
|
+
|
632
|
+
it "#to_bson renders a bson representation of the document" do
|
633
|
+
doc = TestHasManyBsonDoc.new
|
634
|
+
subdoc = SubHasManyBsonDoc.new(:attr => "value")
|
635
|
+
bson = doc.to_bson
|
636
|
+
bson["subdoc"] = [subdoc].to_bson
|
637
|
+
doc.subdoc = subdoc
|
638
|
+
doc.to_bson.should == bson
|
639
|
+
end
|
640
|
+
|
641
|
+
it "roundtrips" do
|
642
|
+
doc = TestHasManyBsonDoc.new
|
643
|
+
subdoc = SubHasManyBsonDoc.new(:attr => "value")
|
644
|
+
doc.subdoc = subdoc
|
645
|
+
MongoDoc::BSON.decode(doc.to_bson).should == doc
|
646
|
+
end
|
647
|
+
|
648
|
+
it "roundtrips the proxy" do
|
649
|
+
doc = TestHasManyBsonDoc.new(:subdoc => SubHasManyBsonDoc.new(:attr => "value"))
|
650
|
+
MongoDoc::Proxy.should === MongoDoc::BSON.decode(doc.to_bson).subdoc
|
651
|
+
end
|
652
|
+
end
|
653
|
+
end
|
654
|
+
end
|
655
|
+
|
656
|
+
context "misc class methods" do
|
657
|
+
class ClassMethods < MongoDoc::Document
|
658
|
+
end
|
659
|
+
|
660
|
+
it ".count calls the collection count" do
|
661
|
+
collection = stub('collection')
|
662
|
+
ClassMethods.stub(:collection).and_return(collection)
|
663
|
+
collection.should_receive(:count).and_return(1)
|
664
|
+
ClassMethods.count
|
665
|
+
end
|
666
|
+
|
667
|
+
it ".collection_name returns the name of the collection for this class" do
|
668
|
+
ClassMethods.collection_name.should == ClassMethods.to_s.tableize.gsub('/', '.')
|
669
|
+
end
|
670
|
+
|
671
|
+
it ".collection returns a wrapped MongoDoc::Collection" do
|
672
|
+
db = stub('db')
|
673
|
+
db.should_receive(:collection).with(ClassMethods.to_s.tableize.gsub('/', '.'))
|
674
|
+
MongoDoc.should_receive(:database).and_return(db)
|
675
|
+
MongoDoc::Collection.should === ClassMethods.collection
|
676
|
+
end
|
677
|
+
end
|
678
|
+
end
|
data/spec/parent_proxy_spec.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
2
|
|
3
|
-
describe "MongoDoc::
|
3
|
+
describe "MongoDoc::ParentProxy" do
|
4
4
|
class Parent
|
5
5
|
def path_to_root(attrs)
|
6
6
|
attrs
|
@@ -13,7 +13,7 @@ describe "MongoDoc::Document::ParentProxy" do
|
|
13
13
|
end
|
14
14
|
|
15
15
|
subject do
|
16
|
-
MongoDoc::
|
16
|
+
MongoDoc::ParentProxy.new(@parent, @assoc_name)
|
17
17
|
end
|
18
18
|
|
19
19
|
it "has the association name" do
|
@@ -26,13 +26,13 @@ describe "MongoDoc::Document::ParentProxy" do
|
|
26
26
|
|
27
27
|
it "requires a parent" do
|
28
28
|
expect do
|
29
|
-
MongoDoc::
|
29
|
+
MongoDoc::ParentProxy.new(nil, @assoc_name)
|
30
30
|
end.should raise_error
|
31
31
|
end
|
32
32
|
|
33
33
|
it "requires an association name" do
|
34
34
|
expect do
|
35
|
-
MongoDoc::
|
35
|
+
MongoDoc::ParentProxy.new(@parent, nil)
|
36
36
|
end.should raise_error
|
37
37
|
end
|
38
38
|
|
data/spec/spec_helper.rb
CHANGED