mongo_mapper-unstable 2010.3.8 → 2010.06.23

Sign up to get free protection for your applications and to get access to all the features.
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',