mongoid 8.0.3 → 8.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (188) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/CHANGELOG.md +3 -3
  4. data/README.md +3 -3
  5. data/lib/config/locales/en.yml +46 -14
  6. data/lib/mongoid/association/accessors.rb +2 -2
  7. data/lib/mongoid/association/builders.rb +1 -1
  8. data/lib/mongoid/association/embedded/batchable.rb +2 -2
  9. data/lib/mongoid/association/embedded/embedded_in/buildable.rb +2 -2
  10. data/lib/mongoid/association/embedded/embedded_in/proxy.rb +2 -1
  11. data/lib/mongoid/association/embedded/embeds_many/buildable.rb +3 -2
  12. data/lib/mongoid/association/embedded/embeds_many/proxy.rb +23 -21
  13. data/lib/mongoid/association/embedded/embeds_one/buildable.rb +1 -1
  14. data/lib/mongoid/association/embedded/embeds_one/proxy.rb +1 -1
  15. data/lib/mongoid/association/nested/one.rb +40 -2
  16. data/lib/mongoid/association/proxy.rb +1 -1
  17. data/lib/mongoid/association/referenced/counter_cache.rb +2 -2
  18. data/lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb +5 -1
  19. data/lib/mongoid/association/referenced/has_many/enumerable.rb +2 -2
  20. data/lib/mongoid/association/referenced/has_many/proxy.rb +7 -3
  21. data/lib/mongoid/association/reflections.rb +2 -2
  22. data/lib/mongoid/attributes/dynamic.rb +1 -1
  23. data/lib/mongoid/attributes/nested.rb +2 -2
  24. data/lib/mongoid/attributes/projector.rb +1 -1
  25. data/lib/mongoid/attributes/readonly.rb +1 -1
  26. data/lib/mongoid/attributes.rb +8 -2
  27. data/lib/mongoid/changeable.rb +104 -4
  28. data/lib/mongoid/clients/storage_options.rb +2 -5
  29. data/lib/mongoid/clients/validators/storage.rb +1 -13
  30. data/lib/mongoid/collection_configurable.rb +58 -0
  31. data/lib/mongoid/composable.rb +2 -0
  32. data/lib/mongoid/config/defaults.rb +60 -0
  33. data/lib/mongoid/config/validators/async_query_executor.rb +24 -0
  34. data/lib/mongoid/config/validators.rb +1 -0
  35. data/lib/mongoid/config.rb +101 -0
  36. data/lib/mongoid/contextual/atomic.rb +1 -1
  37. data/lib/mongoid/contextual/memory.rb +233 -33
  38. data/lib/mongoid/contextual/mongo/documents_loader.rb +177 -0
  39. data/lib/mongoid/contextual/mongo.rb +373 -113
  40. data/lib/mongoid/contextual/none.rb +162 -7
  41. data/lib/mongoid/contextual.rb +12 -0
  42. data/lib/mongoid/criteria/findable.rb +2 -2
  43. data/lib/mongoid/criteria/includable.rb +4 -3
  44. data/lib/mongoid/criteria/queryable/extensions/array.rb +1 -1
  45. data/lib/mongoid/criteria/queryable/extensions/hash.rb +1 -1
  46. data/lib/mongoid/criteria/queryable/extensions/numeric.rb +0 -8
  47. data/lib/mongoid/criteria/queryable/extensions/string.rb +1 -11
  48. data/lib/mongoid/criteria/queryable/extensions/symbol.rb +0 -10
  49. data/lib/mongoid/criteria/queryable/key.rb +1 -1
  50. data/lib/mongoid/criteria/queryable/mergeable.rb +1 -1
  51. data/lib/mongoid/criteria/queryable/optional.rb +8 -8
  52. data/lib/mongoid/criteria/queryable/selectable.rb +43 -12
  53. data/lib/mongoid/criteria/translator.rb +45 -0
  54. data/lib/mongoid/criteria.rb +7 -5
  55. data/lib/mongoid/deprecable.rb +1 -1
  56. data/lib/mongoid/document.rb +50 -13
  57. data/lib/mongoid/errors/create_collection_failure.rb +33 -0
  58. data/lib/mongoid/errors/drop_collection_failure.rb +27 -0
  59. data/lib/mongoid/errors/immutable_attribute.rb +26 -0
  60. data/lib/mongoid/errors/invalid_async_query_executor.rb +25 -0
  61. data/lib/mongoid/errors/invalid_global_executor_concurrency.rb +22 -0
  62. data/lib/mongoid/errors/invalid_storage_parent.rb +2 -0
  63. data/lib/mongoid/errors.rb +4 -1
  64. data/lib/mongoid/extensions/object.rb +2 -2
  65. data/lib/mongoid/extensions/time.rb +2 -0
  66. data/lib/mongoid/factory.rb +21 -8
  67. data/lib/mongoid/fields/localized.rb +10 -0
  68. data/lib/mongoid/fields/standard.rb +10 -0
  69. data/lib/mongoid/fields.rb +69 -13
  70. data/lib/mongoid/findable.rb +27 -3
  71. data/lib/mongoid/interceptable.rb +7 -6
  72. data/lib/mongoid/matcher/eq_impl.rb +1 -1
  73. data/lib/mongoid/matcher/type.rb +1 -1
  74. data/lib/mongoid/matcher.rb +21 -6
  75. data/lib/mongoid/persistable/creatable.rb +1 -0
  76. data/lib/mongoid/persistable/deletable.rb +1 -1
  77. data/lib/mongoid/persistable/savable.rb +13 -1
  78. data/lib/mongoid/persistable/unsettable.rb +2 -2
  79. data/lib/mongoid/persistable/updatable.rb +51 -1
  80. data/lib/mongoid/persistable/upsertable.rb +20 -1
  81. data/lib/mongoid/persistable.rb +3 -0
  82. data/lib/mongoid/query_cache.rb +5 -1
  83. data/lib/mongoid/railties/database.rake +7 -2
  84. data/lib/mongoid/shardable.rb +35 -11
  85. data/lib/mongoid/stateful.rb +22 -1
  86. data/lib/mongoid/tasks/database.rake +12 -0
  87. data/lib/mongoid/tasks/database.rb +20 -0
  88. data/lib/mongoid/threaded.rb +30 -0
  89. data/lib/mongoid/traversable.rb +1 -1
  90. data/lib/mongoid/utils.rb +22 -0
  91. data/lib/mongoid/validatable/macros.rb +5 -5
  92. data/lib/mongoid/validatable.rb +4 -1
  93. data/lib/mongoid/version.rb +1 -1
  94. data/lib/mongoid/warnings.rb +17 -1
  95. data/lib/mongoid.rb +16 -3
  96. data/spec/integration/app_spec.rb +2 -2
  97. data/spec/integration/callbacks_models.rb +37 -0
  98. data/spec/integration/callbacks_spec.rb +134 -0
  99. data/spec/integration/discriminator_key_spec.rb +4 -5
  100. data/spec/integration/i18n_fallbacks_spec.rb +3 -2
  101. data/spec/mongoid/association/embedded/embedded_in/proxy_spec.rb +27 -0
  102. data/spec/mongoid/association/embedded/embeds_many/proxy_spec.rb +57 -57
  103. data/spec/mongoid/association/embedded/embeds_many_models.rb +1 -0
  104. data/spec/mongoid/association/embedded/embeds_one/proxy_spec.rb +15 -2
  105. data/spec/mongoid/association/referenced/belongs_to_spec.rb +2 -18
  106. data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_spec.rb +148 -224
  107. data/spec/mongoid/association/referenced/has_many/proxy_spec.rb +111 -164
  108. data/spec/mongoid/association/syncable_spec.rb +1 -1
  109. data/spec/mongoid/attributes_spec.rb +5 -8
  110. data/spec/mongoid/changeable_spec.rb +299 -24
  111. data/spec/mongoid/clients_spec.rb +122 -13
  112. data/spec/mongoid/collection_configurable_spec.rb +158 -0
  113. data/spec/mongoid/config/defaults_spec.rb +160 -0
  114. data/spec/mongoid/config_spec.rb +154 -18
  115. data/spec/mongoid/contextual/memory_spec.rb +332 -76
  116. data/spec/mongoid/contextual/mongo/documents_loader_spec.rb +187 -0
  117. data/spec/mongoid/contextual/mongo_spec.rb +995 -36
  118. data/spec/mongoid/contextual/none_spec.rb +49 -2
  119. data/spec/mongoid/copyable_spec.rb +3 -11
  120. data/spec/mongoid/criteria/queryable/extensions/string_spec.rb +4 -69
  121. data/spec/mongoid/criteria/queryable/extensions/symbol_spec.rb +0 -59
  122. data/spec/mongoid/criteria/queryable/optional_spec.rb +15 -0
  123. data/spec/mongoid/criteria/queryable/options_spec.rb +1 -1
  124. data/spec/mongoid/criteria/queryable/selectable_logical_spec.rb +419 -0
  125. data/spec/mongoid/criteria/queryable/selectable_spec.rb +1 -1
  126. data/spec/mongoid/criteria/queryable/selector_spec.rb +1 -1
  127. data/spec/mongoid/criteria/translator_spec.rb +132 -0
  128. data/spec/mongoid/criteria_projection_spec.rb +1 -4
  129. data/spec/mongoid/criteria_spec.rb +5 -9
  130. data/spec/mongoid/errors/readonly_document_spec.rb +2 -2
  131. data/spec/mongoid/extensions/time_spec.rb +8 -43
  132. data/spec/mongoid/extensions/time_with_zone_spec.rb +7 -52
  133. data/spec/mongoid/fields/localized_spec.rb +46 -28
  134. data/spec/mongoid/fields_spec.rb +136 -34
  135. data/spec/mongoid/findable_spec.rb +391 -34
  136. data/spec/mongoid/indexable_spec.rb +16 -10
  137. data/spec/mongoid/interceptable_spec.rb +15 -3
  138. data/spec/mongoid/persistable/deletable_spec.rb +26 -6
  139. data/spec/mongoid/persistable/destroyable_spec.rb +26 -6
  140. data/spec/mongoid/persistable/incrementable_spec.rb +37 -0
  141. data/spec/mongoid/persistable/logical_spec.rb +37 -0
  142. data/spec/mongoid/persistable/poppable_spec.rb +36 -0
  143. data/spec/mongoid/persistable/pullable_spec.rb +72 -0
  144. data/spec/mongoid/persistable/pushable_spec.rb +72 -0
  145. data/spec/mongoid/persistable/renamable_spec.rb +36 -0
  146. data/spec/mongoid/persistable/savable_spec.rb +96 -0
  147. data/spec/mongoid/persistable/settable_spec.rb +37 -0
  148. data/spec/mongoid/persistable/unsettable_spec.rb +36 -0
  149. data/spec/mongoid/persistable/updatable_spec.rb +20 -28
  150. data/spec/mongoid/persistable/upsertable_spec.rb +80 -6
  151. data/spec/mongoid/persistence_context_spec.rb +7 -57
  152. data/spec/mongoid/query_cache_spec.rb +56 -61
  153. data/spec/mongoid/reloadable_spec.rb +24 -4
  154. data/spec/mongoid/scopable_spec.rb +70 -0
  155. data/spec/mongoid/serializable_spec.rb +9 -30
  156. data/spec/mongoid/shardable_models.rb +14 -0
  157. data/spec/mongoid/shardable_spec.rb +153 -61
  158. data/spec/mongoid/stateful_spec.rb +122 -8
  159. data/spec/mongoid/tasks/database_rake_spec.rb +74 -0
  160. data/spec/mongoid/tasks/database_spec.rb +127 -0
  161. data/spec/mongoid/timestamps_spec.rb +9 -11
  162. data/spec/mongoid/touchable_spec.rb +277 -5
  163. data/spec/mongoid/touchable_spec_models.rb +3 -1
  164. data/spec/mongoid/traversable_spec.rb +9 -24
  165. data/spec/mongoid/validatable/uniqueness_spec.rb +2 -3
  166. data/spec/mongoid_spec.rb +35 -9
  167. data/spec/shared/lib/mrss/docker_runner.rb +7 -0
  168. data/spec/shared/lib/mrss/event_subscriber.rb +15 -5
  169. data/spec/shared/lib/mrss/lite_constraints.rb +10 -2
  170. data/spec/shared/lib/mrss/server_version_registry.rb +16 -23
  171. data/spec/shared/lib/mrss/utils.rb +28 -6
  172. data/spec/shared/share/Dockerfile.erb +36 -40
  173. data/spec/shared/shlib/server.sh +32 -8
  174. data/spec/shared/shlib/set_env.sh +4 -4
  175. data/spec/spec_helper.rb +5 -0
  176. data/spec/support/immutable_ids.rb +118 -0
  177. data/spec/support/macros.rb +47 -15
  178. data/spec/support/models/artist.rb +0 -1
  179. data/spec/support/models/band.rb +1 -0
  180. data/spec/support/models/book.rb +1 -0
  181. data/spec/support/models/building.rb +2 -0
  182. data/spec/support/models/cover.rb +10 -0
  183. data/spec/support/models/product.rb +1 -0
  184. data.tar.gz.sig +0 -0
  185. metadata +700 -656
  186. metadata.gz.sig +0 -0
  187. data/spec/mongoid/criteria/queryable/extensions/bignum_spec.rb +0 -60
  188. data/spec/mongoid/criteria/queryable/extensions/fixnum_spec.rb +0 -60
@@ -75,12 +75,7 @@ describe Mongoid::Findable do
75
75
  context "when the document is not found" do
76
76
 
77
77
  context "when raising a not found error" do
78
-
79
- let!(:raise_option) { Mongoid.raise_not_found_error }
80
-
81
- before { Mongoid.raise_not_found_error = true }
82
-
83
- after { Mongoid.raise_not_found_error = raise_option }
78
+ config_override :raise_not_found_error, true
84
79
 
85
80
  it "raises an error" do
86
81
  expect {
@@ -90,12 +85,7 @@ describe Mongoid::Findable do
90
85
  end
91
86
 
92
87
  context "when raising no error" do
93
-
94
- let!(:raise_option) { Mongoid.raise_not_found_error }
95
-
96
- before { Mongoid.raise_not_found_error = false }
97
-
98
- after { Mongoid.raise_not_found_error = raise_option }
88
+ config_override :raise_not_found_error, false
99
89
 
100
90
  it "returns nil" do
101
91
  expect(person.messages.find_by(body: 'bar')).to be_nil
@@ -134,12 +124,7 @@ describe Mongoid::Findable do
134
124
  context "when the document is not found" do
135
125
 
136
126
  context "when raising a not found error" do
137
-
138
- let!(:raise_option) { Mongoid.raise_not_found_error }
139
-
140
- before { Mongoid.raise_not_found_error = true }
141
-
142
- after { Mongoid.raise_not_found_error = raise_option }
127
+ config_override :raise_not_found_error, true
143
128
 
144
129
  it "raises an error" do
145
130
  expect {
@@ -149,12 +134,7 @@ describe Mongoid::Findable do
149
134
  end
150
135
 
151
136
  context "when raising no error" do
152
-
153
- let!(:raise_option) { Mongoid.raise_not_found_error }
154
-
155
- before { Mongoid.raise_not_found_error = false }
156
-
157
- after { Mongoid.raise_not_found_error = raise_option }
137
+ config_override :raise_not_found_error, false
158
138
 
159
139
  context "when no block is provided" do
160
140
 
@@ -222,31 +202,411 @@ describe Mongoid::Findable do
222
202
 
223
203
  describe "##{method}" do
224
204
 
225
- let!(:person) do
205
+ let!(:person1) do
206
+ Person.create!
207
+ end
208
+
209
+ let!(:person2) do
226
210
  Person.create!
227
211
  end
228
212
 
229
213
  it "returns the first matching document" do
230
- expect(Person.send(method)).to eq(person)
214
+ expect(Person.send(method)).to eq(person1)
231
215
  end
232
216
 
233
217
  it "passes the limit through" do
234
- expect(Person.last(1)).to eq([ person ])
218
+ expect(Person.send(method, 1)).to eq([ person1 ])
235
219
  end
220
+
221
+ it "returns nil when no documents are found" do
222
+ expect(Band.send(method)).to be_nil
223
+ end
224
+ end
225
+ end
226
+
227
+ describe "#first!" do
228
+ let!(:person1) do
229
+ Person.create!
230
+ end
231
+
232
+ let!(:person2) do
233
+ Person.create!
234
+ end
235
+
236
+ it "returns the first matching document" do
237
+ expect(Person.first!).to eq(person1)
238
+ end
239
+
240
+ it "raises an error when there are no documents" do
241
+ expect do
242
+ Band.first!
243
+ end.to raise_error(Mongoid::Errors::DocumentNotFound, /Could not find a document of class Band./)
236
244
  end
237
245
  end
238
246
 
239
247
  describe "#last" do
240
- let!(:person) do
248
+ let!(:person1) do
249
+ Person.create!
250
+ end
251
+
252
+ let!(:person2) do
241
253
  Person.create!
242
254
  end
243
255
 
244
256
  it "returns the first matching document" do
245
- expect(Person.last).to eq(person)
257
+ expect(Person.last).to eq(person2)
246
258
  end
247
259
 
248
260
  it "passes the limit through" do
249
- expect(Person.last(1)).to eq([ person ])
261
+ expect(Person.last(1)).to eq([ person2 ])
262
+ end
263
+
264
+ it "returns nil when no documents are found" do
265
+ expect(Band.last).to be_nil
266
+ end
267
+ end
268
+
269
+ describe "#last!" do
270
+ let!(:person1) do
271
+ Person.create!
272
+ end
273
+
274
+ let!(:person2) do
275
+ Person.create!
276
+ end
277
+
278
+ it "returns the last matching document" do
279
+ expect(Person.last!).to eq(person2)
280
+ end
281
+
282
+ it "raises an error when there are no documents" do
283
+ expect do
284
+ Band.last!
285
+ end.to raise_error(Mongoid::Errors::DocumentNotFound, /Could not find a document of class Band./)
286
+ end
287
+ end
288
+
289
+ describe "#second" do
290
+ let!(:person1) do
291
+ Person.create!
292
+ end
293
+
294
+ let!(:person2) do
295
+ Person.create!
296
+ end
297
+
298
+ it "returns the second matching document" do
299
+ expect(Person.second).to eq(person2)
300
+ end
301
+
302
+ it "returns nil when no documents are found" do
303
+ expect(Band.second).to be_nil
304
+ end
305
+ end
306
+
307
+ describe "#second!" do
308
+ let!(:person1) do
309
+ Person.create!
310
+ end
311
+
312
+ let!(:person2) do
313
+ Person.create!
314
+ end
315
+
316
+ it "returns the second matching document" do
317
+ expect(Person.second!).to eq(person2)
318
+ end
319
+
320
+ it "raises an error when there are no documents" do
321
+ expect do
322
+ Band.second!
323
+ end.to raise_error(Mongoid::Errors::DocumentNotFound, /Could not find a document of class Band./)
324
+ end
325
+ end
326
+
327
+ describe "#third" do
328
+ let!(:person1) do
329
+ Person.create!
330
+ end
331
+
332
+ let!(:person2) do
333
+ Person.create!
334
+ end
335
+
336
+ let!(:person3) do
337
+ Person.create!
338
+ end
339
+
340
+ it "returns the third matching document" do
341
+ expect(Person.third).to eq(person3)
342
+ end
343
+
344
+ it "returns nil when no documents are found" do
345
+ expect(Band.third).to be_nil
346
+ end
347
+ end
348
+
349
+ describe "#third!" do
350
+ let!(:person1) do
351
+ Person.create!
352
+ end
353
+
354
+ let!(:person2) do
355
+ Person.create!
356
+ end
357
+
358
+ let!(:person3) do
359
+ Person.create!
360
+ end
361
+
362
+ it "returns the third matching document" do
363
+ expect(Person.third!).to eq(person3)
364
+ end
365
+
366
+ it "raises an error when there are no documents" do
367
+ expect do
368
+ Band.third!
369
+ end.to raise_error(Mongoid::Errors::DocumentNotFound, /Could not find a document of class Band./)
370
+ end
371
+ end
372
+
373
+ describe "#fourth" do
374
+ let!(:person1) do
375
+ Person.create!
376
+ end
377
+
378
+ let!(:person2) do
379
+ Person.create!
380
+ end
381
+
382
+ let!(:person3) do
383
+ Person.create!
384
+ end
385
+
386
+ let!(:person4) do
387
+ Person.create!
388
+ end
389
+
390
+ it "returns the fourth matching document" do
391
+ expect(Person.fourth).to eq(person4)
392
+ end
393
+
394
+ it "returns nil when no documents are found" do
395
+ expect(Band.fourth).to be_nil
396
+ end
397
+ end
398
+
399
+ describe "#fourth!" do
400
+ let!(:person1) do
401
+ Person.create!
402
+ end
403
+
404
+ let!(:person2) do
405
+ Person.create!
406
+ end
407
+
408
+ let!(:person3) do
409
+ Person.create!
410
+ end
411
+
412
+ let!(:person4) do
413
+ Person.create!
414
+ end
415
+
416
+ it "returns the fourth matching document" do
417
+ expect(Person.fourth!).to eq(person4)
418
+ end
419
+
420
+ it "raises an error when there are no documents" do
421
+ expect do
422
+ Band.fourth!
423
+ end.to raise_error(Mongoid::Errors::DocumentNotFound, /Could not find a document of class Band./)
424
+ end
425
+ end
426
+
427
+ describe "#fifth" do
428
+ let!(:person1) do
429
+ Person.create!
430
+ end
431
+
432
+ let!(:person2) do
433
+ Person.create!
434
+ end
435
+
436
+ let!(:person3) do
437
+ Person.create!
438
+ end
439
+
440
+ let!(:person4) do
441
+ Person.create!
442
+ end
443
+
444
+ let!(:person5) do
445
+ Person.create!
446
+ end
447
+
448
+ it "returns the fifth matching document" do
449
+ expect(Person.fifth).to eq(person5)
450
+ end
451
+
452
+ it "returns nil when no documents are found" do
453
+ expect(Band.fifth).to be_nil
454
+ end
455
+ end
456
+
457
+ describe "#fifth!" do
458
+ let!(:person1) do
459
+ Person.create!
460
+ end
461
+
462
+ let!(:person2) do
463
+ Person.create!
464
+ end
465
+
466
+ let!(:person3) do
467
+ Person.create!
468
+ end
469
+
470
+ let!(:person4) do
471
+ Person.create!
472
+ end
473
+
474
+ let!(:person5) do
475
+ Person.create!
476
+ end
477
+
478
+ it "returns the fifth matching document" do
479
+ expect(Person.fifth!).to eq(person5)
480
+ end
481
+
482
+ it "raises an error when there are no documents" do
483
+ expect do
484
+ Band.fifth!
485
+ end.to raise_error(Mongoid::Errors::DocumentNotFound, /Could not find a document of class Band./)
486
+ end
487
+ end
488
+
489
+ describe "#second_to_last" do
490
+ let!(:person1) do
491
+ Person.create!
492
+ end
493
+
494
+ let!(:person2) do
495
+ Person.create!
496
+ end
497
+
498
+ let!(:person3) do
499
+ Person.create!
500
+ end
501
+
502
+ let!(:person4) do
503
+ Person.create!
504
+ end
505
+
506
+ let!(:person5) do
507
+ Person.create!
508
+ end
509
+
510
+ it "returns the second to last matching document" do
511
+ expect(Person.second_to_last).to eq(person4)
512
+ end
513
+
514
+ it "returns nil when no documents are found" do
515
+ expect(Band.second_to_last).to be_nil
516
+ end
517
+ end
518
+
519
+ describe "#second_to_last!" do
520
+ let!(:person1) do
521
+ Person.create!
522
+ end
523
+
524
+ let!(:person2) do
525
+ Person.create!
526
+ end
527
+
528
+ let!(:person3) do
529
+ Person.create!
530
+ end
531
+
532
+ let!(:person4) do
533
+ Person.create!
534
+ end
535
+
536
+ let!(:person5) do
537
+ Person.create!
538
+ end
539
+
540
+ it "returns the second to last matching document" do
541
+ expect(Person.second_to_last!).to eq(person4)
542
+ end
543
+
544
+ it "raises an error when there are no documents" do
545
+ expect do
546
+ Band.second_to_last!
547
+ end.to raise_error(Mongoid::Errors::DocumentNotFound, /Could not find a document of class Band./)
548
+ end
549
+ end
550
+
551
+ describe "#third_to_last" do
552
+ let!(:person1) do
553
+ Person.create!
554
+ end
555
+
556
+ let!(:person2) do
557
+ Person.create!
558
+ end
559
+
560
+ let!(:person3) do
561
+ Person.create!
562
+ end
563
+
564
+ let!(:person4) do
565
+ Person.create!
566
+ end
567
+
568
+ let!(:person5) do
569
+ Person.create!
570
+ end
571
+
572
+ it "returns the third to last matching document" do
573
+ expect(Person.third_to_last).to eq(person3)
574
+ end
575
+
576
+ it "returns nil when no documents are found" do
577
+ expect(Band.third_to_last).to be_nil
578
+ end
579
+ end
580
+
581
+ describe "#third_to_last!" do
582
+ let!(:person1) do
583
+ Person.create!
584
+ end
585
+
586
+ let!(:person2) do
587
+ Person.create!
588
+ end
589
+
590
+ let!(:person3) do
591
+ Person.create!
592
+ end
593
+
594
+ let!(:person4) do
595
+ Person.create!
596
+ end
597
+
598
+ let!(:person5) do
599
+ Person.create!
600
+ end
601
+
602
+ it "returns the third to last matching document" do
603
+ expect(Person.third_to_last!).to eq(person3)
604
+ end
605
+
606
+ it "raises an error when there are no documents" do
607
+ expect do
608
+ Band.third_to_last!
609
+ end.to raise_error(Mongoid::Errors::DocumentNotFound, /Could not find a document of class Band./)
250
610
  end
251
611
  end
252
612
 
@@ -541,10 +901,7 @@ describe Mongoid::Findable do
541
901
  context 'when Mongoid is configured to use activesupport time zone' do
542
902
  config_override :use_utc, false
543
903
  config_override :use_activesupport_time_zone, true
544
-
545
- before do
546
- Time.zone = "Asia/Kolkata"
547
- end
904
+ time_zone_override "Asia/Kolkata"
548
905
 
549
906
  let!(:time) do
550
907
  Time.zone.now.tap do |t|
@@ -109,7 +109,6 @@ describe Mongoid::Indexable do
109
109
 
110
110
  after do
111
111
  klass.remove_indexes
112
- Mongoid::Config.background_indexing = false
113
112
  end
114
113
 
115
114
  let(:indexes) do
@@ -118,20 +117,27 @@ describe Mongoid::Indexable do
118
117
  end
119
118
  end
120
119
 
121
- it "creates the indexes by using default background_indexing option" do
122
- klass.create_indexes
120
+ context "when the background_indexing option is false" do
121
+ config_override :background_indexing, false
122
+
123
+ it "creates the indexes correctly" do
124
+ klass.create_indexes
123
125
 
124
- index = indexes.get(_type: 1)
125
- expect(index[:background]).to eq(Mongoid::Config.background_indexing)
126
+ index = indexes.get(_type: 1)
127
+ expect(index[:background]).to be false
128
+ end
126
129
  end
127
130
 
128
- it "creates the indexes by using specified background_indexing option" do
129
- Mongoid::Config.background_indexing = true
131
+ context "when the background_indexing option is true" do
132
+ config_override :background_indexing, true
130
133
 
131
- klass.create_indexes
134
+ it "creates the indexes correctly" do
132
135
 
133
- index = indexes.get(_type: 1)
134
- expect(index[:background]).to eq(true)
136
+ klass.create_indexes
137
+
138
+ index = indexes.get(_type: 1)
139
+ expect(index[:background]).to be true
140
+ end
135
141
  end
136
142
  end
137
143
 
@@ -580,10 +580,22 @@ describe Mongoid::Interceptable do
580
580
  end
581
581
 
582
582
  context "when saving the root" do
583
+ context 'with prevent_multiple_calls_of_embedded_callbacks enabled' do
584
+ config_override :prevent_multiple_calls_of_embedded_callbacks, true
583
585
 
584
- it "only executes the callbacks once for each embed" do
585
- expect(note).to receive(:update_saved).twice
586
- band.save!
586
+ it "executes the callbacks only once for each document" do
587
+ expect(note).to receive(:update_saved).once
588
+ band.save!
589
+ end
590
+ end
591
+
592
+ context 'with prevent_multiple_calls_of_embedded_callbacks disabled' do
593
+ config_override :prevent_multiple_calls_of_embedded_callbacks, false
594
+
595
+ it "executes the callbacks once for each ember" do
596
+ expect(note).to receive(:update_saved).twice
597
+ band.save!
598
+ end
587
599
  end
588
600
  end
589
601
  end
@@ -12,14 +12,34 @@ describe Mongoid::Persistable::Deletable do
12
12
 
13
13
  context "when deleting a readonly document" do
14
14
 
15
- let(:from_db) do
16
- Person.only(:_id).first
15
+ context "when legacy_attributes is true" do
16
+ config_override :legacy_readonly, true
17
+
18
+ let(:from_db) do
19
+ Person.only(:_id).first
20
+ end
21
+
22
+ it "raises an error" do
23
+ expect(from_db.readonly?).to be true
24
+ expect {
25
+ from_db.delete
26
+ }.to raise_error(Mongoid::Errors::ReadonlyDocument)
27
+ end
17
28
  end
18
29
 
19
- it "raises an error" do
20
- expect {
21
- from_db.delete
22
- }.to raise_error(Mongoid::Errors::ReadonlyDocument)
30
+ context "when legacy_attributes is false" do
31
+ config_override :legacy_readonly, false
32
+
33
+ let(:from_db) do
34
+ Person.first.tap(&:readonly!)
35
+ end
36
+
37
+ it "raises an error" do
38
+ expect(from_db.readonly?).to be true
39
+ expect {
40
+ from_db.delete
41
+ }.to raise_error(Mongoid::Errors::ReadonlyDocument)
42
+ end
23
43
  end
24
44
  end
25
45
 
@@ -12,14 +12,34 @@ describe Mongoid::Persistable::Destroyable do
12
12
 
13
13
  context "when destroying a readonly document" do
14
14
 
15
- let(:from_db) do
16
- Person.only(:_id).first
15
+ context "when legacy_attributes is true" do
16
+ config_override :legacy_readonly, true
17
+
18
+ let(:from_db) do
19
+ Person.only(:_id).first
20
+ end
21
+
22
+ it "raises an error" do
23
+ expect(from_db.readonly?).to be true
24
+ expect {
25
+ from_db.destroy
26
+ }.to raise_error(Mongoid::Errors::ReadonlyDocument)
27
+ end
17
28
  end
18
29
 
19
- it "raises an error" do
20
- expect {
21
- from_db.destroy
22
- }.to raise_error(Mongoid::Errors::ReadonlyDocument)
30
+ context "when legacy_attributes is false" do
31
+ config_override :legacy_readonly, false
32
+
33
+ let(:from_db) do
34
+ Person.first.tap(&:readonly!)
35
+ end
36
+
37
+ it "raises an error" do
38
+ expect(from_db.readonly?).to be true
39
+ expect {
40
+ from_db.destroy
41
+ }.to raise_error(Mongoid::Errors::ReadonlyDocument)
42
+ end
23
43
  end
24
44
  end
25
45
 
@@ -237,5 +237,42 @@ describe Mongoid::Persistable::Incrementable do
237
237
  end
238
238
  end
239
239
  end
240
+
241
+ context "when executing on a readonly document" do
242
+
243
+ let(:person) do
244
+ Person.create!(age: 10, score: 100)
245
+ end
246
+
247
+ context "when legacy_readonly is true" do
248
+ config_override :legacy_readonly, true
249
+
250
+ before do
251
+ person.__selected_fields = { "age" => 1, "score" => 1 }
252
+ end
253
+
254
+ it "persists the changes" do
255
+ expect(person).to be_readonly
256
+ person.inc(age: 15, score: 2)
257
+ expect(person.age).to eq(25)
258
+ expect(person.score).to eq(102)
259
+ end
260
+ end
261
+
262
+ context "when legacy_readonly is false" do
263
+ config_override :legacy_readonly, false
264
+
265
+ before do
266
+ person.readonly!
267
+ end
268
+
269
+ it "raises a ReadonlyDocument error" do
270
+ expect(person).to be_readonly
271
+ expect do
272
+ person.inc(age: 15, score: 2)
273
+ end.to raise_error(Mongoid::Errors::ReadonlyDocument)
274
+ end
275
+ end
276
+ end
240
277
  end
241
278
  end