mongoid 7.5.4 → 8.1.7

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 (442) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +3 -3
  3. data/README.md +6 -6
  4. data/Rakefile +44 -46
  5. data/lib/config/locales/en.yml +92 -43
  6. data/lib/mongoid/association/accessors.rb +44 -11
  7. data/lib/mongoid/association/bindable.rb +50 -2
  8. data/lib/mongoid/association/builders.rb +5 -3
  9. data/lib/mongoid/association/constrainable.rb +0 -1
  10. data/lib/mongoid/association/eager_loadable.rb +29 -7
  11. data/lib/mongoid/association/embedded/batchable.rb +34 -11
  12. data/lib/mongoid/association/embedded/cyclic.rb +1 -1
  13. data/lib/mongoid/association/embedded/embedded_in/binding.rb +24 -2
  14. data/lib/mongoid/association/embedded/embedded_in/buildable.rb +2 -2
  15. data/lib/mongoid/association/embedded/embedded_in/proxy.rb +4 -3
  16. data/lib/mongoid/association/embedded/embedded_in.rb +3 -2
  17. data/lib/mongoid/association/embedded/embeds_many/binding.rb +1 -0
  18. data/lib/mongoid/association/embedded/embeds_many/buildable.rb +4 -3
  19. data/lib/mongoid/association/embedded/embeds_many/proxy.rb +85 -46
  20. data/lib/mongoid/association/embedded/embeds_many.rb +2 -2
  21. data/lib/mongoid/association/embedded/embeds_one/buildable.rb +19 -5
  22. data/lib/mongoid/association/embedded/embeds_one/proxy.rb +24 -5
  23. data/lib/mongoid/association/embedded/embeds_one.rb +3 -3
  24. data/lib/mongoid/association/macros.rb +8 -1
  25. data/lib/mongoid/association/many.rb +11 -7
  26. data/lib/mongoid/association/nested/many.rb +5 -4
  27. data/lib/mongoid/association/nested/nested_buildable.rb +4 -4
  28. data/lib/mongoid/association/nested/one.rb +45 -7
  29. data/lib/mongoid/association/one.rb +2 -2
  30. data/lib/mongoid/association/options.rb +9 -9
  31. data/lib/mongoid/association/proxy.rb +15 -4
  32. data/lib/mongoid/association/referenced/auto_save.rb +4 -3
  33. data/lib/mongoid/association/referenced/belongs_to/binding.rb +1 -0
  34. data/lib/mongoid/association/referenced/belongs_to/buildable.rb +1 -1
  35. data/lib/mongoid/association/referenced/belongs_to/proxy.rb +5 -6
  36. data/lib/mongoid/association/referenced/belongs_to.rb +2 -2
  37. data/lib/mongoid/association/referenced/counter_cache.rb +10 -10
  38. data/lib/mongoid/association/referenced/eager.rb +2 -2
  39. data/lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb +70 -13
  40. data/lib/mongoid/association/referenced/has_and_belongs_to_many.rb +6 -3
  41. data/lib/mongoid/association/referenced/has_many/enumerable.rb +22 -30
  42. data/lib/mongoid/association/referenced/has_many/proxy.rb +40 -21
  43. data/lib/mongoid/association/referenced/has_many.rb +3 -3
  44. data/lib/mongoid/association/referenced/has_one/buildable.rb +1 -1
  45. data/lib/mongoid/association/referenced/has_one/nested_builder.rb +5 -5
  46. data/lib/mongoid/association/referenced/has_one/proxy.rb +9 -12
  47. data/lib/mongoid/association/referenced/has_one.rb +3 -3
  48. data/lib/mongoid/association/referenced/syncable.rb +4 -4
  49. data/lib/mongoid/association/reflections.rb +4 -4
  50. data/lib/mongoid/association/relatable.rb +44 -10
  51. data/lib/mongoid/association.rb +5 -5
  52. data/lib/mongoid/atomic/modifiers.rb +2 -2
  53. data/lib/mongoid/atomic.rb +16 -7
  54. data/lib/mongoid/attributes/dynamic.rb +4 -4
  55. data/lib/mongoid/attributes/nested.rb +6 -6
  56. data/lib/mongoid/attributes/processing.rb +37 -6
  57. data/lib/mongoid/attributes/projector.rb +2 -2
  58. data/lib/mongoid/attributes/readonly.rb +3 -3
  59. data/lib/mongoid/attributes.rb +51 -42
  60. data/lib/mongoid/changeable.rb +147 -14
  61. data/lib/mongoid/clients/options.rb +5 -1
  62. data/lib/mongoid/clients/sessions.rb +2 -14
  63. data/lib/mongoid/clients/storage_options.rb +2 -5
  64. data/lib/mongoid/clients/validators/storage.rb +3 -15
  65. data/lib/mongoid/collection_configurable.rb +58 -0
  66. data/lib/mongoid/composable.rb +2 -0
  67. data/lib/mongoid/config/defaults.rb +60 -0
  68. data/lib/mongoid/config/options.rb +3 -0
  69. data/lib/mongoid/config/validators/async_query_executor.rb +24 -0
  70. data/lib/mongoid/config/validators/client.rb +6 -6
  71. data/lib/mongoid/config/validators.rb +1 -0
  72. data/lib/mongoid/config.rb +153 -18
  73. data/lib/mongoid/contextual/aggregable/memory.rb +24 -16
  74. data/lib/mongoid/contextual/aggregable/mongo.rb +5 -5
  75. data/lib/mongoid/contextual/aggregable/none.rb +1 -1
  76. data/lib/mongoid/contextual/atomic.rb +1 -1
  77. data/lib/mongoid/contextual/geo_near.rb +7 -7
  78. data/lib/mongoid/contextual/map_reduce.rb +2 -2
  79. data/lib/mongoid/contextual/memory.rb +285 -58
  80. data/lib/mongoid/contextual/mongo/documents_loader.rb +177 -0
  81. data/lib/mongoid/contextual/mongo.rb +540 -346
  82. data/lib/mongoid/contextual/none.rb +193 -20
  83. data/lib/mongoid/contextual/queryable.rb +1 -1
  84. data/lib/mongoid/contextual.rb +14 -2
  85. data/lib/mongoid/copyable.rb +32 -8
  86. data/lib/mongoid/criteria/findable.rb +8 -5
  87. data/lib/mongoid/criteria/includable.rb +27 -22
  88. data/lib/mongoid/criteria/marshalable.rb +10 -2
  89. data/lib/mongoid/criteria/permission.rb +1 -1
  90. data/lib/mongoid/criteria/queryable/aggregable.rb +2 -2
  91. data/lib/mongoid/criteria/queryable/extensions/array.rb +3 -16
  92. data/lib/mongoid/criteria/queryable/extensions/big_decimal.rb +25 -4
  93. data/lib/mongoid/criteria/queryable/extensions/boolean.rb +2 -2
  94. data/lib/mongoid/criteria/queryable/extensions/date.rb +6 -1
  95. data/lib/mongoid/criteria/queryable/extensions/date_time.rb +6 -1
  96. data/lib/mongoid/criteria/queryable/extensions/hash.rb +1 -17
  97. data/lib/mongoid/criteria/queryable/extensions/numeric.rb +15 -9
  98. data/lib/mongoid/criteria/queryable/extensions/object.rb +2 -1
  99. data/lib/mongoid/criteria/queryable/extensions/range.rb +13 -5
  100. data/lib/mongoid/criteria/queryable/extensions/regexp.rb +3 -3
  101. data/lib/mongoid/criteria/queryable/extensions/set.rb +1 -1
  102. data/lib/mongoid/criteria/queryable/extensions/string.rb +4 -14
  103. data/lib/mongoid/criteria/queryable/extensions/symbol.rb +4 -12
  104. data/lib/mongoid/criteria/queryable/extensions/time.rb +6 -1
  105. data/lib/mongoid/criteria/queryable/extensions/time_with_zone.rb +6 -1
  106. data/lib/mongoid/criteria/queryable/key.rb +4 -4
  107. data/lib/mongoid/criteria/queryable/mergeable.rb +1 -1
  108. data/lib/mongoid/criteria/queryable/optional.rb +11 -17
  109. data/lib/mongoid/criteria/queryable/options.rb +2 -2
  110. data/lib/mongoid/criteria/queryable/pipeline.rb +1 -1
  111. data/lib/mongoid/criteria/queryable/selectable.rb +47 -38
  112. data/lib/mongoid/criteria/queryable/selector.rb +92 -7
  113. data/lib/mongoid/criteria/queryable/smash.rb +40 -7
  114. data/lib/mongoid/criteria/queryable.rb +12 -7
  115. data/lib/mongoid/criteria/scopable.rb +2 -2
  116. data/lib/mongoid/criteria/translator.rb +45 -0
  117. data/lib/mongoid/criteria.rb +20 -40
  118. data/lib/mongoid/deprecable.rb +37 -0
  119. data/lib/mongoid/deprecation.rb +25 -0
  120. data/lib/mongoid/document.rb +127 -35
  121. data/lib/mongoid/equality.rb +8 -8
  122. data/lib/mongoid/errors/create_collection_failure.rb +33 -0
  123. data/lib/mongoid/errors/document_not_found.rb +10 -6
  124. data/lib/mongoid/errors/drop_collection_failure.rb +27 -0
  125. data/lib/mongoid/errors/immutable_attribute.rb +26 -0
  126. data/lib/mongoid/errors/invalid_async_query_executor.rb +25 -0
  127. data/lib/mongoid/errors/invalid_config_option.rb +1 -1
  128. data/lib/mongoid/errors/invalid_dependent_strategy.rb +1 -1
  129. data/lib/mongoid/errors/invalid_dot_dollar_assignment.rb +23 -0
  130. data/lib/mongoid/errors/invalid_field.rb +6 -2
  131. data/lib/mongoid/errors/invalid_field_type.rb +26 -0
  132. data/lib/mongoid/errors/invalid_global_executor_concurrency.rb +22 -0
  133. data/lib/mongoid/errors/invalid_relation.rb +1 -1
  134. data/lib/mongoid/errors/invalid_relation_option.rb +1 -1
  135. data/lib/mongoid/errors/invalid_session_use.rb +1 -1
  136. data/lib/mongoid/errors/invalid_storage_options.rb +1 -1
  137. data/lib/mongoid/errors/invalid_storage_parent.rb +2 -0
  138. data/lib/mongoid/errors/mongoid_error.rb +3 -3
  139. data/lib/mongoid/errors/nested_attributes_metadata_not_found.rb +1 -1
  140. data/lib/mongoid/errors/no_client_database.rb +1 -1
  141. data/lib/mongoid/errors/no_client_hosts.rb +1 -1
  142. data/lib/mongoid/errors/readonly_attribute.rb +1 -1
  143. data/lib/mongoid/errors/too_many_nested_attribute_records.rb +1 -1
  144. data/lib/mongoid/errors/unknown_attribute.rb +1 -1
  145. data/lib/mongoid/errors.rb +6 -3
  146. data/lib/mongoid/extensions/array.rb +9 -7
  147. data/lib/mongoid/extensions/big_decimal.rb +33 -10
  148. data/lib/mongoid/extensions/binary.rb +42 -0
  149. data/lib/mongoid/extensions/boolean.rb +8 -2
  150. data/lib/mongoid/extensions/date.rb +26 -20
  151. data/lib/mongoid/extensions/date_time.rb +1 -1
  152. data/lib/mongoid/extensions/false_class.rb +1 -1
  153. data/lib/mongoid/extensions/float.rb +7 -4
  154. data/lib/mongoid/extensions/hash.rb +38 -9
  155. data/lib/mongoid/extensions/integer.rb +7 -4
  156. data/lib/mongoid/extensions/module.rb +1 -1
  157. data/lib/mongoid/extensions/object.rb +10 -8
  158. data/lib/mongoid/extensions/range.rb +41 -10
  159. data/lib/mongoid/extensions/regexp.rb +11 -4
  160. data/lib/mongoid/extensions/set.rb +11 -4
  161. data/lib/mongoid/extensions/string.rb +11 -22
  162. data/lib/mongoid/extensions/symbol.rb +4 -15
  163. data/lib/mongoid/extensions/time.rb +29 -16
  164. data/lib/mongoid/extensions/time_with_zone.rb +1 -2
  165. data/lib/mongoid/extensions/true_class.rb +1 -1
  166. data/lib/mongoid/extensions.rb +1 -0
  167. data/lib/mongoid/factory.rb +55 -7
  168. data/lib/mongoid/fields/foreign_key.rb +11 -4
  169. data/lib/mongoid/fields/localized.rb +19 -4
  170. data/lib/mongoid/fields/standard.rb +17 -7
  171. data/lib/mongoid/fields/validators/macro.rb +3 -9
  172. data/lib/mongoid/fields.rb +142 -28
  173. data/lib/mongoid/findable.rb +54 -24
  174. data/lib/mongoid/indexable/specification.rb +2 -2
  175. data/lib/mongoid/indexable/validators/options.rb +6 -2
  176. data/lib/mongoid/interceptable.rb +186 -16
  177. data/lib/mongoid/matchable.rb +1 -1
  178. data/lib/mongoid/matcher/eq_impl.rb +1 -1
  179. data/lib/mongoid/matcher/type.rb +1 -1
  180. data/lib/mongoid/matcher.rb +48 -14
  181. data/lib/mongoid/persistable/creatable.rb +19 -9
  182. data/lib/mongoid/persistable/deletable.rb +2 -2
  183. data/lib/mongoid/persistable/destroyable.rb +1 -1
  184. data/lib/mongoid/persistable/savable.rb +14 -2
  185. data/lib/mongoid/persistable/unsettable.rb +2 -2
  186. data/lib/mongoid/persistable/updatable.rb +69 -12
  187. data/lib/mongoid/persistable/upsertable.rb +21 -2
  188. data/lib/mongoid/persistable.rb +6 -3
  189. data/lib/mongoid/persistence_context.rb +6 -4
  190. data/lib/mongoid/query_cache.rb +13 -261
  191. data/lib/mongoid/railties/controller_runtime.rb +1 -1
  192. data/lib/mongoid/railties/database.rake +7 -2
  193. data/lib/mongoid/reloadable.rb +10 -8
  194. data/lib/mongoid/scopable.rb +15 -13
  195. data/lib/mongoid/selectable.rb +1 -2
  196. data/lib/mongoid/serializable.rb +17 -13
  197. data/lib/mongoid/stateful.rb +57 -10
  198. data/lib/mongoid/tasks/database.rake +12 -0
  199. data/lib/mongoid/tasks/database.rb +20 -2
  200. data/lib/mongoid/threaded/lifecycle.rb +5 -5
  201. data/lib/mongoid/threaded.rb +42 -12
  202. data/lib/mongoid/timestamps/created.rb +1 -1
  203. data/lib/mongoid/timestamps/updated.rb +2 -2
  204. data/lib/mongoid/touchable.rb +3 -4
  205. data/lib/mongoid/traversable.rb +10 -5
  206. data/lib/mongoid/utils.rb +22 -0
  207. data/lib/mongoid/validatable/associated.rb +98 -17
  208. data/lib/mongoid/validatable/localizable.rb +1 -1
  209. data/lib/mongoid/validatable/macros.rb +5 -7
  210. data/lib/mongoid/validatable/presence.rb +2 -2
  211. data/lib/mongoid/validatable/uniqueness.rb +9 -8
  212. data/lib/mongoid/validatable.rb +17 -6
  213. data/lib/mongoid/version.rb +1 -1
  214. data/lib/mongoid/warnings.rb +19 -4
  215. data/lib/mongoid.rb +17 -3
  216. data/spec/config/mongoid.yml +16 -0
  217. data/spec/integration/app_spec.rb +24 -19
  218. data/spec/integration/associations/belongs_to_spec.rb +18 -0
  219. data/spec/integration/associations/embedded_spec.rb +15 -0
  220. data/spec/integration/associations/embeds_many_spec.rb +15 -2
  221. data/spec/integration/associations/embeds_one_spec.rb +18 -0
  222. data/spec/integration/associations/foreign_key_spec.rb +9 -0
  223. data/spec/integration/associations/has_and_belongs_to_many_spec.rb +61 -0
  224. data/spec/integration/associations/has_one_spec.rb +97 -1
  225. data/spec/integration/associations/scope_option_spec.rb +1 -1
  226. data/spec/integration/callbacks_models.rb +132 -1
  227. data/spec/integration/callbacks_spec.rb +381 -4
  228. data/spec/integration/criteria/range_spec.rb +95 -1
  229. data/spec/integration/discriminator_key_spec.rb +118 -80
  230. data/spec/integration/dots_and_dollars_spec.rb +277 -0
  231. data/spec/integration/i18n_fallbacks_spec.rb +3 -32
  232. data/spec/integration/matcher_examples_spec.rb +20 -13
  233. data/spec/integration/matcher_operator_data/type_decimal.yml +3 -2
  234. data/spec/integration/matcher_operator_spec.rb +3 -5
  235. data/spec/integration/persistence/range_field_spec.rb +350 -0
  236. data/spec/mongoid/association/counter_cache_spec.rb +1 -1
  237. data/spec/mongoid/association/depending_spec.rb +9 -9
  238. data/spec/mongoid/association/eager_spec.rb +2 -1
  239. data/spec/mongoid/association/embedded/embedded_in/binding_spec.rb +2 -1
  240. data/spec/mongoid/association/embedded/embedded_in/buildable_spec.rb +54 -0
  241. data/spec/mongoid/association/embedded/embedded_in/proxy_spec.rb +96 -9
  242. data/spec/mongoid/association/embedded/embeds_many/buildable_spec.rb +112 -0
  243. data/spec/mongoid/association/embedded/embeds_many/proxy_spec.rb +290 -65
  244. data/spec/mongoid/association/embedded/embeds_many_models.rb +37 -0
  245. data/spec/mongoid/association/embedded/embeds_many_query_spec.rb +16 -0
  246. data/spec/mongoid/association/embedded/embeds_many_spec.rb +68 -0
  247. data/spec/mongoid/association/embedded/embeds_one/buildable_spec.rb +25 -0
  248. data/spec/mongoid/association/embedded/embeds_one/proxy_spec.rb +15 -2
  249. data/spec/mongoid/association/embedded/embeds_one_models.rb +19 -0
  250. data/spec/mongoid/association/embedded/embeds_one_spec.rb +28 -0
  251. data/spec/mongoid/association/referenced/belongs_to/binding_spec.rb +2 -1
  252. data/spec/mongoid/association/referenced/belongs_to/buildable_spec.rb +54 -0
  253. data/spec/mongoid/association/referenced/belongs_to/proxy_spec.rb +19 -0
  254. data/spec/mongoid/association/referenced/belongs_to_models.rb +11 -0
  255. data/spec/mongoid/association/referenced/belongs_to_spec.rb +4 -20
  256. data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_spec.rb +186 -229
  257. data/spec/mongoid/association/referenced/has_and_belongs_to_many_models.rb +25 -0
  258. data/spec/mongoid/association/referenced/has_and_belongs_to_many_spec.rb +35 -2
  259. data/spec/mongoid/association/referenced/has_many/buildable_spec.rb +109 -0
  260. data/spec/mongoid/association/referenced/has_many/enumerable_spec.rb +2 -56
  261. data/spec/mongoid/association/referenced/has_many/proxy_spec.rb +215 -177
  262. data/spec/mongoid/association/referenced/has_many_models.rb +3 -1
  263. data/spec/mongoid/association/referenced/has_many_spec.rb +25 -0
  264. data/spec/mongoid/association/referenced/has_one/buildable_spec.rb +2 -2
  265. data/spec/mongoid/association/referenced/has_one/proxy_spec.rb +107 -1
  266. data/spec/mongoid/association/referenced/has_one_models.rb +16 -0
  267. data/spec/mongoid/association/syncable_spec.rb +15 -1
  268. data/spec/mongoid/atomic/paths_spec.rb +0 -14
  269. data/spec/mongoid/attributes/nested_spec.rb +80 -11
  270. data/spec/mongoid/attributes/nested_spec_models.rb +48 -0
  271. data/spec/mongoid/attributes/projector_spec.rb +1 -5
  272. data/spec/mongoid/attributes_spec.rb +526 -33
  273. data/spec/mongoid/changeable_spec.rb +429 -37
  274. data/spec/mongoid/clients/factory_spec.rb +23 -30
  275. data/spec/mongoid/clients/sessions_spec.rb +0 -38
  276. data/spec/mongoid/clients_spec.rb +149 -15
  277. data/spec/mongoid/collection_configurable_spec.rb +158 -0
  278. data/spec/mongoid/config/defaults_spec.rb +160 -0
  279. data/spec/mongoid/config_spec.rb +214 -31
  280. data/spec/mongoid/contextual/aggregable/memory_spec.rb +396 -158
  281. data/spec/mongoid/contextual/aggregable/memory_table.yml +88 -0
  282. data/spec/mongoid/contextual/aggregable/memory_table_spec.rb +62 -0
  283. data/spec/mongoid/contextual/map_reduce_spec.rb +2 -16
  284. data/spec/mongoid/contextual/memory_spec.rb +850 -88
  285. data/spec/mongoid/contextual/mongo/documents_loader_spec.rb +187 -0
  286. data/spec/mongoid/contextual/mongo_spec.rb +2256 -1005
  287. data/spec/mongoid/contextual/none_spec.rb +60 -21
  288. data/spec/mongoid/copyable_spec.rb +453 -11
  289. data/spec/mongoid/criteria/findable_spec.rb +86 -210
  290. data/spec/mongoid/criteria/includable_spec.rb +1492 -0
  291. data/spec/mongoid/criteria/includable_spec_models.rb +54 -0
  292. data/spec/mongoid/criteria/marshalable_spec.rb +18 -1
  293. data/spec/mongoid/criteria/queryable/extensions/array_spec.rb +7 -19
  294. data/spec/mongoid/criteria/queryable/extensions/big_decimal_spec.rb +134 -26
  295. data/spec/mongoid/criteria/queryable/extensions/date_spec.rb +11 -0
  296. data/spec/mongoid/criteria/queryable/extensions/date_time_spec.rb +11 -0
  297. data/spec/mongoid/criteria/queryable/extensions/hash_spec.rb +0 -15
  298. data/spec/mongoid/criteria/queryable/extensions/numeric_spec.rb +73 -7
  299. data/spec/mongoid/criteria/queryable/extensions/string_spec.rb +4 -69
  300. data/spec/mongoid/criteria/queryable/extensions/symbol_spec.rb +0 -59
  301. data/spec/mongoid/criteria/queryable/extensions/time_spec.rb +11 -0
  302. data/spec/mongoid/criteria/queryable/extensions/time_with_zone_spec.rb +11 -0
  303. data/spec/mongoid/criteria/queryable/optional_spec.rb +15 -484
  304. data/spec/mongoid/criteria/queryable/options_spec.rb +1 -1
  305. data/spec/mongoid/criteria/queryable/selectable_logical_spec.rb +469 -0
  306. data/spec/mongoid/criteria/queryable/selectable_spec.rb +78 -86
  307. data/spec/mongoid/criteria/queryable/selector_spec.rb +15 -3
  308. data/spec/mongoid/criteria/translator_spec.rb +132 -0
  309. data/spec/mongoid/criteria_projection_spec.rb +1 -5
  310. data/spec/mongoid/criteria_spec.rb +469 -1205
  311. data/spec/mongoid/document_fields_spec.rb +173 -24
  312. data/spec/mongoid/document_spec.rb +32 -41
  313. data/spec/mongoid/errors/document_not_found_spec.rb +29 -2
  314. data/spec/mongoid/errors/invalid_field_spec.rb +1 -1
  315. data/spec/mongoid/errors/invalid_field_type_spec.rb +55 -0
  316. data/spec/mongoid/errors/mongoid_error_spec.rb +3 -1
  317. data/spec/mongoid/errors/no_environment_spec.rb +3 -3
  318. data/spec/mongoid/errors/readonly_document_spec.rb +2 -2
  319. data/spec/mongoid/errors/too_many_nested_attribute_records_spec.rb +1 -1
  320. data/spec/mongoid/extensions/array_spec.rb +16 -2
  321. data/spec/mongoid/extensions/big_decimal_spec.rb +712 -212
  322. data/spec/mongoid/extensions/binary_spec.rb +44 -9
  323. data/spec/mongoid/extensions/boolean_spec.rb +68 -82
  324. data/spec/mongoid/extensions/date_class_mongoize_spec.rb +7 -3
  325. data/spec/mongoid/extensions/date_spec.rb +71 -1
  326. data/spec/mongoid/extensions/date_time_spec.rb +15 -9
  327. data/spec/mongoid/extensions/float_spec.rb +53 -74
  328. data/spec/mongoid/extensions/hash_spec.rb +33 -3
  329. data/spec/mongoid/extensions/integer_spec.rb +50 -64
  330. data/spec/mongoid/extensions/range_spec.rb +255 -54
  331. data/spec/mongoid/extensions/regexp_spec.rb +58 -33
  332. data/spec/mongoid/extensions/set_spec.rb +106 -0
  333. data/spec/mongoid/extensions/string_spec.rb +53 -25
  334. data/spec/mongoid/extensions/symbol_spec.rb +18 -25
  335. data/spec/mongoid/extensions/time_spec.rb +639 -106
  336. data/spec/mongoid/extensions/time_with_zone_spec.rb +24 -83
  337. data/spec/mongoid/factory_spec.rb +61 -1
  338. data/spec/mongoid/fields/localized_spec.rb +80 -37
  339. data/spec/mongoid/fields_spec.rb +503 -87
  340. data/spec/mongoid/findable_spec.rb +450 -58
  341. data/spec/mongoid/indexable/specification_spec.rb +2 -2
  342. data/spec/mongoid/indexable_spec.rb +55 -30
  343. data/spec/mongoid/interceptable_spec.rb +824 -22
  344. data/spec/mongoid/interceptable_spec_models.rb +235 -4
  345. data/spec/mongoid/matcher/extract_attribute_spec.rb +1 -5
  346. data/spec/mongoid/mongoizable_spec.rb +285 -0
  347. data/spec/mongoid/persistable/creatable_spec.rb +2 -2
  348. data/spec/mongoid/persistable/deletable_spec.rb +28 -8
  349. data/spec/mongoid/persistable/destroyable_spec.rb +28 -8
  350. data/spec/mongoid/persistable/incrementable_spec.rb +37 -0
  351. data/spec/mongoid/persistable/logical_spec.rb +37 -0
  352. data/spec/mongoid/persistable/poppable_spec.rb +36 -0
  353. data/spec/mongoid/persistable/pullable_spec.rb +72 -0
  354. data/spec/mongoid/persistable/pushable_spec.rb +72 -0
  355. data/spec/mongoid/persistable/renamable_spec.rb +36 -0
  356. data/spec/mongoid/persistable/savable_spec.rb +96 -0
  357. data/spec/mongoid/persistable/settable_spec.rb +37 -0
  358. data/spec/mongoid/persistable/unsettable_spec.rb +36 -0
  359. data/spec/mongoid/persistable/updatable_spec.rb +20 -28
  360. data/spec/mongoid/persistable/upsertable_spec.rb +89 -1
  361. data/spec/mongoid/persistence_context_spec.rb +31 -57
  362. data/spec/mongoid/query_cache_middleware_spec.rb +0 -18
  363. data/spec/mongoid/query_cache_spec.rb +56 -215
  364. data/spec/mongoid/reloadable_spec.rb +83 -6
  365. data/spec/mongoid/scopable_spec.rb +91 -1
  366. data/spec/mongoid/serializable_spec.rb +25 -39
  367. data/spec/mongoid/shardable_spec.rb +4 -4
  368. data/spec/mongoid/stateful_spec.rb +150 -8
  369. data/spec/mongoid/tasks/database_rake_spec.rb +74 -0
  370. data/spec/mongoid/tasks/database_spec.rb +127 -0
  371. data/spec/mongoid/timestamps_spec.rb +392 -4
  372. data/spec/mongoid/timestamps_spec_models.rb +67 -0
  373. data/spec/mongoid/touchable_spec.rb +390 -2
  374. data/spec/mongoid/touchable_spec_models.rb +14 -8
  375. data/spec/mongoid/traversable_spec.rb +13 -35
  376. data/spec/mongoid/validatable/associated_spec.rb +27 -34
  377. data/spec/mongoid/validatable/presence_spec.rb +1 -1
  378. data/spec/mongoid/validatable/uniqueness_spec.rb +58 -31
  379. data/spec/mongoid/warnings_spec.rb +35 -0
  380. data/spec/mongoid_spec.rb +34 -16
  381. data/spec/rails/controller_extension/controller_runtime_spec.rb +2 -2
  382. data/spec/rails/mongoid_spec.rb +4 -16
  383. data/spec/spec_helper.rb +5 -0
  384. data/spec/support/constraints.rb +24 -0
  385. data/spec/support/immutable_ids.rb +118 -0
  386. data/spec/support/macros.rb +78 -0
  387. data/spec/support/models/artist.rb +0 -1
  388. data/spec/support/models/augmentation.rb +12 -0
  389. data/spec/support/models/band.rb +5 -0
  390. data/spec/support/models/book.rb +1 -0
  391. data/spec/support/models/building.rb +2 -0
  392. data/spec/support/models/catalog.rb +24 -0
  393. data/spec/support/models/circus.rb +3 -0
  394. data/spec/support/models/cover.rb +10 -0
  395. data/spec/support/models/fanatic.rb +8 -0
  396. data/spec/support/models/implant.rb +9 -0
  397. data/spec/support/models/label.rb +2 -0
  398. data/spec/support/models/lat_lng.rb +6 -0
  399. data/spec/support/models/name.rb +10 -0
  400. data/spec/support/models/passport.rb +9 -0
  401. data/spec/support/models/person.rb +2 -0
  402. data/spec/support/models/player.rb +2 -0
  403. data/spec/support/models/powerup.rb +12 -0
  404. data/spec/support/models/product.rb +1 -0
  405. data/spec/support/models/purse.rb +9 -0
  406. data/spec/support/models/registry.rb +1 -0
  407. data/spec/support/models/school.rb +14 -0
  408. data/spec/support/models/shield.rb +18 -0
  409. data/spec/support/models/student.rb +14 -0
  410. data/spec/support/models/weapon.rb +12 -0
  411. metadata +101 -96
  412. checksums.yaml.gz.sig +0 -0
  413. data/lib/mongoid/errors/eager_load.rb +0 -23
  414. data/lib/mongoid/errors/invalid_value.rb +0 -17
  415. data/spec/mongoid/criteria/queryable/extensions/bignum_spec.rb +0 -60
  416. data/spec/mongoid/criteria/queryable/extensions/fixnum_spec.rb +0 -60
  417. data/spec/mongoid/errors/eager_load_spec.rb +0 -31
  418. data/spec/shared/LICENSE +0 -20
  419. data/spec/shared/bin/get-mongodb-download-url +0 -17
  420. data/spec/shared/bin/s3-copy +0 -45
  421. data/spec/shared/bin/s3-upload +0 -69
  422. data/spec/shared/lib/mrss/child_process_helper.rb +0 -80
  423. data/spec/shared/lib/mrss/cluster_config.rb +0 -231
  424. data/spec/shared/lib/mrss/constraints.rb +0 -378
  425. data/spec/shared/lib/mrss/docker_runner.rb +0 -291
  426. data/spec/shared/lib/mrss/eg_config_utils.rb +0 -51
  427. data/spec/shared/lib/mrss/event_subscriber.rb +0 -210
  428. data/spec/shared/lib/mrss/lite_constraints.rb +0 -238
  429. data/spec/shared/lib/mrss/server_version_registry.rb +0 -120
  430. data/spec/shared/lib/mrss/session_registry.rb +0 -69
  431. data/spec/shared/lib/mrss/session_registry_legacy.rb +0 -60
  432. data/spec/shared/lib/mrss/spec_organizer.rb +0 -179
  433. data/spec/shared/lib/mrss/utils.rb +0 -15
  434. data/spec/shared/share/Dockerfile.erb +0 -325
  435. data/spec/shared/share/haproxy-1.conf +0 -16
  436. data/spec/shared/share/haproxy-2.conf +0 -17
  437. data/spec/shared/shlib/config.sh +0 -27
  438. data/spec/shared/shlib/distro.sh +0 -74
  439. data/spec/shared/shlib/server.sh +0 -392
  440. data/spec/shared/shlib/set_env.sh +0 -169
  441. data.tar.gz.sig +0 -0
  442. metadata.gz.sig +0 -3
@@ -580,10 +580,24 @@ describe Mongoid::Interceptable do
580
580
  end
581
581
 
582
582
  context "when saving the root" do
583
+ context 'with prevent_multiple_calls_of_embedded_callbacks enabled' do
584
+ config_override :prevent_multiple_calls_of_embedded_callbacks, true
585
+ config_override :around_callbacks_for_embeds, true
583
586
 
584
- it "only executes the callbacks once for each embed" do
585
- expect(note).to receive(:update_saved).twice
586
- band.save!
587
+ it "executes the callbacks only once for each document" do
588
+ expect(note).to receive(:update_saved).once
589
+ band.save!
590
+ end
591
+ end
592
+
593
+ context 'with prevent_multiple_calls_of_embedded_callbacks disabled' do
594
+ config_override :prevent_multiple_calls_of_embedded_callbacks, false
595
+ config_override :around_callbacks_for_embeds, true
596
+
597
+ it "executes the callbacks once for each ember" do
598
+ expect(note).to receive(:update_saved).twice
599
+ band.save!
600
+ end
587
601
  end
588
602
  end
589
603
  end
@@ -1746,8 +1760,12 @@ describe Mongoid::Interceptable do
1746
1760
  [InterceptableSpec::CbChild, :after_validation],
1747
1761
  [InterceptableSpec::CbParent, :after_validation],
1748
1762
  [InterceptableSpec::CbParent, :before_save],
1763
+ [InterceptableSpec::CbParent, :around_save_open],
1749
1764
  [InterceptableSpec::CbParent, :before_create],
1765
+ [InterceptableSpec::CbParent, :around_create_open],
1766
+ [InterceptableSpec::CbParent, :around_create_close],
1750
1767
  [InterceptableSpec::CbParent, :after_create],
1768
+ [InterceptableSpec::CbParent, :around_save_close],
1751
1769
  [InterceptableSpec::CbParent, :after_save],
1752
1770
  ]
1753
1771
  end
@@ -1767,28 +1785,812 @@ describe Mongoid::Interceptable do
1767
1785
  end
1768
1786
  end
1769
1787
 
1770
- let(:expected) do
1771
- [
1772
- [InterceptableSpec::CbParent, :before_validation],
1773
- [InterceptableSpec::CbCascadedChild, :before_validation],
1774
- [InterceptableSpec::CbCascadedChild, :after_validation],
1775
- [InterceptableSpec::CbParent, :after_validation],
1776
- [InterceptableSpec::CbParent, :before_save],
1777
- [InterceptableSpec::CbCascadedChild, :before_save],
1778
- [InterceptableSpec::CbParent, :before_create],
1779
- [InterceptableSpec::CbCascadedChild, :before_create],
1780
- [InterceptableSpec::CbParent, :after_create],
1781
- [InterceptableSpec::CbCascadedChild, :after_create],
1782
- [InterceptableSpec::CbParent, :after_save],
1783
- [InterceptableSpec::CbCascadedChild, :after_save],
1784
- ]
1788
+ context 'with around callbacks' do
1789
+ config_override :around_callbacks_for_embeds, true
1790
+
1791
+ let(:expected) do
1792
+ [
1793
+ [InterceptableSpec::CbCascadedChild, :before_validation],
1794
+ [InterceptableSpec::CbCascadedChild, :after_validation],
1795
+ [InterceptableSpec::CbParent, :before_validation],
1796
+ [InterceptableSpec::CbCascadedChild, :before_validation],
1797
+ [InterceptableSpec::CbCascadedChild, :after_validation],
1798
+
1799
+ [InterceptableSpec::CbParent, :after_validation],
1800
+ [InterceptableSpec::CbParent, :before_save],
1801
+ [InterceptableSpec::CbParent, :around_save_open],
1802
+ [InterceptableSpec::CbParent, :before_create],
1803
+ [InterceptableSpec::CbParent, :around_create_open],
1804
+
1805
+ [InterceptableSpec::CbCascadedChild, :before_save],
1806
+ [InterceptableSpec::CbCascadedChild, :around_save_open],
1807
+ [InterceptableSpec::CbCascadedChild, :before_create],
1808
+ [InterceptableSpec::CbCascadedChild, :around_create_open],
1809
+
1810
+ [InterceptableSpec::CbCascadedChild, :around_create_close],
1811
+ [InterceptableSpec::CbCascadedChild, :after_create],
1812
+ [InterceptableSpec::CbCascadedChild, :around_save_close],
1813
+ [InterceptableSpec::CbCascadedChild, :after_save],
1814
+
1815
+ [InterceptableSpec::CbParent, :around_create_close],
1816
+ [InterceptableSpec::CbParent, :after_create],
1817
+ [InterceptableSpec::CbParent, :around_save_close],
1818
+ [InterceptableSpec::CbParent, :after_save]
1819
+ ]
1820
+ end
1821
+
1822
+ it 'calls callbacks in the right order' do
1823
+ parent.save!
1824
+ expect(registry.calls).to eq expected
1825
+ end
1785
1826
  end
1786
1827
 
1787
- it 'calls callbacks in the right order' do
1788
- pending 'MONGOID-3795'
1828
+ context 'without around callbacks' do
1829
+ config_override :around_callbacks_for_embeds, false
1789
1830
 
1790
- parent.save!
1791
- expect(registry.calls).to eq expected
1831
+ let(:expected) do
1832
+ [
1833
+ [InterceptableSpec::CbCascadedChild, :before_validation],
1834
+ [InterceptableSpec::CbCascadedChild, :after_validation],
1835
+ [InterceptableSpec::CbParent, :before_validation],
1836
+ [InterceptableSpec::CbCascadedChild, :before_validation],
1837
+ [InterceptableSpec::CbCascadedChild, :after_validation],
1838
+
1839
+ [InterceptableSpec::CbParent, :after_validation],
1840
+ [InterceptableSpec::CbParent, :before_save],
1841
+ [InterceptableSpec::CbParent, :around_save_open],
1842
+ [InterceptableSpec::CbParent, :before_create],
1843
+ [InterceptableSpec::CbParent, :around_create_open],
1844
+
1845
+ [InterceptableSpec::CbCascadedChild, :before_save],
1846
+ [InterceptableSpec::CbCascadedChild, :before_create],
1847
+
1848
+ [InterceptableSpec::CbCascadedChild, :after_create],
1849
+ [InterceptableSpec::CbCascadedChild, :after_save],
1850
+
1851
+ [InterceptableSpec::CbParent, :around_create_close],
1852
+ [InterceptableSpec::CbParent, :after_create],
1853
+ [InterceptableSpec::CbParent, :around_save_close],
1854
+ [InterceptableSpec::CbParent, :after_save]
1855
+ ]
1856
+ end
1857
+
1858
+ it 'calls callbacks in the right order' do
1859
+ parent.save!
1860
+ expect(registry.calls).to eq expected
1861
+ end
1862
+ end
1863
+ end
1864
+
1865
+ context "with associations" do
1866
+ context "has_one" do
1867
+ let(:registry) { InterceptableSpec::CallbackRegistry.new }
1868
+
1869
+ let(:parent) do
1870
+ InterceptableSpec::CbHasOneParent.new(registry).tap do |parent|
1871
+ parent.child = InterceptableSpec::CbHasOneChild.new(registry)
1872
+ end
1873
+ end
1874
+
1875
+ let(:expected) do
1876
+ [
1877
+ [InterceptableSpec::CbHasOneParent, :before_validation],
1878
+ [InterceptableSpec::CbHasOneChild, :before_validation],
1879
+ [InterceptableSpec::CbHasOneChild, :after_validation],
1880
+ [InterceptableSpec::CbHasOneParent, :after_validation],
1881
+ [InterceptableSpec::CbHasOneParent, :before_save],
1882
+
1883
+ [InterceptableSpec::CbHasOneParent, :around_save_open],
1884
+ [InterceptableSpec::CbHasOneParent, :before_create],
1885
+ [InterceptableSpec::CbHasOneParent, :around_create_open],
1886
+
1887
+ [InterceptableSpec::CbHasOneParent, :insert_into_database],
1888
+
1889
+ [InterceptableSpec::CbHasOneChild, :before_validation],
1890
+ [InterceptableSpec::CbHasOneChild, :after_validation],
1891
+ [InterceptableSpec::CbHasOneChild, :before_save],
1892
+ [InterceptableSpec::CbHasOneChild, :around_save_open],
1893
+ [InterceptableSpec::CbHasOneChild, :before_create],
1894
+ [InterceptableSpec::CbHasOneChild, :around_create_open],
1895
+
1896
+ [InterceptableSpec::CbHasOneChild, :around_create_close],
1897
+ [InterceptableSpec::CbHasOneChild, :after_create],
1898
+ [InterceptableSpec::CbHasOneChild, :around_save_close],
1899
+ [InterceptableSpec::CbHasOneChild, :after_save],
1900
+
1901
+ [InterceptableSpec::CbHasOneParent, :around_create_close],
1902
+ [InterceptableSpec::CbHasOneParent, :after_create],
1903
+ [InterceptableSpec::CbHasOneParent, :around_save_close],
1904
+ [InterceptableSpec::CbHasOneParent, :after_save],
1905
+ ]
1906
+ end
1907
+
1908
+ it 'calls callbacks in the right order' do
1909
+ parent.save!
1910
+ expect(registry.calls).to eq expected
1911
+ end
1912
+ end
1913
+
1914
+ context "embeds_one" do
1915
+ let(:registry) { InterceptableSpec::CallbackRegistry.new }
1916
+
1917
+ let(:parent) do
1918
+ InterceptableSpec::CbEmbedsOneParent.new(registry).tap do |parent|
1919
+ parent.child = InterceptableSpec::CbEmbedsOneChild.new(registry)
1920
+ end
1921
+ end
1922
+
1923
+ context "create" do
1924
+ context "with around callbacks" do
1925
+ config_override :around_callbacks_for_embeds, true
1926
+
1927
+ let(:expected) do
1928
+ [
1929
+ [InterceptableSpec::CbEmbedsOneChild, :before_validation],
1930
+ [InterceptableSpec::CbEmbedsOneChild, :after_validation],
1931
+ [InterceptableSpec::CbEmbedsOneParent, :before_validation],
1932
+ [InterceptableSpec::CbEmbedsOneChild, :before_validation],
1933
+ [InterceptableSpec::CbEmbedsOneChild, :after_validation],
1934
+ [InterceptableSpec::CbEmbedsOneParent, :after_validation],
1935
+
1936
+ [InterceptableSpec::CbEmbedsOneParent, :before_save],
1937
+ [InterceptableSpec::CbEmbedsOneParent, :around_save_open],
1938
+ [InterceptableSpec::CbEmbedsOneParent, :before_create],
1939
+ [InterceptableSpec::CbEmbedsOneParent, :around_create_open],
1940
+
1941
+ [InterceptableSpec::CbEmbedsOneChild, :before_save],
1942
+ [InterceptableSpec::CbEmbedsOneChild, :around_save_open],
1943
+ [InterceptableSpec::CbEmbedsOneChild, :before_create],
1944
+ [InterceptableSpec::CbEmbedsOneChild, :around_create_open],
1945
+
1946
+ [InterceptableSpec::CbEmbedsOneParent, :insert_into_database],
1947
+
1948
+ [InterceptableSpec::CbEmbedsOneChild, :around_create_close],
1949
+ [InterceptableSpec::CbEmbedsOneChild, :after_create],
1950
+ [InterceptableSpec::CbEmbedsOneChild, :around_save_close],
1951
+ [InterceptableSpec::CbEmbedsOneChild, :after_save],
1952
+
1953
+ [InterceptableSpec::CbEmbedsOneParent, :around_create_close],
1954
+ [InterceptableSpec::CbEmbedsOneParent, :after_create],
1955
+ [InterceptableSpec::CbEmbedsOneParent, :around_save_close],
1956
+ [InterceptableSpec::CbEmbedsOneParent, :after_save]
1957
+ ]
1958
+ end
1959
+
1960
+ it 'calls callbacks in the right order' do
1961
+ parent.save!
1962
+ expect(registry.calls).to eq expected
1963
+ end
1964
+ end
1965
+
1966
+ context "without around callbacks" do
1967
+ config_override :around_callbacks_for_embeds, false
1968
+
1969
+ let(:expected) do
1970
+ [
1971
+ [InterceptableSpec::CbEmbedsOneChild, :before_validation],
1972
+ [InterceptableSpec::CbEmbedsOneChild, :after_validation],
1973
+ [InterceptableSpec::CbEmbedsOneParent, :before_validation],
1974
+ [InterceptableSpec::CbEmbedsOneChild, :before_validation],
1975
+ [InterceptableSpec::CbEmbedsOneChild, :after_validation],
1976
+ [InterceptableSpec::CbEmbedsOneParent, :after_validation],
1977
+
1978
+ [InterceptableSpec::CbEmbedsOneParent, :before_save],
1979
+ [InterceptableSpec::CbEmbedsOneParent, :around_save_open],
1980
+ [InterceptableSpec::CbEmbedsOneParent, :before_create],
1981
+ [InterceptableSpec::CbEmbedsOneParent, :around_create_open],
1982
+
1983
+ [InterceptableSpec::CbEmbedsOneChild, :before_save],
1984
+ [InterceptableSpec::CbEmbedsOneChild, :before_create],
1985
+
1986
+ [InterceptableSpec::CbEmbedsOneParent, :insert_into_database],
1987
+
1988
+ [InterceptableSpec::CbEmbedsOneChild, :after_create],
1989
+ [InterceptableSpec::CbEmbedsOneChild, :after_save],
1990
+
1991
+ [InterceptableSpec::CbEmbedsOneParent, :around_create_close],
1992
+ [InterceptableSpec::CbEmbedsOneParent, :after_create],
1993
+ [InterceptableSpec::CbEmbedsOneParent, :around_save_close],
1994
+ [InterceptableSpec::CbEmbedsOneParent, :after_save]
1995
+ ]
1996
+ end
1997
+
1998
+ it 'calls callbacks in the right order' do
1999
+ parent.save!
2000
+ expect(registry.calls).to eq expected
2001
+ end
2002
+ end
2003
+ end
2004
+
2005
+ context "update" do
2006
+ context "with around callbacks" do
2007
+ config_override :around_callbacks_for_embeds, true
2008
+
2009
+ let(:expected) do
2010
+ [
2011
+ [InterceptableSpec::CbEmbedsOneChild, :before_validation],
2012
+ [InterceptableSpec::CbEmbedsOneChild, :after_validation],
2013
+ [InterceptableSpec::CbEmbedsOneParent, :before_validation],
2014
+ [InterceptableSpec::CbEmbedsOneChild, :before_validation],
2015
+ [InterceptableSpec::CbEmbedsOneChild, :after_validation],
2016
+ [InterceptableSpec::CbEmbedsOneParent, :after_validation],
2017
+
2018
+ [InterceptableSpec::CbEmbedsOneParent, :before_save],
2019
+ [InterceptableSpec::CbEmbedsOneParent, :around_save_open],
2020
+ [InterceptableSpec::CbEmbedsOneParent, :before_update],
2021
+ [InterceptableSpec::CbEmbedsOneParent, :around_update_open],
2022
+
2023
+ [InterceptableSpec::CbEmbedsOneChild, :before_save],
2024
+ [InterceptableSpec::CbEmbedsOneChild, :around_save_open],
2025
+ [InterceptableSpec::CbEmbedsOneChild, :before_update],
2026
+ [InterceptableSpec::CbEmbedsOneChild, :around_update_open],
2027
+
2028
+ [InterceptableSpec::CbEmbedsOneChild, :around_update_close],
2029
+ [InterceptableSpec::CbEmbedsOneChild, :after_update],
2030
+ [InterceptableSpec::CbEmbedsOneChild, :around_save_close],
2031
+ [InterceptableSpec::CbEmbedsOneChild, :after_save],
2032
+
2033
+ [InterceptableSpec::CbEmbedsOneParent, :around_update_close],
2034
+ [InterceptableSpec::CbEmbedsOneParent, :after_update],
2035
+ [InterceptableSpec::CbEmbedsOneParent, :around_save_close],
2036
+ [InterceptableSpec::CbEmbedsOneParent, :after_save]
2037
+ ]
2038
+ end
2039
+
2040
+ it 'calls callbacks in the right order' do
2041
+ parent.callback_registry = nil
2042
+ parent.child.callback_registry = nil
2043
+ parent.save!
2044
+
2045
+ parent.callback_registry = registry
2046
+ parent.child.callback_registry = registry
2047
+ parent.name = "name"
2048
+ parent.child.age = 10
2049
+
2050
+ parent.save!
2051
+ expect(registry.calls).to eq expected
2052
+ end
2053
+ end
2054
+
2055
+ context "without around callbacks" do
2056
+ config_override :around_callbacks_for_embeds, false
2057
+
2058
+ let(:expected) do
2059
+ [
2060
+ [InterceptableSpec::CbEmbedsOneChild, :before_validation],
2061
+ [InterceptableSpec::CbEmbedsOneChild, :after_validation],
2062
+ [InterceptableSpec::CbEmbedsOneParent, :before_validation],
2063
+ [InterceptableSpec::CbEmbedsOneChild, :before_validation],
2064
+ [InterceptableSpec::CbEmbedsOneChild, :after_validation],
2065
+ [InterceptableSpec::CbEmbedsOneParent, :after_validation],
2066
+
2067
+ [InterceptableSpec::CbEmbedsOneParent, :before_save],
2068
+ [InterceptableSpec::CbEmbedsOneParent, :around_save_open],
2069
+ [InterceptableSpec::CbEmbedsOneParent, :before_update],
2070
+ [InterceptableSpec::CbEmbedsOneParent, :around_update_open],
2071
+
2072
+ [InterceptableSpec::CbEmbedsOneChild, :before_save],
2073
+ [InterceptableSpec::CbEmbedsOneChild, :before_update],
2074
+
2075
+ [InterceptableSpec::CbEmbedsOneChild, :after_update],
2076
+ [InterceptableSpec::CbEmbedsOneChild, :after_save],
2077
+
2078
+ [InterceptableSpec::CbEmbedsOneParent, :around_update_close],
2079
+ [InterceptableSpec::CbEmbedsOneParent, :after_update],
2080
+ [InterceptableSpec::CbEmbedsOneParent, :around_save_close],
2081
+ [InterceptableSpec::CbEmbedsOneParent, :after_save]
2082
+ ]
2083
+ end
2084
+
2085
+ it 'calls callbacks in the right order' do
2086
+ parent.callback_registry = nil
2087
+ parent.child.callback_registry = nil
2088
+ parent.save!
2089
+
2090
+ parent.callback_registry = registry
2091
+ parent.child.callback_registry = registry
2092
+ parent.name = "name"
2093
+ parent.child.age = 10
2094
+
2095
+ parent.save!
2096
+ expect(registry.calls).to eq expected
2097
+ end
2098
+ end
2099
+ end
2100
+ end
2101
+
2102
+ context "has_many" do
2103
+ let(:registry) { InterceptableSpec::CallbackRegistry.new }
2104
+
2105
+ let(:parent) do
2106
+ InterceptableSpec::CbHasManyParent.new(registry).tap do |parent|
2107
+ parent.children = [
2108
+ InterceptableSpec::CbHasManyChild.new(registry),
2109
+ InterceptableSpec::CbHasManyChild.new(registry)
2110
+ ]
2111
+ end
2112
+ end
2113
+
2114
+ let(:expected) do
2115
+ [
2116
+ [InterceptableSpec::CbHasManyParent, :before_validation],
2117
+ [InterceptableSpec::CbHasManyChild, :before_validation],
2118
+ [InterceptableSpec::CbHasManyChild, :after_validation],
2119
+ [InterceptableSpec::CbHasManyChild, :before_validation],
2120
+ [InterceptableSpec::CbHasManyChild, :after_validation],
2121
+ [InterceptableSpec::CbHasManyParent, :after_validation],
2122
+
2123
+ [InterceptableSpec::CbHasManyParent, :before_save],
2124
+ [InterceptableSpec::CbHasManyParent, :around_save_open],
2125
+ [InterceptableSpec::CbHasManyParent, :before_create],
2126
+ [InterceptableSpec::CbHasManyParent, :around_create_open],
2127
+
2128
+ [InterceptableSpec::CbHasManyParent, :insert_into_database],
2129
+
2130
+ [InterceptableSpec::CbHasManyChild, :before_validation],
2131
+ [InterceptableSpec::CbHasManyChild, :after_validation],
2132
+ [InterceptableSpec::CbHasManyChild, :before_save],
2133
+ [InterceptableSpec::CbHasManyChild, :around_save_open],
2134
+ [InterceptableSpec::CbHasManyChild, :before_create],
2135
+ [InterceptableSpec::CbHasManyChild, :around_create_open],
2136
+ [InterceptableSpec::CbHasManyChild, :around_create_close],
2137
+ [InterceptableSpec::CbHasManyChild, :after_create],
2138
+ [InterceptableSpec::CbHasManyChild, :around_save_close],
2139
+ [InterceptableSpec::CbHasManyChild, :after_save],
2140
+
2141
+ [InterceptableSpec::CbHasManyChild, :before_validation],
2142
+ [InterceptableSpec::CbHasManyChild, :after_validation],
2143
+ [InterceptableSpec::CbHasManyChild, :before_save],
2144
+ [InterceptableSpec::CbHasManyChild, :around_save_open],
2145
+ [InterceptableSpec::CbHasManyChild, :before_create],
2146
+ [InterceptableSpec::CbHasManyChild, :around_create_open],
2147
+ [InterceptableSpec::CbHasManyChild, :around_create_close],
2148
+ [InterceptableSpec::CbHasManyChild, :after_create],
2149
+ [InterceptableSpec::CbHasManyChild, :around_save_close],
2150
+ [InterceptableSpec::CbHasManyChild, :after_save],
2151
+
2152
+ [InterceptableSpec::CbHasManyParent, :around_create_close],
2153
+ [InterceptableSpec::CbHasManyParent, :after_create],
2154
+ [InterceptableSpec::CbHasManyParent, :around_save_close],
2155
+ [InterceptableSpec::CbHasManyParent, :after_save]
2156
+ ]
2157
+ end
2158
+
2159
+ it 'calls callbacks in the right order' do
2160
+ parent.save!
2161
+ expect(registry.calls).to eq expected
2162
+ end
2163
+ end
2164
+
2165
+ context "embeds_many" do
2166
+ let(:registry) { InterceptableSpec::CallbackRegistry.new }
2167
+
2168
+ let(:parent) do
2169
+ InterceptableSpec::CbEmbedsManyParent.new(registry).tap do |parent|
2170
+ parent.children = [
2171
+ InterceptableSpec::CbEmbedsManyChild.new(registry),
2172
+ InterceptableSpec::CbEmbedsManyChild.new(registry),
2173
+ ]
2174
+ end
2175
+ end
2176
+
2177
+ context "with around callbacks" do
2178
+ config_override :around_callbacks_for_embeds, true
2179
+
2180
+ let(:expected) do
2181
+ [
2182
+ [InterceptableSpec::CbEmbedsManyChild, :before_validation],
2183
+ [InterceptableSpec::CbEmbedsManyChild, :after_validation],
2184
+ [InterceptableSpec::CbEmbedsManyChild, :before_validation],
2185
+ [InterceptableSpec::CbEmbedsManyChild, :after_validation],
2186
+ [InterceptableSpec::CbEmbedsManyParent, :before_validation],
2187
+ [InterceptableSpec::CbEmbedsManyChild, :before_validation],
2188
+ [InterceptableSpec::CbEmbedsManyChild, :after_validation],
2189
+ [InterceptableSpec::CbEmbedsManyChild, :before_validation],
2190
+ [InterceptableSpec::CbEmbedsManyChild, :after_validation],
2191
+ [InterceptableSpec::CbEmbedsManyParent, :after_validation],
2192
+
2193
+ [InterceptableSpec::CbEmbedsManyParent, :before_save],
2194
+ [InterceptableSpec::CbEmbedsManyParent, :around_save_open],
2195
+ [InterceptableSpec::CbEmbedsManyParent, :before_create],
2196
+ [InterceptableSpec::CbEmbedsManyParent, :around_create_open],
2197
+
2198
+ [InterceptableSpec::CbEmbedsManyChild, :before_save],
2199
+ [InterceptableSpec::CbEmbedsManyChild, :around_save_open],
2200
+ [InterceptableSpec::CbEmbedsManyChild, :before_save],
2201
+
2202
+ [InterceptableSpec::CbEmbedsManyChild, :around_save_open],
2203
+ [InterceptableSpec::CbEmbedsManyChild, :before_create],
2204
+ [InterceptableSpec::CbEmbedsManyChild, :around_create_open],
2205
+
2206
+ [InterceptableSpec::CbEmbedsManyChild, :before_create],
2207
+ [InterceptableSpec::CbEmbedsManyChild, :around_create_open],
2208
+
2209
+ [InterceptableSpec::CbEmbedsManyParent, :insert_into_database],
2210
+
2211
+ [InterceptableSpec::CbEmbedsManyChild, :around_create_close],
2212
+ [InterceptableSpec::CbEmbedsManyChild, :after_create],
2213
+
2214
+ [InterceptableSpec::CbEmbedsManyChild, :around_create_close],
2215
+ [InterceptableSpec::CbEmbedsManyChild, :after_create],
2216
+
2217
+ [InterceptableSpec::CbEmbedsManyChild, :around_save_close],
2218
+ [InterceptableSpec::CbEmbedsManyChild, :after_save],
2219
+
2220
+ [InterceptableSpec::CbEmbedsManyChild, :around_save_close],
2221
+ [InterceptableSpec::CbEmbedsManyChild, :after_save],
2222
+
2223
+ [InterceptableSpec::CbEmbedsManyParent, :around_create_close],
2224
+ [InterceptableSpec::CbEmbedsManyParent, :after_create],
2225
+ [InterceptableSpec::CbEmbedsManyParent, :around_save_close],
2226
+ [InterceptableSpec::CbEmbedsManyParent, :after_save]
2227
+ ]
2228
+ end
2229
+
2230
+ it 'calls callbacks in the right order' do
2231
+ parent.save!
2232
+ expect(registry.calls).to eq expected
2233
+ end
2234
+ end
2235
+
2236
+ context "without around callbacks" do
2237
+ config_override :around_callbacks_for_embeds, false
2238
+
2239
+ let(:expected) do
2240
+ [
2241
+ [InterceptableSpec::CbEmbedsManyChild, :before_validation],
2242
+ [InterceptableSpec::CbEmbedsManyChild, :after_validation],
2243
+ [InterceptableSpec::CbEmbedsManyChild, :before_validation],
2244
+ [InterceptableSpec::CbEmbedsManyChild, :after_validation],
2245
+ [InterceptableSpec::CbEmbedsManyParent, :before_validation],
2246
+ [InterceptableSpec::CbEmbedsManyChild, :before_validation],
2247
+ [InterceptableSpec::CbEmbedsManyChild, :after_validation],
2248
+ [InterceptableSpec::CbEmbedsManyChild, :before_validation],
2249
+ [InterceptableSpec::CbEmbedsManyChild, :after_validation],
2250
+ [InterceptableSpec::CbEmbedsManyParent, :after_validation],
2251
+
2252
+ [InterceptableSpec::CbEmbedsManyParent, :before_save],
2253
+ [InterceptableSpec::CbEmbedsManyParent, :around_save_open],
2254
+ [InterceptableSpec::CbEmbedsManyParent, :before_create],
2255
+ [InterceptableSpec::CbEmbedsManyParent, :around_create_open],
2256
+
2257
+ [InterceptableSpec::CbEmbedsManyChild, :before_save],
2258
+ [InterceptableSpec::CbEmbedsManyChild, :before_save],
2259
+
2260
+ [InterceptableSpec::CbEmbedsManyChild, :before_create],
2261
+
2262
+ [InterceptableSpec::CbEmbedsManyChild, :before_create],
2263
+
2264
+ [InterceptableSpec::CbEmbedsManyParent, :insert_into_database],
2265
+
2266
+ [InterceptableSpec::CbEmbedsManyChild, :after_create],
2267
+
2268
+ [InterceptableSpec::CbEmbedsManyChild, :after_create],
2269
+
2270
+ [InterceptableSpec::CbEmbedsManyChild, :after_save],
2271
+
2272
+ [InterceptableSpec::CbEmbedsManyChild, :after_save],
2273
+
2274
+ [InterceptableSpec::CbEmbedsManyParent, :around_create_close],
2275
+ [InterceptableSpec::CbEmbedsManyParent, :after_create],
2276
+ [InterceptableSpec::CbEmbedsManyParent, :around_save_close],
2277
+ [InterceptableSpec::CbEmbedsManyParent, :after_save]
2278
+ ]
2279
+ end
2280
+
2281
+ it 'calls callbacks in the right order' do
2282
+ parent.save!
2283
+ expect(registry.calls).to eq expected
2284
+ end
2285
+ end
2286
+ end
2287
+ end
2288
+
2289
+ context "when accessing parent document from callbacks" do
2290
+ shared_examples 'accesses the correct parent' do
2291
+ it "accesses the correct parent in after_find" do
2292
+ expect(from_db.after_find_player).to eq(player._id)
2293
+ end
2294
+
2295
+ it "accesses the correct parent in after_initialize" do
2296
+ expect(from_db.after_initialize_player).to eq(player._id)
2297
+ end
2298
+
2299
+ it "accesses the correct parent in default" do
2300
+ expect(from_db.after_default_player).to eq(player._id)
2301
+ end
2302
+
2303
+ it "accesses the correct parent in unpersisted after_initialize" do
2304
+ expect(unpersisted.after_initialize_player).to eq(player._id)
2305
+ end
2306
+ end
2307
+
2308
+ context "when using create methods" do
2309
+
2310
+ context "when the child is an embeds_many association" do
2311
+ let!(:player) do
2312
+ Player.create!.tap do |player|
2313
+ player.implants.create!
2314
+ end
2315
+ end
2316
+
2317
+ let(:unpersisted) { player.implants.first }
2318
+
2319
+ before do
2320
+ # The default is originally set when creating this document, and it is
2321
+ # subsequently persisted to the database. Therefore when we retrieve
2322
+ # this document from the database, this field is already set, and
2323
+ # the default Proc is not called. This unset is needed to allow the
2324
+ # default Proc to be called when the document is retrieved from the
2325
+ # database.
2326
+ Player.find(player.id).implants.first.unset(:after_default_player)
2327
+ end
2328
+
2329
+ let(:from_db) do
2330
+ Player.find(player.id).implants.first
2331
+ end
2332
+
2333
+ include_examples 'accesses the correct parent'
2334
+ end
2335
+
2336
+ context "when the child is an embeds_one association" do
2337
+ let!(:player) do
2338
+ Player.create!.tap do |player|
2339
+ player.create_augmentation
2340
+ end
2341
+ end
2342
+
2343
+ let(:unpersisted) { player.augmentation }
2344
+
2345
+ before do
2346
+ Player.find(player.id).augmentation.unset(:after_default_player)
2347
+ end
2348
+
2349
+ let(:from_db) do
2350
+ Player.find(player.id).augmentation
2351
+ end
2352
+
2353
+ include_examples 'accesses the correct parent'
2354
+ end
2355
+
2356
+ context "when the child is a has_many association" do
2357
+ let!(:player) do
2358
+ Player.create!.tap do |player|
2359
+ player.weapons.create!
2360
+ end
2361
+ end
2362
+
2363
+ let(:unpersisted) { player.weapons.first }
2364
+
2365
+ before do
2366
+ Player.find(player.id).weapons.first.unset(:after_default_player)
2367
+ end
2368
+
2369
+ let(:from_db) do
2370
+ Player.find(player.id).weapons.first
2371
+ end
2372
+
2373
+ include_examples 'accesses the correct parent'
2374
+ end
2375
+
2376
+ context "when the child is a has_one association" do
2377
+ let!(:player) do
2378
+ Player.create!.tap do |player|
2379
+ player.create_powerup
2380
+ player.save!
2381
+ end
2382
+ end
2383
+
2384
+ let(:unpersisted) { player.powerup }
2385
+
2386
+ before do
2387
+ Player.find(player.id).powerup.unset(:after_default_player)
2388
+ end
2389
+
2390
+ let(:from_db) do
2391
+ Player.find(player.id).powerup
2392
+ end
2393
+
2394
+ include_examples 'accesses the correct parent'
2395
+ end
2396
+
2397
+ context "when the child is a has_and_belongs_to_many association" do
2398
+ let!(:player) do
2399
+ Player.create!.tap do |player|
2400
+ player.shields.create!
2401
+ end
2402
+ end
2403
+
2404
+ let(:unpersisted) { player.shields.first }
2405
+
2406
+ before do
2407
+ Player.find(player.id).shields.unset(:after_default_player)
2408
+ end
2409
+
2410
+ let(:from_db) do
2411
+ Player.find(player.id).shields.first
2412
+ end
2413
+
2414
+ include_examples 'accesses the correct parent'
2415
+ end
2416
+ end
2417
+
2418
+ context "when using build methods" do
2419
+
2420
+ context "when the child is an embeds_many association" do
2421
+ let!(:player) do
2422
+ Player.create!.tap do |player|
2423
+ player.implants.build
2424
+ player.implants.first.save!
2425
+ end
2426
+ end
2427
+
2428
+ let(:unpersisted) { player.implants.first }
2429
+
2430
+ before do
2431
+ Player.find(player.id).implants.first.unset(:after_default_player)
2432
+ end
2433
+
2434
+ let(:from_db) do
2435
+ Player.find(player.id).implants.first
2436
+ end
2437
+
2438
+ include_examples 'accesses the correct parent'
2439
+ end
2440
+
2441
+ context "when the child is an embeds_one association" do
2442
+ let!(:player) do
2443
+ Player.create!.tap do |player|
2444
+ player.build_augmentation
2445
+ player.save!
2446
+ end
2447
+ end
2448
+
2449
+ let(:unpersisted) { player.augmentation }
2450
+
2451
+ before do
2452
+ Player.find(player.id).augmentation.unset(:after_default_player)
2453
+ end
2454
+
2455
+ let(:from_db) do
2456
+ Player.find(player.id).augmentation
2457
+ end
2458
+
2459
+ include_examples 'accesses the correct parent'
2460
+ end
2461
+
2462
+ context "when the child is a has_many association" do
2463
+ let!(:player) do
2464
+ Player.create!.tap do |player|
2465
+ player.weapons.build
2466
+ player.weapons.first.save!
2467
+ end
2468
+ end
2469
+
2470
+ let(:unpersisted) { player.weapons.first }
2471
+
2472
+ before do
2473
+ Player.find(player.id).weapons.first.unset(:after_default_player)
2474
+ end
2475
+
2476
+ let(:from_db) do
2477
+ Player.find(player.id).weapons.first
2478
+ end
2479
+
2480
+ include_examples 'accesses the correct parent'
2481
+ end
2482
+
2483
+ context "when the child is a has_one association" do
2484
+ let!(:player) do
2485
+ Player.create!.tap do |player|
2486
+ player.build_powerup
2487
+ player.powerup.save!
2488
+ end
2489
+ end
2490
+
2491
+ let(:unpersisted) { player.powerup }
2492
+
2493
+ before do
2494
+ Player.find(player.id).powerup.unset(:after_default_player)
2495
+ end
2496
+
2497
+ let(:from_db) do
2498
+ Player.find(player.id).powerup
2499
+ end
2500
+
2501
+ include_examples 'accesses the correct parent'
2502
+ end
2503
+
2504
+ context "when the child is a has_and_belongs_to_many association" do
2505
+ let!(:player) do
2506
+ Player.create!.tap do |player|
2507
+ player.shields.build
2508
+ player.shields.first.save!
2509
+ end
2510
+ end
2511
+
2512
+ let(:unpersisted) { player.shields.first }
2513
+
2514
+ before do
2515
+ Player.find(player.id).shields.unset(:after_default_player)
2516
+ end
2517
+
2518
+ let(:from_db) do
2519
+ Player.find(player.id).shields.first
2520
+ end
2521
+
2522
+ include_examples 'accesses the correct parent'
2523
+ end
2524
+ end
2525
+ end
2526
+
2527
+ context "when accessing associations in defaults" do
2528
+ context "when not using autobuilding" do
2529
+ let(:band) { InterceptableBand.create(name: "Molejo") }
2530
+ let(:song) { band.songs.create(name: "Cilada") }
2531
+
2532
+ it "assigns the default correctly" do
2533
+ expect(song.band_name).to eq("Molejo")
2534
+ end
2535
+ end
2536
+
2537
+ context "when using autobuilding" do
2538
+ before do
2539
+ InterceptablePlane.create!.tap do |plane|
2540
+ plane.wings.create!
2541
+ end
2542
+ end
2543
+
2544
+ let(:plane) { InterceptablePlane.first }
2545
+ let(:wing) { InterceptableWing.first }
2546
+ let(:engine) { wing.engine }
2547
+
2548
+ it "sets the defaults correctly" do
2549
+ expect(wing._id).to eq("hello-wing")
2550
+ expect(wing.p_id).to eq(plane._id.to_s)
2551
+ expect(wing.e_id).to eq(engine._id.to_s)
2552
+ expect(engine._id).to eq("hello-engine-#{wing.id}")
2553
+ end
2554
+ end
2555
+ end
2556
+
2557
+ # This case is rather niche. The _ids method used to use the `.only` method
2558
+ # to get only the _ids for an association, which was causing a
2559
+ # MissingAttributeError to be raised when accessing another association. This
2560
+ # was fixed by using `.pluck` over `.only`. Look at MONGOID-5306 for a more
2561
+ # detailed explanation.
2562
+ context "when accessing _ids in validate and access an association in after_initialize" do
2563
+ it "doesn't raise a MissingAttributeError" do
2564
+ company = InterceptableCompany.create!
2565
+ shop = InterceptableShop.create!(company: company)
2566
+ user = InterceptableUser.new
2567
+ user.company = company
2568
+ expect do
2569
+ user.save!
2570
+ end.to_not raise_error(ActiveModel::MissingAttributeError)
2571
+ end
2572
+ end
2573
+
2574
+ context "when around callbacks for embedded are disabled" do
2575
+ config_override :around_callbacks_for_embeds, false
2576
+
2577
+ context "when around callback is defined" do
2578
+ let(:registry) { InterceptableSpec::CallbackRegistry.new }
2579
+
2580
+ let(:parent) do
2581
+ InterceptableSpec::CbEmbedsOneParent.new(registry).tap do |parent|
2582
+ parent.child = InterceptableSpec::CbEmbedsOneChild.new(registry)
2583
+ end
2584
+ end
2585
+
2586
+ before do
2587
+ expect(Mongoid.logger).to receive(:warn).with(/Around callbacks are disabled for embedded documents/).twice.and_call_original
2588
+ expect(Mongoid.logger).to receive(:warn).with(/To enable around callbacks for embedded documents/).twice.and_call_original
2589
+ end
2590
+
2591
+ it "logs a warning" do
2592
+ parent.save!
2593
+ end
1792
2594
  end
1793
2595
  end
1794
2596
  end