mongoid 7.2.1 → 9.0.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 (1082) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/CHANGELOG.md +20 -20
  4. data/LICENSE +1 -1
  5. data/README.md +7 -12
  6. data/Rakefile +58 -1
  7. data/lib/config/locales/en.yml +191 -60
  8. data/lib/mongoid/association/accessors.rb +67 -53
  9. data/lib/mongoid/association/bindable.rb +77 -31
  10. data/lib/mongoid/association/builders.rb +8 -14
  11. data/lib/mongoid/association/constrainable.rb +2 -5
  12. data/lib/mongoid/association/depending.rb +20 -12
  13. data/lib/mongoid/association/eager.rb +160 -0
  14. data/lib/mongoid/association/eager_loadable.rb +41 -11
  15. data/lib/mongoid/association/embedded/batchable.rb +63 -52
  16. data/lib/mongoid/association/embedded/cyclic.rb +4 -12
  17. data/lib/mongoid/association/embedded/eager.rb +23 -0
  18. data/lib/mongoid/association/embedded/embedded_in/binding.rb +29 -13
  19. data/lib/mongoid/association/embedded/embedded_in/buildable.rb +3 -5
  20. data/lib/mongoid/association/embedded/embedded_in/proxy.rb +25 -23
  21. data/lib/mongoid/association/embedded/embedded_in.rb +11 -26
  22. data/lib/mongoid/association/embedded/embeds_many/binding.rb +4 -9
  23. data/lib/mongoid/association/embedded/embeds_many/buildable.rb +5 -6
  24. data/lib/mongoid/association/embedded/embeds_many/proxy.rb +226 -203
  25. data/lib/mongoid/association/embedded/embeds_many.rb +3 -33
  26. data/lib/mongoid/association/embedded/embeds_one/binding.rb +3 -9
  27. data/lib/mongoid/association/embedded/embeds_one/buildable.rb +20 -8
  28. data/lib/mongoid/association/embedded/embeds_one/proxy.rb +131 -42
  29. data/lib/mongoid/association/embedded/embeds_one.rb +4 -30
  30. data/lib/mongoid/association/embedded.rb +2 -1
  31. data/lib/mongoid/association/macros.rb +47 -16
  32. data/lib/mongoid/association/many.rb +12 -24
  33. data/lib/mongoid/association/marshalable.rb +4 -5
  34. data/lib/mongoid/association/nested/many.rb +14 -19
  35. data/lib/mongoid/association/nested/nested_buildable.rb +36 -13
  36. data/lib/mongoid/association/nested/one.rb +54 -26
  37. data/lib/mongoid/association/nested.rb +1 -3
  38. data/lib/mongoid/association/one.rb +3 -11
  39. data/lib/mongoid/association/options.rb +18 -44
  40. data/lib/mongoid/association/proxy.rb +49 -42
  41. data/lib/mongoid/association/referenced/auto_save.rb +11 -15
  42. data/lib/mongoid/association/referenced/belongs_to/binding.rb +2 -7
  43. data/lib/mongoid/association/referenced/belongs_to/buildable.rb +6 -6
  44. data/lib/mongoid/association/referenced/belongs_to/eager.rb +2 -2
  45. data/lib/mongoid/association/referenced/belongs_to/proxy.rb +23 -32
  46. data/lib/mongoid/association/referenced/belongs_to.rb +13 -37
  47. data/lib/mongoid/association/referenced/counter_cache.rb +18 -26
  48. data/lib/mongoid/association/referenced/has_and_belongs_to_many/binding.rb +15 -8
  49. data/lib/mongoid/association/referenced/has_and_belongs_to_many/buildable.rb +1 -3
  50. data/lib/mongoid/association/referenced/has_and_belongs_to_many/eager.rb +2 -2
  51. data/lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb +191 -123
  52. data/lib/mongoid/association/referenced/has_and_belongs_to_many.rb +23 -42
  53. data/lib/mongoid/association/referenced/has_many/binding.rb +1 -5
  54. data/lib/mongoid/association/referenced/has_many/buildable.rb +1 -3
  55. data/lib/mongoid/association/referenced/has_many/eager.rb +2 -2
  56. data/lib/mongoid/association/referenced/has_many/enumerable.rb +471 -496
  57. data/lib/mongoid/association/referenced/has_many/proxy.rb +182 -179
  58. data/lib/mongoid/association/referenced/has_many.rb +17 -43
  59. data/lib/mongoid/association/referenced/has_one/binding.rb +1 -7
  60. data/lib/mongoid/association/referenced/has_one/buildable.rb +5 -5
  61. data/lib/mongoid/association/referenced/has_one/eager.rb +3 -4
  62. data/lib/mongoid/association/referenced/has_one/proxy.rb +38 -41
  63. data/lib/mongoid/association/referenced/has_one.rb +17 -36
  64. data/lib/mongoid/association/referenced/syncable.rb +11 -27
  65. data/lib/mongoid/association/referenced.rb +1 -1
  66. data/lib/mongoid/association/reflections.rb +9 -9
  67. data/lib/mongoid/association/relatable.rb +55 -74
  68. data/lib/mongoid/association.rb +10 -22
  69. data/lib/mongoid/atomic/modifiers.rb +7 -53
  70. data/lib/mongoid/atomic/paths/embedded/many.rb +20 -5
  71. data/lib/mongoid/atomic/paths/embedded/one.rb +1 -5
  72. data/lib/mongoid/atomic/paths/embedded.rb +1 -3
  73. data/lib/mongoid/atomic/paths/root.rb +1 -5
  74. data/lib/mongoid/atomic/paths.rb +1 -1
  75. data/lib/mongoid/atomic.rb +39 -86
  76. data/lib/mongoid/atomic_update_preparer.rb +88 -0
  77. data/lib/mongoid/attributes/dynamic.rb +5 -21
  78. data/lib/mongoid/attributes/embedded.rb +34 -0
  79. data/lib/mongoid/attributes/nested.rb +9 -13
  80. data/lib/mongoid/attributes/processing.rb +43 -28
  81. data/lib/mongoid/attributes/projector.rb +120 -0
  82. data/lib/mongoid/attributes/readonly.rb +4 -8
  83. data/lib/mongoid/attributes.rb +85 -89
  84. data/lib/mongoid/cacheable.rb +5 -9
  85. data/lib/mongoid/changeable.rb +183 -97
  86. data/lib/mongoid/clients/factory.rb +58 -15
  87. data/lib/mongoid/clients/options.rb +117 -8
  88. data/lib/mongoid/clients/sessions.rb +246 -84
  89. data/lib/mongoid/clients/storage_options.rb +37 -11
  90. data/lib/mongoid/clients/validators/storage.rb +4 -24
  91. data/lib/mongoid/clients/validators.rb +1 -1
  92. data/lib/mongoid/clients.rb +37 -14
  93. data/lib/mongoid/collection_configurable.rb +59 -0
  94. data/lib/mongoid/composable.rb +7 -7
  95. data/lib/mongoid/config/defaults.rb +40 -0
  96. data/lib/mongoid/config/encryption.rb +213 -0
  97. data/lib/mongoid/config/environment.rb +25 -5
  98. data/lib/mongoid/config/introspection.rb +152 -0
  99. data/lib/mongoid/config/options.rb +11 -14
  100. data/lib/mongoid/config/validators/async_query_executor.rb +34 -0
  101. data/lib/mongoid/config/validators/client.rb +7 -23
  102. data/lib/mongoid/config/validators/option.rb +1 -3
  103. data/lib/mongoid/config/validators.rb +2 -1
  104. data/lib/mongoid/config.rb +183 -46
  105. data/lib/mongoid/contextual/aggregable/memory.rb +38 -26
  106. data/lib/mongoid/contextual/aggregable/mongo.rb +26 -32
  107. data/lib/mongoid/contextual/aggregable/none.rb +66 -0
  108. data/lib/mongoid/contextual/aggregable.rb +18 -0
  109. data/lib/mongoid/contextual/atomic.rb +97 -30
  110. data/lib/mongoid/contextual/command.rb +3 -5
  111. data/lib/mongoid/contextual/map_reduce.rb +8 -33
  112. data/lib/mongoid/contextual/memory.rb +396 -89
  113. data/lib/mongoid/contextual/mongo/documents_loader.rb +178 -0
  114. data/lib/mongoid/contextual/mongo.rb +640 -311
  115. data/lib/mongoid/contextual/none.rb +244 -30
  116. data/lib/mongoid/contextual/queryable.rb +5 -4
  117. data/lib/mongoid/contextual.rb +18 -7
  118. data/lib/mongoid/copyable.rb +34 -14
  119. data/lib/mongoid/criteria/findable.rb +52 -22
  120. data/lib/mongoid/criteria/includable.rb +31 -34
  121. data/lib/mongoid/criteria/inspectable.rb +4 -3
  122. data/lib/mongoid/criteria/marshalable.rb +14 -7
  123. data/lib/mongoid/criteria/modifiable.rb +5 -19
  124. data/lib/mongoid/criteria/options.rb +1 -3
  125. data/lib/mongoid/criteria/permission.rb +6 -2
  126. data/lib/mongoid/criteria/queryable/aggregable.rb +3 -15
  127. data/lib/mongoid/criteria/queryable/expandable.rb +1 -25
  128. data/lib/mongoid/criteria/queryable/extensions/array.rb +6 -41
  129. data/lib/mongoid/criteria/queryable/extensions/big_decimal.rb +25 -9
  130. data/lib/mongoid/criteria/queryable/extensions/boolean.rb +5 -7
  131. data/lib/mongoid/criteria/queryable/extensions/date.rb +10 -11
  132. data/lib/mongoid/criteria/queryable/extensions/date_time.rb +8 -7
  133. data/lib/mongoid/criteria/queryable/extensions/hash.rb +3 -41
  134. data/lib/mongoid/criteria/queryable/extensions/nil_class.rb +2 -14
  135. data/lib/mongoid/criteria/queryable/extensions/numeric.rb +3 -21
  136. data/lib/mongoid/criteria/queryable/extensions/object.rb +7 -30
  137. data/lib/mongoid/criteria/queryable/extensions/range.rb +48 -17
  138. data/lib/mongoid/criteria/queryable/extensions/regexp.rb +10 -13
  139. data/lib/mongoid/criteria/queryable/extensions/set.rb +3 -5
  140. data/lib/mongoid/criteria/queryable/extensions/string.rb +19 -34
  141. data/lib/mongoid/criteria/queryable/extensions/symbol.rb +6 -22
  142. data/lib/mongoid/criteria/queryable/extensions/time.rb +8 -9
  143. data/lib/mongoid/criteria/queryable/extensions/time_with_zone.rb +9 -9
  144. data/lib/mongoid/criteria/queryable/extensions.rb +1 -5
  145. data/lib/mongoid/criteria/queryable/key.rb +15 -18
  146. data/lib/mongoid/criteria/queryable/macroable.rb +1 -3
  147. data/lib/mongoid/criteria/queryable/mergeable.rb +69 -50
  148. data/lib/mongoid/criteria/queryable/optional.rb +12 -62
  149. data/lib/mongoid/criteria/queryable/options.rb +3 -21
  150. data/lib/mongoid/criteria/queryable/pipeline.rb +2 -14
  151. data/lib/mongoid/criteria/queryable/selectable.rb +87 -124
  152. data/lib/mongoid/criteria/queryable/selector.rb +96 -25
  153. data/lib/mongoid/criteria/queryable/smash.rb +41 -18
  154. data/lib/mongoid/criteria/queryable/storable.rb +14 -9
  155. data/lib/mongoid/criteria/queryable.rb +12 -13
  156. data/lib/mongoid/criteria/scopable.rb +32 -21
  157. data/lib/mongoid/criteria/translator.rb +46 -0
  158. data/lib/mongoid/criteria.rb +60 -109
  159. data/lib/mongoid/deprecable.rb +38 -0
  160. data/lib/mongoid/deprecation.rb +29 -0
  161. data/lib/mongoid/document.rb +263 -173
  162. data/lib/mongoid/encryptable.rb +53 -0
  163. data/lib/mongoid/equality.rb +22 -25
  164. data/lib/mongoid/errors/ambiguous_relationship.rb +3 -5
  165. data/lib/mongoid/errors/attribute_not_loaded.rb +34 -0
  166. data/lib/mongoid/errors/callback.rb +1 -3
  167. data/lib/mongoid/errors/create_collection_failure.rb +34 -0
  168. data/lib/mongoid/errors/criteria_argument_required.rb +1 -1
  169. data/lib/mongoid/errors/delete_restriction.rb +9 -12
  170. data/lib/mongoid/errors/document_not_destroyed.rb +3 -7
  171. data/lib/mongoid/errors/document_not_found.rb +34 -21
  172. data/lib/mongoid/errors/drop_collection_failure.rb +28 -0
  173. data/lib/mongoid/errors/empty_config_file.rb +26 -0
  174. data/lib/mongoid/errors/immutable_attribute.rb +27 -0
  175. data/lib/mongoid/errors/in_memory_collation_not_supported.rb +1 -3
  176. data/lib/mongoid/errors/invalid_async_query_executor.rb +26 -0
  177. data/lib/mongoid/errors/invalid_auto_encryption_configuration.rb +33 -0
  178. data/lib/mongoid/errors/invalid_collection.rb +1 -1
  179. data/lib/mongoid/errors/invalid_config_file.rb +26 -0
  180. data/lib/mongoid/errors/invalid_config_option.rb +2 -4
  181. data/lib/mongoid/errors/invalid_dependent_strategy.rb +2 -4
  182. data/lib/mongoid/errors/invalid_discriminator_key_target.rb +1 -1
  183. data/lib/mongoid/errors/invalid_dot_dollar_assignment.rb +24 -0
  184. data/lib/mongoid/errors/invalid_elem_match_operator.rb +1 -1
  185. data/lib/mongoid/errors/invalid_estimated_count_criteria.rb +6 -5
  186. data/lib/mongoid/errors/invalid_estimated_count_scoping.rb +27 -0
  187. data/lib/mongoid/errors/invalid_expression_operator.rb +1 -1
  188. data/lib/mongoid/errors/invalid_field.rb +7 -7
  189. data/lib/mongoid/errors/invalid_field_operator.rb +1 -1
  190. data/lib/mongoid/errors/invalid_field_option.rb +1 -3
  191. data/lib/mongoid/errors/invalid_field_type.rb +27 -0
  192. data/lib/mongoid/errors/invalid_find.rb +1 -3
  193. data/lib/mongoid/errors/invalid_global_executor_concurrency.rb +23 -0
  194. data/lib/mongoid/errors/invalid_includes.rb +1 -3
  195. data/lib/mongoid/errors/invalid_index.rb +1 -3
  196. data/lib/mongoid/errors/invalid_options.rb +1 -3
  197. data/lib/mongoid/errors/invalid_path.rb +1 -3
  198. data/lib/mongoid/errors/invalid_persistence_option.rb +1 -5
  199. data/lib/mongoid/errors/invalid_query.rb +1 -1
  200. data/lib/mongoid/errors/invalid_relation.rb +2 -8
  201. data/lib/mongoid/errors/invalid_relation_option.rb +2 -4
  202. data/lib/mongoid/errors/invalid_scope.rb +1 -3
  203. data/lib/mongoid/errors/invalid_session_nesting.rb +17 -0
  204. data/lib/mongoid/errors/invalid_set_polymorphic_relation.rb +1 -2
  205. data/lib/mongoid/errors/invalid_storage_options.rb +2 -4
  206. data/lib/mongoid/errors/invalid_time.rb +1 -3
  207. data/lib/mongoid/errors/invalid_transaction_nesting.rb +17 -0
  208. data/lib/mongoid/errors/inverse_not_found.rb +1 -3
  209. data/lib/mongoid/errors/mixed_client_configuration.rb +1 -3
  210. data/lib/mongoid/errors/mixed_relations.rb +1 -3
  211. data/lib/mongoid/errors/mongoid_error.rb +8 -16
  212. data/lib/mongoid/errors/nested_attributes_metadata_not_found.rb +2 -4
  213. data/lib/mongoid/errors/no_client_config.rb +1 -3
  214. data/lib/mongoid/errors/no_client_database.rb +2 -4
  215. data/lib/mongoid/errors/no_client_hosts.rb +2 -4
  216. data/lib/mongoid/errors/no_clients_config.rb +1 -3
  217. data/lib/mongoid/errors/no_default_client.rb +1 -3
  218. data/lib/mongoid/errors/no_environment.rb +1 -3
  219. data/lib/mongoid/errors/no_map_reduce_output.rb +1 -3
  220. data/lib/mongoid/errors/no_metadata.rb +1 -3
  221. data/lib/mongoid/errors/no_parent.rb +1 -3
  222. data/lib/mongoid/errors/readonly_attribute.rb +2 -4
  223. data/lib/mongoid/errors/readonly_document.rb +2 -6
  224. data/lib/mongoid/errors/rollback.rb +15 -0
  225. data/lib/mongoid/errors/scope_overwrite.rb +1 -1
  226. data/lib/mongoid/errors/sessions_not_supported.rb +17 -0
  227. data/lib/mongoid/errors/too_many_nested_attribute_records.rb +2 -2
  228. data/lib/mongoid/errors/transaction_error.rb +25 -0
  229. data/lib/mongoid/errors/transactions_not_supported.rb +17 -0
  230. data/lib/mongoid/errors/unknown_attribute.rb +2 -4
  231. data/lib/mongoid/errors/unknown_model.rb +1 -3
  232. data/lib/mongoid/errors/unsaved_document.rb +2 -2
  233. data/lib/mongoid/errors/unsupported_javascript.rb +1 -3
  234. data/lib/mongoid/errors/validations.rb +1 -1
  235. data/lib/mongoid/errors.rb +18 -5
  236. data/lib/mongoid/evolvable.rb +2 -4
  237. data/lib/mongoid/extensions/array.rb +20 -58
  238. data/lib/mongoid/extensions/big_decimal.rb +44 -24
  239. data/lib/mongoid/extensions/binary.rb +45 -0
  240. data/lib/mongoid/extensions/boolean.rb +11 -6
  241. data/lib/mongoid/extensions/date.rb +31 -29
  242. data/lib/mongoid/extensions/date_time.rb +5 -16
  243. data/lib/mongoid/extensions/decimal128.rb +3 -5
  244. data/lib/mongoid/extensions/false_class.rb +8 -10
  245. data/lib/mongoid/extensions/float.rb +11 -12
  246. data/lib/mongoid/extensions/hash.rb +28 -148
  247. data/lib/mongoid/extensions/integer.rb +13 -14
  248. data/lib/mongoid/extensions/module.rb +5 -5
  249. data/lib/mongoid/extensions/nil_class.rb +5 -7
  250. data/lib/mongoid/extensions/object.rb +32 -81
  251. data/lib/mongoid/extensions/object_id.rb +3 -7
  252. data/lib/mongoid/extensions/range.rb +47 -24
  253. data/lib/mongoid/extensions/raw_value.rb +34 -0
  254. data/lib/mongoid/extensions/regexp.rb +14 -7
  255. data/lib/mongoid/extensions/set.rb +24 -13
  256. data/lib/mongoid/extensions/string.rb +30 -62
  257. data/lib/mongoid/extensions/symbol.rb +9 -22
  258. data/lib/mongoid/extensions/time.rb +30 -40
  259. data/lib/mongoid/extensions/time_with_zone.rb +18 -11
  260. data/lib/mongoid/extensions/true_class.rb +8 -10
  261. data/lib/mongoid/extensions.rb +3 -20
  262. data/lib/mongoid/factory.rb +178 -37
  263. data/lib/mongoid/fields/encrypted.rb +48 -0
  264. data/lib/mongoid/fields/foreign_key.rb +39 -27
  265. data/lib/mongoid/fields/localized.rb +25 -15
  266. data/lib/mongoid/fields/standard.rb +22 -40
  267. data/lib/mongoid/fields/validators/macro.rb +6 -19
  268. data/lib/mongoid/fields/validators.rb +1 -1
  269. data/lib/mongoid/fields.rb +354 -76
  270. data/lib/mongoid/findable.rb +62 -22
  271. data/lib/mongoid/indexable/specification.rb +55 -34
  272. data/lib/mongoid/indexable/validators/options.rb +7 -9
  273. data/lib/mongoid/indexable.rb +2 -18
  274. data/lib/mongoid/inspectable.rb +34 -11
  275. data/lib/mongoid/interceptable.rb +197 -41
  276. data/lib/mongoid/loadable.rb +83 -0
  277. data/lib/mongoid/loggable.rb +1 -9
  278. data/lib/mongoid/matchable.rb +2 -6
  279. data/lib/mongoid/matcher/all.rb +15 -0
  280. data/lib/mongoid/matcher/and.rb +14 -0
  281. data/lib/mongoid/matcher/bits.rb +60 -0
  282. data/lib/mongoid/matcher/bits_all_clear.rb +41 -0
  283. data/lib/mongoid/matcher/bits_all_set.rb +41 -0
  284. data/lib/mongoid/matcher/bits_any_clear.rb +41 -0
  285. data/lib/mongoid/matcher/bits_any_set.rb +41 -0
  286. data/lib/mongoid/matcher/elem_match.rb +17 -1
  287. data/lib/mongoid/matcher/elem_match_expression.rb +14 -2
  288. data/lib/mongoid/matcher/eq.rb +15 -0
  289. data/lib/mongoid/matcher/eq_impl.rb +54 -2
  290. data/lib/mongoid/matcher/eq_impl_with_regexp.rb +18 -1
  291. data/lib/mongoid/matcher/exists.rb +15 -0
  292. data/lib/mongoid/matcher/expression.rb +22 -14
  293. data/lib/mongoid/matcher/expression_operator.rb +14 -0
  294. data/lib/mongoid/matcher/field_expression.rb +19 -5
  295. data/lib/mongoid/matcher/field_operator.rb +30 -0
  296. data/lib/mongoid/matcher/gt.rb +15 -0
  297. data/lib/mongoid/matcher/gte.rb +15 -0
  298. data/lib/mongoid/matcher/in.rb +15 -0
  299. data/lib/mongoid/matcher/lt.rb +15 -0
  300. data/lib/mongoid/matcher/lte.rb +15 -0
  301. data/lib/mongoid/matcher/mod.rb +33 -0
  302. data/lib/mongoid/matcher/ne.rb +15 -0
  303. data/lib/mongoid/matcher/nin.rb +15 -0
  304. data/lib/mongoid/matcher/nor.rb +14 -0
  305. data/lib/mongoid/matcher/not.rb +16 -0
  306. data/lib/mongoid/matcher/or.rb +14 -0
  307. data/lib/mongoid/matcher/regex.rb +24 -0
  308. data/lib/mongoid/matcher/size.rb +16 -0
  309. data/lib/mongoid/matcher/type.rb +124 -0
  310. data/lib/mongoid/matcher.rb +59 -52
  311. data/lib/mongoid/persistable/creatable.rb +25 -29
  312. data/lib/mongoid/persistable/deletable.rb +10 -23
  313. data/lib/mongoid/persistable/destroyable.rb +37 -11
  314. data/lib/mongoid/persistable/incrementable.rb +2 -6
  315. data/lib/mongoid/persistable/logical.rb +1 -5
  316. data/lib/mongoid/persistable/maxable.rb +37 -0
  317. data/lib/mongoid/persistable/minable.rb +37 -0
  318. data/lib/mongoid/persistable/multipliable.rb +36 -0
  319. data/lib/mongoid/persistable/poppable.rb +1 -5
  320. data/lib/mongoid/persistable/pullable.rb +1 -7
  321. data/lib/mongoid/persistable/pushable.rb +1 -7
  322. data/lib/mongoid/persistable/renamable.rb +1 -5
  323. data/lib/mongoid/persistable/savable.rb +14 -8
  324. data/lib/mongoid/persistable/settable.rb +1 -5
  325. data/lib/mongoid/persistable/unsettable.rb +3 -7
  326. data/lib/mongoid/persistable/updatable.rb +114 -28
  327. data/lib/mongoid/persistable/upsertable.rb +33 -8
  328. data/lib/mongoid/persistable.rb +17 -27
  329. data/lib/mongoid/persistence_context.rb +111 -43
  330. data/lib/mongoid/positional.rb +1 -5
  331. data/lib/mongoid/railtie.rb +23 -15
  332. data/lib/mongoid/railties/bson_object_id_serializer.rb +39 -0
  333. data/lib/mongoid/railties/console_sandbox.rb +42 -0
  334. data/lib/mongoid/railties/controller_runtime.rb +21 -6
  335. data/lib/mongoid/railties/database.rake +19 -2
  336. data/lib/mongoid/reloadable.rb +45 -42
  337. data/lib/mongoid/scopable.rb +25 -53
  338. data/lib/mongoid/search_indexable.rb +167 -0
  339. data/lib/mongoid/selectable.rb +6 -17
  340. data/lib/mongoid/serializable.rb +11 -21
  341. data/lib/mongoid/shardable.rb +50 -16
  342. data/lib/mongoid/stateful.rb +66 -22
  343. data/lib/mongoid/stringified_symbol.rb +19 -7
  344. data/lib/mongoid/tasks/database.rake +25 -0
  345. data/lib/mongoid/tasks/database.rb +84 -8
  346. data/lib/mongoid/tasks/encryption.rake +59 -0
  347. data/lib/mongoid/tasks/encryption.rb +108 -0
  348. data/lib/mongoid/threaded/lifecycle.rb +6 -26
  349. data/lib/mongoid/threaded.rb +131 -92
  350. data/lib/mongoid/timestamps/created/short.rb +1 -1
  351. data/lib/mongoid/timestamps/created.rb +4 -4
  352. data/lib/mongoid/timestamps/short.rb +1 -1
  353. data/lib/mongoid/timestamps/timeless.rb +29 -7
  354. data/lib/mongoid/timestamps/updated/short.rb +1 -1
  355. data/lib/mongoid/timestamps/updated.rb +3 -5
  356. data/lib/mongoid/timestamps.rb +1 -1
  357. data/lib/mongoid/touchable.rb +155 -29
  358. data/lib/mongoid/traversable.rb +180 -125
  359. data/lib/mongoid/utils.rb +52 -0
  360. data/lib/mongoid/validatable/associated.rb +97 -21
  361. data/lib/mongoid/validatable/format.rb +1 -1
  362. data/lib/mongoid/validatable/length.rb +1 -1
  363. data/lib/mongoid/validatable/localizable.rb +2 -4
  364. data/lib/mongoid/validatable/macros.rb +10 -14
  365. data/lib/mongoid/validatable/presence.rb +7 -13
  366. data/lib/mongoid/validatable/queryable.rb +9 -3
  367. data/lib/mongoid/validatable/uniqueness.rb +26 -39
  368. data/lib/mongoid/validatable.rb +20 -29
  369. data/lib/mongoid/version.rb +2 -2
  370. data/lib/mongoid/warnings.rb +37 -0
  371. data/lib/mongoid.rb +56 -22
  372. data/lib/rails/generators/mongoid/config/config_generator.rb +25 -5
  373. data/lib/rails/generators/mongoid/config/templates/mongoid.rb +25 -0
  374. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +44 -64
  375. data/lib/rails/generators/mongoid/model/model_generator.rb +4 -1
  376. data/lib/rails/generators/mongoid_generator.rb +13 -1
  377. data/lib/rails/mongoid.rb +4 -32
  378. data/spec/config/mongoid.yml +16 -1
  379. data/spec/config/mongoid_with_schema_map_uuid.yml +27 -0
  380. data/spec/integration/active_job_spec.rb +32 -0
  381. data/spec/integration/app_spec.rb +180 -89
  382. data/spec/integration/associations/belongs_to_spec.rb +19 -1
  383. data/spec/integration/associations/embedded_dirty_spec.rb +58 -0
  384. data/spec/integration/associations/embedded_spec.rb +90 -7
  385. data/spec/integration/associations/embeds_many_spec.rb +197 -1
  386. data/spec/integration/associations/embeds_one_spec.rb +19 -1
  387. data/spec/integration/associations/foreign_key_spec.rb +10 -1
  388. data/spec/integration/associations/foreign_key_spec_models.rb +1 -1
  389. data/spec/integration/associations/has_and_belongs_to_many_spec.rb +62 -0
  390. data/spec/integration/associations/has_many_spec.rb +1 -1
  391. data/spec/integration/associations/has_one_spec.rb +145 -1
  392. data/spec/integration/associations/nested_attributes_assignment_spec.rb +1 -1
  393. data/spec/integration/associations/reverse_population_spec.rb +1 -1
  394. data/spec/integration/associations/reverse_population_spec_models.rb +1 -1
  395. data/spec/integration/associations/scope_option_spec.rb +102 -0
  396. data/spec/integration/atomic/modifiers_spec.rb +1 -1
  397. data/spec/integration/bson_regexp_raw_spec.rb +1 -1
  398. data/spec/integration/callbacks_models.rb +147 -3
  399. data/spec/integration/callbacks_spec.rb +398 -8
  400. data/spec/integration/contextual/empty_spec.rb +142 -0
  401. data/spec/integration/criteria/alias_query_spec.rb +98 -0
  402. data/spec/integration/criteria/date_field_spec.rb +2 -2
  403. data/spec/integration/criteria/default_scope_spec.rb +52 -0
  404. data/spec/integration/criteria/logical_spec.rb +12 -0
  405. data/spec/integration/criteria/range_spec.rb +358 -0
  406. data/spec/integration/criteria/raw_value_spec.rb +525 -0
  407. data/spec/integration/criteria/time_with_zone_spec.rb +126 -15
  408. data/spec/integration/discriminator_key_spec.rb +119 -81
  409. data/spec/integration/discriminator_value_spec.rb +1 -1
  410. data/spec/integration/document_spec.rb +31 -1
  411. data/spec/integration/dots_and_dollars_spec.rb +278 -0
  412. data/spec/integration/encryption_spec.rb +100 -0
  413. data/spec/integration/i18n_fallbacks_spec.rb +10 -52
  414. data/spec/integration/matcher_examples_spec.rb +21 -14
  415. data/spec/integration/matcher_operator_data/bits_all_clear.yml +144 -0
  416. data/spec/integration/matcher_operator_data/bits_all_set.yml +144 -0
  417. data/spec/integration/matcher_operator_data/bits_any_clear.yml +144 -0
  418. data/spec/integration/matcher_operator_data/bits_any_set.yml +144 -0
  419. data/spec/integration/matcher_operator_data/comment.yml +22 -0
  420. data/spec/integration/matcher_operator_data/elem_match.yml +46 -0
  421. data/spec/integration/matcher_operator_data/implicit_traversal.yml +96 -0
  422. data/spec/integration/matcher_operator_data/in.yml +16 -0
  423. data/spec/integration/matcher_operator_data/mod.yml +55 -0
  424. data/spec/integration/matcher_operator_data/size.yml +0 -3
  425. data/spec/integration/matcher_operator_data/type.yml +64 -0
  426. data/spec/integration/matcher_operator_data/type_array.yml +15 -0
  427. data/spec/integration/matcher_operator_data/type_binary.yml +18 -0
  428. data/spec/integration/matcher_operator_data/type_boolean.yml +39 -0
  429. data/spec/integration/matcher_operator_data/type_code.yml +26 -0
  430. data/spec/integration/matcher_operator_data/type_code_with_scope.yml +26 -0
  431. data/spec/integration/matcher_operator_data/type_date.yml +39 -0
  432. data/spec/integration/matcher_operator_data/type_db_pointer.yml +19 -0
  433. data/spec/integration/matcher_operator_data/type_decimal.yml +37 -0
  434. data/spec/integration/matcher_operator_data/type_double.yml +15 -0
  435. data/spec/integration/matcher_operator_data/type_int32.yml +33 -0
  436. data/spec/integration/matcher_operator_data/type_int64.yml +33 -0
  437. data/spec/integration/matcher_operator_data/type_max_key.yml +17 -0
  438. data/spec/integration/matcher_operator_data/type_min_key.yml +17 -0
  439. data/spec/integration/matcher_operator_data/type_null.yml +23 -0
  440. data/spec/integration/matcher_operator_data/type_object.yml +23 -0
  441. data/spec/integration/matcher_operator_data/type_object_id.yml +25 -0
  442. data/spec/integration/matcher_operator_data/type_regex.yml +44 -0
  443. data/spec/integration/matcher_operator_data/type_string.yml +15 -0
  444. data/spec/integration/matcher_operator_data/type_symbol.yml +32 -0
  445. data/spec/integration/matcher_operator_data/type_timestamp.yml +25 -0
  446. data/spec/integration/matcher_operator_data/type_undefined.yml +17 -0
  447. data/spec/integration/matcher_operator_spec.rb +26 -3
  448. data/spec/integration/matcher_spec.rb +50 -1
  449. data/spec/integration/persistence/range_field_spec.rb +351 -0
  450. data/spec/integration/server_query_spec.rb +1 -1
  451. data/spec/integration/shardable_spec.rb +1 -1
  452. data/spec/integration/stringified_symbol_field_spec.rb +17 -3
  453. data/spec/lite_spec_helper.rb +47 -14
  454. data/spec/mongoid/association/accessors_spec.rb +31 -19
  455. data/spec/mongoid/association/auto_save_spec.rb +73 -34
  456. data/spec/mongoid/association/builders_spec.rb +2 -2
  457. data/spec/mongoid/association/constrainable_spec.rb +1 -1
  458. data/spec/mongoid/association/counter_cache_spec.rb +34 -34
  459. data/spec/mongoid/association/depending_spec.rb +397 -358
  460. data/spec/mongoid/association/eager_spec.rb +56 -6
  461. data/spec/mongoid/association/embedded/cyclic_spec.rb +3 -3
  462. data/spec/mongoid/association/embedded/dirty_spec.rb +3 -3
  463. data/spec/mongoid/association/embedded/embedded_in/binding_spec.rb +3 -2
  464. data/spec/mongoid/association/embedded/embedded_in/buildable_spec.rb +55 -1
  465. data/spec/mongoid/association/embedded/embedded_in/proxy_spec.rb +110 -23
  466. data/spec/mongoid/association/embedded/embedded_in_spec.rb +19 -8
  467. data/spec/mongoid/association/embedded/embeds_many/binding_spec.rb +1 -1
  468. data/spec/mongoid/association/embedded/embeds_many/buildable_spec.rb +113 -1
  469. data/spec/mongoid/association/embedded/embeds_many/proxy_spec.rb +712 -203
  470. data/spec/mongoid/association/embedded/embeds_many_models.rb +189 -1
  471. data/spec/mongoid/association/embedded/embeds_many_query_spec.rb +14 -2
  472. data/spec/mongoid/association/embedded/embeds_many_spec.rb +69 -1
  473. data/spec/mongoid/association/embedded/embeds_one/binding_spec.rb +1 -1
  474. data/spec/mongoid/association/embedded/embeds_one/buildable_spec.rb +26 -1
  475. data/spec/mongoid/association/embedded/embeds_one/proxy_spec.rb +37 -24
  476. data/spec/mongoid/association/embedded/embeds_one_dnl_models.rb +1 -1
  477. data/spec/mongoid/association/embedded/embeds_one_models.rb +25 -2
  478. data/spec/mongoid/association/embedded/embeds_one_query_spec.rb +2 -2
  479. data/spec/mongoid/association/embedded/embeds_one_spec.rb +29 -1
  480. data/spec/mongoid/association/macros_spec.rb +10 -10
  481. data/spec/mongoid/association/nested/many_spec.rb +1 -1
  482. data/spec/mongoid/association/nested/one_spec.rb +17 -13
  483. data/spec/mongoid/association/options_spec.rb +1 -1
  484. data/spec/mongoid/association/polymorphic_spec.rb +1 -1
  485. data/spec/mongoid/association/referenced/belongs_to/binding_spec.rb +3 -2
  486. data/spec/mongoid/association/referenced/belongs_to/buildable_spec.rb +110 -17
  487. data/spec/mongoid/association/referenced/belongs_to/eager_spec.rb +51 -15
  488. data/spec/mongoid/association/referenced/belongs_to/proxy_spec.rb +113 -59
  489. data/spec/mongoid/association/referenced/belongs_to_models.rb +12 -0
  490. data/spec/mongoid/association/referenced/belongs_to_query_spec.rb +22 -2
  491. data/spec/mongoid/association/referenced/belongs_to_spec.rb +27 -22
  492. data/spec/mongoid/association/referenced/has_and_belongs_to_many/binding_spec.rb +2 -2
  493. data/spec/mongoid/association/referenced/has_and_belongs_to_many/buildable_spec.rb +28 -3
  494. data/spec/mongoid/association/referenced/has_and_belongs_to_many/eager_spec.rb +32 -3
  495. data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_persistence_spec.rb +1 -1
  496. data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_spec.rb +386 -376
  497. data/spec/mongoid/association/referenced/has_and_belongs_to_many_models.rb +44 -1
  498. data/spec/mongoid/association/referenced/has_and_belongs_to_many_query_spec.rb +2 -2
  499. data/spec/mongoid/association/referenced/has_and_belongs_to_many_spec.rb +57 -3
  500. data/spec/mongoid/association/referenced/has_many/binding_spec.rb +2 -2
  501. data/spec/mongoid/association/referenced/has_many/buildable_spec.rb +131 -1
  502. data/spec/mongoid/association/referenced/has_many/eager_spec.rb +24 -7
  503. data/spec/mongoid/association/referenced/has_many/enumerable_spec.rb +313 -134
  504. data/spec/mongoid/association/referenced/has_many/proxy_query_spec.rb +1 -1
  505. data/spec/mongoid/association/referenced/has_many/proxy_spec.rb +1313 -2109
  506. data/spec/mongoid/association/referenced/has_many_models.rb +39 -2
  507. data/spec/mongoid/association/referenced/has_many_query_spec.rb +2 -2
  508. data/spec/mongoid/association/referenced/has_many_spec.rb +47 -1
  509. data/spec/mongoid/association/referenced/has_one/binding_spec.rb +1 -1
  510. data/spec/mongoid/association/referenced/has_one/buildable_spec.rb +54 -10
  511. data/spec/mongoid/association/referenced/has_one/eager_spec.rb +18 -2
  512. data/spec/mongoid/association/referenced/has_one/proxy_spec.rb +134 -28
  513. data/spec/mongoid/association/referenced/has_one_models.rb +43 -1
  514. data/spec/mongoid/association/referenced/has_one_query_spec.rb +2 -2
  515. data/spec/mongoid/association/referenced/has_one_spec.rb +22 -1
  516. data/spec/mongoid/association/reflections_spec.rb +1 -1
  517. data/spec/mongoid/association/syncable_spec.rb +47 -33
  518. data/spec/mongoid/association_spec.rb +1 -1
  519. data/spec/mongoid/atomic/modifiers_spec.rb +1 -1
  520. data/spec/mongoid/atomic/paths/embedded/many_spec.rb +1 -1
  521. data/spec/mongoid/atomic/paths/embedded/one_spec.rb +1 -1
  522. data/spec/mongoid/atomic/paths/root_spec.rb +1 -1
  523. data/spec/mongoid/atomic/paths_spec.rb +65 -27
  524. data/spec/mongoid/atomic_spec.rb +29 -7
  525. data/spec/mongoid/atomic_update_preparer_spec.rb +83 -0
  526. data/spec/mongoid/attributes/dynamic_spec.rb +1 -1
  527. data/spec/mongoid/attributes/embedded_spec.rb +118 -0
  528. data/spec/mongoid/attributes/nested_spec.rb +147 -78
  529. data/spec/mongoid/attributes/nested_spec_models.rb +49 -0
  530. data/spec/mongoid/attributes/projector_data/embedded.yml +105 -0
  531. data/spec/mongoid/attributes/projector_data/fields.yml +93 -0
  532. data/spec/mongoid/attributes/projector_spec.rb +41 -0
  533. data/spec/mongoid/attributes/readonly_spec.rb +23 -23
  534. data/spec/mongoid/attributes_spec.rb +921 -69
  535. data/spec/mongoid/cacheable_spec.rb +5 -5
  536. data/spec/mongoid/changeable_spec.rb +468 -76
  537. data/spec/mongoid/clients/factory_spec.rb +152 -30
  538. data/spec/mongoid/clients/options_spec.rb +24 -12
  539. data/spec/mongoid/clients/sessions_spec.rb +49 -71
  540. data/spec/mongoid/clients/transactions_spec.rb +971 -176
  541. data/spec/mongoid/clients/transactions_spec_models.rb +159 -0
  542. data/spec/mongoid/clients_spec.rb +230 -22
  543. data/spec/mongoid/collection_configurable_spec.rb +159 -0
  544. data/spec/mongoid/composable_spec.rb +1 -1
  545. data/spec/mongoid/config/defaults_spec.rb +99 -0
  546. data/spec/mongoid/config/encryption_spec.rb +152 -0
  547. data/spec/mongoid/config/environment_spec.rb +126 -39
  548. data/spec/mongoid/config/introspection_spec.rb +114 -0
  549. data/spec/mongoid/config/options_spec.rb +1 -1
  550. data/spec/mongoid/config_spec.rb +375 -43
  551. data/spec/mongoid/contextual/aggregable/memory_spec.rb +432 -154
  552. data/spec/mongoid/contextual/aggregable/memory_table.yml +88 -0
  553. data/spec/mongoid/contextual/aggregable/memory_table_spec.rb +63 -0
  554. data/spec/mongoid/contextual/aggregable/mongo_spec.rb +95 -20
  555. data/spec/mongoid/contextual/aggregable/none_spec.rb +49 -0
  556. data/spec/mongoid/contextual/atomic_spec.rb +329 -87
  557. data/spec/mongoid/contextual/map_reduce_spec.rb +5 -19
  558. data/spec/mongoid/contextual/memory_spec.rb +1479 -127
  559. data/spec/mongoid/contextual/mongo/documents_loader_spec.rb +194 -0
  560. data/spec/mongoid/contextual/mongo_spec.rb +3374 -1254
  561. data/spec/mongoid/contextual/none_spec.rb +79 -68
  562. data/spec/mongoid/copyable_spec.rb +465 -23
  563. data/spec/mongoid/copyable_spec_models.rb +1 -1
  564. data/spec/mongoid/criteria/findable_spec.rb +295 -229
  565. data/spec/mongoid/criteria/includable_spec.rb +1493 -0
  566. data/spec/mongoid/criteria/includable_spec_models.rb +55 -0
  567. data/spec/mongoid/criteria/inspectable_spec.rb +1 -1
  568. data/spec/mongoid/criteria/marshalable_spec.rb +19 -2
  569. data/spec/mongoid/criteria/modifiable_spec.rb +38 -38
  570. data/spec/mongoid/criteria/options_spec.rb +1 -1
  571. data/spec/mongoid/criteria/queryable/aggregable_spec.rb +2 -2
  572. data/spec/mongoid/criteria/queryable/expandable_spec.rb +1 -74
  573. data/spec/mongoid/criteria/queryable/extensions/array_spec.rb +8 -20
  574. data/spec/mongoid/criteria/queryable/extensions/big_decimal_spec.rb +135 -27
  575. data/spec/mongoid/criteria/queryable/extensions/boolean_spec.rb +2 -2
  576. data/spec/mongoid/criteria/queryable/extensions/date_spec.rb +32 -12
  577. data/spec/mongoid/criteria/queryable/extensions/date_time_spec.rb +12 -1
  578. data/spec/mongoid/criteria/queryable/extensions/float_spec.rb +1 -1
  579. data/spec/mongoid/criteria/queryable/extensions/hash_spec.rb +1 -16
  580. data/spec/mongoid/criteria/queryable/extensions/integer_spec.rb +1 -1
  581. data/spec/mongoid/criteria/queryable/extensions/nil_class_spec.rb +1 -1
  582. data/spec/mongoid/criteria/queryable/extensions/numeric_spec.rb +74 -8
  583. data/spec/mongoid/criteria/queryable/extensions/object_spec.rb +1 -1
  584. data/spec/mongoid/criteria/queryable/extensions/range_spec.rb +238 -179
  585. data/spec/mongoid/criteria/queryable/extensions/regexp_raw_spec.rb +1 -12
  586. data/spec/mongoid/criteria/queryable/extensions/regexp_spec.rb +1 -12
  587. data/spec/mongoid/criteria/queryable/extensions/set_spec.rb +1 -1
  588. data/spec/mongoid/criteria/queryable/extensions/string_spec.rb +48 -132
  589. data/spec/mongoid/criteria/queryable/extensions/symbol_spec.rb +5 -60
  590. data/spec/mongoid/criteria/queryable/extensions/time_spec.rb +12 -1
  591. data/spec/mongoid/criteria/queryable/extensions/time_with_zone_spec.rb +12 -1
  592. data/spec/mongoid/criteria/queryable/key_spec.rb +1 -1
  593. data/spec/mongoid/criteria/queryable/mergeable_spec.rb +106 -8
  594. data/spec/mongoid/criteria/queryable/optional_spec.rb +17 -486
  595. data/spec/mongoid/criteria/queryable/options_spec.rb +2 -2
  596. data/spec/mongoid/criteria/queryable/pipeline_spec.rb +1 -1
  597. data/spec/mongoid/criteria/queryable/queryable_spec.rb +2 -2
  598. data/spec/mongoid/criteria/queryable/selectable_logical_spec.rb +700 -26
  599. data/spec/mongoid/criteria/queryable/selectable_shared_examples.rb +39 -0
  600. data/spec/mongoid/criteria/queryable/selectable_spec.rb +149 -683
  601. data/spec/mongoid/criteria/queryable/selectable_where_spec.rb +590 -0
  602. data/spec/mongoid/criteria/queryable/selector_spec.rb +186 -6
  603. data/spec/mongoid/criteria/queryable/smash_spec.rb +1 -1
  604. data/spec/mongoid/criteria/queryable/storable_spec.rb +87 -1
  605. data/spec/mongoid/criteria/scopable_spec.rb +128 -1
  606. data/spec/mongoid/criteria/translator_spec.rb +133 -0
  607. data/spec/mongoid/criteria_projection_spec.rb +407 -0
  608. data/spec/mongoid/criteria_spec.rb +1029 -1806
  609. data/spec/mongoid/document_fields_spec.rb +180 -5
  610. data/spec/mongoid/document_persistence_context_spec.rb +77 -1
  611. data/spec/mongoid/document_query_spec.rb +55 -4
  612. data/spec/mongoid/document_spec.rb +43 -172
  613. data/spec/mongoid/equality_spec.rb +7 -8
  614. data/spec/mongoid/errors/ambiguous_relationship_spec.rb +1 -1
  615. data/spec/mongoid/errors/attribute_not_loaded_spec.rb +32 -0
  616. data/spec/mongoid/errors/callback_spec.rb +1 -1
  617. data/spec/mongoid/errors/delete_restriction_spec.rb +2 -2
  618. data/spec/mongoid/errors/document_not_destroyed_spec.rb +1 -1
  619. data/spec/mongoid/errors/document_not_found_spec.rb +77 -1
  620. data/spec/mongoid/errors/invalid_collection_spec.rb +1 -1
  621. data/spec/mongoid/errors/{eager_load_spec.rb → invalid_config_file_spec.rb} +6 -6
  622. data/spec/mongoid/errors/invalid_config_option_spec.rb +1 -1
  623. data/spec/mongoid/errors/invalid_field_option_spec.rb +1 -1
  624. data/spec/mongoid/errors/invalid_field_spec.rb +2 -2
  625. data/spec/mongoid/errors/invalid_field_type_spec.rb +56 -0
  626. data/spec/mongoid/errors/invalid_find_spec.rb +1 -1
  627. data/spec/mongoid/errors/invalid_includes_spec.rb +1 -1
  628. data/spec/mongoid/errors/invalid_index_spec.rb +1 -1
  629. data/spec/mongoid/errors/invalid_options_spec.rb +1 -1
  630. data/spec/mongoid/errors/invalid_path_spec.rb +1 -1
  631. data/spec/mongoid/errors/invalid_relation_spec.rb +1 -1
  632. data/spec/mongoid/errors/invalid_scope_spec.rb +2 -2
  633. data/spec/mongoid/errors/invalid_set_polymorphic_relation_spec.rb +1 -1
  634. data/spec/mongoid/errors/invalid_storage_options_spec.rb +1 -1
  635. data/spec/mongoid/errors/invalid_time_spec.rb +1 -1
  636. data/spec/mongoid/errors/inverse_not_found_spec.rb +1 -1
  637. data/spec/mongoid/errors/mixed_client_configuration_spec.rb +1 -1
  638. data/spec/mongoid/errors/mixed_relations_spec.rb +1 -1
  639. data/spec/mongoid/errors/mongoid_error_spec.rb +4 -4
  640. data/spec/mongoid/errors/nested_attributes_metadata_not_found_spec.rb +1 -1
  641. data/spec/mongoid/errors/no_client_config_spec.rb +1 -1
  642. data/spec/mongoid/errors/no_client_database_spec.rb +1 -1
  643. data/spec/mongoid/errors/no_client_hosts_spec.rb +1 -1
  644. data/spec/mongoid/errors/no_clients_config_spec.rb +1 -1
  645. data/spec/mongoid/errors/no_environment_spec.rb +4 -4
  646. data/spec/mongoid/errors/no_map_reduce_output_spec.rb +1 -1
  647. data/spec/mongoid/errors/no_metadata_spec.rb +1 -1
  648. data/spec/mongoid/errors/no_parent_spec.rb +1 -1
  649. data/spec/mongoid/errors/readonly_attribute_spec.rb +1 -1
  650. data/spec/mongoid/errors/readonly_document_spec.rb +3 -3
  651. data/spec/mongoid/errors/scope_overwrite_spec.rb +1 -1
  652. data/spec/mongoid/errors/too_many_nested_attribute_records_spec.rb +2 -2
  653. data/spec/mongoid/errors/unknown_attribute_spec.rb +3 -3
  654. data/spec/mongoid/errors/unsaved_document_spec.rb +1 -1
  655. data/spec/mongoid/errors/unsupported_javascript_spec.rb +1 -1
  656. data/spec/mongoid/errors/validations_spec.rb +1 -1
  657. data/spec/mongoid/extensions/array_spec.rb +19 -265
  658. data/spec/mongoid/extensions/big_decimal_spec.rb +713 -213
  659. data/spec/mongoid/extensions/binary_spec.rb +45 -10
  660. data/spec/mongoid/extensions/boolean_spec.rb +69 -83
  661. data/spec/mongoid/extensions/date_class_mongoize_spec.rb +15 -11
  662. data/spec/mongoid/extensions/date_spec.rb +74 -22
  663. data/spec/mongoid/extensions/date_time_spec.rb +18 -19
  664. data/spec/mongoid/extensions/decimal128_spec.rb +1 -1
  665. data/spec/mongoid/extensions/false_class_spec.rb +2 -9
  666. data/spec/mongoid/extensions/float_spec.rb +56 -84
  667. data/spec/mongoid/extensions/hash_spec.rb +45 -219
  668. data/spec/mongoid/extensions/integer_spec.rb +53 -73
  669. data/spec/mongoid/extensions/module_spec.rb +1 -1
  670. data/spec/mongoid/extensions/nil_class_spec.rb +1 -1
  671. data/spec/mongoid/extensions/object_id_spec.rb +1 -1
  672. data/spec/mongoid/extensions/object_spec.rb +1 -177
  673. data/spec/mongoid/extensions/range_spec.rb +254 -64
  674. data/spec/mongoid/extensions/raw_value_spec.rb +67 -0
  675. data/spec/mongoid/extensions/regexp_spec.rb +59 -34
  676. data/spec/mongoid/extensions/set_spec.rb +105 -1
  677. data/spec/mongoid/extensions/string_spec.rb +21 -104
  678. data/spec/mongoid/extensions/stringified_symbol_spec.rb +1 -1
  679. data/spec/mongoid/extensions/symbol_spec.rb +15 -53
  680. data/spec/mongoid/extensions/time_spec.rb +345 -131
  681. data/spec/mongoid/extensions/time_with_zone_spec.rb +34 -107
  682. data/spec/mongoid/extensions/true_class_spec.rb +2 -9
  683. data/spec/mongoid/factory_spec.rb +63 -2
  684. data/spec/mongoid/fields/foreign_key_spec.rb +282 -120
  685. data/spec/mongoid/fields/localized_spec.rb +85 -42
  686. data/spec/mongoid/fields/standard_spec.rb +1 -1
  687. data/spec/mongoid/fields_spec.rb +826 -121
  688. data/spec/mongoid/findable_spec.rb +442 -80
  689. data/spec/mongoid/indexable/specification_spec.rb +132 -14
  690. data/spec/mongoid/indexable_spec.rb +361 -23
  691. data/spec/mongoid/inspectable_spec.rb +93 -5
  692. data/spec/mongoid/interceptable_spec.rb +926 -116
  693. data/spec/mongoid/interceptable_spec_models.rb +236 -4
  694. data/spec/mongoid/loading_spec.rb +110 -0
  695. data/spec/mongoid/loggable_spec.rb +1 -1
  696. data/spec/mongoid/matcher/extract_attribute_data/numeric_keys.yml +104 -0
  697. data/spec/mongoid/matcher/extract_attribute_data/traversal.yml +68 -88
  698. data/spec/mongoid/matcher/extract_attribute_spec.rb +5 -15
  699. data/spec/mongoid/mongoizable_spec.rb +286 -0
  700. data/spec/mongoid/monkey_patches_spec.rb +211 -0
  701. data/spec/mongoid/persistable/creatable_spec.rb +5 -5
  702. data/spec/mongoid/persistable/deletable_spec.rb +267 -27
  703. data/spec/mongoid/persistable/destroyable_spec.rb +409 -24
  704. data/spec/mongoid/persistable/incrementable_spec.rb +46 -9
  705. data/spec/mongoid/persistable/logical_spec.rb +42 -5
  706. data/spec/mongoid/persistable/maxable_spec.rb +147 -0
  707. data/spec/mongoid/persistable/minable_spec.rb +147 -0
  708. data/spec/mongoid/persistable/multipliable_spec.rb +227 -0
  709. data/spec/mongoid/persistable/poppable_spec.rb +41 -5
  710. data/spec/mongoid/persistable/pullable_spec.rb +81 -9
  711. data/spec/mongoid/persistable/pushable_spec.rb +81 -9
  712. data/spec/mongoid/persistable/renamable_spec.rb +40 -4
  713. data/spec/mongoid/persistable/savable_spec.rb +114 -20
  714. data/spec/mongoid/persistable/settable_spec.rb +77 -10
  715. data/spec/mongoid/persistable/unsettable_spec.rb +41 -5
  716. data/spec/mongoid/persistable/updatable_spec.rb +64 -52
  717. data/spec/mongoid/persistable/upsertable_spec.rb +124 -4
  718. data/spec/mongoid/persistable_spec.rb +4 -4
  719. data/spec/mongoid/persistence_context_spec.rb +58 -59
  720. data/spec/mongoid/positional_spec.rb +1 -1
  721. data/spec/mongoid/railties/bson_object_id_serializer_spec.rb +24 -0
  722. data/spec/mongoid/railties/console_sandbox_spec.rb +44 -0
  723. data/spec/mongoid/relations/proxy_spec.rb +7 -7
  724. data/spec/mongoid/reloadable_spec.rb +255 -30
  725. data/spec/mongoid/scopable_spec.rb +198 -58
  726. data/spec/mongoid/search_indexable_spec.rb +147 -0
  727. data/spec/mongoid/selectable_spec.rb +7 -7
  728. data/spec/mongoid/serializable_spec.rb +19 -40
  729. data/spec/mongoid/shardable_models.rb +15 -0
  730. data/spec/mongoid/shardable_spec.rb +181 -31
  731. data/spec/mongoid/stateful_spec.rb +152 -10
  732. data/spec/mongoid/tasks/database_rake_spec.rb +193 -42
  733. data/spec/mongoid/tasks/database_spec.rb +175 -2
  734. data/spec/mongoid/tasks/encryption_spec.rb +187 -0
  735. data/spec/mongoid/threaded_spec.rb +40 -3
  736. data/spec/mongoid/timestamps/created/short_spec.rb +2 -2
  737. data/spec/mongoid/timestamps/created_spec.rb +2 -2
  738. data/spec/mongoid/timestamps/timeless_spec.rb +3 -3
  739. data/spec/mongoid/timestamps/updated/short_spec.rb +4 -4
  740. data/spec/mongoid/timestamps/updated_spec.rb +4 -4
  741. data/spec/mongoid/timestamps_spec.rb +399 -11
  742. data/spec/mongoid/timestamps_spec_models.rb +68 -0
  743. data/spec/mongoid/touchable_spec.rb +971 -54
  744. data/spec/mongoid/touchable_spec_models.rb +154 -0
  745. data/spec/mongoid/traversable_spec.rb +79 -37
  746. data/spec/mongoid/validatable/associated_spec.rb +14 -31
  747. data/spec/mongoid/validatable/format_spec.rb +1 -1
  748. data/spec/mongoid/validatable/length_spec.rb +1 -1
  749. data/spec/mongoid/validatable/numericality_spec.rb +1 -1
  750. data/spec/mongoid/validatable/presence_spec.rb +27 -23
  751. data/spec/mongoid/validatable/uniqueness_spec.rb +170 -99
  752. data/spec/mongoid/validatable_spec.rb +4 -4
  753. data/spec/mongoid/warnings_spec.rb +36 -0
  754. data/spec/mongoid_spec.rb +61 -11
  755. data/spec/rails/controller_extension/controller_runtime_spec.rb +3 -3
  756. data/spec/rails/mongoid_spec.rb +28 -132
  757. data/spec/shared/bin/get-mongodb-download-url +17 -0
  758. data/spec/shared/bin/s3-copy +45 -0
  759. data/spec/shared/bin/s3-upload +69 -0
  760. data/spec/shared/lib/mrss/cluster_config.rb +24 -4
  761. data/spec/shared/lib/mrss/constraints.rb +77 -29
  762. data/spec/shared/lib/mrss/docker_runner.rb +40 -4
  763. data/spec/shared/lib/mrss/eg_config_utils.rb +51 -0
  764. data/spec/shared/lib/mrss/event_subscriber.rb +210 -0
  765. data/spec/shared/lib/mrss/lite_constraints.rb +64 -1
  766. data/spec/shared/lib/mrss/server_version_registry.rb +78 -34
  767. data/spec/shared/lib/mrss/session_registry.rb +69 -0
  768. data/spec/shared/lib/mrss/session_registry_legacy.rb +60 -0
  769. data/spec/shared/lib/mrss/spec_organizer.rb +32 -2
  770. data/spec/shared/lib/mrss/utils.rb +37 -0
  771. data/spec/shared/share/Dockerfile.erb +123 -71
  772. data/spec/shared/share/haproxy-1.conf +16 -0
  773. data/spec/shared/share/haproxy-2.conf +17 -0
  774. data/spec/shared/shlib/config.sh +27 -0
  775. data/spec/shared/shlib/distro.sh +2 -1
  776. data/spec/shared/shlib/server.sh +187 -40
  777. data/spec/shared/shlib/set_env.sh +49 -31
  778. data/spec/spec_helper.rb +46 -49
  779. data/spec/support/authorization.rb +1 -1
  780. data/spec/support/client_registry.rb +10 -0
  781. data/spec/support/constraints.rb +25 -1
  782. data/spec/support/crypt/models.rb +50 -0
  783. data/spec/support/crypt.rb +80 -0
  784. data/spec/support/expectations.rb +1 -1
  785. data/spec/support/feature_sandbox.rb +72 -0
  786. data/spec/support/helpers.rb +1 -0
  787. data/spec/support/immutable_ids.rb +119 -0
  788. data/spec/support/macros.rb +107 -1
  789. data/spec/support/models/account.rb +2 -2
  790. data/spec/support/models/acolyte.rb +1 -1
  791. data/spec/support/models/actor.rb +1 -1
  792. data/spec/support/models/actress.rb +1 -1
  793. data/spec/support/models/address.rb +7 -1
  794. data/spec/support/models/address_component.rb +1 -1
  795. data/spec/support/models/address_number.rb +1 -1
  796. data/spec/support/models/agency.rb +1 -1
  797. data/spec/support/models/agent.rb +1 -1
  798. data/spec/support/models/album.rb +1 -1
  799. data/spec/support/models/alert.rb +1 -1
  800. data/spec/support/models/animal.rb +1 -1
  801. data/spec/support/models/answer.rb +1 -1
  802. data/spec/support/models/appointment.rb +1 -1
  803. data/spec/support/models/armrest.rb +1 -1
  804. data/spec/support/models/array_field.rb +1 -1
  805. data/spec/support/models/article.rb +1 -1
  806. data/spec/support/models/artist.rb +3 -2
  807. data/spec/support/models/artwork.rb +1 -1
  808. data/spec/support/models/audible_sound.rb +4 -0
  809. data/spec/support/models/audio.rb +1 -1
  810. data/spec/support/models/augmentation.rb +13 -1
  811. data/spec/support/models/author.rb +1 -1
  812. data/spec/support/models/baby.rb +1 -1
  813. data/spec/support/models/band.rb +13 -1
  814. data/spec/support/models/bar.rb +1 -1
  815. data/spec/support/models/basic.rb +1 -1
  816. data/spec/support/models/bed.rb +1 -1
  817. data/spec/support/models/big_palette.rb +1 -1
  818. data/spec/support/models/birthday.rb +1 -1
  819. data/spec/support/models/bolt.rb +8 -0
  820. data/spec/support/models/bomb.rb +1 -1
  821. data/spec/support/models/book.rb +2 -1
  822. data/spec/support/models/breed.rb +1 -1
  823. data/spec/support/models/browser.rb +1 -1
  824. data/spec/support/models/building.rb +3 -1
  825. data/spec/support/models/building_address.rb +1 -1
  826. data/spec/support/models/bus.rb +1 -1
  827. data/spec/support/models/business.rb +1 -1
  828. data/spec/support/models/callback_test.rb +1 -1
  829. data/spec/support/models/canvas.rb +1 -1
  830. data/spec/support/models/car.rb +1 -1
  831. data/spec/support/models/cat.rb +1 -1
  832. data/spec/support/models/catalog.rb +25 -0
  833. data/spec/support/models/category.rb +1 -1
  834. data/spec/support/models/child.rb +1 -1
  835. data/spec/support/models/child_doc.rb +4 -4
  836. data/spec/support/models/church.rb +1 -1
  837. data/spec/support/models/circle.rb +1 -1
  838. data/spec/support/models/circuit.rb +1 -1
  839. data/spec/support/models/circus.rb +4 -1
  840. data/spec/support/models/code.rb +3 -1
  841. data/spec/support/models/coding/pull_request.rb +1 -1
  842. data/spec/support/models/coding.rb +1 -1
  843. data/spec/support/models/comment.rb +1 -1
  844. data/spec/support/models/company.rb +1 -1
  845. data/spec/support/models/consumption_period.rb +1 -1
  846. data/spec/support/models/contextable_item.rb +1 -1
  847. data/spec/support/models/contractor.rb +1 -1
  848. data/spec/support/models/cookie.rb +1 -1
  849. data/spec/support/models/country_code.rb +3 -1
  850. data/spec/support/models/courier_job.rb +1 -1
  851. data/spec/support/models/cover.rb +11 -0
  852. data/spec/support/models/crate.rb +1 -1
  853. data/spec/support/models/customer.rb +1 -1
  854. data/spec/support/models/customer_address.rb +1 -1
  855. data/spec/support/models/deed.rb +1 -1
  856. data/spec/support/models/definition.rb +1 -1
  857. data/spec/support/models/delegating_patient.rb +1 -1
  858. data/spec/support/models/description.rb +1 -1
  859. data/spec/support/models/dictionary.rb +1 -1
  860. data/spec/support/models/division.rb +1 -1
  861. data/spec/support/models/doctor.rb +1 -1
  862. data/spec/support/models/dog.rb +1 -1
  863. data/spec/support/models/dokument.rb +1 -1
  864. data/spec/support/models/draft.rb +1 -1
  865. data/spec/support/models/dragon.rb +1 -1
  866. data/spec/support/models/driver.rb +1 -1
  867. data/spec/support/models/drug.rb +1 -1
  868. data/spec/support/models/dungeon.rb +1 -1
  869. data/spec/support/models/edit.rb +1 -1
  870. data/spec/support/models/email.rb +1 -1
  871. data/spec/support/models/employer.rb +1 -1
  872. data/spec/support/models/entry.rb +1 -1
  873. data/spec/support/models/eraser.rb +1 -1
  874. data/spec/support/models/even.rb +1 -1
  875. data/spec/support/models/event.rb +1 -1
  876. data/spec/support/models/exhibition.rb +1 -1
  877. data/spec/support/models/exhibitor.rb +1 -1
  878. data/spec/support/models/explosion.rb +1 -1
  879. data/spec/support/models/eye.rb +1 -1
  880. data/spec/support/models/eye_bowl.rb +1 -1
  881. data/spec/support/models/face.rb +1 -1
  882. data/spec/support/models/fanatic.rb +9 -0
  883. data/spec/support/models/favorite.rb +8 -2
  884. data/spec/support/models/filesystem.rb +1 -1
  885. data/spec/support/models/fire_hydrant.rb +1 -1
  886. data/spec/support/models/firefox.rb +1 -1
  887. data/spec/support/models/fish.rb +1 -1
  888. data/spec/support/models/folder.rb +1 -1
  889. data/spec/support/models/folder_item.rb +1 -1
  890. data/spec/support/models/fruits.rb +1 -1
  891. data/spec/support/models/game.rb +1 -1
  892. data/spec/support/models/ghost.rb +1 -1
  893. data/spec/support/models/guitar.rb +1 -1
  894. data/spec/support/models/hole.rb +13 -0
  895. data/spec/support/models/home.rb +1 -1
  896. data/spec/support/models/house.rb +1 -1
  897. data/spec/support/models/html_writer.rb +1 -1
  898. data/spec/support/models/id_key.rb +1 -1
  899. data/spec/support/models/idnodef.rb +1 -1
  900. data/spec/support/models/image.rb +1 -1
  901. data/spec/support/models/implant.rb +10 -1
  902. data/spec/support/models/instrument.rb +1 -1
  903. data/spec/support/models/item.rb +1 -1
  904. data/spec/support/models/jar.rb +1 -1
  905. data/spec/support/models/kaleidoscope.rb +1 -1
  906. data/spec/support/models/kangaroo.rb +1 -1
  907. data/spec/support/models/label.rb +5 -2
  908. data/spec/support/models/language.rb +1 -1
  909. data/spec/support/models/lat_lng.rb +1 -1
  910. data/spec/support/models/league.rb +1 -1
  911. data/spec/support/models/learner.rb +1 -1
  912. data/spec/support/models/line_item.rb +1 -1
  913. data/spec/support/models/location.rb +1 -1
  914. data/spec/support/models/login.rb +1 -1
  915. data/spec/support/models/manufacturer.rb +1 -1
  916. data/spec/support/models/meat.rb +1 -1
  917. data/spec/support/models/membership.rb +2 -1
  918. data/spec/support/models/message.rb +1 -1
  919. data/spec/support/models/minim.rb +1 -1
  920. data/spec/support/models/mixed_drink.rb +1 -1
  921. data/spec/support/models/mop.rb +10 -1
  922. data/spec/support/models/movie.rb +1 -1
  923. data/spec/support/models/my_hash.rb +1 -1
  924. data/spec/support/models/name.rb +11 -1
  925. data/spec/support/models/name_only.rb +1 -1
  926. data/spec/support/models/node.rb +1 -1
  927. data/spec/support/models/note.rb +1 -1
  928. data/spec/support/models/nut.rb +8 -0
  929. data/spec/support/models/odd.rb +1 -1
  930. data/spec/support/models/order.rb +3 -1
  931. data/spec/support/models/ordered_post.rb +2 -2
  932. data/spec/support/models/ordered_preference.rb +1 -1
  933. data/spec/support/models/oscar.rb +1 -1
  934. data/spec/support/models/other_owner_object.rb +1 -1
  935. data/spec/support/models/override.rb +1 -1
  936. data/spec/support/models/ownable.rb +1 -1
  937. data/spec/support/models/owner.rb +1 -1
  938. data/spec/support/models/pack.rb +1 -1
  939. data/spec/support/models/page.rb +1 -1
  940. data/spec/support/models/page_question.rb +1 -1
  941. data/spec/support/models/palette.rb +1 -1
  942. data/spec/support/models/parent.rb +1 -1
  943. data/spec/support/models/parent_doc.rb +1 -1
  944. data/spec/support/models/passport.rb +15 -1
  945. data/spec/support/models/patient.rb +1 -1
  946. data/spec/support/models/pdf_writer.rb +1 -1
  947. data/spec/support/models/pencil.rb +1 -1
  948. data/spec/support/models/person.rb +19 -1
  949. data/spec/support/models/pet.rb +1 -1
  950. data/spec/support/models/pet_owner.rb +1 -1
  951. data/spec/support/models/phone.rb +3 -2
  952. data/spec/support/models/piano.rb +1 -1
  953. data/spec/support/models/pizza.rb +1 -1
  954. data/spec/support/models/player.rb +3 -1
  955. data/spec/support/models/post.rb +1 -1
  956. data/spec/support/models/post_genre.rb +1 -1
  957. data/spec/support/models/powerup.rb +13 -1
  958. data/spec/support/models/preference.rb +1 -1
  959. data/spec/support/models/princess.rb +1 -1
  960. data/spec/support/models/product.rb +2 -1
  961. data/spec/support/models/profile.rb +1 -1
  962. data/spec/support/models/pronunciation.rb +1 -1
  963. data/spec/support/models/pub.rb +1 -1
  964. data/spec/support/models/publication/encyclopedia.rb +1 -1
  965. data/spec/support/models/publication/review.rb +1 -1
  966. data/spec/support/models/publication.rb +1 -1
  967. data/spec/support/models/purchase.rb +1 -1
  968. data/spec/support/models/purchased_item.rb +11 -0
  969. data/spec/support/models/purse.rb +9 -0
  970. data/spec/support/models/question.rb +1 -1
  971. data/spec/support/models/quiz.rb +1 -1
  972. data/spec/support/models/rating.rb +1 -1
  973. data/spec/support/models/record.rb +1 -1
  974. data/spec/support/models/registry.rb +2 -1
  975. data/spec/support/models/role.rb +1 -1
  976. data/spec/support/models/root_category.rb +1 -1
  977. data/spec/support/models/sandbox/app/models/app_models_message.rb +4 -0
  978. data/spec/support/models/sandbox/lib/models/lib_models_message.rb +4 -0
  979. data/spec/support/models/sandbox/sandbox_message.rb +4 -0
  980. data/spec/support/models/sandbox/sandbox_user.rb +4 -0
  981. data/spec/support/models/sandbox/subdir/sandbox_comment.rb +4 -0
  982. data/spec/support/models/sandwich.rb +1 -1
  983. data/spec/support/models/scheduler.rb +1 -1
  984. data/spec/support/models/school.rb +15 -0
  985. data/spec/support/models/scribe.rb +1 -1
  986. data/spec/support/models/sealer.rb +8 -0
  987. data/spec/support/models/seat.rb +1 -1
  988. data/spec/support/models/seo.rb +1 -1
  989. data/spec/support/models/series.rb +1 -1
  990. data/spec/support/models/server.rb +1 -1
  991. data/spec/support/models/service.rb +1 -1
  992. data/spec/support/models/shape.rb +1 -1
  993. data/spec/support/models/shelf.rb +1 -1
  994. data/spec/support/models/shield.rb +19 -0
  995. data/spec/support/models/shipment_address.rb +1 -1
  996. data/spec/support/models/shipping_container.rb +1 -1
  997. data/spec/support/models/shipping_pack.rb +1 -1
  998. data/spec/support/models/shirt.rb +12 -0
  999. data/spec/support/models/shop.rb +1 -1
  1000. data/spec/support/models/short_agent.rb +1 -1
  1001. data/spec/support/models/short_quiz.rb +1 -1
  1002. data/spec/support/models/simple.rb +1 -1
  1003. data/spec/support/models/slave.rb +1 -1
  1004. data/spec/support/models/song.rb +1 -1
  1005. data/spec/support/models/sound.rb +1 -1
  1006. data/spec/support/models/spacer.rb +8 -0
  1007. data/spec/support/models/square.rb +1 -1
  1008. data/spec/support/models/staff.rb +1 -1
  1009. data/spec/support/models/store_as_dup_test1.rb +1 -1
  1010. data/spec/support/models/store_as_dup_test2.rb +1 -1
  1011. data/spec/support/models/store_as_dup_test3.rb +1 -1
  1012. data/spec/support/models/store_as_dup_test4.rb +1 -1
  1013. data/spec/support/models/strategy.rb +1 -1
  1014. data/spec/support/models/student.rb +15 -0
  1015. data/spec/support/models/sub_item.rb +1 -1
  1016. data/spec/support/models/subscription.rb +1 -1
  1017. data/spec/support/models/survey.rb +1 -1
  1018. data/spec/support/models/symptom.rb +1 -1
  1019. data/spec/support/models/system_role.rb +1 -0
  1020. data/spec/support/models/tag.rb +1 -1
  1021. data/spec/support/models/target.rb +1 -1
  1022. data/spec/support/models/template.rb +1 -1
  1023. data/spec/support/models/thing.rb +1 -1
  1024. data/spec/support/models/threadlocker.rb +8 -0
  1025. data/spec/support/models/title.rb +1 -1
  1026. data/spec/support/models/tool.rb +1 -1
  1027. data/spec/support/models/topping.rb +1 -1
  1028. data/spec/support/models/toy.rb +1 -1
  1029. data/spec/support/models/track.rb +1 -1
  1030. data/spec/support/models/translation.rb +1 -1
  1031. data/spec/support/models/tree.rb +1 -1
  1032. data/spec/support/models/truck.rb +1 -1
  1033. data/spec/support/models/updatable.rb +1 -1
  1034. data/spec/support/models/user.rb +1 -1
  1035. data/spec/support/models/user_account.rb +1 -1
  1036. data/spec/support/models/validation_callback.rb +1 -1
  1037. data/spec/support/models/vehicle.rb +1 -1
  1038. data/spec/support/models/version.rb +1 -1
  1039. data/spec/support/models/vertex.rb +1 -1
  1040. data/spec/support/models/vet_visit.rb +1 -1
  1041. data/spec/support/models/video.rb +1 -1
  1042. data/spec/support/models/video_game.rb +1 -1
  1043. data/spec/support/models/washer.rb +8 -0
  1044. data/spec/support/models/weapon.rb +13 -1
  1045. data/spec/support/models/wiki_page.rb +1 -1
  1046. data/spec/support/models/word.rb +1 -1
  1047. data/spec/support/models/word_origin.rb +1 -1
  1048. data/spec/support/models/writer.rb +1 -1
  1049. data/spec/support/rails_mock.rb +32 -0
  1050. data/spec/support/schema_maps/schema_map_aws.json +17 -0
  1051. data/spec/support/schema_maps/schema_map_aws_key_alt_names.json +12 -0
  1052. data/spec/support/schema_maps/schema_map_azure.json +17 -0
  1053. data/spec/support/schema_maps/schema_map_azure_key_alt_names.json +12 -0
  1054. data/spec/support/schema_maps/schema_map_gcp.json +17 -0
  1055. data/spec/support/schema_maps/schema_map_gcp_key_alt_names.json +12 -0
  1056. data/spec/support/schema_maps/schema_map_kmip.json +17 -0
  1057. data/spec/support/schema_maps/schema_map_kmip_key_alt_names.json +12 -0
  1058. data/spec/support/schema_maps/schema_map_local.json +18 -0
  1059. data/spec/support/schema_maps/schema_map_local_key_alt_names.json +12 -0
  1060. data/spec/support/shared/time.rb +3 -22
  1061. data/spec/support/sinatra_mock.rb +7 -0
  1062. data/spec/support/spec_config.rb +42 -7
  1063. data.tar.gz.sig +0 -0
  1064. metadata +883 -562
  1065. metadata.gz.sig +0 -0
  1066. data/lib/mongoid/association/referenced/eager.rb +0 -184
  1067. data/lib/mongoid/association/referenced/has_one/nested_builder.rb +0 -128
  1068. data/lib/mongoid/contextual/geo_near.rb +0 -269
  1069. data/lib/mongoid/errors/eager_load.rb +0 -26
  1070. data/lib/mongoid/errors/invalid_session_use.rb +0 -26
  1071. data/lib/mongoid/errors/invalid_storage_parent.rb +0 -28
  1072. data/lib/mongoid/errors/invalid_value.rb +0 -18
  1073. data/lib/mongoid/query_cache.rb +0 -333
  1074. data/lib/support/ruby_version.rb +0 -29
  1075. data/spec/mongoid/contextual/geo_near_spec.rb +0 -472
  1076. data/spec/mongoid/criteria/queryable/extensions/bignum_spec.rb +0 -61
  1077. data/spec/mongoid/criteria/queryable/extensions/fixnum_spec.rb +0 -61
  1078. data/spec/mongoid/extensions_spec.rb +0 -32
  1079. data/spec/mongoid/query_cache_middleware_spec.rb +0 -61
  1080. data/spec/mongoid/query_cache_spec.rb +0 -978
  1081. data/spec/support/cluster_config.rb +0 -158
  1082. data/spec/support/session_registry.rb +0 -50
@@ -1,7 +1,18 @@
1
1
  # frozen_string_literal: true
2
- # encoding: utf-8
2
+ # rubocop:todo all
3
3
 
4
4
  require "spec_helper"
5
+ require_relative './transactions_spec_models'
6
+
7
+ def capture_exception
8
+ e = nil
9
+ begin
10
+ yield
11
+ rescue => ex
12
+ e = ex
13
+ end
14
+ e
15
+ end
5
16
 
6
17
  describe Mongoid::Clients::Sessions do
7
18
  before(:all) do
@@ -62,158 +73,327 @@ describe Mongoid::Clients::Sessions do
62
73
  Mongoid::Clients.with_name(:other).database.collections.each(&:drop)
63
74
  Mongoid::Clients.with_name(:other).command(create: :people)
64
75
  Mongoid::Clients.with_name(:other).command(create: :posts)
76
+ Mongoid::Clients.with_name(:other).command(create: :canvases)
65
77
  subscriber.clear_events!
66
- Person.with(client: :other) do
67
- example.run
78
+ Canvas.with(client: :other) do
79
+ Person.with(client: :other) do
80
+ example.run
81
+ end
68
82
  end
69
83
  Mongoid::Clients.with_name(:other).database.collections.each(&:drop)
70
84
  end
71
85
 
72
86
  context 'when another thread is started' do
87
+ shared_examples 'it does not use the transaction for that thread' do
88
+ it do
89
+ expect(Person.count).to be(2)
90
+ expect(Person.with(client: :default) { Person.count }).to be(1)
91
+ expect(insert_events.count { |e| e.command['startTransaction'] }).to be(1)
92
+ expect(other_events.count { |e| e.command_name == 'commitTransaction' }).to be(1)
93
+ end
94
+ end
73
95
 
74
- let!(:last_use_diff) do
75
- Person.with_session do |s|
76
- s.start_transaction
77
- Person.create
78
- Person.create
79
- Thread.new { Person.create }.value
80
- s.commit_transaction
96
+ context 'using #with_session' do
97
+ let!(:last_use_diff) do
98
+ Person.with_session do |s|
99
+ s.start_transaction
100
+ Person.create!
101
+ Person.create!
102
+ Thread.new { Person.create! }.value
103
+ s.commit_transaction
104
+ end
81
105
  end
106
+
107
+ include_examples 'it does not use the transaction for that thread'
82
108
  end
83
109
 
84
- it 'does not use the transaction for that thread' do
85
- expect(Person.count).to be(2)
86
- expect(Person.with(client: :default) { Person.count }).to be(1)
87
- expect(insert_events.count { |e| e.command['startTransaction'] }).to be(1)
88
- expect(other_events.count { |e| e.command_name == 'commitTransaction' }).to be(1)
110
+ context 'using #transaction' do
111
+ let!(:last_use_diff) do
112
+ Person.transaction do
113
+ Person.create!
114
+ Person.create!
115
+ Thread.new { Person.create! }.value
116
+ end
117
+ end
118
+
119
+ include_examples 'it does not use the transaction for that thread'
89
120
  end
90
121
  end
91
122
 
92
123
  context 'when the operations in the transactions block are all on the class' do
124
+ shared_examples 'it uses a single transaction number for all operations on the class' do
125
+ it do
126
+ expect(Person.count).to be(2)
127
+ expect(insert_events_txn_numbers.size).to eq(2)
128
+ expect(insert_events_txn_numbers.uniq.size).to eq(1)
129
+ end
130
+ end
93
131
 
94
- before do
95
- Person.with_session do |s|
96
- s.start_transaction
97
- Person.create
98
- Person.create
99
- s.commit_transaction
132
+ context 'using #with_session' do
133
+ before do
134
+ Person.with_session do |s|
135
+ s.start_transaction
136
+ Person.create!
137
+ Person.create!
138
+ s.commit_transaction
139
+ end
100
140
  end
141
+
142
+ include_examples 'it uses a single transaction number for all operations on the class'
101
143
  end
102
144
 
103
- it 'uses a single transaction number for all operations on the class' do
104
- expect(Person.count).to be(2)
105
- expect(insert_events_txn_numbers.size).to eq(2)
106
- expect(insert_events_txn_numbers.uniq.size).to eq(1)
145
+ context 'using #transaction' do
146
+ before do
147
+ Person.transaction do
148
+ Person.create!
149
+ Person.create!
150
+ end
151
+ end
152
+
153
+ include_examples 'it uses a single transaction number for all operations on the class'
107
154
  end
108
155
  end
109
156
 
110
157
  context 'when the operations in the transactions block are also on another class' do
111
-
112
158
  context 'when the other class uses the same client' do
159
+ shared_examples 'it uses a single transaction number for all operations on the class' do
160
+ it do
161
+ expect(Post.with(client: :other) { |klass| klass.count }).to be(1)
162
+ expect(insert_events_txn_numbers.size).to eq(3)
163
+ expect(insert_events_txn_numbers.uniq.size).to eq(1)
164
+ end
165
+ end
113
166
 
114
- before do
115
- Post.with(client: :other) do
116
- Person.with_session do |s|
117
- s.start_transaction
118
- Person.create
119
- Person.create
120
- Post.create
121
- s.commit_transaction
167
+ context 'using #with_session' do
168
+ before do
169
+ Post.with(client: :other) do
170
+ Person.with_session do |s|
171
+ s.start_transaction
172
+ Person.create!
173
+ Person.create!
174
+ Post.create!
175
+ s.commit_transaction
176
+ end
122
177
  end
123
178
  end
179
+
180
+ include_examples 'it uses a single transaction number for all operations on the class'
124
181
  end
125
182
 
126
- it 'uses a single transaction number for all operations on the class' do
127
- expect(Post.with(client: :other) { |klass| klass.count }).to be(1)
128
- expect(insert_events_txn_numbers.size).to eq(3)
129
- expect(insert_events_txn_numbers.uniq.size).to eq(1)
183
+ context 'using #transaction' do
184
+ before do
185
+ Post.with(client: :other) do
186
+ Person.transaction do
187
+ Person.create!
188
+ Person.create!
189
+ Post.create!
190
+ end
191
+ end
192
+ end
193
+
194
+ include_examples 'it uses a single transaction number for all operations on the class'
130
195
  end
131
196
  end
132
197
 
133
198
  context 'when the other class uses a different client' do
199
+ shared_examples 'it does not abort the transaction' do
200
+ it 'does not raise an error' do
201
+ expect(error).to be_nil
202
+ end
134
203
 
135
- let!(:error) do
136
- e = nil
137
- begin
138
- Person.with_session do |s|
139
- s.start_transaction
140
- Person.create
141
- Person.create
142
- Post.create
143
- s.commit_transaction
144
- end
145
- rescue => ex
146
- e = ex
204
+ it 'committed the transaction' do
205
+ expect(Person.count).to be(2)
206
+ expect(Post.count).to be(1)
207
+ expect(insert_events_txn_numbers.size).to eq(2)
208
+ expect(other_events.count { |e| e.command_name == 'abortTransaction'}).to be(0)
209
+ expect(other_events.count { |e| e.command_name == 'commitTransaction'}).to be(1)
147
210
  end
148
- e
149
211
  end
150
212
 
151
- it 'raises an error' do
152
- expect(error).to be_a(Mongoid::Errors::InvalidSessionUse)
213
+ context 'using #with_session' do
214
+ let!(:error) do
215
+ capture_exception do
216
+ Person.with_session do |s|
217
+ s.start_transaction
218
+ Person.create!
219
+ Person.create!
220
+ Post.create!
221
+ s.commit_transaction
222
+ end
223
+ end
224
+ end
225
+
226
+ include_examples 'it does not abort the transaction'
153
227
  end
154
228
 
155
- it 'aborted the transaction' do
156
- expect(Person.count).to be(0)
157
- expect(Post.count).to be(0)
158
- expect(insert_events_txn_numbers.size).to eq(2)
159
- expect(other_events.count { |e| e.command_name == 'abortTransaction'}).to be(1)
160
- expect(other_events.count { |e| e.command_name == 'commitTransaction'}).to be(0)
229
+ context 'using #transaction' do
230
+ let!(:error) do
231
+ capture_exception do
232
+ Person.transaction do
233
+ Person.create!
234
+ Person.create!
235
+ Post.create!
236
+ end
237
+ end
238
+ end
239
+
240
+ include_examples 'it does not abort the transaction'
161
241
  end
162
242
  end
163
243
 
164
244
  context 'when transactions are nested' do
245
+ shared_examples 'it aborts the transaction' do |error_class|
246
+ it 'raises an error' do
247
+ expect(error).to be_a(error_class)
248
+ end
249
+
250
+ it 'does not execute any operations' do
251
+ expect(Person.count).to be(0)
252
+ expect(Post.count).to be(0)
253
+ expect(insert_events).to be_empty
254
+ end
255
+ end
165
256
 
166
- let!(:error) do
167
- e = nil
168
- begin
169
- Person.with_session do |s|
170
- s.start_transaction
171
- s.start_transaction
172
- Person.create
173
- Post.create
174
- s.commit_transaction
257
+ context 'using #with_session' do
258
+ let!(:error) do
259
+ capture_exception do
260
+ Person.with_session do |s|
261
+ s.start_transaction
262
+ s.start_transaction
263
+ Person.create!
264
+ Post.create!
265
+ s.commit_transaction
266
+ end
175
267
  end
176
- rescue => ex
177
- e = ex
178
268
  end
179
- e
269
+
270
+ include_examples 'it aborts the transaction', Mongo::Error::InvalidTransactionOperation
180
271
  end
181
272
 
182
- it 'raises an error' do
183
- expect(error).to be_a(Mongo::Error::InvalidTransactionOperation)
273
+ context 'using #transaction' do
274
+ let!(:error) do
275
+ capture_exception do
276
+ Person.transaction do
277
+ Person.transaction do
278
+ Person.create!
279
+ Post.create!
280
+ end
281
+ end
282
+ end
283
+ end
284
+
285
+ include_examples 'it aborts the transaction', Mongoid::Errors::InvalidTransactionNesting
184
286
  end
287
+ end
288
+ end
289
+
290
+ context 'when reloading an embedded document created inside a transaction' do
291
+ context 'using #with_session' do
292
+ it 'does not raise an error and has the correct document' do
293
+ Canvas.with_session do |s|
294
+ s.start_transaction
295
+ p = Palette.new
296
+ c = Canvas.new(palette: p)
297
+ c.save!
298
+
299
+ expect do
300
+ p.reload
301
+ end.to_not raise_error
185
302
 
186
- it 'does not execute any operations' do
187
- expect(Person.count).to be(0)
188
- expect(Post.count).to be(0)
189
- expect(insert_events).to be_empty
303
+ expect(c.palette).to eq(p)
304
+
305
+ s.commit_transaction
306
+ end
307
+ end
308
+ end
309
+
310
+ context 'using #transaction' do
311
+ it 'does not raise an error and has the correct document' do
312
+ Canvas.transaction do
313
+
314
+ p = Palette.new
315
+ c = Canvas.new(palette: p)
316
+ c.save!
317
+
318
+ expect do
319
+ p.reload
320
+ end.to_not raise_error
321
+
322
+ expect(c.palette).to eq(p)
323
+ end
324
+ end
325
+ end
326
+ end
327
+
328
+ context 'when Mongoid::Errors:Rollback raised' do
329
+ let!(:error) do
330
+ capture_exception do
331
+ Person.transaction do
332
+ Person.create!
333
+ raise Mongoid::Errors::Rollback
334
+ end
190
335
  end
191
336
  end
337
+
338
+ it 'does not bass on the exception' do
339
+ expect(error).to be_nil
340
+ end
341
+
342
+ it 'aborts the transaction' do
343
+ expect(other_events.count { |e| e.command_name == 'abortTransaction'}).to be(1)
344
+ expect(other_events.count { |e| e.command_name == 'commitTransaction'}).to be(0)
345
+ end
192
346
  end
193
347
  end
194
348
 
195
349
  context 'when sessions are supported but transactions are not' do
196
350
  min_server_version '3.6'
197
351
  # Could also test 4.0 in sharded cluster
198
- max_server_version '3.6'
352
+ max_server_version '3.6.99'
199
353
 
200
- let!(:error) do
201
- e = nil
202
- begin
203
- Person.with_session do |s|
204
- s.start_transaction
205
- Person.create
206
- s.commit_transaction
354
+ shared_examples 'it raises a transactions not supported error' do
355
+ it do
356
+ expect(Person.count).to eq(0)
357
+ expect(error).to be_a(Mongoid::Errors::TransactionsNotSupported)
358
+ end
359
+ end
360
+
361
+ context 'using #with_session' do
362
+ let!(:error) do
363
+ capture_exception do
364
+ Person.with_session do |s|
365
+ s.start_transaction
366
+ Person.create!
367
+ s.commit_transaction
368
+ end
207
369
  end
208
- rescue => ex
209
- e = ex
210
370
  end
211
- e
371
+
372
+ include_examples 'it raises a transactions not supported error'
212
373
  end
213
374
 
214
- it 'raises a transactions not supported error' do
215
- expect(Person.count).to eq(0)
216
- expect(error).to be_a(Mongo::Error::OperationFailure)
375
+ context 'using #transaction' do
376
+ let!(:error) do
377
+ capture_exception do
378
+ Person.transaction do
379
+ Person.create!
380
+ end
381
+ end
382
+ end
383
+
384
+ include_examples 'it raises a transactions not supported error'
385
+ end
386
+ end
387
+
388
+ context 'when transactions are not supported' do
389
+ require_topology :single
390
+
391
+ it 'it raises a transactions not supported error' do
392
+ expect do
393
+ Person.transaction do
394
+ Person.create!
395
+ end
396
+ end.to raise_error(Mongoid::Errors::TransactionsNotSupported)
217
397
  end
218
398
  end
219
399
  end
@@ -222,7 +402,7 @@ describe Mongoid::Clients::Sessions do
222
402
 
223
403
  let!(:person) do
224
404
  Person.with(client: :other) do |klass|
225
- klass.create
405
+ klass.create!
226
406
  end
227
407
  end
228
408
 
@@ -241,119 +421,215 @@ describe Mongoid::Clients::Sessions do
241
421
  end
242
422
 
243
423
  context 'when the operations in the transaction block are all on the instance' do
424
+ shared_examples 'it uses a single transaction number for all operations on the class' do
425
+ it do
426
+ expect(person.reload.username).to eq('Emily')
427
+ expect(person.reload.age).to eq(80)
428
+ expect(update_events_txn_numbers.size).to eq(2)
429
+ expect(update_events_txn_numbers.uniq.size).to eq(1)
430
+ end
431
+ end
244
432
 
245
- before do
246
- person.with_session do |s|
247
- s.start_transaction
248
- person.username = 'Emily'
249
- person.save
250
- person.age = 80
251
- person.save
252
- s.commit_transaction
433
+ context 'using #with_session' do
434
+ before do
435
+ person.with_session do |s|
436
+ s.start_transaction
437
+ person.username = 'Emily'
438
+ person.save!
439
+ person.age = 80
440
+ person.save!
441
+ s.commit_transaction
442
+ end
253
443
  end
444
+
445
+ include_examples 'it uses a single transaction number for all operations on the class'
254
446
  end
255
447
 
256
- it 'uses a single transaction number for all operations on the class' do
257
- expect(person.reload.username).to eq('Emily')
258
- expect(person.reload.age).to eq(80)
259
- expect(update_events_txn_numbers.size).to eq(2)
260
- expect(update_events_txn_numbers.uniq.size).to eq(1)
448
+ context 'using #transaction' do
449
+ before do
450
+ person.transaction do
451
+ person.username = 'Emily'
452
+ person.save!
453
+ person.age = 80
454
+ person.save!
455
+ end
456
+ end
457
+
458
+ include_examples 'it uses a single transaction number for all operations on the class'
261
459
  end
262
460
  end
263
461
 
264
462
  context 'when the operations in the transaction block are also on another class' do
265
463
 
266
464
  context 'when the other class uses the same client' do
465
+ shared_examples 'it uses a single transaction number for all operations on the class' do
466
+ it do
467
+ expect(person.reload.username).to eq('Emily')
468
+ expect(Post.with(client: :other) { Post.count }).to be(1)
469
+ expect(update_events_txn_numbers.size).to eq(3) # person update, counter cache, post assignment
470
+ expect(update_events_txn_numbers.uniq.size).to eq(1) # person update, counter cache, post assignment
471
+ expect(insert_events_txn_numbers.size).to eq(2)
472
+ expect(insert_events_txn_numbers.uniq.size).to eq(1)
473
+ expect(update_events_txn_numbers.uniq).to eq(insert_events_txn_numbers.uniq)
474
+ end
475
+ end
267
476
 
268
- before do
269
- Post.with(client: :other) do
270
- person.with_session do |s|
271
- s.start_transaction
272
- person.username = 'Emily'
273
- person.save
274
- person.posts << Post.create
275
- s.commit_transaction
477
+ context 'using #with_session' do
478
+ before do
479
+ Post.with(client: :other) do
480
+ person.with_session do |s|
481
+ s.start_transaction
482
+ person.username = 'Emily'
483
+ person.save!
484
+ person.posts << Post.create!
485
+ s.commit_transaction
486
+ end
276
487
  end
277
488
  end
489
+
490
+ include_examples 'it uses a single transaction number for all operations on the class'
278
491
  end
279
492
 
280
- it 'uses a single transaction number for all operations on the class' do
281
- expect(person.reload.username).to eq('Emily')
282
- expect(Post.with(client: :other) { Post.count }).to be(1)
283
- expect(update_events_txn_numbers.size).to eq(3) # person update, counter cache, post assignment
284
- expect(update_events_txn_numbers.uniq.size).to eq(1) # person update, counter cache, post assignment
285
- expect(insert_events_txn_numbers.size).to eq(2)
286
- expect(insert_events_txn_numbers.uniq.size).to eq(1)
287
- expect(update_events_txn_numbers.uniq).to eq(insert_events_txn_numbers.uniq)
493
+ context 'using #transaction' do
494
+ before do
495
+ Post.with(client: :other) do
496
+ person.transaction do
497
+ person.username = 'Emily'
498
+ person.save!
499
+ person.posts << Post.create!
500
+ end
501
+ end
502
+ end
503
+
504
+ include_examples 'it uses a single transaction number for all operations on the class'
288
505
  end
289
506
  end
290
507
 
291
508
  context 'when the other class uses a different client' do
509
+ shared_examples 'does not abort the transaction' do
510
+ it 'raises an error' do
511
+ expect(error).to be_nil
512
+ end
292
513
 
293
- let!(:error) do
294
- e = nil
295
- begin
296
- person.with_session do |s|
297
- s.start_transaction
298
- person.username = 'Emily'
299
- person.save
300
- person.posts << Post.create
301
- s.commit_transaction
302
- end
303
- rescue => ex
304
- e = ex
514
+ it 'did not abort the transaction' do
515
+ expect(person.reload.username).to eq('Emily')
516
+ expect(Post.count).to be(1)
517
+ expect(update_events_txn_numbers.size).to eq(2)
518
+ expect(insert_events_txn_numbers.size).to eq(1)
305
519
  end
306
- e
307
520
  end
308
521
 
309
- it 'raises an error' do
310
- expect(error).to be_a(Mongoid::Errors::InvalidSessionUse)
522
+ context 'using #with_session' do
523
+ let!(:error) do
524
+ capture_exception do
525
+ person.with_session do |s|
526
+ s.start_transaction
527
+ person.username = 'Emily'
528
+ person.save!
529
+ person.posts << Post.create!
530
+ s.commit_transaction
531
+ end
532
+ end
533
+ end
534
+
535
+ include_examples 'does not abort the transaction'
311
536
  end
312
537
 
313
- it 'aborted the transction' do
314
- expect(person.reload.username).not_to eq('Emily')
315
- expect(Post.count).to be(0)
316
- expect(update_events_txn_numbers.size).to eq(1)
317
- expect(insert_events_txn_numbers.size).to eq(1)
538
+ context 'using #transaction' do
539
+ let!(:error) do
540
+ capture_exception do
541
+ person.transaction do
542
+ person.username = 'Emily'
543
+ person.save!
544
+ person.posts << Post.create!
545
+ end
546
+ rescue => ex
547
+ end
548
+ end
549
+
550
+ include_examples 'does not abort the transaction'
318
551
  end
319
552
  end
320
553
 
321
554
  context 'when transactions are nested' do
322
-
323
- let!(:error) do
324
- e = nil
325
- begin
326
- person.with_session do |s|
327
- s.start_transaction
328
- s.start_transaction
329
- person.username = 'Emily'
330
- person.save
331
- person.posts << Post.create
332
- s.commit_transaction
555
+ context 'use #with_session' do
556
+ let!(:error) do
557
+ capture_exception do
558
+ person.with_session do |s|
559
+ s.start_transaction
560
+ s.start_transaction
561
+ person.username = 'Emily'
562
+ person.save!
563
+ person.posts << Post.create!
564
+ s.commit_transaction
565
+ end
333
566
  end
334
- rescue => ex
335
- e = ex
336
567
  end
337
- e
568
+
569
+ it 'raises an error' do
570
+ expect(error).to be_a(Mongo::Error::InvalidTransactionOperation)
571
+ end
572
+
573
+ it 'does not execute any operations' do
574
+ expect(person.reload.username).not_to eq('Emily')
575
+ expect(Post.count).to be(0)
576
+ expect(update_events).to be_empty
577
+ end
338
578
  end
339
579
 
340
- it 'raises an error' do
341
- expect(error).to be_a(Mongo::Error::InvalidTransactionOperation)
580
+ context 'use #transaction' do
581
+ let!(:error) do
582
+ capture_exception do
583
+ person.transaction do
584
+ person.transaction do
585
+ person.username = 'Emily'
586
+ person.save!
587
+ person.posts << Post.create!
588
+ end
589
+ end
590
+ end
591
+ end
592
+
593
+ it 'raises an error' do
594
+ expect(error).to be_a(Mongoid::Errors::InvalidTransactionNesting)
595
+ end
596
+
597
+ it 'does not execute any operations' do
598
+ expect(person.reload.username).not_to eq('Emily')
599
+ expect(Post.count).to be(0)
600
+ expect(update_events).to be_empty
601
+ end
342
602
  end
343
603
 
344
- it 'does not execute any operations' do
345
- expect(person.reload.username).not_to eq('Emily')
346
- expect(Post.count).to be(0)
347
- expect(update_events).to be_empty
604
+ end
605
+ end
606
+
607
+ context 'when Mongoid::Errors:Rollback raised' do
608
+ let!(:error) do
609
+ capture_exception do
610
+ person.transaction do
611
+ person.username = 'John'
612
+ person.save!
613
+ raise Mongoid::Errors::Rollback
614
+ end
348
615
  end
349
616
  end
617
+
618
+ it 'does not bass on the exception' do
619
+ expect(error).to be_nil
620
+ end
621
+
622
+ it 'aborts the transaction' do
623
+ expect(other_events.count { |e| e.command_name == 'abortTransaction'}).to be(1)
624
+ expect(other_events.count { |e| e.command_name == 'commitTransaction'}).to be(0)
625
+ end
350
626
  end
351
627
  end
352
628
 
353
629
  context 'when sessions are supported but transactions are not' do
354
630
  min_server_version '3.6'
355
631
  # Could also test 4.0 in sharded cluster
356
- max_server_version '3.6'
632
+ max_server_version '3.6.99'
357
633
 
358
634
  around do |example|
359
635
  Mongoid::Clients.with_name(:other).database.collections.each(&:drop)
@@ -369,24 +645,543 @@ describe Mongoid::Clients::Sessions do
369
645
  end
370
646
  end
371
647
 
372
- let!(:error) do
373
- e = nil
374
- begin
375
- person.with_session do |s|
376
- s.start_transaction
377
- person.username = 'Emily'
378
- person.save
379
- s.commit_transaction
648
+ context 'using #with_session' do
649
+ let!(:error) do
650
+ capture_exception do
651
+ person.with_session do |s|
652
+ s.start_transaction
653
+ person.username = 'Emily'
654
+ person.save!
655
+ s.commit_transaction
656
+ end
657
+ end
658
+ end
659
+
660
+ it 'raises a transactions not supported error' do
661
+ expect(person.reload.username).not_to be('Emily')
662
+ expect(error).to be_a(Mongoid::Errors::TransactionsNotSupported)
663
+ end
664
+ end
665
+
666
+ context 'using #transaction' do
667
+ let!(:error) do
668
+ capture_exception do
669
+ person.transaction do
670
+ person.username = 'Emily'
671
+ person.save!
672
+ end
673
+ end
674
+ end
675
+
676
+ it 'raises a transactions not supported error' do
677
+ expect(person.reload.username).not_to be('Emily')
678
+ expect(error).to be_a(Mongoid::Errors::TransactionsNotSupported)
679
+ end
680
+ end
681
+ end
682
+
683
+ context 'when transactions are not supported' do
684
+ require_topology :single
685
+
686
+ it 'it raises a transactions not supported error' do
687
+ expect do
688
+ Person.transaction do
689
+ Person.create!
690
+ end
691
+ end.to raise_error(Mongoid::Errors::TransactionsNotSupported)
692
+ end
693
+ end
694
+ end
695
+
696
+ context 'when a transaction is used on Mongoid module' do
697
+ let(:subscriber) do
698
+ Mongoid::Clients.with_name(:default).send(:monitoring).subscribers['Command'].find do |s|
699
+ s.is_a?(EventSubscriber)
700
+ end
701
+ end
702
+
703
+ before do
704
+ Mongoid::Clients.with_name(:default).database.collections.each(&:drop)
705
+ Person.collection.create
706
+ Account.collection.create
707
+ Mongoid::Clients.with_name(:default).subscribe(Mongo::Monitoring::COMMAND, EventSubscriber.new)
708
+ subscriber.clear_events!
709
+ end
710
+
711
+ after do
712
+ Mongoid::Clients.with_name(:default).database.collections.each(&:drop)
713
+ end
714
+
715
+ context 'when transactions are supported' do
716
+ require_transaction_support
717
+
718
+ context 'when no error raised' do
719
+ before do
720
+ Mongoid.transaction do
721
+ Person.create!
722
+ end
723
+ end
724
+
725
+ it 'commits the transacrion' do
726
+ expect(other_events.count { |e| e.command_name == 'abortTransaction'}).to be(0)
727
+ expect(other_events.count { |e| e.command_name == 'commitTransaction'}).to be(1)
728
+ end
729
+
730
+ it 'executes the commands inside the transaction' do
731
+ expect(Person.count).to be(1)
732
+ end
733
+ end
734
+
735
+ context 'When an error raised' do
736
+ let!(:error) do
737
+ capture_exception do
738
+ Mongoid.transaction do
739
+ Person.create!
740
+ Account.create!
741
+ end
742
+ end
743
+ end
744
+
745
+ it 'aborts the transaction' do
746
+ expect(other_events.count { |e| e.command_name == 'abortTransaction'}).to be(1)
747
+ expect(other_events.count { |e| e.command_name == 'commitTransaction'}).to be(0)
748
+ end
749
+
750
+ it 'passes on the error' do
751
+ expect(error).to be_a(Mongoid::Errors::Validations)
752
+ end
753
+
754
+ it 'reverts changes' do
755
+ expect(Account.count).to be(0)
756
+ expect(Person.count).to be(0)
757
+ end
758
+ end
759
+ end
760
+ end
761
+
762
+ context 'callbacks' do
763
+ shared_examples 'commit callbacks are called' do
764
+ it 'calls after_commit once' do
765
+ expect(subject.after_commit_counter.value).to eq(1)
766
+ end
767
+
768
+ it 'does not call after_rollback' do
769
+ expect(subject.after_rollback_counter.value).to eq(0)
770
+ end
771
+ end
772
+
773
+ shared_examples 'rollback callbacks are called' do
774
+ it 'does not call after_commit' do
775
+ expect(subject.after_commit_counter.value).to eq(0)
776
+ end
777
+
778
+ it 'calls after_rollback once' do
779
+ expect(subject.after_rollback_counter.value).to eq(1)
780
+ end
781
+ end
782
+
783
+ context 'with explicit transaction' do
784
+ require_transaction_support
785
+
786
+ before do
787
+ Mongoid::Clients.with_name(:default).database.collections.each(&:drop)
788
+ TransactionsSpecPerson.collection.create
789
+ TransactionsSpecPersonWithOnCreate.collection.create
790
+ TransactionsSpecPersonWithOnUpdate.collection.create
791
+ TransactionsSpecPersonWithOnDestroy.collection.create
792
+ TransactionSpecRaisesBeforeSave.collection.create
793
+ TransactionSpecRaisesAfterSave.collection.create
794
+ end
795
+
796
+ context 'when commit the transaction' do
797
+ context 'create' do
798
+ context 'without :on option' do
799
+ let!(:subject) do
800
+ person = nil
801
+ TransactionsSpecPerson.transaction do
802
+ person = TransactionsSpecPerson.create!(name: 'James Bond')
803
+ end
804
+ person
805
+ end
806
+
807
+ it_behaves_like 'commit callbacks are called'
808
+ end
809
+
810
+ context 'when callback has :on option' do
811
+ let!(:subject) do
812
+ person = nil
813
+ TransactionsSpecPersonWithOnCreate.transaction do
814
+ person = TransactionsSpecPersonWithOnCreate.create!(name: 'James Bond')
815
+ end
816
+ person
817
+ end
818
+
819
+ it_behaves_like 'commit callbacks are called'
820
+ end
821
+ end
822
+
823
+ context 'save' do
824
+ context 'without :on option' do
825
+ let(:subject) do
826
+ TransactionsSpecPerson.create!(name: 'James Bond').tap do |subject|
827
+ subject.after_commit_counter.reset
828
+ subject.after_rollback_counter.reset
829
+ end
830
+ end
831
+
832
+ context 'when modified once' do
833
+ before do
834
+ subject.transaction do
835
+ subject.name = 'Austin Powers'
836
+ subject.save!
837
+ end
838
+ end
839
+
840
+ it_behaves_like 'commit callbacks are called'
841
+ end
842
+
843
+ context 'when modified multiple times' do
844
+ before do
845
+ subject.transaction do
846
+ subject.name = 'Austin Powers'
847
+ subject.save!
848
+ subject.name = 'Jason Bourne'
849
+ subject.save!
850
+ end
851
+ end
852
+
853
+ it_behaves_like 'commit callbacks are called'
854
+ end
855
+ end
856
+
857
+ context 'with :on option' do
858
+ let(:subject) do
859
+ TransactionsSpecPersonWithOnUpdate.create!(name: 'James Bond').tap do |subject|
860
+ subject.after_commit_counter.reset
861
+ subject.after_rollback_counter.reset
862
+ end
863
+ end
864
+
865
+ context 'when modified once' do
866
+ before do
867
+ subject.transaction do
868
+ subject.name = 'Austin Powers'
869
+ subject.save!
870
+ end
871
+ end
872
+
873
+ it_behaves_like 'commit callbacks are called'
874
+ end
875
+
876
+ context 'when modified multiple times' do
877
+ before do
878
+ subject.transaction do
879
+ subject.name = 'Austin Powers'
880
+ subject.save!
881
+ subject.name = 'Jason Bourne'
882
+ subject.save!
883
+ end
884
+ end
885
+
886
+ it_behaves_like 'commit callbacks are called'
887
+ end
888
+ end
889
+ end
890
+
891
+ context 'update_attributes' do
892
+ context 'without :on option' do
893
+ let(:subject) do
894
+ TransactionsSpecPerson.create!(name: 'James Bond').tap do |subject|
895
+ subject.after_commit_counter.reset
896
+ subject.after_rollback_counter.reset
897
+ end
898
+ end
899
+
900
+ before do
901
+ subject.transaction do
902
+ subject.update_attributes!(name: 'Austin Powers')
903
+ end
904
+ end
905
+
906
+ it_behaves_like 'commit callbacks are called'
907
+ end
908
+
909
+ context 'when callback has on option' do
910
+ let(:subject) do
911
+ TransactionsSpecPersonWithOnUpdate.create!(name: 'Jason Bourne')
912
+ end
913
+
914
+ before do
915
+ TransactionsSpecPersonWithOnUpdate.transaction do
916
+ subject.update_attributes!(name: 'Foma Kiniaev')
917
+ end
918
+ end
919
+
920
+ it_behaves_like 'commit callbacks are called'
921
+ end
922
+ end
923
+
924
+ context 'destroy' do
925
+ context 'without :on option' do
926
+ let(:after_commit_counter) do
927
+ TransactionsSpecCounter.new
928
+ end
929
+
930
+ let(:after_rollback_counter) do
931
+ TransactionsSpecCounter.new
932
+ end
933
+
934
+ let(:subject) do
935
+ TransactionsSpecPerson.create!(name: 'James Bond').tap do |p|
936
+ p.after_commit_counter = after_commit_counter
937
+ p.after_rollback_counter = after_rollback_counter
938
+ end
939
+ end
940
+
941
+ before do
942
+ subject.transaction do
943
+ subject.destroy
944
+ end
945
+ end
946
+
947
+ it_behaves_like 'commit callbacks are called'
948
+ end
949
+
950
+ context 'with :on option' do
951
+ let(:after_commit_counter) do
952
+ TransactionsSpecCounter.new
953
+ end
954
+
955
+ let(:after_rollback_counter) do
956
+ TransactionsSpecCounter.new
957
+ end
958
+
959
+ let(:subject) do
960
+ TransactionsSpecPersonWithOnDestroy.create!(name: 'James Bond').tap do |p|
961
+ p.after_commit_counter = after_commit_counter
962
+ p.after_rollback_counter = after_rollback_counter
963
+ end
964
+ end
965
+
966
+ before do
967
+ subject.transaction do
968
+ subject.destroy
969
+ end
970
+ end
971
+
972
+ it_behaves_like 'commit callbacks are called'
973
+ end
974
+ end
975
+ end
976
+
977
+ context 'when rollback the transaction' do
978
+ context 'create' do
979
+ context 'without :on option' do
980
+ let!(:subject) do
981
+ person = nil
982
+ TransactionsSpecPerson.transaction do
983
+ person = TransactionsSpecPerson.create!(name: 'James Bond')
984
+ raise Mongoid::Errors::Rollback
985
+ end
986
+ person
987
+ end
988
+
989
+ it_behaves_like 'rollback callbacks are called'
990
+ end
991
+
992
+ context 'with :on option' do
993
+ let!(:subject) do
994
+ person = nil
995
+ TransactionsSpecPersonWithOnCreate.transaction do
996
+ person = TransactionsSpecPersonWithOnCreate.create!(name: 'James Bond')
997
+ raise Mongoid::Errors::Rollback
998
+ end
999
+ person
1000
+ end
1001
+
1002
+ it_behaves_like 'rollback callbacks are called'
1003
+ end
1004
+ end
1005
+
1006
+ context 'save' do
1007
+ let(:subject) do
1008
+ TransactionsSpecPerson.create!(name: 'James Bond').tap do |subject|
1009
+ subject.after_commit_counter.reset
1010
+ subject.after_rollback_counter.reset
1011
+ end
1012
+ end
1013
+
1014
+ context 'when modified once' do
1015
+ before do
1016
+ begin
1017
+ subject.transaction do
1018
+ subject.name = 'Austin Powers'
1019
+ subject.save!
1020
+ raise 'Something went wrong'
1021
+ end
1022
+ rescue RuntimeError
1023
+ end
1024
+ end
1025
+
1026
+ it_behaves_like 'rollback callbacks are called'
1027
+ end
1028
+
1029
+ context 'when modified multiple times' do
1030
+ before do
1031
+ subject.transaction do
1032
+ subject.name = 'Austin Powers'
1033
+ subject.save!
1034
+ subject.name = 'Jason Bourne'
1035
+ subject.save!
1036
+ raise Mongoid::Errors::Rollback
1037
+ end
1038
+ end
1039
+
1040
+ it_behaves_like 'rollback callbacks are called'
1041
+ end
1042
+
1043
+ context 'when exception is raised in a callback' do
1044
+ context 'in before_save' do
1045
+ let(:subject) do
1046
+ TransactionSpecRaisesBeforeSave.new
1047
+ end
1048
+
1049
+ before do
1050
+ begin
1051
+ subject.transaction do
1052
+ subject.save!
1053
+ end
1054
+ rescue RuntimeError
1055
+ end
1056
+ end
1057
+
1058
+ it 'does not call any transaction callbacks' do
1059
+ # This is according to Rails behavior
1060
+ expect(subject.after_commit_counter.value).to eq(0)
1061
+ expect(subject.after_rollback_counter.value).to eq(0)
1062
+ end
1063
+ end
1064
+
1065
+ context 'in after_save' do
1066
+ let(:subject) do
1067
+ TransactionSpecRaisesAfterSave.new
1068
+ end
1069
+
1070
+ before do
1071
+ begin
1072
+ subject.transaction do
1073
+ subject.save!
1074
+ end
1075
+ rescue RuntimeError
1076
+ end
1077
+ end
1078
+
1079
+ it_behaves_like 'rollback callbacks are called'
1080
+ end
1081
+ end
1082
+ end
1083
+
1084
+ context 'update_attributes' do
1085
+ let(:subject) do
1086
+ TransactionsSpecPerson.create!(name: 'James Bond').tap do |p|
1087
+ p.after_commit_counter.reset
1088
+ p.after_rollback_counter.reset
1089
+ end
380
1090
  end
381
- rescue => ex
382
- e = ex
1091
+
1092
+ before do
1093
+ subject.transaction do
1094
+ subject.update_attributes!(name: 'Austin Powers')
1095
+ raise Mongoid::Errors::Rollback
1096
+ end
1097
+ end
1098
+
1099
+ it_behaves_like 'rollback callbacks are called'
1100
+ end
1101
+
1102
+ context 'destroy' do
1103
+ let(:after_commit_counter) do
1104
+ TransactionsSpecCounter.new
1105
+ end
1106
+
1107
+ let(:after_rollback_counter) do
1108
+ TransactionsSpecCounter.new
1109
+ end
1110
+
1111
+ let(:subject) do
1112
+ TransactionsSpecPerson.create!(name: 'James Bond').tap do |p|
1113
+ p.after_commit_counter = after_commit_counter
1114
+ p.after_rollback_counter = after_rollback_counter
1115
+ end
1116
+ end
1117
+
1118
+ before do
1119
+ subject.transaction do
1120
+ subject.destroy
1121
+ raise Mongoid::Errors::Rollback
1122
+ end
1123
+ end
1124
+
1125
+ it_behaves_like 'rollback callbacks are called'
383
1126
  end
384
- e
385
1127
  end
1128
+ end
1129
+
1130
+ context 'without explicit transaction' do
1131
+ context 'when operation is successful' do
1132
+ context 'create' do
1133
+ let!(:subject) do
1134
+ TransactionsSpecPerson.create!(name: 'James Bond')
1135
+ end
1136
+
1137
+ it_behaves_like 'commit callbacks are called'
1138
+ end
386
1139
 
387
- it 'raises a sessions not supported error' do
388
- expect(person.reload.username).not_to be('Emily')
389
- expect(error).to be_a(Mongo::Error::OperationFailure)
1140
+ context 'save' do
1141
+ let(:subject) do
1142
+ TransactionsSpecPerson.create!(name: 'James Bond').tap do |person|
1143
+ person.after_commit_counter.reset
1144
+ person.after_rollback_counter.reset
1145
+ end
1146
+ end
1147
+
1148
+ before do
1149
+ subject.name = 'Jason Bourne'
1150
+ subject.save!
1151
+ end
1152
+
1153
+ it_behaves_like 'commit callbacks are called'
1154
+ end
1155
+
1156
+ context 'save' do
1157
+ let(:subject) do
1158
+ TransactionsSpecPerson.create!(name: 'James Bond').tap do |person|
1159
+ person.after_commit_counter.reset
1160
+ person.after_rollback_counter.reset
1161
+ end
1162
+ end
1163
+
1164
+ before do
1165
+ subject.update_attributes!(name: 'Jason Bourne')
1166
+ end
1167
+
1168
+ it_behaves_like 'commit callbacks are called'
1169
+ end
1170
+
1171
+ context 'destroy' do
1172
+ let(:subject) do
1173
+ TransactionsSpecPerson.create!(name: 'James Bond').tap do |person|
1174
+ person.after_commit_counter.reset
1175
+ person.after_rollback_counter.reset
1176
+ end
1177
+ end
1178
+
1179
+ before do
1180
+ subject.destroy
1181
+ end
1182
+
1183
+ it_behaves_like 'commit callbacks are called'
1184
+ end
390
1185
  end
391
1186
  end
392
1187
  end