mongo_mapper-rails3 0.7.0.1 → 0.7.2

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