mongo_mapper-unstable 2010.3.8 → 2010.06.23

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.
Files changed (143) hide show
  1. data/README.rdoc +4 -8
  2. data/bin/mmconsole +1 -1
  3. data/examples/keys.rb +37 -0
  4. data/examples/plugins.rb +41 -0
  5. data/examples/querying.rb +35 -0
  6. data/examples/scopes.rb +52 -0
  7. data/lib/mongo_mapper/connection.rb +83 -0
  8. data/lib/mongo_mapper/document.rb +11 -329
  9. data/lib/mongo_mapper/embedded_document.rb +9 -38
  10. data/lib/mongo_mapper/exceptions.rb +30 -0
  11. data/lib/mongo_mapper/extensions/array.rb +19 -0
  12. data/lib/mongo_mapper/extensions/binary.rb +22 -0
  13. data/lib/mongo_mapper/extensions/boolean.rb +44 -0
  14. data/lib/mongo_mapper/extensions/date.rb +25 -0
  15. data/lib/mongo_mapper/extensions/float.rb +14 -0
  16. data/lib/mongo_mapper/extensions/hash.rb +14 -0
  17. data/lib/mongo_mapper/extensions/integer.rb +19 -0
  18. data/lib/mongo_mapper/extensions/kernel.rb +9 -0
  19. data/lib/mongo_mapper/extensions/nil_class.rb +18 -0
  20. data/lib/mongo_mapper/extensions/object.rb +27 -0
  21. data/lib/mongo_mapper/extensions/object_id.rb +30 -0
  22. data/lib/mongo_mapper/extensions/set.rb +20 -0
  23. data/lib/mongo_mapper/extensions/string.rb +18 -0
  24. data/lib/mongo_mapper/extensions/time.rb +29 -0
  25. data/lib/mongo_mapper/plugins/accessible.rb +44 -0
  26. data/lib/mongo_mapper/plugins/associations/base.rb +7 -6
  27. data/lib/mongo_mapper/plugins/associations/belongs_to_polymorphic_proxy.rb +5 -6
  28. data/lib/mongo_mapper/plugins/associations/belongs_to_proxy.rb +5 -6
  29. data/lib/mongo_mapper/plugins/associations/collection.rb +1 -0
  30. data/lib/mongo_mapper/plugins/associations/embedded_collection.rb +2 -1
  31. data/lib/mongo_mapper/plugins/associations/in_array_proxy.rb +25 -39
  32. data/lib/mongo_mapper/plugins/associations/many_documents_as_proxy.rb +4 -4
  33. data/lib/mongo_mapper/plugins/associations/many_documents_proxy.rb +36 -46
  34. data/lib/mongo_mapper/plugins/associations/many_embedded_polymorphic_proxy.rb +1 -0
  35. data/lib/mongo_mapper/plugins/associations/many_embedded_proxy.rb +5 -4
  36. data/lib/mongo_mapper/plugins/associations/many_polymorphic_proxy.rb +1 -0
  37. data/lib/mongo_mapper/plugins/associations/one_embedded_proxy.rb +40 -0
  38. data/lib/mongo_mapper/plugins/associations/one_proxy.rb +7 -7
  39. data/lib/mongo_mapper/plugins/associations/proxy.rb +16 -8
  40. data/lib/mongo_mapper/plugins/associations.rb +14 -22
  41. data/lib/mongo_mapper/plugins/caching.rb +21 -0
  42. data/lib/mongo_mapper/plugins/callbacks.rb +17 -5
  43. data/lib/mongo_mapper/plugins/clone.rb +10 -4
  44. data/lib/mongo_mapper/plugins/descendants.rb +3 -2
  45. data/lib/mongo_mapper/plugins/dirty.rb +1 -0
  46. data/lib/mongo_mapper/plugins/document.rb +41 -0
  47. data/lib/mongo_mapper/{support/find.rb → plugins/dynamic_querying/dynamic_finder.rb} +3 -36
  48. data/lib/mongo_mapper/plugins/dynamic_querying.rb +43 -0
  49. data/lib/mongo_mapper/plugins/embedded_document.rb +49 -0
  50. data/lib/mongo_mapper/plugins/equality.rb +4 -10
  51. data/lib/mongo_mapper/plugins/identity_map.rb +29 -23
  52. data/lib/mongo_mapper/plugins/indexes.rb +12 -0
  53. data/lib/mongo_mapper/plugins/inspect.rb +1 -0
  54. data/lib/mongo_mapper/plugins/keys/key.rb +55 -0
  55. data/lib/mongo_mapper/plugins/keys.rb +85 -110
  56. data/lib/mongo_mapper/plugins/logger.rb +1 -0
  57. data/lib/mongo_mapper/plugins/modifiers.rb +41 -16
  58. data/lib/mongo_mapper/plugins/pagination.rb +5 -15
  59. data/lib/mongo_mapper/plugins/persistence.rb +69 -0
  60. data/lib/mongo_mapper/plugins/protected.rb +9 -1
  61. data/lib/mongo_mapper/plugins/querying/decorator.rb +46 -0
  62. data/lib/mongo_mapper/plugins/querying/plucky_methods.rb +15 -0
  63. data/lib/mongo_mapper/plugins/querying.rb +176 -0
  64. data/lib/mongo_mapper/plugins/rails.rb +6 -1
  65. data/lib/mongo_mapper/plugins/safe.rb +28 -0
  66. data/lib/mongo_mapper/plugins/sci.rb +32 -0
  67. data/lib/mongo_mapper/plugins/scopes.rb +21 -0
  68. data/lib/mongo_mapper/plugins/serialization.rb +5 -4
  69. data/lib/mongo_mapper/plugins/timestamps.rb +2 -1
  70. data/lib/mongo_mapper/plugins/userstamps.rb +1 -0
  71. data/lib/mongo_mapper/plugins/validations.rb +9 -5
  72. data/lib/mongo_mapper/plugins.rb +1 -20
  73. data/lib/mongo_mapper/support/descendant_appends.rb +5 -6
  74. data/lib/mongo_mapper/version.rb +4 -0
  75. data/lib/mongo_mapper.rb +71 -128
  76. data/test/{NOTE_ON_TESTING → _NOTE_ON_TESTING} +0 -0
  77. data/test/functional/associations/test_belongs_to_polymorphic_proxy.rb +5 -5
  78. data/test/functional/associations/test_belongs_to_proxy.rb +13 -21
  79. data/test/functional/associations/test_in_array_proxy.rb +7 -9
  80. data/test/functional/associations/test_many_documents_as_proxy.rb +5 -5
  81. data/test/functional/associations/test_many_documents_proxy.rb +186 -64
  82. data/test/functional/associations/test_many_embedded_polymorphic_proxy.rb +22 -22
  83. data/test/functional/associations/test_many_embedded_proxy.rb +32 -32
  84. data/test/functional/associations/test_many_polymorphic_proxy.rb +47 -47
  85. data/test/functional/associations/test_one_embedded_proxy.rb +67 -0
  86. data/test/functional/associations/test_one_proxy.rb +70 -49
  87. data/test/functional/test_accessible.rb +168 -0
  88. data/test/functional/test_associations.rb +11 -11
  89. data/test/functional/test_binary.rb +5 -5
  90. data/test/functional/test_caching.rb +76 -0
  91. data/test/functional/test_callbacks.rb +104 -34
  92. data/test/functional/test_dirty.rb +16 -16
  93. data/test/functional/test_document.rb +12 -924
  94. data/test/functional/test_dynamic_querying.rb +75 -0
  95. data/test/functional/test_embedded_document.rb +88 -8
  96. data/test/functional/test_identity_map.rb +41 -43
  97. data/test/functional/{test_indexing.rb → test_indexes.rb} +3 -5
  98. data/test/functional/test_logger.rb +1 -1
  99. data/test/functional/test_modifiers.rb +275 -181
  100. data/test/functional/test_pagination.rb +13 -15
  101. data/test/functional/test_protected.rb +25 -11
  102. data/test/functional/test_querying.rb +873 -0
  103. data/test/functional/test_safe.rb +76 -0
  104. data/test/functional/test_sci.rb +230 -0
  105. data/test/functional/test_scopes.rb +171 -0
  106. data/test/functional/test_string_id_compatibility.rb +11 -11
  107. data/test/functional/test_timestamps.rb +0 -2
  108. data/test/functional/test_userstamps.rb +0 -1
  109. data/test/functional/test_validations.rb +44 -31
  110. data/test/models.rb +18 -17
  111. data/test/{active_model_lint_test.rb → test_active_model_lint.rb} +3 -1
  112. data/test/test_helper.rb +59 -16
  113. data/test/unit/associations/test_base.rb +47 -42
  114. data/test/unit/associations/test_proxy.rb +15 -15
  115. data/test/unit/serializers/test_json_serializer.rb +29 -29
  116. data/test/unit/test_clone.rb +69 -0
  117. data/test/unit/test_descendant_appends.rb +3 -3
  118. data/test/unit/test_document.rb +49 -67
  119. data/test/unit/test_dynamic_finder.rb +53 -51
  120. data/test/unit/test_embedded_document.rb +19 -38
  121. data/test/unit/{test_support.rb → test_extensions.rb} +136 -122
  122. data/test/unit/test_key.rb +185 -0
  123. data/test/unit/test_keys.rb +29 -147
  124. data/test/unit/test_mongo_mapper.rb +3 -48
  125. data/test/unit/test_pagination.rb +1 -150
  126. data/test/unit/test_rails.rb +77 -19
  127. data/test/unit/test_rails_compatibility.rb +12 -12
  128. data/test/unit/test_serialization.rb +5 -5
  129. data/test/unit/test_time_zones.rb +9 -9
  130. data/test/unit/test_validations.rb +46 -46
  131. metadata +157 -155
  132. data/.gitignore +0 -10
  133. data/Rakefile +0 -55
  134. data/VERSION +0 -1
  135. data/lib/mongo_mapper/plugins/pagination/proxy.rb +0 -72
  136. data/lib/mongo_mapper/query.rb +0 -130
  137. data/lib/mongo_mapper/support.rb +0 -215
  138. data/mongo_mapper.gemspec +0 -196
  139. data/performance/read_write.rb +0 -52
  140. data/specs.watchr +0 -51
  141. data/test/support/custom_matchers.rb +0 -55
  142. data/test/support/timing.rb +0 -16
  143. data/test/unit/test_query.rb +0 -340
@@ -4,8 +4,6 @@ require 'models'
4
4
  class DocumentTest < Test::Unit::TestCase
5
5
  def setup
6
6
  @document = Doc do
7
- set_collection_name 'users'
8
-
9
7
  key :first_name, String
10
8
  key :last_name, String
11
9
  key :age, Integer
@@ -132,488 +130,6 @@ class DocumentTest < Test::Unit::TestCase
132
130
  end
133
131
  end
134
132
 
135
- context "ClassMethods#create (single document)" do
136
- setup do
137
- @doc_instance = @document.create({:first_name => 'John', :last_name => 'Nunemaker', :age => '27'})
138
- end
139
-
140
- should "create a document in correct collection" do
141
- @document.count.should == 1
142
- end
143
-
144
- should "automatically set id" do
145
- @doc_instance.id.should be_instance_of(Mongo::ObjectID)
146
- @doc_instance._id.should be_instance_of(Mongo::ObjectID)
147
- end
148
-
149
- should "no longer be new?" do
150
- @doc_instance.new?.should be_false
151
- end
152
-
153
- should "return instance of document" do
154
- @doc_instance.should be_instance_of(@document)
155
- @doc_instance.first_name.should == 'John'
156
- @doc_instance.last_name.should == 'Nunemaker'
157
- @doc_instance.age.should == 27
158
- end
159
-
160
- should "not fail if no attributes provided" do
161
- document = Doc()
162
- lambda { document.create }.should change { document.count }.by(1)
163
- end
164
- end
165
-
166
- context "ClassMethods#create (multiple documents)" do
167
- setup do
168
- @doc_instances = @document.create([
169
- {:first_name => 'John', :last_name => 'Nunemaker', :age => '27'},
170
- {:first_name => 'Steve', :last_name => 'Smith', :age => '28'},
171
- ])
172
- end
173
-
174
- should "create multiple documents" do
175
- @document.count.should == 2
176
- end
177
-
178
- should "return an array of doc instances" do
179
- @doc_instances.map do |doc_instance|
180
- doc_instance.should be_instance_of(@document)
181
- end
182
- end
183
- end
184
-
185
- context "ClassMethods#update (single document)" do
186
- setup do
187
- doc = @document.create({:first_name => 'John', :last_name => 'Nunemaker', :age => '27'})
188
- @doc_instance = @document.update(doc._id, {:age => 40})
189
- end
190
-
191
- should "update attributes provided" do
192
- @doc_instance.age.should == 40
193
- end
194
-
195
- should "not update existing attributes that were not set to update" do
196
- @doc_instance.first_name.should == 'John'
197
- @doc_instance.last_name.should == 'Nunemaker'
198
- end
199
-
200
- should "not create new document" do
201
- @document.count.should == 1
202
- end
203
-
204
- should "raise error if not provided id" do
205
- doc = @document.create({:first_name => 'John', :last_name => 'Nunemaker', :age => '27'})
206
- lambda { @document.update }.should raise_error(ArgumentError)
207
- end
208
-
209
- should "raise error if not provided attributes" do
210
- doc = @document.create({:first_name => 'John', :last_name => 'Nunemaker', :age => '27'})
211
- lambda { @document.update(doc._id) }.should raise_error(ArgumentError)
212
- lambda { @document.update(doc._id, [1]) }.should raise_error(ArgumentError)
213
- end
214
- end
215
-
216
- context "ClassMethods#update (multiple documents)" do
217
- setup do
218
- @doc1 = @document.create({:first_name => 'John', :last_name => 'Nunemaker', :age => '27'})
219
- @doc2 = @document.create({:first_name => 'Steve', :last_name => 'Smith', :age => '28'})
220
-
221
- @doc_instances = @document.update({
222
- @doc1._id => {:age => 30},
223
- @doc2._id => {:age => 30},
224
- })
225
- end
226
-
227
- should "not create any new documents" do
228
- @document.count.should == 2
229
- end
230
-
231
- should "should return an array of doc instances" do
232
- @doc_instances.map do |doc_instance|
233
- doc_instance.should be_instance_of(@document)
234
- end
235
- end
236
-
237
- should "update the documents" do
238
- @document.find(@doc1._id).age.should == 30
239
- @document.find(@doc2._id).age.should == 30
240
- end
241
-
242
- should "raise error if not a hash" do
243
- lambda { @document.update([1, 2]) }.should raise_error(ArgumentError)
244
- end
245
- end
246
-
247
- context "ClassMethods#find" do
248
- setup do
249
- @doc1 = @document.create({:first_name => 'John', :last_name => 'Nunemaker', :age => '27'})
250
- @doc2 = @document.create({:first_name => 'Steve', :last_name => 'Smith', :age => '28'})
251
- @doc3 = @document.create({:first_name => 'Steph', :last_name => 'Nunemaker', :age => '26'})
252
- end
253
-
254
- should "return nil if nothing provided for find" do
255
- @document.find.should be_nil
256
- end
257
-
258
- should "raise document not found if nothing provided for find!" do
259
- assert_raises(MongoMapper::DocumentNotFound) do
260
- @document.find!
261
- end
262
- end
263
-
264
- should "raise error if trying to find with :all, :first, or :last" do
265
- [:all, :first, :last].each do |m|
266
- assert_raises(ArgumentError) { @document.find(m) }
267
- end
268
-
269
- [:all, :first, :last].each do |m|
270
- assert_raises(ArgumentError) { @document.find!(m) }
271
- end
272
- end
273
-
274
- context "(with a single id)" do
275
- should "work" do
276
- @document.find(@doc1._id).should == @doc1
277
- end
278
-
279
- should "return nil if document not found with find" do
280
- @document.find(123).should be_nil
281
- end
282
-
283
- should "raise error if document not found with find!" do
284
- assert_raises(MongoMapper::DocumentNotFound) { @document.find!(123) }
285
- end
286
- end
287
-
288
- context "(with multiple id's)" do
289
- should "work as arguments" do
290
- @document.find(@doc1._id, @doc2._id).should == [@doc1, @doc2]
291
- end
292
-
293
- should "work as array" do
294
- @document.find([@doc1._id, @doc2._id]).should == [@doc1, @doc2]
295
- end
296
-
297
- should "compact not found when using find" do
298
- @document.find(@doc1._id, 1234).should == [@doc1]
299
- end
300
-
301
- should "raise error if not all found when using find!" do
302
- assert_raises(MongoMapper::DocumentNotFound) do
303
- @document.find!(@doc1._id, 1234)
304
- end
305
- end
306
-
307
- should "return array if array with one element" do
308
- @document.find([@doc1._id]).should == [@doc1]
309
- end
310
- end
311
-
312
- should "be able to find using condition auto-detection" do
313
- @document.first(:first_name => 'John').should == @doc1
314
- @document.all(:last_name => 'Nunemaker', :order => 'age desc').should == [@doc1, @doc3]
315
- end
316
-
317
- context "#all" do
318
- should "find all documents based on criteria" do
319
- @document.all(:order => 'first_name').should == [@doc1, @doc3, @doc2]
320
- @document.all(:last_name => 'Nunemaker', :order => 'age desc').should == [@doc1, @doc3]
321
- end
322
- end
323
-
324
- context "#first" do
325
- should "find first document based on criteria" do
326
- @document.first(:order => 'first_name').should == @doc1
327
- @document.first(:age => 28).should == @doc2
328
- end
329
- end
330
-
331
- context "#last" do
332
- should "find last document based on criteria" do
333
- @document.last(:order => 'age').should == @doc2
334
- @document.last(:order => 'age', :age => 28).should == @doc2
335
- end
336
-
337
- should "raise error if no order provided" do
338
- lambda { @document.last() }.should raise_error
339
- end
340
- end
341
-
342
- context "#find_by..." do
343
- should "find document based on argument" do
344
- @document.find_by_first_name('John').should == @doc1
345
- @document.find_by_last_name('Nunemaker', :order => 'age desc').should == @doc1
346
- @document.find_by_age(27).should == @doc1
347
- end
348
-
349
- should "not raise error" do
350
- @document.find_by_first_name('Mongo').should be_nil
351
- end
352
-
353
- should "define a method for each key" do
354
- @document.methods(false).select { |e| e =~ /^find_by_/ }.size == @document.keys.size
355
- end
356
- end
357
-
358
- context "#find_each" do
359
- should "yield all documents found, based on criteria" do
360
- yield_documents = []
361
- @document.find_each(:order => "first_name") {|doc| yield_documents << doc }
362
- yield_documents.should == [@doc1, @doc3, @doc2]
363
-
364
- yield_documents = []
365
- @document.find_each(:last_name => 'Nunemaker', :order => 'age desc') {|doc| yield_documents << doc }
366
- yield_documents.should == [@doc1, @doc3]
367
- end
368
- end
369
-
370
- context "dynamic finders" do
371
- should "find document based on all arguments" do
372
- @document.find_by_first_name_and_last_name_and_age('John', 'Nunemaker', 27).should == @doc1
373
- end
374
-
375
- should "not find the document if an argument is wrong" do
376
- @document.find_by_first_name_and_last_name_and_age('John', 'Nunemaker', 28).should be_nil
377
- end
378
-
379
- should "find all documents based on arguments" do
380
- docs = @document.find_all_by_last_name('Nunemaker')
381
- docs.should be_kind_of(Array)
382
- docs.should include(@doc1)
383
- docs.should include(@doc3)
384
- end
385
-
386
- should "initialize document with given arguments" do
387
- doc = @document.find_or_initialize_by_first_name_and_last_name('David', 'Cuadrado')
388
- doc.should be_new
389
- doc.first_name.should == 'David'
390
- end
391
-
392
- should "not initialize document if document is found" do
393
- doc = @document.find_or_initialize_by_first_name('John')
394
- doc.should_not be_new
395
- end
396
-
397
- should "create document with given arguments" do
398
- doc = @document.find_or_create_by_first_name_and_last_name('David', 'Cuadrado')
399
- doc.should_not be_new
400
- doc.first_name.should == 'David'
401
- end
402
-
403
- should "raise error if document is not found when using !" do
404
- lambda {
405
- @document.find_by_first_name_and_last_name!(1,2)
406
- }.should raise_error(MongoMapper::DocumentNotFound)
407
- end
408
- end
409
- end # finding documents
410
-
411
- context "ClassMethods#find_by_id" do
412
- setup do
413
- @doc1 = @document.create({:first_name => 'John', :last_name => 'Nunemaker', :age => '27'})
414
- @doc2 = @document.create({:first_name => 'Steve', :last_name => 'Smith', :age => '28'})
415
- end
416
-
417
- should "be able to find by id" do
418
- @document.find_by_id(@doc1._id).should == @doc1
419
- @document.find_by_id(@doc2._id).should == @doc2
420
- end
421
-
422
- should "return nil if document not found" do
423
- @document.find_by_id(1234).should be_nil
424
- end
425
- end
426
-
427
- context "first_or_create" do
428
- should "find if exists" do
429
- created = @document.create(:first_name => 'John', :last_name => 'Nunemaker')
430
- lambda {
431
- found = @document.first_or_create(:first_name => 'John', :last_name => 'Nunemaker')
432
- found.should == created
433
- }.should_not change { @document.count }
434
- end
435
-
436
- should "create if not found" do
437
- lambda {
438
- created = @document.first_or_create(:first_name => 'John', :last_name => 'Nunemaker')
439
- created.first_name.should == 'John'
440
- created.last_name.should == 'Nunemaker'
441
- }.should change { @document.count }.by(1)
442
- end
443
- end
444
-
445
- context "first_or_new" do
446
- should "find if exists" do
447
- created = @document.create(:first_name => 'John', :last_name => 'Nunemaker')
448
- lambda {
449
- found = @document.first_or_new(:first_name => 'John', :last_name => 'Nunemaker')
450
- found.should == created
451
- }.should_not change { @document.count }
452
- end
453
-
454
- should "initialize if not found" do
455
- lambda {
456
- created = @document.first_or_new(:first_name => 'John', :last_name => 'Nunemaker')
457
- created.first_name.should == 'John'
458
- created.last_name.should == 'Nunemaker'
459
- created.should be_new
460
- }.should_not change { @document.count }
461
- end
462
- end
463
-
464
- context "ClassMethods#delete (single document)" do
465
- setup do
466
- @doc1 = @document.create({:first_name => 'John', :last_name => 'Nunemaker', :age => '27'})
467
- @doc2 = @document.create({:first_name => 'Steve', :last_name => 'Smith', :age => '28'})
468
- @document.delete(@doc1._id)
469
- end
470
-
471
- should "remove document from collection" do
472
- @document.count.should == 1
473
- end
474
-
475
- should "not remove other documents" do
476
- @document.find(@doc2._id).should_not be(nil)
477
- end
478
- end
479
-
480
- context "ClassMethods#delete (multiple documents)" do
481
- should "work with multiple arguments" do
482
- @doc1 = @document.create({:first_name => 'John', :last_name => 'Nunemaker', :age => '27'})
483
- @doc2 = @document.create({:first_name => 'Steve', :last_name => 'Smith', :age => '28'})
484
- @doc3 = @document.create({:first_name => 'Steph', :last_name => 'Nunemaker', :age => '26'})
485
- @document.delete(@doc1._id, @doc2._id)
486
-
487
- @document.count.should == 1
488
- end
489
-
490
- should "work with array as argument" do
491
- @doc1 = @document.create({:first_name => 'John', :last_name => 'Nunemaker', :age => '27'})
492
- @doc2 = @document.create({:first_name => 'Steve', :last_name => 'Smith', :age => '28'})
493
- @doc3 = @document.create({:first_name => 'Steph', :last_name => 'Nunemaker', :age => '26'})
494
- @document.delete([@doc1._id, @doc2._id])
495
-
496
- @document.count.should == 1
497
- end
498
- end
499
-
500
- context "ClassMethods#delete_all" do
501
- setup do
502
- @doc1 = @document.create({:first_name => 'John', :last_name => 'Nunemaker', :age => '27'})
503
- @doc2 = @document.create({:first_name => 'Steve', :last_name => 'Smith', :age => '28'})
504
- @doc3 = @document.create({:first_name => 'Steph', :last_name => 'Nunemaker', :age => '26'})
505
- end
506
-
507
- should "remove all documents when given no conditions" do
508
- @document.delete_all
509
- @document.count.should == 0
510
- end
511
-
512
- should "only remove matching documents when given conditions" do
513
- @document.delete_all({:first_name => 'John'})
514
- @document.count.should == 2
515
- end
516
-
517
- should "convert the conditions to mongo criteria" do
518
- @document.delete_all(:age => [26, 27])
519
- @document.count.should == 1
520
- end
521
- end
522
-
523
- context "ClassMethods#destroy (single document)" do
524
- setup do
525
- @doc1 = @document.create({:first_name => 'John', :last_name => 'Nunemaker', :age => '27'})
526
- @doc2 = @document.create({:first_name => 'Steve', :last_name => 'Smith', :age => '28'})
527
- @document.destroy(@doc1._id)
528
- end
529
-
530
- should "remove document from collection" do
531
- @document.count.should == 1
532
- end
533
-
534
- should "not remove other documents" do
535
- @document.find(@doc2._id).should_not be(nil)
536
- end
537
- end
538
-
539
- context "ClassMethods#destroy (multiple documents)" do
540
- should "work with multiple arguments" do
541
- @doc1 = @document.create({:first_name => 'John', :last_name => 'Nunemaker', :age => '27'})
542
- @doc2 = @document.create({:first_name => 'Steve', :last_name => 'Smith', :age => '28'})
543
- @doc3 = @document.create({:first_name => 'Steph', :last_name => 'Nunemaker', :age => '26'})
544
- @document.destroy(@doc1._id, @doc2._id)
545
-
546
- @document.count.should == 1
547
- end
548
-
549
- should "work with array as argument" do
550
- @doc1 = @document.create({:first_name => 'John', :last_name => 'Nunemaker', :age => '27'})
551
- @doc2 = @document.create({:first_name => 'Steve', :last_name => 'Smith', :age => '28'})
552
- @doc3 = @document.create({:first_name => 'Steph', :last_name => 'Nunemaker', :age => '26'})
553
- @document.destroy([@doc1._id, @doc2._id])
554
-
555
- @document.count.should == 1
556
- end
557
- end
558
-
559
- context "ClassMethods#destroy_all" do
560
- setup do
561
- @doc1 = @document.create({:first_name => 'John', :last_name => 'Nunemaker', :age => '27'})
562
- @doc2 = @document.create({:first_name => 'Steve', :last_name => 'Smith', :age => '28'})
563
- @doc3 = @document.create({:first_name => 'Steph', :last_name => 'Nunemaker', :age => '26'})
564
- end
565
-
566
- should "remove all documents when given no conditions" do
567
- @document.destroy_all
568
- @document.count.should == 0
569
- end
570
-
571
- should "only remove matching documents when given conditions" do
572
- @document.destroy_all(:first_name => 'John')
573
- @document.count.should == 2
574
- @document.destroy_all(:age => 26)
575
- @document.count.should == 1
576
- end
577
-
578
- should "convert the conditions to mongo criteria" do
579
- @document.destroy_all(:age => [26, 27])
580
- @document.count.should == 1
581
- end
582
- end
583
-
584
- context "ClassMethods#count" do
585
- setup do
586
- @doc1 = @document.create({:first_name => 'John', :last_name => 'Nunemaker', :age => '27'})
587
- @doc2 = @document.create({:first_name => 'Steve', :last_name => 'Smith', :age => '28'})
588
- @doc3 = @document.create({:first_name => 'Steph', :last_name => 'Nunemaker', :age => '26'})
589
- end
590
-
591
- should "count all with no arguments" do
592
- @document.count.should == 3
593
- end
594
-
595
- should "return 0 if there are no documents in the collection" do
596
- @document.delete_all
597
- @document.count.should == 0
598
- end
599
-
600
- should "return 0 if the collection does not exist" do
601
- klass = Doc do
602
- set_collection_name 'foobarbazwickdoesnotexist'
603
- end
604
-
605
- klass.count.should == 0
606
- end
607
-
608
- should "return count for matching documents if conditions provided" do
609
- @document.count(:age => 27).should == 1
610
- end
611
-
612
- should "convert the conditions to mongo criteria" do
613
- @document.count(:age => [26, 27]).should == 2
614
- end
615
- end
616
-
617
133
  should "have instance method for collection" do
618
134
  @document.new.collection.name.should == @document.collection.name
619
135
  end
@@ -622,272 +138,6 @@ class DocumentTest < Test::Unit::TestCase
622
138
  @document.new.database.should == @document.database
623
139
  end
624
140
 
625
- context "#update_attributes (new document)" do
626
- setup do
627
- @doc = @document.new(:first_name => 'John', :age => '27')
628
- @doc.update_attributes(:first_name => 'Johnny', :age => 30)
629
- end
630
-
631
- should "insert document into the collection" do
632
- @document.count.should == 1
633
- end
634
-
635
- should "assign an id for the document" do
636
- @doc.id.should be_instance_of(Mongo::ObjectID)
637
- end
638
-
639
- should "save attributes" do
640
- @doc.first_name.should == 'Johnny'
641
- @doc.age.should == 30
642
- end
643
-
644
- should "update attributes in the database" do
645
- doc = @doc.reload
646
- doc.should == @doc
647
- doc.first_name.should == 'Johnny'
648
- doc.age.should == 30
649
- end
650
-
651
- should "allow updating custom attributes" do
652
- @doc.update_attributes(:gender => 'mALe')
653
- @doc.reload.gender.should == 'mALe'
654
- end
655
- end
656
-
657
- context "#update_attributes (existing document)" do
658
- setup do
659
- @doc = @document.create(:first_name => 'John', :age => '27')
660
- @doc.update_attributes(:first_name => 'Johnny', :age => 30)
661
- end
662
-
663
- should "not insert document into collection" do
664
- @document.count.should == 1
665
- end
666
-
667
- should "update attributes" do
668
- @doc.first_name.should == 'Johnny'
669
- @doc.age.should == 30
670
- end
671
-
672
- should "update attributes in the database" do
673
- doc = @doc.reload
674
- doc.first_name.should == 'Johnny'
675
- doc.age.should == 30
676
- end
677
- end
678
-
679
- context "#update_attributes (return value)" do
680
- setup do
681
- @document.key :foo, String, :required => true
682
- end
683
-
684
- should "be true if document valid" do
685
- @document.new.update_attributes(:foo => 'bar').should be_true
686
- end
687
-
688
- should "be false if document not valid" do
689
- @document.new.update_attributes({}).should be_false
690
- end
691
- end
692
-
693
- context "#save (new document)" do
694
- setup do
695
- @doc = @document.new(:first_name => 'John', :age => '27')
696
- @doc.save
697
- end
698
-
699
- should "insert document into the collection" do
700
- @document.count.should == 1
701
- end
702
-
703
- should "assign an id for the document" do
704
- @doc.id.should be_instance_of(Mongo::ObjectID)
705
- end
706
-
707
- should "save attributes" do
708
- @doc.first_name.should == 'John'
709
- @doc.age.should == 27
710
- end
711
-
712
- should "update attributes in the database" do
713
- doc = @doc.reload
714
- doc.should == @doc
715
- doc.first_name.should == 'John'
716
- doc.age.should == 27
717
- end
718
-
719
- should "allow to add custom attributes to the document" do
720
- @doc = @document.new(:first_name => 'David', :age => '26', :gender => 'male', :tags => [1, "2"])
721
- @doc.save
722
- doc = @doc.reload
723
- doc.gender.should == 'male'
724
- doc.tags.should == [1, "2"]
725
- end
726
-
727
- should "allow to use custom methods to assign properties" do
728
- klass = Doc do
729
- key :name, String
730
-
731
- def realname=(value)
732
- self.name = value
733
- end
734
- end
735
-
736
- person = klass.new(:realname => 'David')
737
- person.save
738
- person.reload.name.should == 'David'
739
- end
740
-
741
- context "with key of type date" do
742
- should "save the date value as a Time object" do
743
- doc = @document.new(:first_name => 'John', :age => '27', :date => "2009-12-01")
744
- doc.save
745
- doc.date.should == Date.new(2009, 12, 1)
746
- end
747
- end
748
- end
749
-
750
- context "#save (existing document)" do
751
- setup do
752
- @doc = @document.create(:first_name => 'John', :age => '27')
753
- @doc.first_name = 'Johnny'
754
- @doc.age = 30
755
- @doc.save
756
- end
757
-
758
- should "not insert document into collection" do
759
- @document.count.should == 1
760
- end
761
-
762
- should "update attributes" do
763
- @doc.first_name.should == 'Johnny'
764
- @doc.age.should == 30
765
- end
766
-
767
- should "update attributes in the database" do
768
- doc = @doc.reload
769
- doc.first_name.should == 'Johnny'
770
- doc.age.should == 30
771
- end
772
-
773
- should "allow updating custom attributes" do
774
- @doc = @document.new(:first_name => 'David', :age => '26', :gender => 'male')
775
- @doc.gender = 'Male'
776
- @doc.save
777
- @doc.reload.gender.should == 'Male'
778
- end
779
- end
780
-
781
- context "#save (with validations off)" do
782
- setup do
783
- @document = Doc do
784
- key :name, String, :required => true
785
- end
786
- end
787
-
788
- should "insert invalid document" do
789
- doc = @document.new
790
- doc.expects(:valid?).never
791
- doc.save(:validate => false)
792
- @document.count.should == 1
793
- end
794
- end
795
-
796
- context "#save (with options)" do
797
- setup do
798
- @document = Doc do
799
- key :name, String
800
- set_collection_name 'test_indexes'
801
- end
802
- drop_indexes(@document)
803
- @document.ensure_index :name, :unique => true
804
- end
805
-
806
- should "allow passing safe" do
807
- @document.create(:name => 'John')
808
- assert_raises(Mongo::OperationFailure) do
809
- @document.new(:name => 'John').save(:safe => true)
810
- end
811
- end
812
-
813
- should "raise argument error if options has unsupported key" do
814
- assert_raises(ArgumentError) do
815
- @document.new.save(:foo => true)
816
- end
817
- end
818
- end
819
-
820
- context "#save! (with options)" do
821
- setup do
822
- @document = Doc do
823
- key :name, String
824
- set_collection_name 'test_indexes'
825
- end
826
- drop_indexes(@document)
827
- @document.ensure_index :name, :unique => true
828
- end
829
-
830
- should "allow passing safe" do
831
- @document.create(:name => 'John')
832
- assert_raises(Mongo::OperationFailure) do
833
- @document.new(:name => 'John').save!(:safe => true)
834
- end
835
- end
836
-
837
- should "raise argument error if options has unsupported key" do
838
- assert_raises(ArgumentError) do
839
- @document.new.save!(:foo => true)
840
- end
841
- end
842
-
843
- should "raise argument error if using validate as that would be pointless with save!" do
844
- assert_raises(ArgumentError) do
845
- @document.new.save!(:validate => false)
846
- end
847
- end
848
- end
849
-
850
- context "#destroy" do
851
- setup do
852
- @doc = @document.create(:first_name => 'John', :age => '27')
853
- @doc.destroy
854
- end
855
-
856
- should "remove the document from the collection" do
857
- @document.count.should == 0
858
- end
859
- end
860
-
861
- context "#delete" do
862
- setup do
863
- @doc1 = @document.create(:first_name => 'John', :last_name => 'Nunemaker', :age => '27')
864
- @doc2 = @document.create(:first_name => 'Steve', :last_name => 'Smith', :age => '28')
865
-
866
- @document.class_eval do
867
- before_destroy :before_destroy_callback
868
- after_destroy :after_destroy_callback
869
-
870
- def history; @history ||= [] end
871
- def before_destroy_callback; history << :after_destroy end
872
- def after_destroy_callback; history << :after_destroy end
873
- end
874
-
875
- @doc1.delete
876
- end
877
-
878
- should "remove document from collection" do
879
- @document.count.should == 1
880
- end
881
-
882
- should "not remove other documents" do
883
- @document.find(@doc2.id).should_not be(nil)
884
- end
885
-
886
- should "not call before/after destroy callbacks" do
887
- @doc1.history.should == []
888
- end
889
- end
890
-
891
141
  context "#destroyed?" do
892
142
  setup do
893
143
  @doc1 = @document.create(:first_name => 'John', :last_name => 'Nunemaker', :age => '27')
@@ -908,187 +158,25 @@ class DocumentTest < Test::Unit::TestCase
908
158
  end
909
159
  end
910
160
 
911
- context "Single collection inheritance" do
912
- setup do
913
- class ::DocParent
914
- include MongoMapper::Document
915
- key :_type, String
916
- key :name, String
917
- end
918
- DocParent.collection.remove
919
-
920
- class ::DocDaughter < ::DocParent; end
921
- class ::DocSon < ::DocParent; end
922
- class ::DocGrandSon < ::DocSon; end
923
-
924
- DocSon.many :children, :class_name => 'DocGrandSon'
925
-
926
- @parent = DocParent.new({:name => "Daddy Warbucks"})
927
- @daughter = DocDaughter.new({:name => "Little Orphan Annie"})
928
- end
929
-
930
- teardown do
931
- Object.send :remove_const, 'DocParent' if defined?(::DocParent)
932
- Object.send :remove_const, 'DocDaughter' if defined?(::DocDaughter)
933
- Object.send :remove_const, 'DocSon' if defined?(::DocSon)
934
- Object.send :remove_const, 'DocGrandSon' if defined?(::DocGrandSon)
935
- end
936
-
937
- should "use the same collection in the subclass" do
938
- DocDaughter.collection.name.should == DocParent.collection.name
939
- end
940
-
941
- should "assign the class name into the _type property" do
942
- @parent._type.should == 'DocParent'
943
- @daughter._type.should == 'DocDaughter'
944
- end
945
-
946
- should "load the document with the assigned type" do
947
- @parent.save
948
- @daughter.save
949
-
950
- collection = DocParent.all
951
- collection.size.should == 2
952
- collection.first.should be_kind_of(DocParent)
953
- collection.first.name.should == "Daddy Warbucks"
954
- collection.last.should be_kind_of(DocDaughter)
955
- collection.last.name.should == "Little Orphan Annie"
956
- end
957
-
958
- should "gracefully handle when the type can't be constantized" do
959
- doc = DocParent.new(:name => 'Nunes')
960
- doc._type = 'FoobarBaz'
961
- doc.save
962
-
963
- collection = DocParent.all
964
- collection.last.should == doc
965
- collection.last.should be_kind_of(DocParent)
966
- end
967
-
968
- should "find scoped to class" do
969
- john = DocSon.create(:name => 'John')
970
- steve = DocSon.create(:name => 'Steve')
971
- steph = DocDaughter.create(:name => 'Steph')
972
- carrie = DocDaughter.create(:name => 'Carrie')
973
-
974
- DocGrandSon.all(:order => 'name').should == []
975
- DocSon.all(:order => 'name').should == [john, steve]
976
- DocDaughter.all(:order => 'name').should == [carrie, steph]
977
- DocParent.all(:order => 'name').should == [carrie, john, steph, steve]
978
- end
979
-
980
- should "work with nested hash conditions" do
981
- john = DocSon.create(:name => 'John')
982
- steve = DocSon.create(:name => 'Steve')
983
- DocSon.all(:name => {'$ne' => 'Steve'}).should == [john]
984
- end
985
-
986
- should "raise error if not found scoped to class" do
987
- john = DocSon.create(:name => 'John')
988
- steph = DocDaughter.create(:name => 'Steph')
989
-
990
- lambda {
991
- DocSon.find!(steph._id)
992
- }.should raise_error(MongoMapper::DocumentNotFound)
993
- end
994
-
995
- should "not raise error for find with parent" do
996
- john = DocSon.create(:name => 'John')
997
-
998
- DocParent.find!(john._id).should == john
999
- end
1000
-
1001
- should "count scoped to class" do
1002
- john = DocSon.create(:name => 'John')
1003
- steve = DocSon.create(:name => 'Steve')
1004
- steph = DocDaughter.create(:name => 'Steph')
1005
- carrie = DocDaughter.create(:name => 'Carrie')
1006
-
1007
- DocGrandSon.count.should == 0
1008
- DocSon.count.should == 2
1009
- DocDaughter.count.should == 2
1010
- DocParent.count.should == 4
1011
- end
1012
-
1013
- should "know if it is single_collection_inherited?" do
1014
- DocParent.single_collection_inherited?.should be_false
1015
-
1016
- DocDaughter.single_collection_inherited?.should be_true
1017
- DocSon.single_collection_inherited?.should be_true
1018
- end
1019
-
1020
- should "know if single_collection_inherited_superclass?" do
1021
- DocParent.single_collection_inherited_superclass?.should be_false
1022
-
1023
- DocDaughter.single_collection_inherited_superclass?.should be_true
1024
- DocSon.single_collection_inherited_superclass?.should be_true
1025
- DocGrandSon.single_collection_inherited_superclass?.should be_true
1026
- end
1027
-
1028
- should "not be able to destroy each other" do
1029
- john = DocSon.create(:name => 'John')
1030
- steph = DocDaughter.create(:name => 'Steph')
1031
-
1032
- lambda {
1033
- DocSon.destroy(steph._id)
1034
- }.should raise_error(MongoMapper::DocumentNotFound)
1035
- end
1036
-
1037
- should "not be able to delete each other" do
1038
- john = DocSon.create(:name => 'John')
1039
- steph = DocDaughter.create(:name => 'Steph')
1040
-
1041
- lambda {
1042
- DocSon.delete(steph._id)
1043
- }.should_not change { DocParent.count }
1044
- end
1045
-
1046
- should "be able to destroy using parent" do
1047
- john = DocSon.create(:name => 'John')
1048
- steph = DocDaughter.create(:name => 'Steph')
1049
-
1050
- lambda {
1051
- DocParent.destroy_all
1052
- }.should change { DocParent.count }.by(-2)
1053
- end
1054
-
1055
- should "be able to delete using parent" do
1056
- john = DocSon.create(:name => 'John')
1057
- steph = DocDaughter.create(:name => 'Steph')
1058
-
1059
- lambda {
1060
- DocParent.delete_all
1061
- }.should change { DocParent.count }.by(-2)
1062
- end
1063
-
1064
- should "be able to reload parent inherited class" do
1065
- brian = DocParent.create(:name => 'Brian')
1066
- brian.name = 'B-Dawg'
1067
- brian.reload
1068
- brian.name.should == 'Brian'
1069
- end
1070
- end
1071
-
1072
- context "#exists?" do
161
+ context "#persisted?" do
1073
162
  setup do
1074
- @doc = @document.create(:first_name => "James", :age => 27)
163
+ @doc = @document.new(:first_name => 'John', :last_name => 'Nunemaker', :age => '27')
1075
164
  end
1076
165
 
1077
- should "be true when at least one document exists" do
1078
- @document.exists?.should == true
166
+ should "be false if new" do
167
+ @doc.should_not be_persisted
1079
168
  end
1080
169
 
1081
- should "be false when no documents exist" do
170
+ should "be false if destroyed" do
171
+ @doc.save
1082
172
  @doc.destroy
1083
- @document.exists?.should == false
173
+ @doc.should be_destroyed
174
+ @doc.should_not be_persisted
1084
175
  end
1085
176
 
1086
- should "be true when at least one document exists that matches the conditions" do
1087
- @document.exists?(:first_name => "James").should == true
1088
- end
1089
-
1090
- should "be false when no documents exist with the provided conditions" do
1091
- @document.exists?(:first_name => "Jean").should == false
177
+ should "be true if not new or destroyed" do
178
+ @doc.save
179
+ @doc.should be_persisted
1092
180
  end
1093
181
  end
1094
182
 
@@ -1142,7 +230,7 @@ class DocumentTest < Test::Unit::TestCase
1142
230
 
1143
231
  context "database has keys not defined in model" do
1144
232
  setup do
1145
- @id = Mongo::ObjectID.new
233
+ @id = BSON::ObjectID.new
1146
234
  @document.collection.insert({
1147
235
  :_id => @id,
1148
236
  :first_name => 'John',