mongoid 7.4.0 → 8.0.1

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 (315) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/README.md +3 -3
  4. data/lib/config/locales/en.yml +51 -28
  5. data/lib/mongoid/association/accessors.rb +32 -3
  6. data/lib/mongoid/association/bindable.rb +48 -0
  7. data/lib/mongoid/association/builders.rb +4 -2
  8. data/lib/mongoid/association/eager_loadable.rb +29 -7
  9. data/lib/mongoid/association/embedded/batchable.rb +48 -8
  10. data/lib/mongoid/association/embedded/embedded_in/binding.rb +24 -2
  11. data/lib/mongoid/association/embedded/embedded_in.rb +2 -1
  12. data/lib/mongoid/association/embedded/embeds_many/binding.rb +1 -0
  13. data/lib/mongoid/association/embedded/embeds_many/buildable.rb +1 -1
  14. data/lib/mongoid/association/embedded/embeds_many/proxy.rb +40 -18
  15. data/lib/mongoid/association/embedded/embeds_one/buildable.rb +18 -4
  16. data/lib/mongoid/association/embedded/embeds_one/proxy.rb +21 -2
  17. data/lib/mongoid/association/macros.rb +22 -1
  18. data/lib/mongoid/association/many.rb +5 -0
  19. data/lib/mongoid/association/nested/many.rb +2 -1
  20. data/lib/mongoid/association/proxy.rb +12 -0
  21. data/lib/mongoid/association/referenced/auto_save.rb +3 -2
  22. data/lib/mongoid/association/referenced/belongs_to/binding.rb +1 -0
  23. data/lib/mongoid/association/referenced/belongs_to/buildable.rb +1 -1
  24. data/lib/mongoid/association/referenced/belongs_to.rb +1 -1
  25. data/lib/mongoid/association/referenced/counter_cache.rb +8 -8
  26. data/lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb +64 -11
  27. data/lib/mongoid/association/referenced/has_and_belongs_to_many.rb +4 -1
  28. data/lib/mongoid/association/referenced/has_many/enumerable.rb +10 -14
  29. data/lib/mongoid/association/referenced/has_many/proxy.rb +12 -9
  30. data/lib/mongoid/association/referenced/has_one/buildable.rb +1 -1
  31. data/lib/mongoid/association/referenced/has_one/proxy.rb +8 -11
  32. data/lib/mongoid/association/referenced/syncable.rb +2 -2
  33. data/lib/mongoid/association/relatable.rb +38 -4
  34. data/lib/mongoid/atomic/paths/embedded/many.rb +19 -0
  35. data/lib/mongoid/attributes/processing.rb +9 -2
  36. data/lib/mongoid/attributes.rb +30 -27
  37. data/lib/mongoid/changeable.rb +37 -2
  38. data/lib/mongoid/clients/options.rb +4 -0
  39. data/lib/mongoid/clients/sessions.rb +2 -14
  40. data/lib/mongoid/config/environment.rb +20 -4
  41. data/lib/mongoid/config.rb +25 -10
  42. data/lib/mongoid/contextual/aggregable/memory.rb +23 -15
  43. data/lib/mongoid/contextual/aggregable/mongo.rb +1 -1
  44. data/lib/mongoid/contextual/map_reduce.rb +2 -2
  45. data/lib/mongoid/contextual/memory.rb +176 -17
  46. data/lib/mongoid/contextual/mongo.rb +226 -206
  47. data/lib/mongoid/contextual/none.rb +66 -4
  48. data/lib/mongoid/copyable.rb +32 -8
  49. data/lib/mongoid/criteria/includable.rb +24 -20
  50. data/lib/mongoid/criteria/marshalable.rb +10 -2
  51. data/lib/mongoid/criteria/queryable/extensions/array.rb +2 -13
  52. data/lib/mongoid/criteria/queryable/extensions/big_decimal.rb +25 -4
  53. data/lib/mongoid/criteria/queryable/extensions/boolean.rb +1 -1
  54. data/lib/mongoid/criteria/queryable/extensions/date.rb +6 -1
  55. data/lib/mongoid/criteria/queryable/extensions/date_time.rb +6 -1
  56. data/lib/mongoid/criteria/queryable/extensions/hash.rb +0 -14
  57. data/lib/mongoid/criteria/queryable/extensions/numeric.rb +1 -1
  58. data/lib/mongoid/criteria/queryable/extensions/object.rb +2 -1
  59. data/lib/mongoid/criteria/queryable/extensions/range.rb +13 -5
  60. data/lib/mongoid/criteria/queryable/extensions/regexp.rb +1 -1
  61. data/lib/mongoid/criteria/queryable/extensions/symbol.rb +3 -1
  62. data/lib/mongoid/criteria/queryable/extensions/time.rb +6 -1
  63. data/lib/mongoid/criteria/queryable/extensions/time_with_zone.rb +6 -1
  64. data/lib/mongoid/criteria/queryable/mergeable.rb +21 -0
  65. data/lib/mongoid/criteria/queryable/optional.rb +3 -9
  66. data/lib/mongoid/criteria/queryable/options.rb +1 -1
  67. data/lib/mongoid/criteria/queryable/selectable.rb +28 -34
  68. data/lib/mongoid/criteria/queryable/selector.rb +89 -4
  69. data/lib/mongoid/criteria/queryable/smash.rb +39 -6
  70. data/lib/mongoid/criteria/queryable.rb +11 -6
  71. data/lib/mongoid/criteria.rb +1 -26
  72. data/lib/mongoid/deprecable.rb +36 -0
  73. data/lib/mongoid/deprecation.rb +25 -0
  74. data/lib/mongoid/document.rb +96 -32
  75. data/lib/mongoid/errors/document_not_found.rb +29 -8
  76. data/lib/mongoid/errors/invalid_dot_dollar_assignment.rb +23 -0
  77. data/lib/mongoid/errors/invalid_field.rb +5 -1
  78. data/lib/mongoid/errors/invalid_field_type.rb +26 -0
  79. data/lib/mongoid/errors/too_many_nested_attribute_records.rb +1 -1
  80. data/lib/mongoid/errors.rb +2 -2
  81. data/lib/mongoid/extensions/array.rb +8 -6
  82. data/lib/mongoid/extensions/big_decimal.rb +29 -10
  83. data/lib/mongoid/extensions/binary.rb +42 -0
  84. data/lib/mongoid/extensions/boolean.rb +8 -2
  85. data/lib/mongoid/extensions/date.rb +26 -20
  86. data/lib/mongoid/extensions/date_time.rb +1 -1
  87. data/lib/mongoid/extensions/float.rb +4 -5
  88. data/lib/mongoid/extensions/hash.rb +12 -5
  89. data/lib/mongoid/extensions/integer.rb +4 -5
  90. data/lib/mongoid/extensions/object.rb +2 -0
  91. data/lib/mongoid/extensions/range.rb +41 -10
  92. data/lib/mongoid/extensions/regexp.rb +11 -4
  93. data/lib/mongoid/extensions/set.rb +11 -4
  94. data/lib/mongoid/extensions/string.rb +2 -13
  95. data/lib/mongoid/extensions/symbol.rb +3 -14
  96. data/lib/mongoid/extensions/time.rb +27 -16
  97. data/lib/mongoid/extensions/time_with_zone.rb +1 -2
  98. data/lib/mongoid/extensions.rb +1 -0
  99. data/lib/mongoid/factory.rb +42 -7
  100. data/lib/mongoid/fields/foreign_key.rb +7 -0
  101. data/lib/mongoid/fields/validators/macro.rb +3 -9
  102. data/lib/mongoid/fields.rb +194 -28
  103. data/lib/mongoid/findable.rb +27 -7
  104. data/lib/mongoid/indexable/specification.rb +1 -1
  105. data/lib/mongoid/indexable/validators/options.rb +4 -1
  106. data/lib/mongoid/interceptable.rb +69 -9
  107. data/lib/mongoid/persistable/creatable.rb +14 -5
  108. data/lib/mongoid/persistable/updatable.rb +12 -5
  109. data/lib/mongoid/persistable/upsertable.rb +1 -1
  110. data/lib/mongoid/persistence_context.rb +19 -2
  111. data/lib/mongoid/query_cache.rb +6 -258
  112. data/lib/mongoid/railties/controller_runtime.rb +1 -1
  113. data/lib/mongoid/reloadable.rb +7 -3
  114. data/lib/mongoid/selectable.rb +1 -2
  115. data/lib/mongoid/stateful.rb +27 -1
  116. data/lib/mongoid/timestamps/created.rb +1 -1
  117. data/lib/mongoid/timestamps/updated.rb +1 -1
  118. data/lib/mongoid/touchable.rb +2 -3
  119. data/lib/mongoid/traversable.rb +5 -1
  120. data/lib/mongoid/validatable/uniqueness.rb +2 -1
  121. data/lib/mongoid/version.rb +1 -1
  122. data/lib/mongoid/warnings.rb +28 -0
  123. data/lib/mongoid.rb +2 -0
  124. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +11 -5
  125. data/spec/config/mongoid.yml +16 -0
  126. data/spec/config/mongoid_with_schema_map_uuid.yml +27 -0
  127. data/spec/integration/app_spec.rb +28 -26
  128. data/spec/integration/associations/belongs_to_spec.rb +18 -0
  129. data/spec/integration/associations/embedded_dirty_spec.rb +28 -0
  130. data/spec/integration/associations/embedded_spec.rb +15 -0
  131. data/spec/integration/associations/embeds_many_spec.rb +15 -2
  132. data/spec/integration/associations/embeds_one_spec.rb +18 -0
  133. data/spec/integration/associations/foreign_key_spec.rb +9 -0
  134. data/spec/integration/associations/has_and_belongs_to_many_spec.rb +21 -0
  135. data/spec/integration/associations/has_one_spec.rb +97 -1
  136. data/spec/integration/associations/scope_option_spec.rb +1 -1
  137. data/spec/integration/callbacks_models.rb +95 -1
  138. data/spec/integration/callbacks_spec.rb +226 -4
  139. data/spec/integration/criteria/range_spec.rb +95 -1
  140. data/spec/integration/discriminator_key_spec.rb +115 -76
  141. data/spec/integration/dots_and_dollars_spec.rb +277 -0
  142. data/spec/integration/matcher_examples_spec.rb +20 -13
  143. data/spec/integration/matcher_operator_data/type_decimal.yml +3 -2
  144. data/spec/integration/matcher_operator_spec.rb +3 -5
  145. data/spec/integration/persistence/range_field_spec.rb +350 -0
  146. data/spec/lite_spec_helper.rb +1 -1
  147. data/spec/mongoid/association/counter_cache_spec.rb +1 -1
  148. data/spec/mongoid/association/depending_spec.rb +9 -9
  149. data/spec/mongoid/association/eager_spec.rb +2 -1
  150. data/spec/mongoid/association/embedded/embedded_in/binding_spec.rb +2 -1
  151. data/spec/mongoid/association/embedded/embedded_in/buildable_spec.rb +54 -0
  152. data/spec/mongoid/association/embedded/embedded_in/proxy_spec.rb +69 -9
  153. data/spec/mongoid/association/embedded/embeds_many/buildable_spec.rb +112 -0
  154. data/spec/mongoid/association/embedded/embeds_many/proxy_spec.rb +219 -8
  155. data/spec/mongoid/association/embedded/embeds_many_models.rb +157 -0
  156. data/spec/mongoid/association/embedded/embeds_many_query_spec.rb +12 -0
  157. data/spec/mongoid/association/embedded/embeds_many_spec.rb +68 -0
  158. data/spec/mongoid/association/embedded/embeds_one/buildable_spec.rb +25 -0
  159. data/spec/mongoid/association/embedded/embeds_one_models.rb +19 -0
  160. data/spec/mongoid/association/embedded/embeds_one_spec.rb +28 -0
  161. data/spec/mongoid/association/referenced/belongs_to/binding_spec.rb +2 -1
  162. data/spec/mongoid/association/referenced/belongs_to/buildable_spec.rb +54 -0
  163. data/spec/mongoid/association/referenced/belongs_to/proxy_spec.rb +15 -0
  164. data/spec/mongoid/association/referenced/belongs_to_models.rb +11 -0
  165. data/spec/mongoid/association/referenced/belongs_to_spec.rb +2 -2
  166. data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_spec.rb +67 -4
  167. data/spec/mongoid/association/referenced/has_and_belongs_to_many_models.rb +25 -0
  168. data/spec/mongoid/association/referenced/has_and_belongs_to_many_spec.rb +35 -2
  169. data/spec/mongoid/association/referenced/has_many/buildable_spec.rb +109 -0
  170. data/spec/mongoid/association/referenced/has_many/enumerable_spec.rb +8 -8
  171. data/spec/mongoid/association/referenced/has_many/proxy_spec.rb +82 -13
  172. data/spec/mongoid/association/referenced/has_many_models.rb +3 -1
  173. data/spec/mongoid/association/referenced/has_many_spec.rb +25 -0
  174. data/spec/mongoid/association/referenced/has_one/buildable_spec.rb +2 -2
  175. data/spec/mongoid/association/referenced/has_one/proxy_spec.rb +107 -1
  176. data/spec/mongoid/association/referenced/has_one_models.rb +16 -0
  177. data/spec/mongoid/association/syncable_spec.rb +14 -0
  178. data/spec/mongoid/atomic/paths_spec.rb +0 -14
  179. data/spec/mongoid/atomic_spec.rb +22 -0
  180. data/spec/mongoid/attributes/nested_spec.rb +80 -11
  181. data/spec/mongoid/attributes/nested_spec_models.rb +48 -0
  182. data/spec/mongoid/attributes/projector_spec.rb +1 -5
  183. data/spec/mongoid/attributes_spec.rb +524 -27
  184. data/spec/mongoid/changeable_spec.rb +130 -13
  185. data/spec/mongoid/clients/factory_spec.rb +34 -42
  186. data/spec/mongoid/clients/options_spec.rb +1 -0
  187. data/spec/mongoid/clients/sessions_spec.rb +0 -38
  188. data/spec/mongoid/clients_spec.rb +32 -2
  189. data/spec/mongoid/config/environment_spec.rb +39 -1
  190. data/spec/mongoid/config_spec.rb +104 -13
  191. data/spec/mongoid/contextual/aggregable/memory_spec.rb +396 -158
  192. data/spec/mongoid/contextual/aggregable/memory_table.yml +88 -0
  193. data/spec/mongoid/contextual/aggregable/memory_table_spec.rb +62 -0
  194. data/spec/mongoid/contextual/map_reduce_spec.rb +2 -16
  195. data/spec/mongoid/contextual/memory_spec.rb +1337 -69
  196. data/spec/mongoid/contextual/mongo_spec.rb +1105 -172
  197. data/spec/mongoid/contextual/none_spec.rb +38 -0
  198. data/spec/mongoid/copyable_spec.rb +451 -1
  199. data/spec/mongoid/criteria/findable_spec.rb +86 -210
  200. data/spec/mongoid/criteria/includable_spec.rb +1492 -0
  201. data/spec/mongoid/criteria/includable_spec_models.rb +54 -0
  202. data/spec/mongoid/criteria/marshalable_spec.rb +18 -1
  203. data/spec/mongoid/criteria/queryable/extensions/array_spec.rb +7 -19
  204. data/spec/mongoid/criteria/queryable/extensions/big_decimal_spec.rb +134 -26
  205. data/spec/mongoid/criteria/queryable/extensions/date_spec.rb +11 -0
  206. data/spec/mongoid/criteria/queryable/extensions/date_time_spec.rb +11 -0
  207. data/spec/mongoid/criteria/queryable/extensions/hash_spec.rb +0 -15
  208. data/spec/mongoid/criteria/queryable/extensions/numeric_spec.rb +73 -7
  209. data/spec/mongoid/criteria/queryable/extensions/time_spec.rb +11 -0
  210. data/spec/mongoid/criteria/queryable/extensions/time_with_zone_spec.rb +11 -0
  211. data/spec/mongoid/criteria/queryable/optional_spec.rb +0 -484
  212. data/spec/mongoid/criteria/queryable/selectable_logical_spec.rb +50 -0
  213. data/spec/mongoid/criteria/queryable/selectable_spec.rb +289 -124
  214. data/spec/mongoid/criteria/queryable/selector_spec.rb +14 -2
  215. data/spec/mongoid/criteria_spec.rb +474 -1198
  216. data/spec/mongoid/document_fields_spec.rb +173 -24
  217. data/spec/mongoid/document_spec.rb +32 -41
  218. data/spec/mongoid/errors/document_not_found_spec.rb +76 -0
  219. data/spec/mongoid/errors/invalid_field_spec.rb +1 -1
  220. data/spec/mongoid/errors/invalid_field_type_spec.rb +55 -0
  221. data/spec/mongoid/errors/mongoid_error_spec.rb +3 -1
  222. data/spec/mongoid/errors/no_environment_spec.rb +3 -3
  223. data/spec/mongoid/errors/too_many_nested_attribute_records_spec.rb +1 -1
  224. data/spec/mongoid/extensions/array_spec.rb +16 -2
  225. data/spec/mongoid/extensions/big_decimal_spec.rb +697 -212
  226. data/spec/mongoid/extensions/binary_spec.rb +44 -9
  227. data/spec/mongoid/extensions/boolean_spec.rb +68 -82
  228. data/spec/mongoid/extensions/date_class_mongoize_spec.rb +7 -3
  229. data/spec/mongoid/extensions/date_spec.rb +71 -1
  230. data/spec/mongoid/extensions/date_time_spec.rb +15 -9
  231. data/spec/mongoid/extensions/float_spec.rb +48 -76
  232. data/spec/mongoid/extensions/hash_spec.rb +30 -0
  233. data/spec/mongoid/extensions/integer_spec.rb +45 -66
  234. data/spec/mongoid/extensions/range_spec.rb +255 -54
  235. data/spec/mongoid/extensions/regexp_spec.rb +58 -33
  236. data/spec/mongoid/extensions/set_spec.rb +106 -0
  237. data/spec/mongoid/extensions/string_spec.rb +53 -25
  238. data/spec/mongoid/extensions/symbol_spec.rb +18 -25
  239. data/spec/mongoid/extensions/time_spec.rb +634 -66
  240. data/spec/mongoid/extensions/time_with_zone_spec.rb +17 -31
  241. data/spec/mongoid/factory_spec.rb +61 -1
  242. data/spec/mongoid/fields_spec.rb +321 -50
  243. data/spec/mongoid/findable_spec.rb +80 -15
  244. data/spec/mongoid/indexable/specification_spec.rb +2 -2
  245. data/spec/mongoid/indexable_spec.rb +16 -19
  246. data/spec/mongoid/interceptable_spec.rb +584 -5
  247. data/spec/mongoid/interceptable_spec_models.rb +235 -4
  248. data/spec/mongoid/matcher/extract_attribute_spec.rb +1 -5
  249. data/spec/mongoid/mongoizable_spec.rb +285 -0
  250. data/spec/mongoid/persistable/creatable_spec.rb +2 -2
  251. data/spec/mongoid/persistable/deletable_spec.rb +2 -2
  252. data/spec/mongoid/persistable/destroyable_spec.rb +2 -2
  253. data/spec/mongoid/persistable/upsertable_spec.rb +14 -0
  254. data/spec/mongoid/persistence_context_spec.rb +50 -1
  255. data/spec/mongoid/query_cache_middleware_spec.rb +0 -18
  256. data/spec/mongoid/query_cache_spec.rb +0 -154
  257. data/spec/mongoid/reloadable_spec.rb +35 -2
  258. data/spec/mongoid/scopable_spec.rb +21 -1
  259. data/spec/mongoid/shardable_spec.rb +14 -0
  260. data/spec/mongoid/stateful_spec.rb +28 -0
  261. data/spec/mongoid/timestamps_spec.rb +390 -0
  262. data/spec/mongoid/timestamps_spec_models.rb +67 -0
  263. data/spec/mongoid/touchable_spec.rb +116 -0
  264. data/spec/mongoid/touchable_spec_models.rb +12 -8
  265. data/spec/mongoid/traversable_spec.rb +4 -11
  266. data/spec/mongoid/validatable/presence_spec.rb +1 -1
  267. data/spec/mongoid/validatable/uniqueness_spec.rb +60 -31
  268. data/spec/mongoid/warnings_spec.rb +35 -0
  269. data/spec/rails/controller_extension/controller_runtime_spec.rb +2 -2
  270. data/spec/rails/mongoid_spec.rb +4 -16
  271. data/spec/shared/lib/mrss/constraints.rb +8 -16
  272. data/spec/shared/lib/mrss/docker_runner.rb +23 -3
  273. data/spec/shared/lib/mrss/eg_config_utils.rb +51 -0
  274. data/spec/shared/lib/mrss/lite_constraints.rb +32 -1
  275. data/spec/shared/share/Dockerfile.erb +34 -48
  276. data/spec/shared/shlib/config.sh +27 -0
  277. data/spec/shared/shlib/server.sh +32 -19
  278. data/spec/shared/shlib/set_env.sh +37 -0
  279. data/spec/support/constraints.rb +24 -0
  280. data/spec/support/macros.rb +39 -0
  281. data/spec/support/models/augmentation.rb +12 -0
  282. data/spec/support/models/band.rb +3 -0
  283. data/spec/support/models/catalog.rb +24 -0
  284. data/spec/support/models/circus.rb +3 -0
  285. data/spec/support/models/code.rb +2 -0
  286. data/spec/support/models/fanatic.rb +8 -0
  287. data/spec/support/models/implant.rb +9 -0
  288. data/spec/support/models/label.rb +2 -0
  289. data/spec/support/models/membership.rb +1 -0
  290. data/spec/support/models/passport.rb +9 -0
  291. data/spec/support/models/person.rb +1 -0
  292. data/spec/support/models/player.rb +2 -0
  293. data/spec/support/models/powerup.rb +12 -0
  294. data/spec/support/models/registry.rb +1 -0
  295. data/spec/support/models/school.rb +14 -0
  296. data/spec/support/models/shield.rb +18 -0
  297. data/spec/support/models/student.rb +14 -0
  298. data/spec/support/models/weapon.rb +12 -0
  299. data/spec/support/schema_maps/schema_map_aws.json +17 -0
  300. data/spec/support/schema_maps/schema_map_aws_key_alt_names.json +12 -0
  301. data/spec/support/schema_maps/schema_map_azure.json +17 -0
  302. data/spec/support/schema_maps/schema_map_azure_key_alt_names.json +12 -0
  303. data/spec/support/schema_maps/schema_map_gcp.json +17 -0
  304. data/spec/support/schema_maps/schema_map_gcp_key_alt_names.json +12 -0
  305. data/spec/support/schema_maps/schema_map_kmip.json +17 -0
  306. data/spec/support/schema_maps/schema_map_kmip_key_alt_names.json +12 -0
  307. data/spec/support/schema_maps/schema_map_local.json +18 -0
  308. data/spec/support/schema_maps/schema_map_local_key_alt_names.json +12 -0
  309. data/spec/support/spec_config.rb +4 -0
  310. data.tar.gz.sig +0 -0
  311. metadata +76 -13
  312. metadata.gz.sig +0 -0
  313. data/lib/mongoid/errors/eager_load.rb +0 -23
  314. data/lib/mongoid/errors/invalid_value.rb +0 -17
  315. data/spec/mongoid/errors/eager_load_spec.rb +0 -31
@@ -555,6 +555,56 @@ describe Mongoid::Changeable do
555
555
  end
556
556
  end
557
557
 
558
+ describe '#attribute_previously_was' do
559
+ let(:previous_title) do
560
+ "Grand Poobah"
561
+ end
562
+
563
+ let(:age) do
564
+ 10
565
+ end
566
+
567
+ let(:person) do
568
+ Person.create!(title: previous_title, age: age)
569
+ end
570
+
571
+ let(:updated_title) do
572
+ "Captain Obvious"
573
+ end
574
+
575
+ before do
576
+ person.title = updated_title
577
+ person.save!
578
+ end
579
+
580
+ context 'when attribute changed' do
581
+ it "returns the old value" do
582
+ expect(person.send(:attribute_previously_was, "title")).to eq(previous_title)
583
+ end
584
+
585
+ it "allows access via (attribute)_was" do
586
+ expect(person.title_previously_was).to eq(previous_title)
587
+ end
588
+ end
589
+
590
+ context 'when attribute did not change' do
591
+ it "returns the same value" do
592
+ expect(person.send(:attribute_previously_was, "age")).to eq(age)
593
+ end
594
+
595
+ it "allows access via (attribute)_was" do
596
+ expect(person.age_previously_was).to eq(age)
597
+ end
598
+ end
599
+
600
+ it 'clears after reload' do
601
+ person.reload
602
+ expect(person.title_previously_was).to be_nil
603
+ expect(person.age_previously_was).to be_nil
604
+ end
605
+
606
+ end
607
+
558
608
  describe "#attribute_will_change!" do
559
609
 
560
610
  let(:aliases) do
@@ -962,12 +1012,69 @@ describe Mongoid::Changeable do
962
1012
  person.user_accounts << user_account
963
1013
  end
964
1014
 
965
- it 'returns a hash of changes' do
966
- pending 'https://jira.mongodb.org/browse/MONGOID-4843'
1015
+ it 'should not add to the changes or changed_attributes hash' do
1016
+ person.changes.should == {}
1017
+ person.changed_attributes.should == {}
1018
+ end
1019
+ end
1020
+
1021
+ context 'when habtm association _ids changes' do
967
1022
 
968
- person.changes.should == {
969
- user_account_ids: [[], [user_account.id]]
970
- }
1023
+ let(:person) do
1024
+ Person.create!(title: "Grand Poobah")
1025
+ end
1026
+
1027
+ let(:user_account) do
1028
+ UserAccount.create!
1029
+ end
1030
+
1031
+ before do
1032
+ person.user_account_ids << user_account._id
1033
+ end
1034
+
1035
+ it 'should add to the changes or changed_attributes hash' do
1036
+ person.changes.should == { "user_account_ids" => [ nil, [ user_account._id ] ] }
1037
+ person.changed_attributes.should == { "user_account_ids" => nil }
1038
+ end
1039
+ end
1040
+
1041
+ context 'when assigning empty list to habtm association' do
1042
+
1043
+ let(:person) do
1044
+ Person.create!(title: "Grand Poobah", user_accounts: [user_account])
1045
+ end
1046
+
1047
+ let(:user_account) do
1048
+ UserAccount.create!
1049
+ end
1050
+
1051
+ before do
1052
+ person.user_accounts = []
1053
+ end
1054
+
1055
+ it 'should not add to the changes or changed_attributes hash' do
1056
+ person.changes.should == {}
1057
+ person.changed_attributes.should == {}
1058
+ end
1059
+ end
1060
+
1061
+ context 'when assigning empty list to habtm association _ids' do
1062
+
1063
+ let(:person) do
1064
+ Person.create!(title: "Grand Poobah", user_accounts: [user_account])
1065
+ end
1066
+
1067
+ let(:user_account) do
1068
+ UserAccount.create!
1069
+ end
1070
+
1071
+ before do
1072
+ person.user_account_ids = []
1073
+ end
1074
+
1075
+ it 'should not add to the changes or changed_attributes hash' do
1076
+ person.changes.should == { "user_account_ids" => [ [ user_account._id ], [] ] }
1077
+ person.changed_attributes.should == { "user_account_ids" => [ user_account._id ] }
971
1078
  end
972
1079
  end
973
1080
 
@@ -1649,21 +1756,26 @@ describe Mongoid::Changeable do
1649
1756
 
1650
1757
  before do
1651
1758
  Acolyte.set_callback(:save, :after, if: :callback_test?) do |doc|
1652
- doc[:changed_in_callback] = doc.changes.dup
1759
+ doc[:changed_in_after_callback] = doc.changes.dup
1760
+ end
1761
+
1762
+ Acolyte.set_callback(:save, :before, if: :callback_test?) do |doc|
1763
+ doc[:changed_in_before_callback] = doc.changes.dup
1653
1764
  end
1654
1765
  end
1655
1766
 
1656
1767
  after do
1657
1768
  Acolyte._save_callbacks.select do |callback|
1658
- callback.kind == :after
1769
+ [:before, :after].include?(callback.kind)
1659
1770
  end.each do |callback|
1660
1771
  Acolyte._save_callbacks.delete(callback)
1661
1772
  end
1662
1773
  end
1663
1774
 
1664
- it "retains the changes until after all callbacks" do
1775
+ it "does not retain the changes until after all callbacks" do
1665
1776
  acolyte.update_attribute(:status, "testing")
1666
- expect(acolyte.changed_in_callback).to eq({ "status" => [ nil, "testing" ] })
1777
+ expect(acolyte.changed_in_before_callback).to eq({"status"=>[nil, "testing"]})
1778
+ expect(acolyte.changed_in_after_callback).to eq({ })
1667
1779
  end
1668
1780
  end
1669
1781
 
@@ -1675,21 +1787,26 @@ describe Mongoid::Changeable do
1675
1787
 
1676
1788
  before do
1677
1789
  Acolyte.set_callback(:save, :after, if: :callback_test?) do |doc|
1678
- doc[:changed_in_callback] = doc.changes.dup
1790
+ doc[:changed_after_in_callback] = doc.changes.dup
1791
+ end
1792
+
1793
+ Acolyte.set_callback(:save, :before, if: :callback_test?) do |doc|
1794
+ doc[:changed_before_in_callback] = doc.changes.dup
1679
1795
  end
1680
1796
  end
1681
1797
 
1682
1798
  after do
1683
1799
  Acolyte._save_callbacks.select do |callback|
1684
- callback.kind == :after
1800
+ [:before, :after].include?(callback.kind)
1685
1801
  end.each do |callback|
1686
1802
  Acolyte._save_callbacks.delete(callback)
1687
1803
  end
1688
1804
  end
1689
1805
 
1690
- it "retains the changes until after all callbacks" do
1806
+ it "does not retain the changes until after all callbacks" do
1691
1807
  acolyte.save!
1692
- expect(acolyte.changed_in_callback["name"]).to eq([ nil, "callback-test" ])
1808
+ expect(acolyte.changed_before_in_callback["name"]).to eq([ nil, "callback-test" ])
1809
+ expect(acolyte.changed_after_in_callback["name"]).to be_nil
1693
1810
  end
1694
1811
  end
1695
1812
  end
@@ -36,6 +36,7 @@ describe Mongoid::Clients::Factory do
36
36
  context "when the configuration exists" do
37
37
 
38
38
  context "when the configuration is standard" do
39
+ restore_config_clients
39
40
 
40
41
  let(:config) do
41
42
  {
@@ -46,7 +47,6 @@ describe Mongoid::Clients::Factory do
46
47
 
47
48
  before do
48
49
  Mongoid::Config.send(:clients=, config)
49
- # TODO: We should restore overwritten configuration in after block
50
50
  end
51
51
 
52
52
  after do
@@ -65,10 +65,7 @@ describe Mongoid::Clients::Factory do
65
65
  expect(client).to be_a(Mongo::Client)
66
66
  end
67
67
 
68
- context 'not JRuby' do
69
- # Run this test on JRuby when driver 2.16.0 is released -
70
- # see RUBY-2771.
71
- fails_on_jruby
68
+ context 'on driver versions that do not report spurious EOF errors' do
72
69
 
73
70
  it 'does not produce driver warnings' do
74
71
  Mongo::Logger.logger.should_not receive(:warn)
@@ -86,40 +83,37 @@ describe Mongoid::Clients::Factory do
86
83
  expect(client.options[:platform]).to eq(Mongoid::PLATFORM_DETAILS)
87
84
  end
88
85
 
89
- context 'driver 2.13+' do
90
- min_driver_version '2.13'
86
+ it 'sets Mongoid as a wrapping library' do
87
+ client.options[:wrapping_libraries].should == [BSON::Document.new(
88
+ Mongoid::Clients::Factory::MONGOID_WRAPPING_LIBRARY)]
89
+ end
91
90
 
92
- it 'sets Mongoid as a wrapping library' do
93
- client.options[:wrapping_libraries].should == [BSON::Document.new(
94
- Mongoid::Clients::Factory::MONGOID_WRAPPING_LIBRARY)]
95
- end
91
+ context 'when configuration specifies a wrapping library' do
96
92
 
97
- context 'when configuration specifies a wrapping library' do
98
-
99
- let(:config) do
100
- {
101
- default: { hosts: SpecConfig.instance.addresses, database: database_id },
102
- analytics: {
103
- hosts: SpecConfig.instance.addresses,
104
- database: database_id,
105
- options: {
106
- wrapping_libraries: [{name: 'Foo'}],
107
- },
108
- }
93
+ let(:config) do
94
+ {
95
+ default: { hosts: SpecConfig.instance.addresses, database: database_id },
96
+ analytics: {
97
+ hosts: SpecConfig.instance.addresses,
98
+ database: database_id,
99
+ options: {
100
+ wrapping_libraries: [{name: 'Foo'}],
101
+ },
109
102
  }
110
- end
111
-
112
- it 'adds Mongoid as another wrapping library' do
113
- client.options[:wrapping_libraries].should == [
114
- BSON::Document.new(Mongoid::Clients::Factory::MONGOID_WRAPPING_LIBRARY),
115
- {'name' => 'Foo'},
116
- ]
117
- end
103
+ }
104
+ end
105
+
106
+ it 'adds Mongoid as another wrapping library' do
107
+ client.options[:wrapping_libraries].should == [
108
+ BSON::Document.new(Mongoid::Clients::Factory::MONGOID_WRAPPING_LIBRARY),
109
+ {'name' => 'Foo'},
110
+ ]
118
111
  end
119
112
  end
120
113
  end
121
114
 
122
115
  context "when the configuration has no ports" do
116
+ restore_config_clients
123
117
 
124
118
  let(:config) do
125
119
  {
@@ -130,7 +124,6 @@ describe Mongoid::Clients::Factory do
130
124
 
131
125
  before do
132
126
  Mongoid::Config.send(:clients=, config)
133
- # TODO: We should restore overwritten configuration in after block
134
127
  end
135
128
 
136
129
  after do
@@ -165,6 +158,7 @@ describe Mongoid::Clients::Factory do
165
158
  context "when configured via a uri" do
166
159
 
167
160
  context "when the uri has a single host:port" do
161
+ restore_config_clients
168
162
 
169
163
  let(:config) do
170
164
  {
@@ -175,7 +169,6 @@ describe Mongoid::Clients::Factory do
175
169
 
176
170
  before do
177
171
  Mongoid::Config.send(:clients=, config)
178
- # TODO: We should restore overwritten configuration in after block
179
172
  end
180
173
 
181
174
  after do
@@ -204,6 +197,7 @@ describe Mongoid::Clients::Factory do
204
197
  end
205
198
 
206
199
  context "when the uri has multiple host:port pairs" do
200
+ restore_config_clients
207
201
 
208
202
  let(:config) do
209
203
  {
@@ -214,7 +208,6 @@ describe Mongoid::Clients::Factory do
214
208
 
215
209
  before do
216
210
  Mongoid::Config.send(:clients=, config)
217
- # TODO: We should restore overwritten configuration in after block
218
211
  end
219
212
 
220
213
  after do
@@ -255,6 +248,7 @@ describe Mongoid::Clients::Factory do
255
248
  end
256
249
 
257
250
  context "when no name is provided" do
251
+ restore_config_clients
258
252
 
259
253
  let(:config) do
260
254
  { default: { hosts: SpecConfig.instance.addresses, database: database_id }}
@@ -262,7 +256,6 @@ describe Mongoid::Clients::Factory do
262
256
 
263
257
  before do
264
258
  Mongoid::Config.send(:clients=, config)
265
- # TODO: We should restore overwritten configuration in after block
266
259
  end
267
260
 
268
261
  after do
@@ -289,12 +282,12 @@ describe Mongoid::Clients::Factory do
289
282
  end
290
283
 
291
284
  context "when nil is provided and no default config" do
285
+ restore_config_clients
292
286
 
293
287
  let(:config) { nil }
294
288
 
295
289
  before do
296
290
  Mongoid.clients[:default] = nil
297
- # TODO: We should restore overwritten configuration in after block
298
291
  end
299
292
 
300
293
  it "raises NoClientsConfig error" do
@@ -304,6 +297,7 @@ describe Mongoid::Clients::Factory do
304
297
  end
305
298
 
306
299
  describe ".default" do
300
+ restore_config_clients
307
301
 
308
302
  let(:config) do
309
303
  { default: { hosts: SpecConfig.instance.addresses, database: database_id }}
@@ -311,7 +305,6 @@ describe Mongoid::Clients::Factory do
311
305
 
312
306
  before do
313
307
  Mongoid::Config.send(:clients=, config)
314
- # TODO: We should restore overwritten configuration in after block
315
308
  end
316
309
 
317
310
  after do
@@ -338,6 +331,7 @@ describe Mongoid::Clients::Factory do
338
331
  end
339
332
 
340
333
  context "when options are provided with string keys" do
334
+ restore_config_clients
341
335
 
342
336
  let(:config) do
343
337
  {
@@ -354,7 +348,6 @@ describe Mongoid::Clients::Factory do
354
348
 
355
349
  before do
356
350
  Mongoid::Config.send(:clients=, config)
357
- # TODO: We should restore overwritten configuration in after block
358
351
  end
359
352
 
360
353
  after do
@@ -393,6 +386,8 @@ describe Mongoid::Clients::Factory do
393
386
  end
394
387
 
395
388
  context "unexpected config options" do
389
+ restore_config_clients
390
+
396
391
  let(:unknown_opts) do
397
392
  {
398
393
  bad_one: 1,
@@ -410,11 +405,8 @@ describe Mongoid::Clients::Factory do
410
405
  }
411
406
  end
412
407
 
413
- around(:each) do |example|
414
- old_config = Mongoid::Config.clients
408
+ before do
415
409
  Mongoid::Config.send(:clients=, config)
416
- example.run
417
- Mongoid::Config.send(:clients=, old_config)
418
410
  end
419
411
 
420
412
  [:bad_one, :bad_two].each do |env|
@@ -413,6 +413,7 @@ describe Mongoid::Clients::Options, retry: 3 do
413
413
  end
414
414
 
415
415
  context 'when the options create a new cluster' do
416
+ retry_test
416
417
  # This test fails on sharded topologies in Evergreen but not locally
417
418
  require_topology :single, :replica_set
418
419
 
@@ -166,25 +166,6 @@ describe Mongoid::Clients::Sessions do
166
166
  end
167
167
  end
168
168
  end
169
-
170
- context 'when sessions are not supported' do
171
- max_server_version '3.4'
172
-
173
- let!(:error) do
174
- e = nil
175
- begin
176
- Person.with_session {}
177
- rescue => ex
178
- e = ex
179
- end
180
- e
181
- end
182
-
183
- it 'raises a sessions not supported error' do
184
- expect(error).to be_a(Mongoid::Errors::InvalidSessionUse)
185
- expect(error.message).to include('not supported')
186
- end
187
- end
188
169
  end
189
170
 
190
171
  context 'when a session is used on a model instance' do
@@ -312,24 +293,5 @@ describe Mongoid::Clients::Sessions do
312
293
  end
313
294
  end
314
295
  end
315
-
316
- context 'when sessions are not supported' do
317
- max_server_version '3.4'
318
-
319
- let!(:error) do
320
- e = nil
321
- begin
322
- person.with_session {}
323
- rescue => ex
324
- e = ex
325
- end
326
- e
327
- end
328
-
329
- it 'raises a sessions not supported error' do
330
- expect(error).to be_a(Mongoid::Errors::InvalidSessionUse)
331
- expect(error.message).to include('not supported')
332
- end
333
- end
334
296
  end
335
297
  end
@@ -802,7 +802,7 @@ describe Mongoid::Clients do
802
802
  it "does not persist to the default database" do
803
803
  expect {
804
804
  Band.find(band.id)
805
- }.to raise_error(Mongoid::Errors::DocumentNotFound)
805
+ }.to raise_error(Mongoid::Errors::DocumentNotFound, /Document\(s\) not found for class Band with id\(s\)/)
806
806
  end
807
807
 
808
808
  let(:from_db) do
@@ -840,7 +840,7 @@ describe Mongoid::Clients do
840
840
  it "does not persist to the default database" do
841
841
  expect {
842
842
  Band.find(band.id)
843
- }.to raise_error(Mongoid::Errors::DocumentNotFound)
843
+ }.to raise_error(Mongoid::Errors::DocumentNotFound, /Document\(s\) not found for class Band with id\(s\)/)
844
844
  end
845
845
 
846
846
  let(:from_db) do
@@ -1012,6 +1012,36 @@ describe Mongoid::Clients do
1012
1012
  end
1013
1013
  end
1014
1014
  end
1015
+
1016
+ context 'when requesting named client' do
1017
+ let(:secondary_client) do
1018
+ double(Mongo::Client).tap do |client|
1019
+ allow(client).to receive(:cluster).and_return(double("cluster"))
1020
+ end
1021
+ end
1022
+
1023
+ before do
1024
+ expect(Mongoid::Clients::Factory).to receive(:create)
1025
+ .with(:secondary)
1026
+ .and_return(secondary_client)
1027
+ end
1028
+
1029
+ after do
1030
+ Mongoid::Clients.clients.delete(:secondary)
1031
+ end
1032
+
1033
+ it 'does not close the client' do
1034
+ expect(secondary_client).not_to receive(:close)
1035
+
1036
+ Band.with(client: :default) do |klass|
1037
+ klass.mongo_client
1038
+ end
1039
+
1040
+ Band.with(client: :secondary) do |klass|
1041
+ klass.mongo_client
1042
+ end
1043
+ end
1044
+ end
1015
1045
  end
1016
1046
 
1017
1047
  context "when overriding the default database" do
@@ -106,7 +106,7 @@ describe Mongoid::Config::Environment do
106
106
 
107
107
  context 'when file found' do
108
108
  before do
109
- allow(File).to receive(:new).with('mongoid.yml').and_return(StringIO.new(file_contents))
109
+ allow(File).to receive(:read).with('mongoid.yml').and_return(file_contents)
110
110
  end
111
111
 
112
112
  let(:file_contents) do
@@ -162,5 +162,43 @@ describe Mongoid::Config::Environment do
162
162
  it { is_expected.to be_nil }
163
163
  end
164
164
  end
165
+
166
+ context 'when configuration includes schema map' do
167
+ paths = Dir.glob(File.join(File.dirname(__FILE__), '../../support/schema_maps/*.json'))
168
+
169
+ if paths.empty?
170
+ raise "Expected to find some schema maps"
171
+ end
172
+
173
+ before do
174
+ allow(File).to receive(:read).with('mongoid.yml').and_return(file_contents)
175
+ end
176
+
177
+ let(:file_contents) do
178
+ <<~FILE
179
+ test:
180
+ clients:
181
+ default:
182
+ database: mongoid_test
183
+ hosts: [localhost]
184
+ options:
185
+ auto_encryption_options:
186
+ schema_map: #{schema_map.to_yaml.sub(/\A---/, '').gsub(/\n/, "\n" + ' '*100)}
187
+ FILE
188
+ end
189
+
190
+ paths.each do |path|
191
+ context File.basename(path) do
192
+ let(:schema_map) do
193
+ BSON::ExtJSON.parse(File.read(path))
194
+ end
195
+
196
+ it 'loads successfully' do
197
+ subject.should be_a(Hash)
198
+ subject.fetch('clients').fetch('default').fetch('options').fetch('auto_encryption_options').fetch('schema_map').should be_a(Hash)
199
+ end
200
+ end
201
+ end
202
+ end
165
203
  end
166
204
  end