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
@@ -383,10 +383,11 @@ describe Mongoid::Criteria do
383
383
  Person.create!
384
384
  end
385
385
 
386
- context "when no eager loading is involved" do
386
+ context "when the query cache is enabled" do
387
+ query_cache_enabled
387
388
 
388
389
  let(:criteria) do
389
- Person.all.cache
390
+ Person.all
390
391
  end
391
392
 
392
393
  before do
@@ -394,17 +395,19 @@ describe Mongoid::Criteria do
394
395
  end
395
396
 
396
397
  it "does not hit the database after first iteration" do
397
- expect(criteria.context.view).to receive(:each).never
398
- criteria.each do |doc|
399
- expect(doc).to eq(person)
398
+ expect_no_queries do
399
+ criteria.each do |doc|
400
+ expect(doc).to eq(person)
401
+ end
400
402
  end
401
403
  end
402
404
  end
403
405
 
404
406
  context "when the criteria is eager loading" do
407
+ query_cache_enabled
405
408
 
406
409
  let(:criteria) do
407
- Person.includes(:posts).cache
410
+ Person.includes(:posts)
408
411
  end
409
412
 
410
413
  before do
@@ -412,9 +415,10 @@ describe Mongoid::Criteria do
412
415
  end
413
416
 
414
417
  it "does not hit the database after first iteration" do
415
- expect(criteria.context.view).to receive(:each).never
416
- criteria.each do |doc|
417
- expect(doc).to eq(person)
418
+ expect_no_queries do
419
+ criteria.each do |doc|
420
+ expect(doc).to eq(person)
421
+ end
418
422
  end
419
423
  end
420
424
  end
@@ -491,17 +495,6 @@ describe Mongoid::Criteria do
491
495
  end
492
496
  end
493
497
 
494
- describe "#cache" do
495
-
496
- let(:criteria) do
497
- Band.where(name: "Depeche Mode")
498
- end
499
-
500
- it "sets the cache option to true" do
501
- expect(criteria.cache).to be_cached
502
- end
503
- end
504
-
505
498
  describe "#context" do
506
499
 
507
500
  context "when the model is embedded" do
@@ -837,8 +830,8 @@ describe Mongoid::Criteria do
837
830
  end
838
831
  end
839
832
 
840
- context "when given a Proc" do
841
- it "behaves as Enumerable" do
833
+ context "when given a Proc without a block" do
834
+ it "raises an error" do
842
835
  lambda do
843
836
  criteria.find(-> {"default"})
844
837
  # Proc is not serializable to a BSON type
@@ -1000,7 +993,7 @@ describe Mongoid::Criteria do
1000
993
  it "deletes the document from the database" do
1001
994
  expect {
1002
995
  depeche.reload
1003
- }.to raise_error(Mongoid::Errors::DocumentNotFound)
996
+ }.to raise_error(Mongoid::Errors::DocumentNotFound, /Document\(s\) not found for class Band with id\(s\)/)
1004
997
  end
1005
998
  end
1006
999
  end
@@ -1172,1173 +1165,65 @@ describe Mongoid::Criteria do
1172
1165
  end
1173
1166
  end
1174
1167
 
1175
- context "when providing empty strings" do
1176
-
1177
- let(:criteria) do
1178
- Person.send(method, preference_ids: [ id, "" ])
1179
- end
1180
-
1181
- it "returns the matching documents" do
1182
- expect(criteria).to eq([ match_one ])
1183
- end
1184
- end
1185
-
1186
- context "when providing nils" do
1187
-
1188
- context "when the relation is a many to many" do
1189
-
1190
- let(:criteria) do
1191
- Person.send(method, preference_ids: [ id, nil ])
1192
- end
1193
-
1194
- it "returns the matching documents" do
1195
- expect(criteria).to eq([ match_one ])
1196
- end
1197
- end
1198
-
1199
- context "when the relation is a one to one" do
1200
-
1201
- let!(:game) do
1202
- Game.create!
1203
- end
1204
-
1205
- let(:criteria) do
1206
- Game.send(method, person_id: [ nil ])
1207
- end
1208
-
1209
- it "returns the matching documents" do
1210
- expect(criteria).to eq([ game ])
1211
- end
1212
- end
1213
- end
1214
- end
1215
- end
1216
- end
1217
-
1218
- describe "#initialize" do
1219
-
1220
- let(:criteria) do
1221
- described_class.new(Band)
1222
- end
1223
-
1224
- it "sets the class" do
1225
- expect(criteria.klass).to eq(Band)
1226
- end
1227
-
1228
- it "sets the aliased fields" do
1229
- expect(criteria.aliased_fields).to eq(Band.aliased_fields)
1230
- end
1231
-
1232
- it "sets the serializers" do
1233
- expect(criteria.serializers).to eq(Band.fields)
1234
- end
1235
- end
1236
-
1237
- describe "#includes" do
1238
-
1239
- let!(:person) do
1240
- Person.create!(age: 1)
1241
- end
1242
-
1243
- context "when providing a name that is not a relation" do
1244
-
1245
- it "raises an error" do
1246
- expect {
1247
- Person.includes(:members)
1248
- }.to raise_error(Mongoid::Errors::InvalidIncludes)
1249
- end
1250
- end
1251
-
1252
- context "when providing one association" do
1253
-
1254
- let!(:user) do
1255
- User.create!(posts: [ post1 ])
1256
- end
1257
-
1258
- let!(:post1) do
1259
- Post.create!
1260
- end
1261
-
1262
- let(:result) do
1263
- User.includes(:posts).first
1264
- end
1265
-
1266
- it "executes the query" do
1267
- expect(result).to eq(user)
1268
- end
1269
-
1270
- it "includes the related objects" do
1271
- expect(result.posts).to eq([ post1 ])
1272
- end
1273
- end
1274
-
1275
- context "when providing a list of associations" do
1276
-
1277
- let!(:user) do
1278
- User.create!(posts: [ post1 ], descriptions: [ description1 ])
1279
- end
1280
-
1281
- let!(:post1) do
1282
- Post.create!
1283
- end
1284
-
1285
- let!(:description1) do
1286
- Description.create!(details: 1)
1287
- end
1288
-
1289
- let(:result) do
1290
- User.includes(:posts, :descriptions).first
1291
- end
1292
-
1293
- it "executes the query" do
1294
- expect(result).to eq(user)
1295
- end
1296
-
1297
- it "includes the related objects" do
1298
- expect(result.posts).to eq([ post1 ])
1299
- expect(result.descriptions).to eq([ description1 ])
1300
- end
1301
- end
1302
-
1303
- context "when providing a nested association" do
1304
-
1305
- let!(:user) do
1306
- User.create!
1307
- end
1308
-
1309
- before do
1310
- p = Post.create!(alerts: [ Alert.create! ])
1311
- user.posts = [ p ]
1312
- user.save!
1313
- end
1314
-
1315
- let(:result) do
1316
- User.includes(:posts => [:alerts]).first
1317
- end
1318
-
1319
- it "executes the query" do
1320
- expect(result).to eq(user)
1321
- end
1322
-
1323
- it "includes the related objects" do
1324
- expect(result.posts.size).to eq(1)
1325
- expect(result.posts.first.alerts.size).to eq(1)
1326
- end
1327
- end
1328
-
1329
- context "when providing a deeply nested association" do
1330
-
1331
- let!(:user) do
1332
- User.create!
1333
- end
1334
-
1335
- let(:results) do
1336
- User.includes(:posts => [{ :alerts => :items }]).to_a
1337
- end
1338
-
1339
- it "executes the query" do
1340
- expect(results.first).to eq(user)
1341
- end
1342
- end
1343
-
1344
- context "when the models are inherited" do
1345
-
1346
- before(:all) do
1347
- class A
1348
- include Mongoid::Document
1349
- end
1350
-
1351
- class B < A
1352
- belongs_to :c
1353
- end
1354
-
1355
- class C
1356
- include Mongoid::Document
1357
- has_one :b
1358
- end
1359
- end
1360
-
1361
- after(:all) do
1362
- Object.send(:remove_const, :A)
1363
- Object.send(:remove_const, :B)
1364
- Object.send(:remove_const, :C)
1365
- end
1366
-
1367
- context "when the includes is on the subclass" do
1368
-
1369
- let!(:c_one) do
1370
- C.create!
1371
- end
1372
-
1373
- let!(:c_two) do
1374
- C.create!
1375
- end
1376
-
1377
- let!(:b) do
1378
- B.create!(c: c_two)
1379
- end
1380
-
1381
- let!(:results) do
1382
- C.includes(:b).to_a.detect do |c|
1383
- c.id == c_two.id
1384
- end
1385
- end
1386
-
1387
- it "returns the correct documents" do
1388
- expect(results).to eq(c_two)
1389
- end
1390
-
1391
- it "does not query the db" do
1392
- expect_query(0) do
1393
- results.b
1394
- end
1395
- end
1396
- end
1397
- end
1398
-
1399
- context "when the models are inherited from another one model" do
1400
-
1401
- context "when the relation is a has_one" do
1402
-
1403
- before(:all) do
1404
- class A
1405
- include Mongoid::Document
1406
- end
1407
-
1408
- class B < A
1409
- belongs_to :d
1410
- end
1411
-
1412
- class C < A
1413
- belongs_to :d
1414
- end
1415
-
1416
- class D
1417
- include Mongoid::Document
1418
- has_one :b
1419
- has_one :c
1420
- end
1421
- end
1422
-
1423
- after(:all) do
1424
- Object.send(:remove_const, :A)
1425
- Object.send(:remove_const, :B)
1426
- Object.send(:remove_const, :C)
1427
- Object.send(:remove_const, :D)
1428
- end
1429
-
1430
- context "when the includes is on the several relations" do
1431
-
1432
- let!(:d_one) do
1433
- D.create!
1434
- end
1435
-
1436
- let!(:d_two) do
1437
- D.create!
1438
- end
1439
-
1440
- let!(:b) do
1441
- B.create!(d: d_two)
1442
- end
1443
-
1444
- let!(:c) do
1445
- C.create!(d: d_two)
1446
- end
1447
-
1448
- let!(:results) do
1449
- D.includes(:b, :c).entries.detect do |d|
1450
- d.id == d_two.id
1451
- end
1452
- end
1453
-
1454
- it "returns the correct documents" do
1455
- expect(results).to eq(d_two)
1456
- end
1457
-
1458
- it "does not query the db on b" do
1459
- expect_query(0) do
1460
- results.b
1461
- end
1462
- end
1463
-
1464
- it "does not query the db on c" do
1465
- expect_query(0) do
1466
- results.b
1467
- end
1468
- end
1469
- end
1470
- end
1471
-
1472
- context "when the relation is a has_many" do
1473
-
1474
- before(:all) do
1475
- class A
1476
- include Mongoid::Document
1477
- end
1478
-
1479
- class B < A
1480
- belongs_to :d
1481
- end
1482
-
1483
- class C < A
1484
- belongs_to :d
1485
- end
1486
-
1487
- class D
1488
- include Mongoid::Document
1489
- has_many :b
1490
- has_many :c
1491
- end
1492
- end
1493
-
1494
- after(:all) do
1495
- Object.send(:remove_const, :A)
1496
- Object.send(:remove_const, :B)
1497
- Object.send(:remove_const, :C)
1498
- Object.send(:remove_const, :D)
1499
- end
1500
-
1501
- context "when the includes is on the several relations" do
1502
-
1503
- let!(:d_one) do
1504
- D.create!
1505
- end
1506
-
1507
- let!(:d_two) do
1508
- D.create!
1509
- end
1510
-
1511
- let!(:bs) do
1512
- 2.times.map { B.create!(d: d_two) }
1513
- end
1514
-
1515
- let!(:cs) do
1516
- 2.times.map { C.create!(d: d_two) }
1517
- end
1518
-
1519
- let!(:results) do
1520
- D.includes(:b, :c).entries.detect do |d|
1521
- d.id == d_two.id
1522
- end
1523
- end
1524
-
1525
- it "returns the correct documents" do
1526
- expect(results).to eq(d_two)
1527
- end
1528
-
1529
- it "does not query the db on b" do
1530
- expect_query(0) do
1531
- results.b
1532
- end
1533
- end
1534
-
1535
- it "does not query the db on c" do
1536
- expect_query(0) do
1537
- results.b
1538
- end
1539
- end
1540
- end
1541
- end
1542
- end
1543
-
1544
- context "when including the same association multiple times" do
1545
-
1546
- let(:criteria) do
1547
- Person.all.includes(:posts, :posts).includes(:posts)
1548
- end
1549
-
1550
- let(:association) do
1551
- Person.reflect_on_association(:posts)
1552
- end
1553
-
1554
- it "does not duplicate the association in the inclusions" do
1555
- expect(criteria.inclusions).to eq([ association ])
1556
- end
1557
- end
1558
-
1559
- context "when mapping the results more than once" do
1560
-
1561
- let!(:post) do
1562
- person.posts.create!(title: "one")
1563
- end
1564
-
1565
- let(:criteria) do
1566
- Post.includes(:person)
1567
- end
1568
-
1569
- let!(:results) do
1570
- criteria.map { |doc| doc }
1571
- criteria.map { |doc| doc }
1572
- end
1573
-
1574
- it "returns the proper results" do
1575
- expect(results.first.title).to eq("one")
1576
- end
1577
- end
1578
-
1579
- context "when including a belongs to relation" do
1580
-
1581
- context "when the criteria is from the root" do
1582
-
1583
- let!(:person_two) do
1584
- Person.create!(age: 2)
1585
- end
1586
-
1587
- let!(:post_one) do
1588
- person.posts.create!(title: "one")
1589
- end
1590
-
1591
- let!(:post_two) do
1592
- person_two.posts.create!(title: "two")
1593
- end
1594
-
1595
- context "when calling first" do
1596
-
1597
- let(:criteria) do
1598
- Post.includes(:person)
1599
- end
1600
-
1601
- let!(:document) do
1602
- criteria.first
1603
- end
1604
-
1605
- it "eager loads the first document" do
1606
- expect_query(0) do
1607
- expect(document.person).to eq(person)
1608
- end
1609
- end
1610
-
1611
- it "returns the first document" do
1612
- expect(document).to eq(post_one)
1613
- end
1614
- end
1615
-
1616
- context "when calling last" do
1617
-
1618
- let!(:criteria) do
1619
- Post.asc(:_id).includes(:person)
1620
- end
1621
-
1622
- let!(:document) do
1623
- criteria.last
1624
- end
1625
-
1626
- it "eager loads the last document" do
1627
- expect_query(0) do
1628
- expect(document.person).to eq(person_two)
1629
- end
1630
- end
1631
-
1632
- it "returns the last document" do
1633
- expect(document).to eq(post_two)
1634
- end
1635
- end
1636
- end
1637
-
1638
- context "when the criteria is from an embedded relation" do
1639
-
1640
- let(:peep) do
1641
- Person.create!
1642
- end
1643
-
1644
- let!(:address_one) do
1645
- peep.addresses.create!(street: "rosenthaler")
1646
- end
1647
-
1648
- let!(:address_two) do
1649
- peep.addresses.create!(street: "weinmeister")
1650
- end
1651
-
1652
- let!(:depeche) do
1653
- Band.create!(name: "Depeche Mode")
1654
- end
1655
-
1656
- let!(:tool) do
1657
- Band.create!(name: "Tool")
1658
- end
1659
-
1660
- before do
1661
- address_one.band = depeche
1662
- address_two.band = tool
1663
- address_one.save!
1664
- address_two.save!
1665
- end
1666
-
1667
- context "when calling first" do
1668
-
1669
- let(:criteria) do
1670
- peep.reload.addresses.includes(:band)
1671
- end
1672
-
1673
- let(:context) do
1674
- criteria.context
1675
- end
1676
-
1677
- let!(:document) do
1678
- criteria.first
1679
- end
1680
-
1681
- it "eager loads the first document" do
1682
- expect_query(0) do
1683
- expect(document.band).to eq(depeche)
1684
- end
1685
- end
1686
-
1687
- it "returns the document" do
1688
- expect(document).to eq(address_one)
1689
- end
1690
- end
1691
-
1692
- context "when calling last" do
1693
-
1694
- let(:criteria) do
1695
- peep.reload.addresses.includes(:band)
1696
- end
1697
-
1698
- let(:context) do
1699
- criteria.context
1700
- end
1701
-
1702
- let!(:document) do
1703
- criteria.last
1704
- end
1705
-
1706
- it "eager loads the last document" do
1707
- expect_query(0) do
1708
- expect(document.band).to eq(tool)
1709
- end
1710
- end
1711
-
1712
- it "returns the document" do
1713
- expect(document).to eq(address_two)
1714
- end
1715
- end
1716
-
1717
- context "when iterating all documents" do
1718
-
1719
- let(:criteria) do
1720
- peep.reload.addresses.includes(:band)
1721
- end
1722
-
1723
- let(:context) do
1724
- criteria.context
1725
- end
1726
-
1727
- let!(:documents) do
1728
- criteria.to_a
1729
- end
1730
-
1731
- it "eager loads the first document" do
1732
- expect_query(0) do
1733
- expect(documents.first.band).to eq(depeche)
1734
- end
1735
- end
1736
-
1737
- it "eager loads the last document" do
1738
- expect_query(0) do
1739
- expect(documents.last.band).to eq(tool)
1740
- end
1741
- end
1742
-
1743
- it "returns the documents" do
1744
- expect(documents).to eq([ address_one, address_two ])
1745
- end
1746
- end
1747
- end
1748
- end
1749
-
1750
- context "when providing inclusions to the default scope" do
1751
-
1752
- before do
1753
- Person.default_scope(->{ Person.includes(:posts) })
1754
- end
1755
-
1756
- after do
1757
- Person.default_scoping = nil
1758
- end
1759
-
1760
- let!(:post_one) do
1761
- person.posts.create!(title: "one")
1762
- end
1763
-
1764
- let!(:post_two) do
1765
- person.posts.create!(title: "two")
1766
- end
1767
-
1768
- context "when the criteria has no options" do
1769
-
1770
- let!(:criteria) do
1771
- Person.asc(:age).all
1772
- end
1773
-
1774
- let!(:documents) do
1775
- criteria.entries
1776
- end
1777
-
1778
- it "returns the correct documents" do
1779
- expect(documents).to eq([ person ])
1780
- end
1781
-
1782
- it "eager loads the first document" do
1783
- expect_query(0) do
1784
- expect(documents.first.posts.first).to eq(post_one)
1785
- end
1786
- end
1787
-
1788
- it "eager loads the last document" do
1789
- expect_query(0) do
1790
- expect(documents.first.posts.last).to eq(post_two)
1791
- end
1792
- end
1793
-
1794
- context "when executing the query twice" do
1795
-
1796
- let!(:new_criteria) do
1797
- Person.where(id: person.id)
1798
- end
1799
-
1800
- let!(:new_context) do
1801
- new_criteria.context
1802
- end
1803
-
1804
- before do
1805
- expect(new_context).to receive(:eager_load).with([person]).once.and_call_original
1806
- end
1807
-
1808
- let!(:from_db) do
1809
- new_criteria.first
1810
- end
1811
-
1812
- it "does not duplicate documents in the relation" do
1813
- expect(person.posts.size).to eq(2)
1814
- end
1815
- end
1816
- end
1817
-
1818
- context "when calling first on the criteria" do
1819
-
1820
- let(:criteria) do
1821
- Person.asc(:age).all
1822
- end
1823
-
1824
- let!(:from_db) do
1825
- criteria.first
1826
- end
1827
-
1828
- it "returns the correct documents" do
1829
- expect(from_db).to eq(person)
1830
- end
1831
-
1832
- it "eager loads the first document" do
1833
- expect_query(0) do
1834
- expect(from_db.posts.first).to eq(post_one)
1835
- end
1836
- end
1837
-
1838
- it "eager loads the last document" do
1839
- expect_query(0) do
1840
- expect(from_db.posts.last).to eq(post_two)
1841
- end
1842
- end
1843
- end
1844
-
1845
- context "when calling last on the criteria" do
1846
-
1847
- let(:criteria) do
1848
- Person.asc(:age).all
1849
- end
1850
-
1851
- let!(:context) do
1852
- criteria.context
1853
- end
1854
-
1855
- before do
1856
- expect(context).to receive(:eager_load).with([person]).once.and_call_original
1857
- end
1858
-
1859
- let!(:from_db) do
1860
- criteria.last
1861
- end
1862
-
1863
- it "returns the correct documents" do
1864
- expect(from_db).to eq(person)
1865
- end
1866
-
1867
- it "eager loads the first document" do
1868
- expect_query(0) do
1869
- expect(from_db.posts.first).to eq(post_one)
1870
- end
1871
- end
1872
-
1873
- it "eager loads the last document" do
1874
- expect_query(0) do
1875
- expect(from_db.posts.last).to eq(post_two)
1876
- end
1877
- end
1878
- end
1879
-
1880
- context "when the criteria has limiting options" do
1881
-
1882
- let!(:person_two) do
1883
- Person.create!
1884
- end
1885
-
1886
- let!(:post_three) do
1887
- person_two.posts.create!(title: "three")
1888
- end
1889
-
1890
- let!(:criteria) do
1891
- Person.asc(:age).limit(1)
1892
- end
1893
-
1894
- let!(:documents) do
1895
- criteria.entries
1896
- end
1897
-
1898
- it "returns the correct documents" do
1899
- expect(criteria).to eq([ person ])
1900
- end
1901
-
1902
- it "eager loads the first document" do
1903
- expect_query(0) do
1904
- expect(documents.first.posts.first).to eq(post_one)
1905
- end
1906
- end
1907
-
1908
- it "eager loads the second document" do
1909
- expect_query(0) do
1910
- expect(documents.first.posts.last).to eq(post_two)
1911
- end
1912
- end
1913
- end
1914
- end
1915
-
1916
- context "when including a has and belongs to many" do
1917
-
1918
- let!(:preference_one) do
1919
- person.preferences.create!(name: "one")
1920
- end
1921
-
1922
- let!(:preference_two) do
1923
- person.preferences.create!(name: "two")
1924
- end
1925
-
1926
- context "when one of the related items is deleted" do
1927
-
1928
- before do
1929
- person.preferences = [ preference_one, preference_two ]
1930
- preference_two.delete
1931
- end
1932
-
1933
- let(:criteria) do
1934
- Person.where(id: person.id).includes(:preferences)
1935
- end
1936
-
1937
- it "only loads the existing related items" do
1938
- expect(criteria.entries.first.preferences).to eq([ preference_one ])
1939
- end
1940
- end
1941
-
1942
- context "when the criteria has no options" do
1943
-
1944
- let!(:criteria) do
1945
- Person.asc(:age).includes(:preferences)
1946
- end
1947
-
1948
- let!(:documents) do
1949
- criteria.entries
1950
- end
1951
-
1952
- it "returns the correct documents" do
1953
- expect(documents).to eq([ person ])
1954
- end
1955
-
1956
- it "eager loads the first document" do
1957
- expect_query(0) do
1958
- expect(documents.first.preferences.first).to eq(preference_one)
1959
- end
1960
- end
1961
-
1962
- it "eager loads the last document" do
1963
- expect_query(0) do
1964
- expect(documents.first.preferences.last).to eq(preference_two)
1965
- end
1966
- end
1967
- end
1968
-
1969
- context "when calling first on the criteria" do
1970
-
1971
- let!(:criteria) do
1972
- Person.asc(:age).includes(:preferences)
1973
- end
1974
-
1975
- let!(:from_db) do
1976
- criteria.first
1977
- end
1978
-
1979
- it "returns the correct documents" do
1980
- expect(from_db).to eq(person)
1981
- end
1982
-
1983
- it "eager loads the first document" do
1984
- expect_query(0) do
1985
- expect(from_db.preferences.first).to eq(preference_one)
1986
- end
1987
- end
1988
-
1989
- it "eager loads the last document" do
1990
- expect_query(0) do
1991
- expect(from_db.preferences.last).to eq(preference_two)
1992
- end
1993
- end
1994
- end
1995
-
1996
- context "when calling last on the criteria" do
1997
-
1998
- let!(:criteria) do
1999
- Person.asc(:age).includes(:preferences)
2000
- end
2001
-
2002
- let!(:from_db) do
2003
- criteria.last
2004
- end
2005
-
2006
- it "returns the correct documents" do
2007
- expect(from_db).to eq(person)
2008
- end
2009
-
2010
- it "eager loads the first document" do
2011
- expect_query(0) do
2012
- expect(from_db.preferences.first).to eq(preference_one)
2013
- end
2014
- end
2015
-
2016
- it "eager loads the last document" do
2017
- expect_query(0) do
2018
- expect(from_db.preferences.last).to eq(preference_two)
2019
- end
2020
- end
2021
- end
2022
- end
2023
-
2024
- context "when including a has many" do
2025
-
2026
- let!(:post_one) do
2027
- person.posts.create!(title: "one")
2028
- end
2029
-
2030
- let!(:post_two) do
2031
- person.posts.create!(title: "two")
2032
- end
2033
-
2034
- context "when the criteria has no options" do
2035
-
2036
- let!(:criteria) do
2037
- Person.asc(:age).includes(:posts)
2038
- end
2039
-
2040
- let!(:documents) do
2041
- criteria.entries
2042
- end
2043
-
2044
- it "returns the correct documents" do
2045
- expect(documents).to eq([ person ])
2046
- end
2047
-
2048
- it "eager loads the first document" do
2049
- expect_query(0) do
2050
- expect(documents.first.posts.first).to eq(post_one)
2051
- end
2052
- end
2053
-
2054
- it "eager loads the last document" do
2055
- expect_query(0) do
2056
- expect(documents.first.posts.last).to eq(post_two)
2057
- end
2058
- end
2059
- end
2060
-
2061
- context "when calling first on the criteria" do
2062
-
2063
- let!(:criteria) do
2064
- Person.asc(:age).includes(:posts)
2065
- end
2066
-
2067
- let!(:from_db) do
2068
- criteria.first
2069
- end
2070
-
2071
- it "returns the correct documents" do
2072
- expect(from_db).to eq(person)
2073
- end
2074
-
2075
- context "when subsequently getting all documents" do
2076
-
2077
- let!(:documents) do
2078
- criteria.entries
2079
- end
2080
-
2081
- it "returns the correct documents" do
2082
- expect(documents).to eq([ person ])
2083
- end
2084
- end
2085
- end
2086
-
2087
- context "when calling last on the criteria" do
2088
-
2089
- let!(:criteria) do
2090
- Person.asc(:age).includes(:posts)
2091
- end
2092
-
2093
- let!(:from_db) do
2094
- criteria.last
2095
- end
2096
-
2097
- it "returns the correct documents" do
2098
- expect(from_db).to eq(person)
2099
- end
2100
-
2101
- context "when subsequently getting all documents" do
2102
-
2103
- let!(:documents) do
2104
- criteria.entries
2105
- end
2106
-
2107
- it "returns the correct documents" do
2108
- expect(documents).to eq([ person ])
2109
- end
2110
- end
2111
- end
2112
-
2113
- context "when the criteria has limiting options" do
2114
-
2115
- let!(:person_two) do
2116
- Person.create!
2117
- end
2118
-
2119
- let!(:post_three) do
2120
- person_two.posts.create!(title: "three")
2121
- end
2122
-
2123
- let!(:criteria) do
2124
- Person.includes(:posts).asc(:age).limit(1)
2125
- end
2126
-
2127
- let(:context) do
2128
- criteria.context
2129
- end
2130
-
2131
- before do
2132
- expect(context).to receive(:eager_load).with([ person ]).once.and_call_original
2133
- end
2134
-
2135
- let!(:documents) do
2136
- criteria.entries
2137
- end
2138
-
2139
- it "returns the correct documents" do
2140
- expect(documents).to eq([ person ])
2141
- end
2142
- end
2143
- end
2144
-
2145
- context "when including a has one" do
2146
-
2147
- let!(:game_one) do
2148
- person.create_game(name: "one")
2149
- end
2150
-
2151
- let!(:game_two) do
2152
- person.create_game(name: "two")
2153
- end
2154
-
2155
- context "when the criteria has no options" do
2156
-
2157
- let!(:criteria) do
2158
- Person.asc(:age).includes(:game)
2159
- end
2160
-
2161
- let(:context) do
2162
- criteria.context
2163
- end
2164
-
2165
- before do
2166
- expect(context).to receive(:eager_load).with([ person ]).once.and_call_original
2167
- end
2168
-
2169
- let!(:documents) do
2170
- criteria.entries
2171
- end
2172
-
2173
- it "returns the correct documents" do
2174
- expect(documents).to eq([ person ])
2175
- end
2176
- end
2177
-
2178
- context "when the criteria has limiting options" do
2179
-
2180
- let!(:person_two) do
2181
- Person.create!(age: 2)
2182
- end
2183
-
2184
- let!(:game_three) do
2185
- person_two.create_game(name: "Skyrim")
2186
- end
2187
-
2188
- let!(:criteria) do
2189
- Person.where(id: person.id).includes(:game).asc(:age).limit(1)
2190
- end
2191
-
2192
- let(:context) do
2193
- criteria.context
2194
- end
2195
-
2196
- before do
2197
- expect(context).to receive(:eager_load).with([ person ]).once.and_call_original
2198
- end
2199
-
2200
- let!(:documents) do
2201
- criteria.entries
2202
- end
2203
-
2204
- it "returns the correct documents" do
2205
- expect(documents).to eq([ person ])
2206
- end
2207
- end
2208
- end
2209
-
2210
- context "when including a belongs to" do
2211
-
2212
- let(:person_two) do
2213
- Person.create!(age: 2)
2214
- end
2215
-
2216
- let!(:game_one) do
2217
- person.create_game(name: "one")
2218
- end
2219
-
2220
- let!(:game_two) do
2221
- person_two.create_game(name: "two")
2222
- end
2223
-
2224
- context "when providing no options" do
2225
-
2226
- let!(:criteria) do
2227
- Game.includes(:person)
2228
- end
2229
-
2230
- let(:context) do
2231
- criteria.context
2232
- end
2233
-
2234
- before do
2235
- expect(context).to receive(:preload).twice.and_call_original
2236
- end
2237
-
2238
- let!(:documents) do
2239
- criteria.entries
2240
- end
2241
-
2242
- it "returns the correct documents" do
2243
- expect(criteria).to eq([ game_one, game_two ])
2244
- end
2245
- end
2246
-
2247
- context "when the criteria has limiting options" do
2248
-
2249
- let!(:criteria) do
2250
- Game.where(id: game_one.id).includes(:person).asc(:_id).limit(1)
2251
- end
2252
-
2253
- let(:context) do
2254
- criteria.context
2255
- end
2256
-
2257
- before do
2258
- expect(context).to receive(:eager_load).with([ game_one ]).once.and_call_original
2259
- end
2260
-
2261
- let!(:documents) do
2262
- criteria.entries
2263
- end
2264
-
2265
- it "returns the correct documents" do
2266
- expect(documents).to eq([ game_one ])
2267
- end
2268
- end
2269
- end
2270
-
2271
- context "when including multiples in the same criteria" do
2272
-
2273
- let!(:post_one) do
2274
- person.posts.create!(title: "one")
2275
- end
2276
-
2277
- let!(:post_two) do
2278
- person.posts.create!(title: "two")
2279
- end
2280
-
2281
- let!(:game_one) do
2282
- person.create_game(name: "one")
2283
- end
1168
+ context "when providing empty strings" do
2284
1169
 
2285
- let!(:game_two) do
2286
- person.create_game(name: "two")
2287
- end
1170
+ let(:criteria) do
1171
+ Person.send(method, preference_ids: [ id, "" ])
1172
+ end
2288
1173
 
2289
- let!(:criteria) do
2290
- Person.includes(:posts, :game).asc(:age)
2291
- end
1174
+ it "returns the matching documents" do
1175
+ expect(criteria).to eq([ match_one ])
1176
+ end
1177
+ end
2292
1178
 
2293
- let(:context) do
2294
- criteria.context
2295
- end
1179
+ context "when providing nils" do
2296
1180
 
2297
- before do
2298
- expect(context).to receive(:preload).twice.and_call_original
2299
- end
1181
+ context "when the relation is a many to many" do
2300
1182
 
2301
- let!(:documents) do
2302
- criteria.entries
2303
- end
1183
+ let(:criteria) do
1184
+ Person.send(method, preference_ids: [ id, nil ])
1185
+ end
2304
1186
 
2305
- it "returns the correct documents" do
2306
- expect(criteria).to eq([ person ])
2307
- end
2308
- end
2309
- end
1187
+ it "returns the matching documents" do
1188
+ expect(criteria).to eq([ match_one ])
1189
+ end
1190
+ end
2310
1191
 
2311
- describe "#inclusions" do
1192
+ context "when the relation is a one to one" do
2312
1193
 
2313
- let(:criteria) do
2314
- Band.includes(:records)
2315
- end
1194
+ let!(:game) do
1195
+ Game.create!
1196
+ end
2316
1197
 
2317
- let(:association) do
2318
- Band.relations["records"]
2319
- end
1198
+ let(:criteria) do
1199
+ Game.send(method, person_id: [ nil ])
1200
+ end
2320
1201
 
2321
- it "returns the inclusions" do
2322
- expect(criteria.inclusions).to eq([ association ])
1202
+ it "returns the matching documents" do
1203
+ expect(criteria).to eq([ game ])
1204
+ end
1205
+ end
1206
+ end
1207
+ end
2323
1208
  end
2324
1209
  end
2325
1210
 
2326
- describe "#inclusions=" do
1211
+ describe "#initialize" do
2327
1212
 
2328
1213
  let(:criteria) do
2329
- Band.all
1214
+ described_class.new(Band)
2330
1215
  end
2331
1216
 
2332
- let(:association) do
2333
- Band.relations["records"]
1217
+ it "sets the class" do
1218
+ expect(criteria.klass).to eq(Band)
2334
1219
  end
2335
1220
 
2336
- before do
2337
- criteria.inclusions = [ association ]
1221
+ it "sets the aliased fields" do
1222
+ expect(criteria.aliased_fields).to eq(Band.aliased_fields)
2338
1223
  end
2339
1224
 
2340
- it "sets the inclusions" do
2341
- expect(criteria.inclusions).to eq([ association ])
1225
+ it "sets the serializers" do
1226
+ expect(criteria.serializers).to eq(Band.fields)
2342
1227
  end
2343
1228
  end
2344
1229
 
@@ -3047,7 +1932,7 @@ describe Mongoid::Criteria do
3047
1932
  end
3048
1933
 
3049
1934
  with_config_values :legacy_pluck_distinct, true, false do
3050
- it "returns a array with nil values" do
1935
+ it "returns an array with nil values" do
3051
1936
  expect(plucked).to eq([nil, nil, nil])
3052
1937
  end
3053
1938
  end
@@ -3060,7 +1945,7 @@ describe Mongoid::Criteria do
3060
1945
  end
3061
1946
 
3062
1947
  with_config_values :legacy_pluck_distinct, true, false do
3063
- it "returns a nil arrays" do
1948
+ it "returns an array of arrays with nil values" do
3064
1949
  expect(plucked).to eq([[nil, nil], [nil, nil], [nil, nil]])
3065
1950
  end
3066
1951
  end
@@ -3068,6 +1953,7 @@ describe Mongoid::Criteria do
3068
1953
  end
3069
1954
 
3070
1955
  context 'when plucking a localized field' do
1956
+ with_default_i18n_configs
3071
1957
 
3072
1958
  before do
3073
1959
  I18n.locale = :en
@@ -3077,10 +1963,6 @@ describe Mongoid::Criteria do
3077
1963
  d.save!
3078
1964
  end
3079
1965
 
3080
- after do
3081
- I18n.locale = :en
3082
- end
3083
-
3084
1966
  context 'when plucking the entire field' do
3085
1967
  let(:plucked) do
3086
1968
  Dictionary.all.pluck(:description)
@@ -3176,15 +2058,8 @@ describe Mongoid::Criteria do
3176
2058
  context 'when fallbacks are enabled with a locale list' do
3177
2059
  require_fallbacks
3178
2060
 
3179
- around(:all) do |example|
3180
- prev_fallbacks = I18n.fallbacks.dup
2061
+ before do
3181
2062
  I18n.fallbacks[:he] = [ :en ]
3182
- example.run
3183
- I18n.fallbacks = prev_fallbacks
3184
- end
3185
-
3186
- after do
3187
- I18n.locale = :en
3188
2063
  end
3189
2064
 
3190
2065
  let(:plucked) do
@@ -3212,6 +2087,8 @@ describe Mongoid::Criteria do
3212
2087
  end
3213
2088
 
3214
2089
  context "when the localized field is embedded" do
2090
+ with_default_i18n_configs
2091
+
3215
2092
  before do
3216
2093
  p = Passport.new
3217
2094
  I18n.locale = :en
@@ -3222,10 +2099,6 @@ describe Mongoid::Criteria do
3222
2099
  Person.create!(passport: p, employer_id: 12345)
3223
2100
  end
3224
2101
 
3225
- after do
3226
- I18n.locale = :en
3227
- end
3228
-
3229
2102
  let(:plucked) do
3230
2103
  Person.where(employer_id: 12345).pluck("pass.name").first
3231
2104
  end
@@ -3281,18 +2154,45 @@ describe Mongoid::Criteria do
3281
2154
  context "when legacy_pluck_distinct is set" do
3282
2155
  config_override :legacy_pluck_distinct, true
3283
2156
 
3284
- it "does not demongoize the field" do
3285
- expect(plucked.first).to be_a(String)
3286
- expect(plucked.first).to eq("1E2")
2157
+ context 'when value is stored as string' do
2158
+ config_override :map_big_decimal_to_decimal128, false
2159
+
2160
+ it "does not demongoize the field" do
2161
+ expect(plucked.first).to be_a(String)
2162
+ expect(plucked.first).to eq("1E2")
2163
+ end
2164
+ end
2165
+
2166
+ context 'when value is stored as decimal128' do
2167
+ config_override :map_big_decimal_to_decimal128, true
2168
+ max_bson_version '4.99.99'
2169
+
2170
+ it "does not demongoize the field" do
2171
+ expect(plucked.first).to be_a(BSON::Decimal128)
2172
+ expect(plucked.first).to eq(BSON::Decimal128.new("1E2"))
2173
+ end
3287
2174
  end
3288
2175
  end
3289
2176
 
3290
2177
  context "when legacy_pluck_distinct is not set" do
3291
2178
  config_override :legacy_pluck_distinct, false
3292
2179
 
3293
- it "demongoizes the field" do
3294
- expect(plucked.first).to be_a(BigDecimal)
3295
- expect(plucked.first).to eq(BigDecimal("1E2"))
2180
+ context 'when value is stored as string' do
2181
+ config_override :map_big_decimal_to_decimal128, false
2182
+
2183
+ it "demongoizes the field" do
2184
+ expect(plucked.first).to be_a(BigDecimal)
2185
+ expect(plucked.first).to eq(BigDecimal("1E2"))
2186
+ end
2187
+ end
2188
+
2189
+ context 'when value is stored as decimal128' do
2190
+ config_override :map_big_decimal_to_decimal128, true
2191
+
2192
+ it "demongoizes the field" do
2193
+ expect(plucked.first).to be_a(BigDecimal)
2194
+ expect(plucked.first).to eq(BigDecimal("1E2"))
2195
+ end
3296
2196
  end
3297
2197
  end
3298
2198
  end
@@ -3305,9 +2205,11 @@ describe Mongoid::Criteria do
3305
2205
 
3306
2206
  context "when legacy_pluck_distinct is set" do
3307
2207
  config_override :legacy_pluck_distinct, true
2208
+ config_override :map_big_decimal_to_decimal128, true
2209
+ max_bson_version '4.99.99'
3308
2210
 
3309
2211
  it "returns a hash with a non-demongoized field" do
3310
- expect(plucked.first).to eq({ 'sales' => "1E2" })
2212
+ expect(plucked.first).to eq({ 'sales' => BSON::Decimal128.new('1E+2') })
3311
2213
  end
3312
2214
  end
3313
2215
 
@@ -3315,7 +2217,7 @@ describe Mongoid::Criteria do
3315
2217
  config_override :legacy_pluck_distinct, false
3316
2218
 
3317
2219
  it "demongoizes the field" do
3318
- expect(plucked.first).to eq(BigDecimal("1E2"))
2220
+ expect(plucked).to eq([ BigDecimal("1E2") ])
3319
2221
  end
3320
2222
  end
3321
2223
  end
@@ -3328,9 +2230,11 @@ describe Mongoid::Criteria do
3328
2230
 
3329
2231
  context "when legacy_pluck_distinct is set" do
3330
2232
  config_override :legacy_pluck_distinct, true
2233
+ config_override :map_big_decimal_to_decimal128, true
2234
+ max_bson_version '4.99.99'
3331
2235
 
3332
2236
  it "returns a hash with a non-demongoized field" do
3333
- expect(plucked.first).to eq([{ 'sales' => "1E2" }])
2237
+ expect(plucked.first).to eq([{ 'sales' => BSON::Decimal128.new('1E+2') }])
3334
2238
  end
3335
2239
  end
3336
2240
 
@@ -3338,7 +2242,7 @@ describe Mongoid::Criteria do
3338
2242
  config_override :legacy_pluck_distinct, false
3339
2243
 
3340
2244
  it "demongoizes the field" do
3341
- expect(plucked.first).to eq([BigDecimal("1E2")])
2245
+ expect(plucked.first).to eq([ BigDecimal("1E2") ])
3342
2246
  end
3343
2247
  end
3344
2248
  end
@@ -3365,6 +2269,66 @@ describe Mongoid::Criteria do
3365
2269
  end
3366
2270
  end
3367
2271
  end
2272
+
2273
+ context "when tallying deeply nested arrays/embedded associations" do
2274
+
2275
+ before do
2276
+ Person.create!(addresses: [ Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 2 } } ]))) ])
2277
+ Person.create!(addresses: [ Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 2 } } ]))) ])
2278
+ Person.create!(addresses: [ Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 3 } } ]))) ])
2279
+ end
2280
+
2281
+ let(:plucked) do
2282
+ Person.pluck("addresses.code.deepest.array.y.z")
2283
+ end
2284
+
2285
+ it "returns the correct hash" do
2286
+ expect(plucked).to eq([
2287
+ [ [ 1, 2 ] ], [ [ 1, 2 ] ], [ [ 1, 3 ] ]
2288
+ ])
2289
+ end
2290
+ end
2291
+ end
2292
+
2293
+ describe "#pick" do
2294
+
2295
+ let!(:depeche) do
2296
+ Band.create!(name: "Depeche Mode", likes: 3)
2297
+ end
2298
+
2299
+ let!(:tool) do
2300
+ Band.create!(name: "Tool", likes: 3)
2301
+ end
2302
+
2303
+ context "when picking a field" do
2304
+
2305
+ let(:criteria) do
2306
+ Band.all
2307
+ end
2308
+
2309
+ let(:picked) do
2310
+ criteria.pick(:name)
2311
+ end
2312
+
2313
+ it "returns one element" do
2314
+ expect(picked).to eq("Depeche Mode")
2315
+ end
2316
+ end
2317
+
2318
+ context "when picking multiple fields" do
2319
+
2320
+ let(:criteria) do
2321
+ Band.all
2322
+ end
2323
+
2324
+ let(:picked) do
2325
+ criteria.pick(:name, :likes)
2326
+ end
2327
+
2328
+ it "returns an array" do
2329
+ expect(picked).to eq([ "Depeche Mode", 3 ])
2330
+ end
2331
+ end
3368
2332
  end
3369
2333
 
3370
2334
  describe "#respond_to?" do
@@ -3740,20 +2704,109 @@ describe Mongoid::Criteria do
3740
2704
 
3741
2705
  context "when querying on a big decimal" do
3742
2706
 
3743
- let(:sales) do
3744
- BigDecimal('0.1')
2707
+ context 'when map_big_decimal_to_decimal128 is false' do
2708
+ config_override :map_big_decimal_to_decimal128, false
2709
+
2710
+ let(:sales) do
2711
+ BigDecimal('0.1')
2712
+ end
2713
+
2714
+ let!(:band) do
2715
+ Band.create!(name: "Boards of Canada", sales: sales)
2716
+ end
2717
+
2718
+ let(:from_db) do
2719
+ Band.where(sales: sales).first
2720
+ end
2721
+
2722
+ it "finds the document by the big decimal value" do
2723
+ expect(from_db).to eq(band)
2724
+ end
3745
2725
  end
3746
2726
 
3747
- let!(:band) do
3748
- Band.create!(name: "Boards of Canada", sales: sales)
2727
+ context 'when map_big_decimal_to_decimal128 is true' do
2728
+ config_override :map_big_decimal_to_decimal128, true
2729
+
2730
+ let(:sales) do
2731
+ BigDecimal('0.1')
2732
+ end
2733
+
2734
+ let!(:band) do
2735
+ Band.create!(name: "Boards of Canada", sales: sales)
2736
+ end
2737
+
2738
+ let(:from_db) do
2739
+ Band.where(sales: sales).first
2740
+ end
2741
+
2742
+ it "finds the document by the big decimal value" do
2743
+ expect(from_db).to eq(band)
2744
+ end
3749
2745
  end
3750
2746
 
3751
- let(:from_db) do
3752
- Band.where(sales: sales).first
2747
+ context 'when map_big_decimal_to_decimal128 was false and is now true' do
2748
+ config_override :map_big_decimal_to_decimal128, false
2749
+
2750
+ let(:sales) do
2751
+ BigDecimal('0.1')
2752
+ end
2753
+
2754
+ let!(:band) do
2755
+ Mongoid.map_big_decimal_to_decimal128 = false
2756
+ Band.create!(name: "Boards of Canada", sales: sales)
2757
+ end
2758
+
2759
+ let(:from_db) do
2760
+ Mongoid.map_big_decimal_to_decimal128 = true
2761
+ Band.where(sales: sales.to_s).first
2762
+ end
2763
+
2764
+ it "finds the document by the big decimal value" do
2765
+ expect(from_db).to eq(band)
2766
+ end
3753
2767
  end
2768
+ end
3754
2769
 
3755
- it "finds the document by the big decimal value" do
3756
- expect(from_db).to eq(band)
2770
+ context "when querying on a big decimal from a dynamic field" do
2771
+
2772
+ context 'when map_big_decimal_to_decimal128 is false' do
2773
+ config_override :map_big_decimal_to_decimal128, false
2774
+
2775
+ let(:fans) do
2776
+ BigDecimal('139432.0002')
2777
+ end
2778
+
2779
+ let!(:band) do
2780
+ Band.create!(name: "Boards of Canada", fans: fans)
2781
+ end
2782
+
2783
+ let(:from_db) do
2784
+ Band.where(fans: fans.to_s).first
2785
+ end
2786
+
2787
+ it "finds the document by the big decimal value" do
2788
+ expect(from_db).to eq(band)
2789
+ end
2790
+ end
2791
+
2792
+ context 'when map_big_decimal_to_decimal128 is true' do
2793
+ config_override :map_big_decimal_to_decimal128, true
2794
+
2795
+ let(:fans) do
2796
+ BigDecimal('139432.0002')
2797
+ end
2798
+
2799
+ let!(:band) do
2800
+ Band.create!(name: "Boards of Canada", fans: fans)
2801
+ end
2802
+
2803
+ let(:from_db) do
2804
+ Band.where(fans: fans).first
2805
+ end
2806
+
2807
+ it "only finds the document by the string value" do
2808
+ expect(from_db).to eq(band)
2809
+ end
3757
2810
  end
3758
2811
  end
3759
2812
 
@@ -3858,6 +2911,217 @@ describe Mongoid::Criteria do
3858
2911
  expect(dup_criteria.selector).to eq({ "_id" => _id })
3859
2912
  end
3860
2913
  end
2914
+
2915
+ context "when querying an embedded field" do
2916
+ let(:criteria) { Band.where("label.name": 12345) }
2917
+
2918
+ it "mongoizes the embedded field in the selector" do
2919
+ expect(criteria.selector).to eq("label.name" => "12345")
2920
+ end
2921
+ end
2922
+
2923
+ context "when querying with a range" do
2924
+
2925
+ context "when querying an embeds_many association" do
2926
+ let(:criteria) do
2927
+ Band.where("labels" => 10..15)
2928
+ end
2929
+
2930
+ it "correctly uses elemMatch without an inner key" do
2931
+ expect(criteria.selector).to eq(
2932
+ "labels" => {
2933
+ "$elemMatch" => { "$gte" => 10, "$lte" => 15 }
2934
+ }
2935
+ )
2936
+ end
2937
+ end
2938
+
2939
+ context "when querying an element in an embeds_many association" do
2940
+ let(:criteria) do
2941
+ Band.where("labels.age" => 10..15)
2942
+ end
2943
+
2944
+ it "correctly uses elemMatch" do
2945
+ expect(criteria.selector).to eq(
2946
+ "labels" => {
2947
+ "$elemMatch" => {
2948
+ "age" => { "$gte" => 10, "$lte" => 15 }
2949
+ }
2950
+ }
2951
+ )
2952
+ end
2953
+ end
2954
+
2955
+ context "when querying a field of type array" do
2956
+ let(:criteria) do
2957
+ Band.where("genres" => 10..15)
2958
+ end
2959
+
2960
+ it "correctly uses elemMatch without an inner key" do
2961
+ expect(criteria.selector).to eq(
2962
+ "genres" => {
2963
+ "$elemMatch" => { "$gte" => 10, "$lte" => 15 }
2964
+ }
2965
+ )
2966
+ end
2967
+ end
2968
+
2969
+ context "when querying an aliased field of type array" do
2970
+ let(:criteria) do
2971
+ Person.where("array" => 10..15)
2972
+ end
2973
+
2974
+ it "correctly uses the aliased field and elemMatch" do
2975
+ expect(criteria.selector).to eq(
2976
+ "a" => {
2977
+ "$elemMatch" => { "$gte" => 10, "$lte" => 15 }
2978
+ }
2979
+ )
2980
+ end
2981
+ end
2982
+
2983
+ context "when querying a field inside an array" do
2984
+ let(:criteria) do
2985
+ Band.where("genres.age" => 10..15)
2986
+ end
2987
+
2988
+ it "correctly uses elemMatch" do
2989
+ expect(criteria.selector).to eq(
2990
+ "genres" => {
2991
+ "$elemMatch" => {
2992
+ "age" => { "$gte" => 10, "$lte" => 15 }
2993
+ }
2994
+ }
2995
+ )
2996
+ end
2997
+ end
2998
+
2999
+ context "when there are no embeds_manys or Arrays" do
3000
+ let(:criteria) do
3001
+ Band.where("fans.info.age" => 10..15)
3002
+ end
3003
+
3004
+ it "does not use elemMatch" do
3005
+ expect(criteria.selector).to eq(
3006
+ "fans.info.age" => { "$gte" => 10, "$lte" => 15 }
3007
+ )
3008
+ end
3009
+ end
3010
+
3011
+ context "when querying a nested element in an embeds_many association" do
3012
+ let(:criteria) do
3013
+ Band.where("labels.age.number" => 10..15)
3014
+ end
3015
+
3016
+ it "correctly uses elemMatch" do
3017
+ expect(criteria.selector).to eq(
3018
+ "labels" => {
3019
+ "$elemMatch" => {
3020
+ "age.number" => { "$gte" => 10, "$lte" => 15 }
3021
+ }
3022
+ }
3023
+ )
3024
+ end
3025
+ end
3026
+
3027
+ context "when querying a nested element in an Array" do
3028
+ let(:criteria) do
3029
+ Band.where("genres.name.length" => 10..15)
3030
+ end
3031
+
3032
+ it "correctly uses elemMatch" do
3033
+ expect(criteria.selector).to eq(
3034
+ "genres" => {
3035
+ "$elemMatch" => {
3036
+ "name.length" => { "$gte" => 10, "$lte" => 15 }
3037
+ }
3038
+ }
3039
+ )
3040
+ end
3041
+ end
3042
+
3043
+ context "when querying a nested element in a nested embeds_many association" do
3044
+ context "when the outer association is an embeds_many" do
3045
+ let(:criteria) do
3046
+ Band.where("records.tracks.name.length" => 10..15)
3047
+ end
3048
+
3049
+ it "correctly uses elemMatch" do
3050
+ expect(criteria.selector).to eq(
3051
+ "records.tracks" => {
3052
+ "$elemMatch" => {
3053
+ "name.length" => { "$gte" => 10, "$lte" => 15 }
3054
+ }
3055
+ }
3056
+ )
3057
+ end
3058
+ end
3059
+
3060
+ context "when the outer association is an embeds_one" do
3061
+ let(:criteria) do
3062
+ Person.where("name.translations.language.length" => 10..15)
3063
+ end
3064
+
3065
+ it "correctly uses elemMatch" do
3066
+ expect(criteria.selector).to eq(
3067
+ "name.translations" => {
3068
+ "$elemMatch" => {
3069
+ "language.length" => { "$gte" => 10, "$lte" => 15 }
3070
+ }
3071
+ }
3072
+ )
3073
+ end
3074
+ end
3075
+ end
3076
+
3077
+ context "when querying a deeply nested array" do
3078
+ let(:criteria) do
3079
+ Person.where("addresses.code.deepest.array.element.item" => 10..15)
3080
+ end
3081
+
3082
+ it "correctly uses elemMatch" do
3083
+ expect(criteria.selector).to eq(
3084
+ "addresses.code.deepest.array" => {
3085
+ "$elemMatch" => {
3086
+ "element.item" => { "$gte" => 10, "$lte" => 15 }
3087
+ }
3088
+ }
3089
+ )
3090
+ end
3091
+ end
3092
+
3093
+ context "when there are multiple conditions" do
3094
+ let(:criteria) do
3095
+ Band.where("$or" => [{"labels.age" => 10..15}, {labels: 8}])
3096
+ end
3097
+
3098
+ it "correctly combines the conditions" do
3099
+ expect(criteria.selector).to eq("$or" => [
3100
+ { "labels" => {
3101
+ "$elemMatch" => {
3102
+ "age" => { "$gte" => 10, "$lte" => 15 }
3103
+ } } },
3104
+ { "labels" => 8 }
3105
+ ])
3106
+ end
3107
+ end
3108
+
3109
+ context "when the association is aliased" do
3110
+ let(:criteria) do
3111
+ Person.where("passport.passport_pages.num_stamps" => 10..18)
3112
+ end
3113
+
3114
+ it "correctly uses the aliased association" do
3115
+ expect(criteria.selector).to eq(
3116
+ "pass.passport_pages" => {
3117
+ "$elemMatch" => {
3118
+ "num_stamps" => { "$gte" => 10, "$lte" => 18 }
3119
+ }
3120
+ }
3121
+ )
3122
+ end
3123
+ end
3124
+ end
3861
3125
  end
3862
3126
 
3863
3127
  describe "#for_js" do