mongoid 7.5.4 → 8.1.6

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 +33 -13
  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 +10 -6
  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 +5 -4
  206. data/lib/mongoid/utils.rb +22 -0
  207. data/lib/mongoid/validatable/associated.rb +96 -18
  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 +13 -16
  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 +15 -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 +13 -30
  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
@@ -1,12 +1,17 @@
1
1
  class Galaxy
2
2
  include Mongoid::Document
3
+ include Mongoid::Timestamps
3
4
 
4
5
  field :age, type: Integer
5
-
6
+ field :was_touched, type: Mongoid::Boolean, default: false
6
7
  before_validation :set_age
7
8
 
8
9
  embeds_many :stars
9
10
 
11
+ set_callback(:touch, :before) do |document|
12
+ self.was_touched = true
13
+ end
14
+
10
15
  private
11
16
 
12
17
  def set_age
@@ -16,15 +21,21 @@ end
16
21
 
17
22
  class Star
18
23
  include Mongoid::Document
24
+ include Mongoid::Timestamps
19
25
 
20
26
  embedded_in :galaxy
21
27
 
22
28
  field :age, type: Integer
29
+ field :was_touched_after_parent, type: Mongoid::Boolean, default: false
23
30
 
24
31
  before_validation :set_age
25
32
 
26
33
  embeds_many :planets
27
34
 
35
+ set_callback(:touch, :before) do |document|
36
+ self.was_touched_after_parent = true if galaxy.was_touched
37
+ end
38
+
28
39
  private
29
40
 
30
41
  def set_age
@@ -34,13 +45,19 @@ end
34
45
 
35
46
  class Planet
36
47
  include Mongoid::Document
48
+ include Mongoid::Timestamps
37
49
 
38
50
  embedded_in :star
39
51
 
40
52
  field :age, type: Integer
53
+ field :was_touched_after_parent, type: Mongoid::Boolean, default: false
41
54
 
42
55
  before_validation :set_age
43
56
 
57
+ set_callback(:touch, :before) do |document|
58
+ self.was_touched_after_parent = true if star.was_touched_after_parent
59
+ end
60
+
44
61
  private
45
62
 
46
63
  def set_age
@@ -59,3 +76,117 @@ class Emission
59
76
 
60
77
  attr_reader :previous
61
78
  end
79
+
80
+ class Country
81
+ include Mongoid::Document
82
+
83
+ field :age
84
+
85
+ before_validation :set_age
86
+
87
+ embeds_one :president
88
+
89
+ private
90
+
91
+ def set_age
92
+ self.age ||= 245
93
+ end
94
+ end
95
+
96
+ class President
97
+ include Mongoid::Document
98
+
99
+ embedded_in :country
100
+
101
+ field :age
102
+
103
+ field :name
104
+
105
+ before_validation :set_age
106
+
107
+ embeds_one :first_spouse
108
+
109
+ private
110
+
111
+ def set_age
112
+ self.age ||= 79
113
+ end
114
+ end
115
+
116
+ class FirstSpouse
117
+ include Mongoid::Document
118
+
119
+ embedded_in :president
120
+
121
+ field :name
122
+ field :age, type: Integer
123
+
124
+ before_validation :set_age
125
+
126
+ private
127
+
128
+ def set_age
129
+ self.age ||= 70
130
+ end
131
+ end
132
+
133
+ class Architect
134
+ include Mongoid::Document
135
+
136
+ has_and_belongs_to_many :buildings, after_add: :after_add_callback,
137
+ after_remove: :after_remove_callback, dependent: :nullify
138
+
139
+ field :after_add_num_buildings, type: Integer
140
+ field :after_remove_num_buildings, type: Integer
141
+
142
+ def after_add_callback(obj)
143
+ self.after_add_num_buildings = self.buildings.length
144
+ end
145
+
146
+ def after_remove_callback(obj)
147
+ self.after_remove_num_buildings = self.buildings.length
148
+ end
149
+ end
150
+
151
+ class Building
152
+ include Mongoid::Document
153
+
154
+ has_and_belongs_to_many :architects, dependent: :nullify
155
+ end
156
+
157
+ class Root
158
+ include Mongoid::Document
159
+ embeds_many :embedded_once, cascade_callbacks: true
160
+ after_save :trace
161
+
162
+ attr_accessor :logger
163
+
164
+ def trace
165
+ logger << :root
166
+ end
167
+ end
168
+
169
+ class EmbeddedOnce
170
+ include Mongoid::Document
171
+ embeds_many :embedded_twice, cascade_callbacks: true
172
+ embedded_in :root
173
+ after_save :trace
174
+
175
+ attr_accessor :logger
176
+
177
+ def trace
178
+ logger << :embedded_once
179
+ end
180
+ end
181
+
182
+ class EmbeddedTwice
183
+ include Mongoid::Document
184
+ embedded_in :embedded_once
185
+ after_save :trace
186
+
187
+ attr_accessor :logger
188
+
189
+ def trace
190
+ logger << :embedded_twice
191
+ end
192
+ end
@@ -188,8 +188,6 @@ describe 'callbacks integration tests' do
188
188
  end
189
189
 
190
190
  it 'persists the attribute value' do
191
- pending 'MONGOID-4476'
192
-
193
191
  Galaxy.find(instance.id).stars.first.planets.first.age.should == 2_000
194
192
  end
195
193
  end
@@ -211,18 +209,397 @@ describe 'callbacks integration tests' do
211
209
  end
212
210
  end
213
211
  end
212
+
213
+ context 'when updating top-level embeds_one document via #update_attributes!' do
214
+ let!(:instance) do
215
+ Country.create!
216
+ end
217
+
218
+ context 'embedded document' do
219
+ shared_examples 'persists the attribute value' do
220
+ it 'writes the attribute value into the model' do
221
+ instance.president.age.should == 79
222
+ end
223
+
224
+ it 'persists the attribute value' do
225
+ Country.find(instance.id).president.age.should == 79
226
+ end
227
+ end
228
+
229
+ context 'set as a document instance' do
230
+ before do
231
+ instance.update_attributes!(president: President.new)
232
+ end
233
+
234
+ include_examples 'persists the attribute value'
235
+ end
236
+
237
+ context 'set as attributes on parent' do
238
+ before do
239
+ instance.update_attributes!(president: { name: "Abraham Lincoln" })
240
+ end
241
+
242
+ include_examples 'persists the attribute value'
243
+ end
244
+ end
245
+
246
+ context 'nested embedded document' do
247
+ shared_examples 'persists the attribute value' do
248
+ it 'writes the attribute value into the model' do
249
+ instance.president.first_spouse.age.should == 70
250
+ end
251
+
252
+ it 'persists the attribute value' do
253
+ Country.find(instance.id).president.first_spouse.age.should == 70
254
+ end
255
+ end
256
+
257
+ context 'set as a document instance' do
258
+ before do
259
+ instance.update_attributes!(president: President.new(first_spouse: FirstSpouse.new))
260
+ end
261
+
262
+ include_examples 'persists the attribute value'
263
+ end
264
+
265
+ context 'set as attributes on parent' do
266
+ before do
267
+ instance.update_attributes!(president: { first_spouse: { name: "Mary Todd Lincoln" } })
268
+ end
269
+
270
+ include_examples 'persists the attribute value'
271
+ end
272
+ end
273
+ end
214
274
  end
215
275
 
216
276
  context 'attribute_was value in after_save callback' do
217
277
  let!(:obj) { Emission.create!(frequency: 1) }
218
278
 
219
279
  it 'is set to the new value' do
220
- pending 'MONGOID-5104'
221
-
222
280
  obj.frequency = 2
223
281
  obj.save!
224
282
 
225
283
  obj.previous.should == 2
226
284
  end
227
285
  end
286
+
287
+ context 'atomic_selector in after_save callback' do
288
+ let(:name) do
289
+ 'Alice'
290
+ end
291
+
292
+ let(:new_name) do
293
+ 'Bob'
294
+ end
295
+
296
+ class CBIntSpecProfile
297
+ include Mongoid::Document
298
+ field :name, type: String
299
+ shard_key :name
300
+
301
+ attr_reader :atomic_selector_in_after_save
302
+
303
+ after_save do |document|
304
+ @atomic_selector_in_after_save = document.atomic_selector
305
+ end
306
+ end
307
+
308
+ it 'has updated attributes' do
309
+ profile = CBIntSpecProfile.create!(name: name)
310
+ profile.name = new_name
311
+ profile.save!
312
+ expect(
313
+ profile.atomic_selector_in_after_save['name']
314
+ ).to eq(new_name)
315
+ end
316
+ end
317
+
318
+ context "When touching an embedded document" do
319
+ let(:planet) { Planet.new }
320
+ let(:star) { Star.new }
321
+ let(:galaxy) { Galaxy.create! }
322
+
323
+ before do
324
+ star.planets << planet
325
+ galaxy.stars << star
326
+ end
327
+
328
+ it "the parent document touch callback gets called before the child" do
329
+ planet.touch
330
+ expect(galaxy.was_touched).to be true
331
+ expect(star.was_touched_after_parent).to be true
332
+ expect(planet.was_touched_after_parent).to be true
333
+ end
334
+ end
335
+
336
+ context "when reloading has_and_belongs_to_many after_save and after_remove callbacks" do
337
+
338
+ let(:architect) { Architect.create }
339
+
340
+ let(:b1) { Building.create }
341
+
342
+ let(:b2) { Building.create }
343
+
344
+ let(:b3) { Building.create }
345
+
346
+ it "counts added/removed buildings correctly" do
347
+ architect.buildings << b1
348
+ expect(architect.after_add_num_buildings).to eq(1)
349
+
350
+ architect.reload
351
+ architect.buildings << b2
352
+ expect(architect.after_add_num_buildings).to eq(2)
353
+
354
+ architect.reload
355
+ architect.buildings << b3
356
+ expect(architect.after_add_num_buildings).to eq(3)
357
+
358
+ architect.reload
359
+ architect.buildings.delete(b3)
360
+ expect(architect.after_remove_num_buildings).to eq(2)
361
+ end
362
+ end
363
+
364
+ context '_previously was methods in after_save callback' do
365
+ let(:title) do
366
+ "Title"
367
+ end
368
+
369
+ let(:updated_title) do
370
+ "Updated title"
371
+ end
372
+
373
+ let(:age) do
374
+ 10
375
+ end
376
+
377
+ it do
378
+ class PreviouslyWasPerson
379
+ include Mongoid::Document
380
+
381
+ field :title, type: String
382
+ field :age, type: Integer
383
+
384
+ attr_reader :after_save_vals
385
+
386
+ set_callback :save, :after do |doc|
387
+ @after_save_vals ||= []
388
+ @after_save_vals << [doc.title_previously_was, doc.age_previously_was]
389
+ end
390
+ end
391
+
392
+ person = PreviouslyWasPerson.create!(title: title, age: age)
393
+ person.title = updated_title
394
+ person.save!
395
+ expect(person.after_save_vals).to eq([
396
+ # Field values are nil before create
397
+ [nil, nil],
398
+ [title, age]
399
+ ])
400
+ end
401
+ end
402
+
403
+ context 'previously_new_record? in after_save' do
404
+ it do
405
+ class PreviouslyNewRecordPerson
406
+ include Mongoid::Document
407
+
408
+ field :title, type: String
409
+ field :age, type: Integer
410
+
411
+ attr_reader :previously_new_record_value
412
+
413
+ set_callback :save, :after do |doc|
414
+ @previously_new_record_value = doc.previously_new_record?
415
+ end
416
+ end
417
+
418
+ person = PreviouslyNewRecordPerson.create!(title: "title", age: 55)
419
+ expect(person.previously_new_record_value).to be_truthy
420
+ person.title = "New title"
421
+ person.save!
422
+ expect(person.previously_new_record_value).to be_falsey
423
+ end
424
+ end
425
+
426
+ context 'previously_persisted? in after_destroy' do
427
+ it do
428
+ class PreviouslyPersistedPerson
429
+ include Mongoid::Document
430
+
431
+ field :title, type: String
432
+ field :age, type: Integer
433
+
434
+ attr_reader :previously_persisted_value
435
+
436
+ set_callback :destroy, :after do |doc|
437
+ @previously_persisted_value = doc.previously_persisted?
438
+ end
439
+ end
440
+
441
+ unsaved_person = PreviouslyPersistedPerson.new(title: "title", age: 55)
442
+ unsaved_person.destroy
443
+ expect(unsaved_person.previously_persisted_value).to be_falsey
444
+
445
+ saved_person = PreviouslyPersistedPerson.create(title: "title", age: 55)
446
+ saved_person.destroy
447
+ expect(saved_person.previously_persisted_value).to be_truthy
448
+ end
449
+ end
450
+
451
+ context 'saved_change_to_attribute, attribute_before_last_save, will_save_change_to_attribute' do
452
+ class TestSCTAAndABLSInCallbacks
453
+ include Mongoid::Document
454
+
455
+ field :name, type: String
456
+ field :age, type: Integer
457
+
458
+ set_callback :save, :before do |doc|
459
+ [:name, :age].each do |attr|
460
+ saved_change_to_attribute_values_before[attr] += [saved_change_to_attribute(attr)]
461
+ attribute_before_last_save_values_before[attr] += [attribute_before_last_save(attr)]
462
+ will_save_change_to_attribute_values_before[attr] += [will_save_change_to_attribute?(attr)]
463
+ end
464
+ end
465
+
466
+ set_callback :save, :after do |doc|
467
+ [:name, :age].each do |attr|
468
+ saved_change_to_attribute_values_after[attr] += [saved_change_to_attribute(attr)]
469
+ saved_change_to_attribute_q_values_after[attr] += [saved_change_to_attribute?(attr)]
470
+ attribute_before_last_save_values_after[attr] += [attribute_before_last_save(attr)]
471
+ end
472
+ end
473
+
474
+ def saved_change_to_attribute_values_before
475
+ @saved_change_to_attribute_values_before ||= Hash.new do
476
+ []
477
+ end
478
+ end
479
+
480
+ def attribute_before_last_save_values_before
481
+ @attribute_before_last_save_values_before ||= Hash.new do
482
+ []
483
+ end
484
+ end
485
+
486
+ def saved_change_to_attribute_values_after
487
+ @saved_change_to_attribute_values_after ||= Hash.new do
488
+ []
489
+ end
490
+ end
491
+
492
+ def saved_change_to_attribute_q_values_after
493
+ @saved_change_to_attribute_q_values_after ||= Hash.new do
494
+ []
495
+ end
496
+ end
497
+
498
+ def attribute_before_last_save_values_after
499
+ @attribute_before_last_save_values_after ||= Hash.new do
500
+ []
501
+ end
502
+ end
503
+
504
+ def will_save_change_to_attribute_values_before
505
+ @will_save_change_to_attribute_values_before ||= Hash.new do
506
+ []
507
+ end
508
+ end
509
+ end
510
+
511
+ it 'reproduces ActiveRecord::AttributeMethods::Dirty behavior' do
512
+ subject = TestSCTAAndABLSInCallbacks.new(name: 'Name 1')
513
+ subject.save!
514
+ subject.age = 18
515
+ subject.save!
516
+ subject.name = 'Name 2'
517
+ subject.save!
518
+
519
+ expect(subject.saved_change_to_attribute_values_before).to eq(
520
+ {
521
+ :name => [nil, [nil, "Name 1"], nil],
522
+ :age => [nil, nil, [nil, 18]],
523
+ }
524
+ )
525
+ expect(subject.saved_change_to_attribute_values_after).to eq(
526
+ {
527
+ :name => [[nil, "Name 1"], nil, ["Name 1", "Name 2"]],
528
+ :age => [nil, [nil, 18], nil],
529
+ }
530
+ )
531
+ expect(subject.saved_change_to_attribute_q_values_after).to eq(
532
+ {
533
+ :name => [true, false, true],
534
+ :age => [false, true, false],
535
+ }
536
+ )
537
+ expect(subject.attribute_before_last_save_values_before).to eq(
538
+ {
539
+ :name => [nil, nil, "Name 1"],
540
+ :age => [nil, nil, nil]
541
+ }
542
+ )
543
+ expect(subject.attribute_before_last_save_values_after).to eq(
544
+ {
545
+ :name => [nil, "Name 1", "Name 1"],
546
+ :age => [nil, nil, 18]
547
+ }
548
+ )
549
+ expect(subject.will_save_change_to_attribute_values_before).to eq(
550
+ {
551
+ :name => [true, false, true],
552
+ :age => [false, true, false]
553
+ }
554
+ )
555
+ end
556
+ end
557
+
558
+ context 'nested embedded documents' do
559
+ config_override :prevent_multiple_calls_of_embedded_callbacks, true
560
+ config_override :around_callbacks_for_embeds, true
561
+
562
+ let(:logger) { Array.new }
563
+
564
+ let(:root) do
565
+ Root.new(
566
+ embedded_once: [
567
+ EmbeddedOnce.new(
568
+ embedded_twice: [EmbeddedTwice.new]
569
+ )
570
+ ]
571
+ )
572
+ end
573
+
574
+ before(:each) do
575
+ root.logger = logger
576
+ root.embedded_once.first.logger = logger
577
+ root.embedded_once.first.embedded_twice.first.logger = logger
578
+ end
579
+
580
+ it 'runs callbacks in the correct order' do
581
+ root.save!
582
+ expect(logger).to eq(%i[embedded_twice embedded_once root])
583
+ end
584
+ end
585
+
586
+ context 'cascade callbacks' do
587
+ ruby_version_gte '3.0'
588
+ config_override :around_callbacks_for_embeds, false
589
+
590
+ let(:book) do
591
+ Book.new
592
+ end
593
+
594
+ before do
595
+ 1500.times do
596
+ book.pages.build
597
+ end
598
+ end
599
+
600
+ # https://jira.mongodb.org/browse/MONGOID-5658
601
+ it 'does not raise SystemStackError' do
602
+ expect { book.save! }.not_to raise_error(SystemStackError)
603
+ end
604
+ end
228
605
  end
@@ -7,11 +7,15 @@ describe 'Queries with Range criteria' do
7
7
  let(:now_in_zone) { now_utc.in_time_zone('Asia/Tokyo') }
8
8
  let(:today) { Date.new(2020, 1, 1) }
9
9
 
10
+ let(:labels) do
11
+ [ Label.new(age: 12), Label.new(age: 16) ]
12
+ end
13
+
10
14
  let!(:band1) { Band.create!(likes: 0, rating: 0.9, founded: today, updated_at: now_utc) }
11
15
  let!(:band2) { Band.create!(likes: 1, rating: 1.0, founded: today + 1.day, updated_at: now_utc + 1.days) }
12
16
  let!(:band3) { Band.create!(likes: 2, rating: 2.9, founded: today + 2.days, updated_at: now_utc + 2.days) }
13
17
  let!(:band4) { Band.create!(likes: 3, rating: 3.0, founded: today + 3.days, updated_at: now_utc + 3.days) }
14
- let!(:band5) { Band.create!(likes: 4, rating: 3.1, founded: today + 4.days, updated_at: now_utc + 4.days) }
18
+ let!(:band5) { Band.create!(likes: 4, rating: 3.1, founded: today + 4.days, updated_at: now_utc + 4.days, labels: labels) }
15
19
 
16
20
  context 'Range<Integer> criteria vs Integer field' do
17
21
 
@@ -262,4 +266,94 @@ describe 'Queries with Range criteria' do
262
266
  end
263
267
  end
264
268
  end
269
+
270
+ context 'Range<Integer> criteria vs embedded Integer field' do
271
+
272
+ it 'returns objects within the range' do
273
+ expect(Band.where("labels.age" => 10..18).to_a).to eq [band5]
274
+ expect(Band.where("labels.age" => 13...16).to_a).to eq []
275
+ end
276
+
277
+ it "does not return objects out of range" do
278
+ expect(Band.where("labels.age" => 13..14).to_a).to eq []
279
+ end
280
+
281
+ context 'endless range' do
282
+ ruby_version_gte '2.6'
283
+
284
+ it 'returns all objects above the value' do
285
+ expect(Band.where("labels.age": eval('1..')).to_a).to eq [band5]
286
+ end
287
+
288
+ it 'does not return the objects under the value' do
289
+ expect(Band.where("labels.age": eval('100..')).to_a).to eq []
290
+ end
291
+ end
292
+
293
+ context 'beginless range' do
294
+ ruby_version_gte '2.7'
295
+
296
+ it 'returns all objects under the value' do
297
+ expect(Band.where("labels.age": eval('..16')).to_a).to eq [band5]
298
+ end
299
+ it 'does not return the objects above the value' do
300
+ expect(Band.where("labels.age": eval('...12')).to_a).to eq []
301
+ end
302
+ end
303
+ end
304
+
305
+ context 'Range<Integer> criteria vs Array<Integer>' do
306
+ let!(:band6) { Band.create!(genres: [12, 16]) }
307
+
308
+ it 'returns objects within the range' do
309
+ expect(Band.where("genres" => 10..18).to_a).to eq [band6]
310
+ end
311
+
312
+ it "does not return objects out of range" do
313
+ expect(Band.where("genres" => 13..14).to_a).to eq []
314
+ end
315
+ end
316
+
317
+ context 'Range<Integer> criteria vs aliased Array<Integer>' do
318
+ let!(:person) { Person.create!(array: [12, 16]) }
319
+
320
+ it 'returns objects within the range' do
321
+ expect(Person.where("array" => 10..18).to_a).to eq [person]
322
+ end
323
+
324
+ it "does not return objects out of range" do
325
+ expect(Person.where("array" => 13..14).to_a).to eq []
326
+ end
327
+ end
328
+
329
+ context 'Range<Integer> criteria vs Array<Hash<Symbol, Integer>>' do
330
+ let!(:band6) { Band.create!(genres: [{x: 12}, {x: 16}]) }
331
+
332
+ it 'returns objects within the range' do
333
+ expect(Band.where("genres.x" => 10..18).to_a).to eq [band6]
334
+ end
335
+
336
+ it "does not return objects out of range" do
337
+ expect(Band.where("genres.x" => 13..14).to_a).to eq []
338
+ end
339
+ end
340
+
341
+ context 'Range<Integer> criteria vs aliased/doubly embedded Integer' do
342
+ let!(:person) do
343
+ Person.create!(passport: Passport.new).tap do |b|
344
+ b.passport.passport_pages.create!(num_stamps: 12)
345
+ b.passport.passport_pages.create!(num_stamps: 16)
346
+ end
347
+ end
348
+
349
+ config_override :broken_alias_handling, false
350
+
351
+ it 'returns objects within the range' do
352
+ expect(Person.where("passport.passport_pages.num_stamps" => 10..18).to_a).to eq [person]
353
+ end
354
+
355
+ it "does not return objects out of range" do
356
+ expect(Person.where("passport.passport_pages.num_stamps" => 13..14).to_a).to eq []
357
+ end
358
+ end
265
359
  end