mongoid 7.2.6 → 7.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (200) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/README.md +1 -1
  4. data/Rakefile +16 -0
  5. data/lib/config/locales/en.yml +2 -15
  6. data/lib/mongoid/association/accessors.rb +1 -1
  7. data/lib/mongoid/association/constrainable.rb +1 -1
  8. data/lib/mongoid/association/depending.rb +4 -4
  9. data/lib/mongoid/association/embedded/batchable.rb +1 -1
  10. data/lib/mongoid/association/embedded/embedded_in.rb +1 -1
  11. data/lib/mongoid/association/embedded/embeds_many/proxy.rb +11 -4
  12. data/lib/mongoid/association/nested/many.rb +1 -1
  13. data/lib/mongoid/association/nested/one.rb +4 -2
  14. data/lib/mongoid/association/proxy.rb +7 -2
  15. data/lib/mongoid/association/referenced/auto_save.rb +2 -2
  16. data/lib/mongoid/association/referenced/has_many/enumerable.rb +493 -495
  17. data/lib/mongoid/association/referenced/has_many/proxy.rb +3 -3
  18. data/lib/mongoid/association/referenced/has_one/nested_builder.rb +2 -2
  19. data/lib/mongoid/association/relatable.rb +0 -2
  20. data/lib/mongoid/attributes/projector.rb +120 -0
  21. data/lib/mongoid/attributes.rb +24 -13
  22. data/lib/mongoid/cacheable.rb +2 -2
  23. data/lib/mongoid/clients/factory.rb +22 -8
  24. data/lib/mongoid/clients.rb +1 -1
  25. data/lib/mongoid/config/environment.rb +1 -9
  26. data/lib/mongoid/config.rb +19 -2
  27. data/lib/mongoid/contextual/aggregable/mongo.rb +10 -8
  28. data/lib/mongoid/contextual/atomic.rb +2 -7
  29. data/lib/mongoid/contextual/none.rb +0 -3
  30. data/lib/mongoid/copyable.rb +1 -1
  31. data/lib/mongoid/criteria/findable.rb +1 -1
  32. data/lib/mongoid/criteria/queryable/expandable.rb +0 -24
  33. data/lib/mongoid/criteria/queryable/extensions/boolean.rb +1 -1
  34. data/lib/mongoid/criteria/queryable/extensions.rb +0 -4
  35. data/lib/mongoid/criteria/queryable/mergeable.rb +46 -20
  36. data/lib/mongoid/criteria/queryable/selectable.rb +10 -10
  37. data/lib/mongoid/criteria/queryable/storable.rb +4 -4
  38. data/lib/mongoid/criteria.rb +5 -6
  39. data/lib/mongoid/document.rb +3 -18
  40. data/lib/mongoid/errors/delete_restriction.rb +8 -9
  41. data/lib/mongoid/errors/mongoid_error.rb +1 -1
  42. data/lib/mongoid/errors.rb +0 -2
  43. data/lib/mongoid/evolvable.rb +1 -1
  44. data/lib/mongoid/extensions/boolean.rb +1 -2
  45. data/lib/mongoid/extensions/false_class.rb +1 -1
  46. data/lib/mongoid/extensions/hash.rb +2 -2
  47. data/lib/mongoid/extensions/true_class.rb +1 -1
  48. data/lib/mongoid/fields.rb +43 -5
  49. data/lib/mongoid/inspectable.rb +1 -1
  50. data/lib/mongoid/interceptable.rb +1 -1
  51. data/lib/mongoid/matcher/bits.rb +41 -0
  52. data/lib/mongoid/matcher/bits_all_clear.rb +20 -0
  53. data/lib/mongoid/matcher/bits_all_set.rb +20 -0
  54. data/lib/mongoid/matcher/bits_any_clear.rb +20 -0
  55. data/lib/mongoid/matcher/bits_any_set.rb +20 -0
  56. data/lib/mongoid/matcher/expression.rb +4 -0
  57. data/lib/mongoid/matcher/field_operator.rb +6 -0
  58. data/lib/mongoid/matcher/mod.rb +17 -0
  59. data/lib/mongoid/matcher/type.rb +99 -0
  60. data/lib/mongoid/matcher.rb +7 -0
  61. data/lib/mongoid/persistable/deletable.rb +1 -2
  62. data/lib/mongoid/persistable/destroyable.rb +8 -2
  63. data/lib/mongoid/persistable/updatable.rb +27 -2
  64. data/lib/mongoid/persistence_context.rb +1 -3
  65. data/lib/mongoid/query_cache.rb +36 -40
  66. data/lib/mongoid/selectable.rb +5 -7
  67. data/lib/mongoid/shardable.rb +21 -5
  68. data/lib/mongoid/tasks/database.rb +1 -1
  69. data/lib/mongoid/touchable.rb +23 -4
  70. data/lib/mongoid/validatable/associated.rb +1 -1
  71. data/lib/mongoid/validatable/presence.rb +3 -3
  72. data/lib/mongoid/validatable/uniqueness.rb +1 -1
  73. data/lib/mongoid/version.rb +1 -1
  74. data/lib/mongoid.rb +0 -1
  75. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +1 -1
  76. data/spec/integration/app_spec.rb +0 -3
  77. data/spec/integration/associations/embeds_many_spec.rb +44 -0
  78. data/spec/integration/associations/has_one_spec.rb +48 -0
  79. data/spec/integration/criteria/date_field_spec.rb +1 -1
  80. data/spec/integration/document_spec.rb +9 -0
  81. data/spec/integration/matcher_operator_data/bits_all_clear.yml +159 -0
  82. data/spec/integration/matcher_operator_data/bits_all_set.yml +159 -0
  83. data/spec/integration/matcher_operator_data/bits_any_clear.yml +159 -0
  84. data/spec/integration/matcher_operator_data/bits_any_set.yml +159 -0
  85. data/spec/integration/matcher_operator_data/comment.yml +22 -0
  86. data/spec/integration/matcher_operator_data/in.yml +16 -0
  87. data/spec/integration/matcher_operator_data/mod.yml +55 -0
  88. data/spec/integration/matcher_operator_data/type.yml +70 -0
  89. data/spec/integration/matcher_operator_data/type_array.yml +16 -0
  90. data/spec/integration/matcher_operator_data/type_binary.yml +18 -0
  91. data/spec/integration/matcher_operator_data/type_boolean.yml +39 -0
  92. data/spec/integration/matcher_operator_data/type_code.yml +26 -0
  93. data/spec/integration/matcher_operator_data/type_code_with_scope.yml +26 -0
  94. data/spec/integration/matcher_operator_data/type_date.yml +39 -0
  95. data/spec/integration/matcher_operator_data/type_db_pointer.yml +19 -0
  96. data/spec/integration/matcher_operator_data/type_decimal.yml +40 -0
  97. data/spec/integration/matcher_operator_data/type_double.yml +15 -0
  98. data/spec/integration/matcher_operator_data/type_int32.yml +33 -0
  99. data/spec/integration/matcher_operator_data/type_int64.yml +33 -0
  100. data/spec/integration/matcher_operator_data/type_max_key.yml +17 -0
  101. data/spec/integration/matcher_operator_data/type_min_key.yml +17 -0
  102. data/spec/integration/matcher_operator_data/type_null.yml +23 -0
  103. data/spec/integration/matcher_operator_data/type_object.yml +23 -0
  104. data/spec/integration/matcher_operator_data/type_object_id.yml +25 -0
  105. data/spec/integration/matcher_operator_data/type_regex.yml +44 -0
  106. data/spec/integration/matcher_operator_data/type_string.yml +15 -0
  107. data/spec/integration/matcher_operator_data/type_symbol.yml +32 -0
  108. data/spec/integration/matcher_operator_data/type_timestamp.yml +25 -0
  109. data/spec/integration/matcher_operator_data/type_undefined.yml +17 -0
  110. data/spec/integration/stringified_symbol_field_spec.rb +2 -2
  111. data/spec/lite_spec_helper.rb +2 -0
  112. data/spec/mongoid/association/depending_spec.rb +391 -352
  113. data/spec/mongoid/association/embedded/embeds_many/proxy_spec.rb +4 -17
  114. data/spec/mongoid/association/nested/one_spec.rb +18 -14
  115. data/spec/mongoid/association/referenced/belongs_to/proxy_spec.rb +25 -25
  116. data/spec/mongoid/association/referenced/belongs_to_query_spec.rb +0 -20
  117. data/spec/mongoid/association/referenced/has_and_belongs_to_many/binding_spec.rb +1 -1
  118. data/spec/mongoid/association/referenced/has_many/binding_spec.rb +1 -1
  119. data/spec/mongoid/association/referenced/has_many/enumerable_spec.rb +1 -1
  120. data/spec/mongoid/association/referenced/has_many_models.rb +0 -17
  121. data/spec/mongoid/association/referenced/has_one_models.rb +8 -0
  122. data/spec/mongoid/atomic/paths_spec.rb +64 -12
  123. data/spec/mongoid/attributes/projector_data/embedded.yml +105 -0
  124. data/spec/mongoid/attributes/projector_data/fields.yml +93 -0
  125. data/spec/mongoid/attributes/projector_spec.rb +41 -0
  126. data/spec/mongoid/attributes_spec.rb +98 -6
  127. data/spec/mongoid/clients/factory_spec.rb +51 -9
  128. data/spec/mongoid/clients/options_spec.rb +3 -11
  129. data/spec/mongoid/config/environment_spec.rb +8 -86
  130. data/spec/mongoid/config_spec.rb +32 -0
  131. data/spec/mongoid/contextual/atomic_spec.rb +25 -64
  132. data/spec/mongoid/contextual/geo_near_spec.rb +1 -1
  133. data/spec/mongoid/contextual/mongo_spec.rb +2 -2
  134. data/spec/mongoid/criteria/modifiable_spec.rb +1 -1
  135. data/spec/mongoid/criteria/queryable/expandable_spec.rb +0 -73
  136. data/spec/mongoid/criteria/queryable/extensions/boolean_spec.rb +1 -1
  137. data/spec/mongoid/criteria/queryable/mergeable_spec.rb +105 -7
  138. data/spec/mongoid/criteria/queryable/selectable_logical_spec.rb +229 -24
  139. data/spec/mongoid/criteria/queryable/selectable_shared_examples.rb +39 -0
  140. data/spec/mongoid/criteria/queryable/selectable_spec.rb +1 -565
  141. data/spec/mongoid/criteria/queryable/selectable_where_spec.rb +590 -0
  142. data/spec/mongoid/criteria_projection_spec.rb +411 -0
  143. data/spec/mongoid/criteria_spec.rb +0 -279
  144. data/spec/mongoid/document_query_spec.rb +0 -51
  145. data/spec/mongoid/document_spec.rb +14 -34
  146. data/spec/mongoid/errors/delete_restriction_spec.rb +1 -1
  147. data/spec/mongoid/errors/mongoid_error_spec.rb +8 -20
  148. data/spec/mongoid/extensions/false_class_spec.rb +1 -1
  149. data/spec/mongoid/extensions/string_spec.rb +5 -5
  150. data/spec/mongoid/extensions/true_class_spec.rb +1 -1
  151. data/spec/mongoid/fields/localized_spec.rb +4 -4
  152. data/spec/mongoid/fields_spec.rb +4 -4
  153. data/spec/mongoid/inspectable_spec.rb +12 -4
  154. data/spec/mongoid/persistable/deletable_spec.rb +175 -1
  155. data/spec/mongoid/persistable/destroyable_spec.rb +191 -3
  156. data/spec/mongoid/persistable/savable_spec.rb +3 -5
  157. data/spec/mongoid/persistable/updatable_spec.rb +0 -2
  158. data/spec/mongoid/persistable/upsertable_spec.rb +1 -1
  159. data/spec/mongoid/persistable_spec.rb +2 -2
  160. data/spec/mongoid/query_cache_middleware_spec.rb +8 -0
  161. data/spec/mongoid/query_cache_spec.rb +0 -24
  162. data/spec/mongoid/reloadable_spec.rb +18 -1
  163. data/spec/mongoid/shardable_spec.rb +44 -0
  164. data/spec/mongoid/touchable_spec.rb +104 -16
  165. data/spec/mongoid/touchable_spec_models.rb +52 -0
  166. data/spec/mongoid/validatable_spec.rb +1 -1
  167. data/spec/shared/lib/mrss/cluster_config.rb +3 -8
  168. data/spec/shared/lib/mrss/constraints.rb +10 -41
  169. data/spec/shared/lib/mrss/docker_runner.rb +1 -7
  170. data/spec/shared/lib/mrss/server_version_registry.rb +12 -17
  171. data/spec/shared/lib/mrss/spec_organizer.rb +1 -18
  172. data/spec/shared/share/Dockerfile.erb +33 -125
  173. data/spec/shared/shlib/server.sh +23 -100
  174. data/spec/shared/shlib/set_env.sh +1 -4
  175. data/spec/spec_helper.rb +7 -3
  176. data/spec/support/client_registry.rb +9 -0
  177. data/spec/support/models/address.rb +0 -4
  178. data/spec/support/models/bolt.rb +8 -0
  179. data/spec/support/models/hole.rb +13 -0
  180. data/spec/support/models/mop.rb +0 -1
  181. data/spec/support/models/nut.rb +8 -0
  182. data/spec/support/models/person.rb +6 -9
  183. data/spec/support/models/sealer.rb +8 -0
  184. data/spec/support/models/shirt.rb +12 -0
  185. data/spec/support/models/spacer.rb +8 -0
  186. data/spec/support/models/threadlocker.rb +8 -0
  187. data/spec/support/models/washer.rb +8 -0
  188. data.tar.gz.sig +0 -0
  189. metadata +609 -545
  190. metadata.gz.sig +0 -0
  191. data/lib/mongoid/errors/empty_config_file.rb +0 -26
  192. data/lib/mongoid/errors/invalid_config_file.rb +0 -26
  193. data/spec/integration/contextual/empty_spec.rb +0 -142
  194. data/spec/mongoid/errors/invalid_config_file_spec.rb +0 -32
  195. data/spec/shared/bin/s3-copy +0 -45
  196. data/spec/shared/bin/s3-upload +0 -69
  197. data/spec/shared/lib/mrss/event_subscriber.rb +0 -200
  198. data/spec/shared/share/haproxy-1.conf +0 -16
  199. data/spec/shared/share/haproxy-2.conf +0 -17
  200. data/spec/support/cluster_config.rb +0 -158
@@ -8,7 +8,7 @@ describe Mongoid::Persistable::Destroyable do
8
8
  describe "#destroy" do
9
9
 
10
10
  let!(:person) do
11
- Person.create
11
+ Person.create!
12
12
  end
13
13
 
14
14
  context "when destroying a readonly document" do
@@ -24,9 +24,23 @@ describe Mongoid::Persistable::Destroyable do
24
24
  end
25
25
  end
26
26
 
27
+ context 'when destroying a document that was not saved' do
28
+ let(:unsaved_person) { Person.new(id: person.id) }
29
+
30
+ before do
31
+ unsaved_person.destroy
32
+ end
33
+
34
+ it 'deletes the matching document from the database' do
35
+ lambda do
36
+ person.reload
37
+ end.should raise_error(Mongoid::Errors::DocumentNotFound)
38
+ end
39
+ end
40
+
27
41
  context "when removing a root document" do
28
42
 
29
- let!(:destroyd) do
43
+ let!(:destroyed) do
30
44
  person.destroy
31
45
  end
32
46
 
@@ -37,7 +51,7 @@ describe Mongoid::Persistable::Destroyable do
37
51
  end
38
52
 
39
53
  it "returns true" do
40
- expect(destroyd).to be true
54
+ expect(destroyed).to be true
41
55
  end
42
56
 
43
57
  it "resets the flagged for destroy flag" do
@@ -145,6 +159,90 @@ describe Mongoid::Persistable::Destroyable do
145
159
  end
146
160
  end
147
161
  end
162
+
163
+ context 'when there are dependent documents' do
164
+ context 'has_one' do
165
+
166
+ context 'dependent: :destroy' do
167
+ let!(:parent) do
168
+ Hole.create!(bolt: Bolt.create!)
169
+ end
170
+
171
+ it 'destroys dependent documents' do
172
+ Bolt.count.should == 1
173
+ parent.destroy
174
+ Bolt.count.should == 0
175
+ end
176
+ end
177
+
178
+ context 'dependent: :destroy_all' do
179
+ let!(:parent) do
180
+ Hole.create!(threadlocker: Threadlocker.create!)
181
+ end
182
+
183
+ it 'deletes dependent documents' do
184
+ Threadlocker.count.should == 1
185
+ parent.destroy
186
+ Threadlocker.count.should == 0
187
+ end
188
+ end
189
+
190
+ context 'dependent: :restrict_with_exception' do
191
+ let!(:parent) do
192
+ Hole.create!(sealer: Sealer.create!)
193
+ end
194
+
195
+ it 'raises an exception' do
196
+ Sealer.count.should == 1
197
+ lambda do
198
+ parent.destroy
199
+ end.should raise_error(Mongoid::Errors::DeleteRestriction)
200
+ Sealer.count.should == 1
201
+ end
202
+ end
203
+ end
204
+
205
+ context 'has_many' do
206
+
207
+ context 'dependent: :destroy' do
208
+ let!(:parent) do
209
+ Hole.create!(nuts: [Nut.create!])
210
+ end
211
+
212
+ it 'destroys dependent documents' do
213
+ Nut.count.should == 1
214
+ parent.destroy
215
+ Nut.count.should == 0
216
+ end
217
+ end
218
+
219
+ context 'dependent: :destroy_all' do
220
+ let!(:parent) do
221
+ Hole.create!(washers: [Washer.create!])
222
+ end
223
+
224
+ it 'deletes dependent documents' do
225
+ Washer.count.should == 1
226
+ parent.destroy
227
+ Washer.count.should == 0
228
+ end
229
+ end
230
+
231
+ context 'dependent: :restrict_with_exception' do
232
+ let!(:parent) do
233
+ Hole.create!(spacers: [Spacer.create!])
234
+ end
235
+
236
+ it 'raises an exception' do
237
+ Spacer.count.should == 1
238
+ lambda do
239
+ parent.destroy
240
+ end.should raise_error(Mongoid::Errors::DeleteRestriction)
241
+ Spacer.count.should == 1
242
+ end
243
+ end
244
+ end
245
+ end
148
246
  end
149
247
 
150
248
  describe "#destroy!" do
@@ -264,5 +362,95 @@ describe Mongoid::Persistable::Destroyable do
264
362
  end
265
363
  end
266
364
  end
365
+
366
+ context 'when there are dependent documents' do
367
+ context 'has_one' do
368
+
369
+ context 'dependent: :destroy' do
370
+ let!(:parent) do
371
+ Hole.create!.tap do |hole|
372
+ Bolt.create!(hole: hole)
373
+ end
374
+ end
375
+
376
+ it 'destroys dependent documents' do
377
+ Bolt.count.should == 1
378
+ Hole.destroy_all
379
+ Bolt.count.should == 0
380
+ end
381
+ end
382
+
383
+ context 'dependent: :delete_all' do
384
+ let!(:parent) do
385
+ Hole.create!.tap do |hole|
386
+ Threadlocker.create!(hole: hole)
387
+ end
388
+ end
389
+
390
+ it 'deletes dependent documents' do
391
+ Threadlocker.count.should == 1
392
+ Hole.destroy_all
393
+ Threadlocker.count.should == 0
394
+ end
395
+ end
396
+
397
+ context 'dependent: :restrict_with_exception' do
398
+ let!(:parent) do
399
+ Hole.create!.tap do |hole|
400
+ Sealer.create!(hole: hole)
401
+ end
402
+ end
403
+
404
+ it 'raises an exception' do
405
+ Sealer.count.should == 1
406
+ lambda do
407
+ Hole.destroy_all
408
+ end.should raise_error(Mongoid::Errors::DeleteRestriction)
409
+ Sealer.count.should == 1
410
+ end
411
+ end
412
+ end
413
+
414
+ context 'has_many' do
415
+
416
+ context 'dependent: :destroy' do
417
+ let!(:parent) do
418
+ Hole.create!(nuts: [Nut.create!])
419
+ end
420
+
421
+ it 'destroys dependent documents' do
422
+ Nut.count.should == 1
423
+ Hole.destroy_all
424
+ Nut.count.should == 0
425
+ end
426
+ end
427
+
428
+ context 'dependent: :delete_all' do
429
+ let!(:parent) do
430
+ Hole.create!(washers: [Washer.create!])
431
+ end
432
+
433
+ it 'deletes dependent documents' do
434
+ Washer.count.should == 1
435
+ Hole.destroy_all
436
+ Washer.count.should == 0
437
+ end
438
+ end
439
+
440
+ context 'dependent: :restrict_with_exception' do
441
+ let!(:parent) do
442
+ Hole.create!(spacers: [Spacer.create!])
443
+ end
444
+
445
+ it 'raises an exception' do
446
+ Spacer.count.should == 1
447
+ lambda do
448
+ Hole.destroy_all
449
+ end.should raise_error(Mongoid::Errors::DeleteRestriction)
450
+ Spacer.count.should == 1
451
+ end
452
+ end
453
+ end
454
+ end
267
455
  end
268
456
  end
@@ -293,6 +293,8 @@ describe Mongoid::Persistable::Savable do
293
293
  expect(truck.crates[1].volume).to eq 0.8
294
294
  expect(truck.crates[1].toys.size).to eq 0
295
295
 
296
+ # TODO: MONGOID-5026: combine the updates so that there are
297
+ # no conflicts.
296
298
  #expect(truck.atomic_updates[:conflicts]).to eq nil
297
299
 
298
300
  expect { truck.save! }.not_to raise_error
@@ -360,8 +362,6 @@ describe Mongoid::Persistable::Savable do
360
362
 
361
363
  context 'when also updating first embedded top level association' do
362
364
  it 'performs all writes' do
363
- pending 'https://jira.mongodb.org/browse/MONGOID-4982'
364
-
365
365
  truck.crates.first.volume = 2
366
366
  truck.crates.first.toys.build(name: 'Bear')
367
367
  truck.crates.build
@@ -397,8 +397,6 @@ describe Mongoid::Persistable::Savable do
397
397
 
398
398
  context 'when embedded association embeds another association' do
399
399
  it 'persists the new documents' do
400
- pending 'https://jira.mongodb.org/browse/MONGOID-4982'
401
-
402
400
  expect(truck.seats.size).to eq 1
403
401
  expect(truck.seats[0].rating).to eq 1
404
402
 
@@ -409,7 +407,7 @@ describe Mongoid::Persistable::Savable do
409
407
 
410
408
  _truck = Truck.find(truck.id)
411
409
  expect(_truck.seats.size).to eq 2
412
- expect(_truck.seats[0].rating).to eq 1
410
+ expect(_truck.seats[0].rating).to eq 2
413
411
  expect(_truck.seats[0].armrests.length).to eq 1
414
412
  expect(_truck.seats[1].rating).to eq 100
415
413
  end
@@ -458,7 +458,6 @@ describe Mongoid::Persistable::Updatable do
458
458
  describe "##{method}" do
459
459
 
460
460
  context "when saving with a hash field with invalid keys" do
461
- max_server_version '4.9'
462
461
 
463
462
  let(:person) do
464
463
  Person.create
@@ -495,7 +494,6 @@ describe Mongoid::Persistable::Updatable do
495
494
  end
496
495
 
497
496
  context "when the document has been destroyed" do
498
- max_server_version '4.9'
499
497
 
500
498
  let(:person) do
501
499
  Person.create
@@ -32,7 +32,7 @@ describe Mongoid::Persistable::Upsertable do
32
32
  context "when the document is new" do
33
33
 
34
34
  let!(:existing) do
35
- Band.create(name: "Photek")
35
+ Band.create!(name: "Photek")
36
36
  end
37
37
 
38
38
  context "when a matching document exists in the db" do
@@ -178,8 +178,8 @@ describe Mongoid::Persistable do
178
178
 
179
179
  before do
180
180
  class Band
181
- def my_updates(**args)
182
- atomically(**args) do |d|
181
+ def my_updates(*args)
182
+ atomically(*args) do |d|
183
183
  d.set(name: "Placebo")
184
184
  d.unset(:origin)
185
185
  end
@@ -58,4 +58,12 @@ describe Mongoid::QueryCache::Middleware do
58
58
  end
59
59
  end
60
60
  end
61
+
62
+ context 'when driver implements query cache middleware' do
63
+ min_driver_version '2.15'
64
+
65
+ it 'uses the driver query cache middleware' do
66
+ Mongoid::QueryCache::Middleware.should be Mongo::QueryCache::Middleware
67
+ end
68
+ end
61
69
  end
@@ -24,27 +24,10 @@ describe Mongoid::QueryCache do
24
24
  SessionRegistry.instance.verify_sessions_ended!
25
25
  end
26
26
 
27
- let(:reset_legacy_qc_warning) do
28
- begin
29
- Mongoid::QueryCache.remove_instance_variable('@legacy_query_cache_warned')
30
- rescue NameError
31
- # raised if the instance variable wasn't set
32
- end
33
- end
34
-
35
27
  describe '#cache' do
36
28
  context 'with driver query cache' do
37
29
  min_driver_version '2.14'
38
30
 
39
- it 'does not log a deprecation warning' do
40
- reset_legacy_qc_warning
41
-
42
- expect_any_instance_of(Logger).to_not receive(:warn).with(
43
- described_class::LEGACY_WARNING
44
- )
45
- described_class.cache { }
46
- end
47
-
48
31
  context 'when query cache is not enabled' do
49
32
  before do
50
33
  Mongoid::QueryCache.enabled = false
@@ -197,13 +180,6 @@ describe Mongoid::QueryCache do
197
180
  context 'with mongoid query cache' do
198
181
  max_driver_version '2.13'
199
182
 
200
- it 'logs a deprecation warning' do
201
- reset_legacy_qc_warning
202
-
203
- expect_any_instance_of(Logger).to receive(:warn).with(described_class::LEGACY_WARNING)
204
- described_class.cache { }
205
- end
206
-
207
183
  context 'when query cache is not enabled' do
208
184
  before do
209
185
  Mongoid::QueryCache.enabled = false
@@ -110,7 +110,7 @@ describe Mongoid::Reloadable do
110
110
 
111
111
  context "when document not saved" do
112
112
 
113
- context "when raising not found error" do
113
+ context "when there is no document matching our id" do
114
114
 
115
115
  it "raises an error" do
116
116
  expect {
@@ -118,6 +118,23 @@ describe Mongoid::Reloadable do
118
118
  }.to raise_error(Mongoid::Errors::DocumentNotFound)
119
119
  end
120
120
  end
121
+
122
+ context 'when there is a document matching our id' do
123
+
124
+ let!(:previous) { Agent.create!(title: '007') }
125
+
126
+ let(:agent) { Agent.new(id: previous.id) }
127
+
128
+ it 'loads the existing document' do
129
+ agent.title.should be nil
130
+
131
+ lambda do
132
+ agent.reload
133
+ end.should_not raise_error
134
+
135
+ agent.title.should == '007'
136
+ end
137
+ end
121
138
  end
122
139
 
123
140
  context "when the document is embedded" do
@@ -128,6 +128,50 @@ describe Mongoid::Shardable do
128
128
  end
129
129
  end
130
130
 
131
+ context 'when record is persisted' do
132
+ let(:instance) { klass.create(name: value) }
133
+
134
+ it { is_expected.to eq({ 'name' => value }) }
135
+
136
+ context 'changing shard key value' do
137
+ let(:new_value) { 'a-new-value' }
138
+
139
+ before do
140
+ instance.name = new_value
141
+ end
142
+
143
+ it 'uses the newly set shard key value' do
144
+ subject.should == { 'name' => new_value }
145
+ end
146
+ end
147
+ end
148
+ end
149
+
150
+ describe '#shard_key_selector_in_db' do
151
+ subject { instance.shard_key_selector_in_db }
152
+ let(:klass) { Band }
153
+ let(:value) { 'a-brand-name' }
154
+
155
+ before { klass.shard_key(:name) }
156
+
157
+ context 'when record is new' do
158
+ let(:instance) { klass.new(name: value) }
159
+
160
+ it { is_expected.to eq({ 'name' => value }) }
161
+
162
+ context 'changing shard key value' do
163
+ let(:new_value) { 'a-new-value' }
164
+
165
+ before do
166
+ instance.name = new_value
167
+ end
168
+
169
+ it 'uses the existing shard key value' do
170
+ subject.should == { 'name' => new_value }
171
+ end
172
+ end
173
+ end
174
+
131
175
  context 'when record is persisted' do
132
176
  let(:instance) { klass.create(name: value) }
133
177
 
@@ -2,6 +2,7 @@
2
2
  # encoding: utf-8
3
3
 
4
4
  require "spec_helper"
5
+ require_relative './touchable_spec_models'
5
6
 
6
7
  describe Mongoid::Touchable do
7
8
 
@@ -9,7 +10,7 @@ describe Mongoid::Touchable do
9
10
 
10
11
  context "when the document has no associations" do
11
12
  let(:updatable) do
12
- Updatable.create
13
+ Updatable.create!
13
14
  end
14
15
 
15
16
  it "responds to #touch" do
@@ -28,30 +29,117 @@ describe Mongoid::Touchable do
28
29
  end
29
30
  end
30
31
 
31
- context "when the document is embedded" do
32
+ context 'when the document has a parent association' do
32
33
 
33
- before do
34
- Label.send(:include, Mongoid::Touchable::InstanceMethods)
34
+ let(:building) do
35
+ parent_cls.create!
35
36
  end
36
37
 
37
- let(:band) do
38
- Band.create(name: "Placebo")
38
+ let(:entrance) do
39
+ building.entrances.create!
39
40
  end
40
41
 
41
- let(:label) do
42
- band.create_label(name: "Mute", updated_at: 10.days.ago)
42
+ let(:floor) do
43
+ building.floors.create!
43
44
  end
44
45
 
45
- before do
46
- label.touch
46
+ let!(:start_time) { Timecop.freeze(Time.at(Time.now.to_i)) }
47
+
48
+ let(:update_time) do
49
+ Timecop.freeze(Time.at(Time.now.to_i) + 2)
47
50
  end
48
51
 
49
- it "updates the updated_at timestamp" do
50
- expect(label.updated_at).to be_within(1).of(Time.now)
52
+ after do
53
+ Timecop.return
54
+ end
55
+
56
+ shared_examples 'updates the child' do
57
+ it "updates the updated_at timestamp" do
58
+ entrance
59
+ update_time
60
+ entrance.touch
61
+
62
+ entrance.updated_at.should == update_time
63
+ end
64
+
65
+ it "persists the changes" do
66
+ entrance
67
+ update_time
68
+ entrance.touch
69
+
70
+ entrance.reload.updated_at.should == update_time
71
+ end
51
72
  end
52
73
 
53
- it "persists the changes" do
54
- expect(label.reload.updated_at).to be_within(1).of(Time.now)
74
+ shared_examples 'updates the parent when :touch is true' do
75
+
76
+ it 'updates updated_at on parent' do
77
+ floor
78
+ update_time
79
+ floor.touch
80
+
81
+ building.updated_at.should == update_time
82
+ end
83
+
84
+ it 'persists updated updated_at on parent' do
85
+ floor
86
+ update_time
87
+ floor.touch
88
+
89
+ building.reload.updated_at.should == update_time
90
+ end
91
+ end
92
+
93
+ shared_examples 'updates the parent when :touch is not set' do
94
+ it 'does not update updated_at on parent' do
95
+ entrance
96
+ update_time
97
+ entrance.touch
98
+
99
+ building.updated_at.should == update_time
100
+ end
101
+
102
+ it 'does not persist updated updated_at on parent' do
103
+ entrance
104
+ update_time
105
+ entrance.touch
106
+
107
+ building.reload.updated_at.should == update_time
108
+ end
109
+ end
110
+
111
+ shared_examples 'does not update the parent when :touch is not set' do
112
+ it 'does not update updated_at on parent' do
113
+ entrance
114
+ update_time
115
+ entrance.touch
116
+
117
+ building.updated_at.should == start_time
118
+ end
119
+
120
+ it 'does not persist updated updated_at on parent' do
121
+ entrance
122
+ update_time
123
+ entrance.touch
124
+
125
+ building.reload.updated_at.should == start_time
126
+ end
127
+ end
128
+
129
+ context "when the document is embedded" do
130
+ let(:parent_cls) { TouchableSpec::Embedded::Building }
131
+
132
+ include_examples 'updates the child'
133
+ include_examples 'updates the parent when :touch is true'
134
+ include_examples 'updates the parent when :touch is not set'
135
+ end
136
+
137
+ context "when the document is referenced" do
138
+ let(:parent_cls) { TouchableSpec::Referenced::Building }
139
+
140
+ include_examples 'updates the child'
141
+ include_examples 'updates the parent when :touch is true'
142
+ include_examples 'does not update the parent when :touch is not set'
55
143
  end
56
144
  end
57
145
 
@@ -415,11 +503,11 @@ describe Mongoid::Touchable do
415
503
  context "when modifying the child" do
416
504
 
417
505
  let!(:agency) do
418
- Agency.create
506
+ Agency.create!
419
507
  end
420
508
 
421
509
  let!(:agent) do
422
- agency.agents.create(number: '1')
510
+ agency.agents.create!(number: '1')
423
511
  end
424
512
 
425
513
  it "updates the parent's updated at" do
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+ # encoding: utf-8
3
+
4
+ module TouchableSpec
5
+ module Embedded
6
+ class Building
7
+ include Mongoid::Document
8
+ include Mongoid::Timestamps
9
+
10
+ embeds_many :entrances
11
+ embeds_many :floors
12
+ end
13
+
14
+ class Entrance
15
+ include Mongoid::Document
16
+ include Mongoid::Timestamps
17
+
18
+ embedded_in :building
19
+ end
20
+
21
+ class Floor
22
+ include Mongoid::Document
23
+ include Mongoid::Timestamps
24
+
25
+ embedded_in :building, touch: true
26
+ end
27
+ end
28
+
29
+ module Referenced
30
+ class Building
31
+ include Mongoid::Document
32
+ include Mongoid::Timestamps
33
+
34
+ has_many :entrances, inverse_of: :building
35
+ has_many :floors, inverse_of: :building
36
+ end
37
+
38
+ class Entrance
39
+ include Mongoid::Document
40
+ include Mongoid::Timestamps
41
+
42
+ belongs_to :building
43
+ end
44
+
45
+ class Floor
46
+ include Mongoid::Document
47
+ include Mongoid::Timestamps
48
+
49
+ belongs_to :building, touch: true
50
+ end
51
+ end
52
+ end
@@ -37,7 +37,7 @@ describe Mongoid::Validatable do
37
37
  end
38
38
 
39
39
  let(:documents) do
40
- Mongoid::Association::Referenced::HasMany::Targets::Enumerable.new([ address ])
40
+ Mongoid::Association::Referenced::HasMany::Enumerable.new([ address ])
41
41
  end
42
42
 
43
43
  before do