mongoid 7.2.1 → 9.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1082) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/CHANGELOG.md +20 -20
  4. data/LICENSE +1 -1
  5. data/README.md +7 -12
  6. data/Rakefile +58 -1
  7. data/lib/config/locales/en.yml +191 -60
  8. data/lib/mongoid/association/accessors.rb +67 -53
  9. data/lib/mongoid/association/bindable.rb +77 -31
  10. data/lib/mongoid/association/builders.rb +8 -14
  11. data/lib/mongoid/association/constrainable.rb +2 -5
  12. data/lib/mongoid/association/depending.rb +20 -12
  13. data/lib/mongoid/association/eager.rb +160 -0
  14. data/lib/mongoid/association/eager_loadable.rb +41 -11
  15. data/lib/mongoid/association/embedded/batchable.rb +63 -52
  16. data/lib/mongoid/association/embedded/cyclic.rb +4 -12
  17. data/lib/mongoid/association/embedded/eager.rb +23 -0
  18. data/lib/mongoid/association/embedded/embedded_in/binding.rb +29 -13
  19. data/lib/mongoid/association/embedded/embedded_in/buildable.rb +3 -5
  20. data/lib/mongoid/association/embedded/embedded_in/proxy.rb +25 -23
  21. data/lib/mongoid/association/embedded/embedded_in.rb +11 -26
  22. data/lib/mongoid/association/embedded/embeds_many/binding.rb +4 -9
  23. data/lib/mongoid/association/embedded/embeds_many/buildable.rb +5 -6
  24. data/lib/mongoid/association/embedded/embeds_many/proxy.rb +226 -203
  25. data/lib/mongoid/association/embedded/embeds_many.rb +3 -33
  26. data/lib/mongoid/association/embedded/embeds_one/binding.rb +3 -9
  27. data/lib/mongoid/association/embedded/embeds_one/buildable.rb +20 -8
  28. data/lib/mongoid/association/embedded/embeds_one/proxy.rb +131 -42
  29. data/lib/mongoid/association/embedded/embeds_one.rb +4 -30
  30. data/lib/mongoid/association/embedded.rb +2 -1
  31. data/lib/mongoid/association/macros.rb +47 -16
  32. data/lib/mongoid/association/many.rb +12 -24
  33. data/lib/mongoid/association/marshalable.rb +4 -5
  34. data/lib/mongoid/association/nested/many.rb +14 -19
  35. data/lib/mongoid/association/nested/nested_buildable.rb +36 -13
  36. data/lib/mongoid/association/nested/one.rb +54 -26
  37. data/lib/mongoid/association/nested.rb +1 -3
  38. data/lib/mongoid/association/one.rb +3 -11
  39. data/lib/mongoid/association/options.rb +18 -44
  40. data/lib/mongoid/association/proxy.rb +49 -42
  41. data/lib/mongoid/association/referenced/auto_save.rb +11 -15
  42. data/lib/mongoid/association/referenced/belongs_to/binding.rb +2 -7
  43. data/lib/mongoid/association/referenced/belongs_to/buildable.rb +6 -6
  44. data/lib/mongoid/association/referenced/belongs_to/eager.rb +2 -2
  45. data/lib/mongoid/association/referenced/belongs_to/proxy.rb +23 -32
  46. data/lib/mongoid/association/referenced/belongs_to.rb +13 -37
  47. data/lib/mongoid/association/referenced/counter_cache.rb +18 -26
  48. data/lib/mongoid/association/referenced/has_and_belongs_to_many/binding.rb +15 -8
  49. data/lib/mongoid/association/referenced/has_and_belongs_to_many/buildable.rb +1 -3
  50. data/lib/mongoid/association/referenced/has_and_belongs_to_many/eager.rb +2 -2
  51. data/lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb +191 -123
  52. data/lib/mongoid/association/referenced/has_and_belongs_to_many.rb +23 -42
  53. data/lib/mongoid/association/referenced/has_many/binding.rb +1 -5
  54. data/lib/mongoid/association/referenced/has_many/buildable.rb +1 -3
  55. data/lib/mongoid/association/referenced/has_many/eager.rb +2 -2
  56. data/lib/mongoid/association/referenced/has_many/enumerable.rb +471 -496
  57. data/lib/mongoid/association/referenced/has_many/proxy.rb +182 -179
  58. data/lib/mongoid/association/referenced/has_many.rb +17 -43
  59. data/lib/mongoid/association/referenced/has_one/binding.rb +1 -7
  60. data/lib/mongoid/association/referenced/has_one/buildable.rb +5 -5
  61. data/lib/mongoid/association/referenced/has_one/eager.rb +3 -4
  62. data/lib/mongoid/association/referenced/has_one/proxy.rb +38 -41
  63. data/lib/mongoid/association/referenced/has_one.rb +17 -36
  64. data/lib/mongoid/association/referenced/syncable.rb +11 -27
  65. data/lib/mongoid/association/referenced.rb +1 -1
  66. data/lib/mongoid/association/reflections.rb +9 -9
  67. data/lib/mongoid/association/relatable.rb +55 -74
  68. data/lib/mongoid/association.rb +10 -22
  69. data/lib/mongoid/atomic/modifiers.rb +7 -53
  70. data/lib/mongoid/atomic/paths/embedded/many.rb +20 -5
  71. data/lib/mongoid/atomic/paths/embedded/one.rb +1 -5
  72. data/lib/mongoid/atomic/paths/embedded.rb +1 -3
  73. data/lib/mongoid/atomic/paths/root.rb +1 -5
  74. data/lib/mongoid/atomic/paths.rb +1 -1
  75. data/lib/mongoid/atomic.rb +39 -86
  76. data/lib/mongoid/atomic_update_preparer.rb +88 -0
  77. data/lib/mongoid/attributes/dynamic.rb +5 -21
  78. data/lib/mongoid/attributes/embedded.rb +34 -0
  79. data/lib/mongoid/attributes/nested.rb +9 -13
  80. data/lib/mongoid/attributes/processing.rb +43 -28
  81. data/lib/mongoid/attributes/projector.rb +120 -0
  82. data/lib/mongoid/attributes/readonly.rb +4 -8
  83. data/lib/mongoid/attributes.rb +85 -89
  84. data/lib/mongoid/cacheable.rb +5 -9
  85. data/lib/mongoid/changeable.rb +183 -97
  86. data/lib/mongoid/clients/factory.rb +58 -15
  87. data/lib/mongoid/clients/options.rb +117 -8
  88. data/lib/mongoid/clients/sessions.rb +246 -84
  89. data/lib/mongoid/clients/storage_options.rb +37 -11
  90. data/lib/mongoid/clients/validators/storage.rb +4 -24
  91. data/lib/mongoid/clients/validators.rb +1 -1
  92. data/lib/mongoid/clients.rb +37 -14
  93. data/lib/mongoid/collection_configurable.rb +59 -0
  94. data/lib/mongoid/composable.rb +7 -7
  95. data/lib/mongoid/config/defaults.rb +40 -0
  96. data/lib/mongoid/config/encryption.rb +213 -0
  97. data/lib/mongoid/config/environment.rb +25 -5
  98. data/lib/mongoid/config/introspection.rb +152 -0
  99. data/lib/mongoid/config/options.rb +11 -14
  100. data/lib/mongoid/config/validators/async_query_executor.rb +34 -0
  101. data/lib/mongoid/config/validators/client.rb +7 -23
  102. data/lib/mongoid/config/validators/option.rb +1 -3
  103. data/lib/mongoid/config/validators.rb +2 -1
  104. data/lib/mongoid/config.rb +183 -46
  105. data/lib/mongoid/contextual/aggregable/memory.rb +38 -26
  106. data/lib/mongoid/contextual/aggregable/mongo.rb +26 -32
  107. data/lib/mongoid/contextual/aggregable/none.rb +66 -0
  108. data/lib/mongoid/contextual/aggregable.rb +18 -0
  109. data/lib/mongoid/contextual/atomic.rb +97 -30
  110. data/lib/mongoid/contextual/command.rb +3 -5
  111. data/lib/mongoid/contextual/map_reduce.rb +8 -33
  112. data/lib/mongoid/contextual/memory.rb +396 -89
  113. data/lib/mongoid/contextual/mongo/documents_loader.rb +178 -0
  114. data/lib/mongoid/contextual/mongo.rb +640 -311
  115. data/lib/mongoid/contextual/none.rb +244 -30
  116. data/lib/mongoid/contextual/queryable.rb +5 -4
  117. data/lib/mongoid/contextual.rb +18 -7
  118. data/lib/mongoid/copyable.rb +34 -14
  119. data/lib/mongoid/criteria/findable.rb +52 -22
  120. data/lib/mongoid/criteria/includable.rb +31 -34
  121. data/lib/mongoid/criteria/inspectable.rb +4 -3
  122. data/lib/mongoid/criteria/marshalable.rb +14 -7
  123. data/lib/mongoid/criteria/modifiable.rb +5 -19
  124. data/lib/mongoid/criteria/options.rb +1 -3
  125. data/lib/mongoid/criteria/permission.rb +6 -2
  126. data/lib/mongoid/criteria/queryable/aggregable.rb +3 -15
  127. data/lib/mongoid/criteria/queryable/expandable.rb +1 -25
  128. data/lib/mongoid/criteria/queryable/extensions/array.rb +6 -41
  129. data/lib/mongoid/criteria/queryable/extensions/big_decimal.rb +25 -9
  130. data/lib/mongoid/criteria/queryable/extensions/boolean.rb +5 -7
  131. data/lib/mongoid/criteria/queryable/extensions/date.rb +10 -11
  132. data/lib/mongoid/criteria/queryable/extensions/date_time.rb +8 -7
  133. data/lib/mongoid/criteria/queryable/extensions/hash.rb +3 -41
  134. data/lib/mongoid/criteria/queryable/extensions/nil_class.rb +2 -14
  135. data/lib/mongoid/criteria/queryable/extensions/numeric.rb +3 -21
  136. data/lib/mongoid/criteria/queryable/extensions/object.rb +7 -30
  137. data/lib/mongoid/criteria/queryable/extensions/range.rb +48 -17
  138. data/lib/mongoid/criteria/queryable/extensions/regexp.rb +10 -13
  139. data/lib/mongoid/criteria/queryable/extensions/set.rb +3 -5
  140. data/lib/mongoid/criteria/queryable/extensions/string.rb +19 -34
  141. data/lib/mongoid/criteria/queryable/extensions/symbol.rb +6 -22
  142. data/lib/mongoid/criteria/queryable/extensions/time.rb +8 -9
  143. data/lib/mongoid/criteria/queryable/extensions/time_with_zone.rb +9 -9
  144. data/lib/mongoid/criteria/queryable/extensions.rb +1 -5
  145. data/lib/mongoid/criteria/queryable/key.rb +15 -18
  146. data/lib/mongoid/criteria/queryable/macroable.rb +1 -3
  147. data/lib/mongoid/criteria/queryable/mergeable.rb +69 -50
  148. data/lib/mongoid/criteria/queryable/optional.rb +12 -62
  149. data/lib/mongoid/criteria/queryable/options.rb +3 -21
  150. data/lib/mongoid/criteria/queryable/pipeline.rb +2 -14
  151. data/lib/mongoid/criteria/queryable/selectable.rb +87 -124
  152. data/lib/mongoid/criteria/queryable/selector.rb +96 -25
  153. data/lib/mongoid/criteria/queryable/smash.rb +41 -18
  154. data/lib/mongoid/criteria/queryable/storable.rb +14 -9
  155. data/lib/mongoid/criteria/queryable.rb +12 -13
  156. data/lib/mongoid/criteria/scopable.rb +32 -21
  157. data/lib/mongoid/criteria/translator.rb +46 -0
  158. data/lib/mongoid/criteria.rb +60 -109
  159. data/lib/mongoid/deprecable.rb +38 -0
  160. data/lib/mongoid/deprecation.rb +29 -0
  161. data/lib/mongoid/document.rb +263 -173
  162. data/lib/mongoid/encryptable.rb +53 -0
  163. data/lib/mongoid/equality.rb +22 -25
  164. data/lib/mongoid/errors/ambiguous_relationship.rb +3 -5
  165. data/lib/mongoid/errors/attribute_not_loaded.rb +34 -0
  166. data/lib/mongoid/errors/callback.rb +1 -3
  167. data/lib/mongoid/errors/create_collection_failure.rb +34 -0
  168. data/lib/mongoid/errors/criteria_argument_required.rb +1 -1
  169. data/lib/mongoid/errors/delete_restriction.rb +9 -12
  170. data/lib/mongoid/errors/document_not_destroyed.rb +3 -7
  171. data/lib/mongoid/errors/document_not_found.rb +34 -21
  172. data/lib/mongoid/errors/drop_collection_failure.rb +28 -0
  173. data/lib/mongoid/errors/empty_config_file.rb +26 -0
  174. data/lib/mongoid/errors/immutable_attribute.rb +27 -0
  175. data/lib/mongoid/errors/in_memory_collation_not_supported.rb +1 -3
  176. data/lib/mongoid/errors/invalid_async_query_executor.rb +26 -0
  177. data/lib/mongoid/errors/invalid_auto_encryption_configuration.rb +33 -0
  178. data/lib/mongoid/errors/invalid_collection.rb +1 -1
  179. data/lib/mongoid/errors/invalid_config_file.rb +26 -0
  180. data/lib/mongoid/errors/invalid_config_option.rb +2 -4
  181. data/lib/mongoid/errors/invalid_dependent_strategy.rb +2 -4
  182. data/lib/mongoid/errors/invalid_discriminator_key_target.rb +1 -1
  183. data/lib/mongoid/errors/invalid_dot_dollar_assignment.rb +24 -0
  184. data/lib/mongoid/errors/invalid_elem_match_operator.rb +1 -1
  185. data/lib/mongoid/errors/invalid_estimated_count_criteria.rb +6 -5
  186. data/lib/mongoid/errors/invalid_estimated_count_scoping.rb +27 -0
  187. data/lib/mongoid/errors/invalid_expression_operator.rb +1 -1
  188. data/lib/mongoid/errors/invalid_field.rb +7 -7
  189. data/lib/mongoid/errors/invalid_field_operator.rb +1 -1
  190. data/lib/mongoid/errors/invalid_field_option.rb +1 -3
  191. data/lib/mongoid/errors/invalid_field_type.rb +27 -0
  192. data/lib/mongoid/errors/invalid_find.rb +1 -3
  193. data/lib/mongoid/errors/invalid_global_executor_concurrency.rb +23 -0
  194. data/lib/mongoid/errors/invalid_includes.rb +1 -3
  195. data/lib/mongoid/errors/invalid_index.rb +1 -3
  196. data/lib/mongoid/errors/invalid_options.rb +1 -3
  197. data/lib/mongoid/errors/invalid_path.rb +1 -3
  198. data/lib/mongoid/errors/invalid_persistence_option.rb +1 -5
  199. data/lib/mongoid/errors/invalid_query.rb +1 -1
  200. data/lib/mongoid/errors/invalid_relation.rb +2 -8
  201. data/lib/mongoid/errors/invalid_relation_option.rb +2 -4
  202. data/lib/mongoid/errors/invalid_scope.rb +1 -3
  203. data/lib/mongoid/errors/invalid_session_nesting.rb +17 -0
  204. data/lib/mongoid/errors/invalid_set_polymorphic_relation.rb +1 -2
  205. data/lib/mongoid/errors/invalid_storage_options.rb +2 -4
  206. data/lib/mongoid/errors/invalid_time.rb +1 -3
  207. data/lib/mongoid/errors/invalid_transaction_nesting.rb +17 -0
  208. data/lib/mongoid/errors/inverse_not_found.rb +1 -3
  209. data/lib/mongoid/errors/mixed_client_configuration.rb +1 -3
  210. data/lib/mongoid/errors/mixed_relations.rb +1 -3
  211. data/lib/mongoid/errors/mongoid_error.rb +8 -16
  212. data/lib/mongoid/errors/nested_attributes_metadata_not_found.rb +2 -4
  213. data/lib/mongoid/errors/no_client_config.rb +1 -3
  214. data/lib/mongoid/errors/no_client_database.rb +2 -4
  215. data/lib/mongoid/errors/no_client_hosts.rb +2 -4
  216. data/lib/mongoid/errors/no_clients_config.rb +1 -3
  217. data/lib/mongoid/errors/no_default_client.rb +1 -3
  218. data/lib/mongoid/errors/no_environment.rb +1 -3
  219. data/lib/mongoid/errors/no_map_reduce_output.rb +1 -3
  220. data/lib/mongoid/errors/no_metadata.rb +1 -3
  221. data/lib/mongoid/errors/no_parent.rb +1 -3
  222. data/lib/mongoid/errors/readonly_attribute.rb +2 -4
  223. data/lib/mongoid/errors/readonly_document.rb +2 -6
  224. data/lib/mongoid/errors/rollback.rb +15 -0
  225. data/lib/mongoid/errors/scope_overwrite.rb +1 -1
  226. data/lib/mongoid/errors/sessions_not_supported.rb +17 -0
  227. data/lib/mongoid/errors/too_many_nested_attribute_records.rb +2 -2
  228. data/lib/mongoid/errors/transaction_error.rb +25 -0
  229. data/lib/mongoid/errors/transactions_not_supported.rb +17 -0
  230. data/lib/mongoid/errors/unknown_attribute.rb +2 -4
  231. data/lib/mongoid/errors/unknown_model.rb +1 -3
  232. data/lib/mongoid/errors/unsaved_document.rb +2 -2
  233. data/lib/mongoid/errors/unsupported_javascript.rb +1 -3
  234. data/lib/mongoid/errors/validations.rb +1 -1
  235. data/lib/mongoid/errors.rb +18 -5
  236. data/lib/mongoid/evolvable.rb +2 -4
  237. data/lib/mongoid/extensions/array.rb +20 -58
  238. data/lib/mongoid/extensions/big_decimal.rb +44 -24
  239. data/lib/mongoid/extensions/binary.rb +45 -0
  240. data/lib/mongoid/extensions/boolean.rb +11 -6
  241. data/lib/mongoid/extensions/date.rb +31 -29
  242. data/lib/mongoid/extensions/date_time.rb +5 -16
  243. data/lib/mongoid/extensions/decimal128.rb +3 -5
  244. data/lib/mongoid/extensions/false_class.rb +8 -10
  245. data/lib/mongoid/extensions/float.rb +11 -12
  246. data/lib/mongoid/extensions/hash.rb +28 -148
  247. data/lib/mongoid/extensions/integer.rb +13 -14
  248. data/lib/mongoid/extensions/module.rb +5 -5
  249. data/lib/mongoid/extensions/nil_class.rb +5 -7
  250. data/lib/mongoid/extensions/object.rb +32 -81
  251. data/lib/mongoid/extensions/object_id.rb +3 -7
  252. data/lib/mongoid/extensions/range.rb +47 -24
  253. data/lib/mongoid/extensions/raw_value.rb +34 -0
  254. data/lib/mongoid/extensions/regexp.rb +14 -7
  255. data/lib/mongoid/extensions/set.rb +24 -13
  256. data/lib/mongoid/extensions/string.rb +30 -62
  257. data/lib/mongoid/extensions/symbol.rb +9 -22
  258. data/lib/mongoid/extensions/time.rb +30 -40
  259. data/lib/mongoid/extensions/time_with_zone.rb +18 -11
  260. data/lib/mongoid/extensions/true_class.rb +8 -10
  261. data/lib/mongoid/extensions.rb +3 -20
  262. data/lib/mongoid/factory.rb +178 -37
  263. data/lib/mongoid/fields/encrypted.rb +48 -0
  264. data/lib/mongoid/fields/foreign_key.rb +39 -27
  265. data/lib/mongoid/fields/localized.rb +25 -15
  266. data/lib/mongoid/fields/standard.rb +22 -40
  267. data/lib/mongoid/fields/validators/macro.rb +6 -19
  268. data/lib/mongoid/fields/validators.rb +1 -1
  269. data/lib/mongoid/fields.rb +354 -76
  270. data/lib/mongoid/findable.rb +62 -22
  271. data/lib/mongoid/indexable/specification.rb +55 -34
  272. data/lib/mongoid/indexable/validators/options.rb +7 -9
  273. data/lib/mongoid/indexable.rb +2 -18
  274. data/lib/mongoid/inspectable.rb +34 -11
  275. data/lib/mongoid/interceptable.rb +197 -41
  276. data/lib/mongoid/loadable.rb +83 -0
  277. data/lib/mongoid/loggable.rb +1 -9
  278. data/lib/mongoid/matchable.rb +2 -6
  279. data/lib/mongoid/matcher/all.rb +15 -0
  280. data/lib/mongoid/matcher/and.rb +14 -0
  281. data/lib/mongoid/matcher/bits.rb +60 -0
  282. data/lib/mongoid/matcher/bits_all_clear.rb +41 -0
  283. data/lib/mongoid/matcher/bits_all_set.rb +41 -0
  284. data/lib/mongoid/matcher/bits_any_clear.rb +41 -0
  285. data/lib/mongoid/matcher/bits_any_set.rb +41 -0
  286. data/lib/mongoid/matcher/elem_match.rb +17 -1
  287. data/lib/mongoid/matcher/elem_match_expression.rb +14 -2
  288. data/lib/mongoid/matcher/eq.rb +15 -0
  289. data/lib/mongoid/matcher/eq_impl.rb +54 -2
  290. data/lib/mongoid/matcher/eq_impl_with_regexp.rb +18 -1
  291. data/lib/mongoid/matcher/exists.rb +15 -0
  292. data/lib/mongoid/matcher/expression.rb +22 -14
  293. data/lib/mongoid/matcher/expression_operator.rb +14 -0
  294. data/lib/mongoid/matcher/field_expression.rb +19 -5
  295. data/lib/mongoid/matcher/field_operator.rb +30 -0
  296. data/lib/mongoid/matcher/gt.rb +15 -0
  297. data/lib/mongoid/matcher/gte.rb +15 -0
  298. data/lib/mongoid/matcher/in.rb +15 -0
  299. data/lib/mongoid/matcher/lt.rb +15 -0
  300. data/lib/mongoid/matcher/lte.rb +15 -0
  301. data/lib/mongoid/matcher/mod.rb +33 -0
  302. data/lib/mongoid/matcher/ne.rb +15 -0
  303. data/lib/mongoid/matcher/nin.rb +15 -0
  304. data/lib/mongoid/matcher/nor.rb +14 -0
  305. data/lib/mongoid/matcher/not.rb +16 -0
  306. data/lib/mongoid/matcher/or.rb +14 -0
  307. data/lib/mongoid/matcher/regex.rb +24 -0
  308. data/lib/mongoid/matcher/size.rb +16 -0
  309. data/lib/mongoid/matcher/type.rb +124 -0
  310. data/lib/mongoid/matcher.rb +59 -52
  311. data/lib/mongoid/persistable/creatable.rb +25 -29
  312. data/lib/mongoid/persistable/deletable.rb +10 -23
  313. data/lib/mongoid/persistable/destroyable.rb +37 -11
  314. data/lib/mongoid/persistable/incrementable.rb +2 -6
  315. data/lib/mongoid/persistable/logical.rb +1 -5
  316. data/lib/mongoid/persistable/maxable.rb +37 -0
  317. data/lib/mongoid/persistable/minable.rb +37 -0
  318. data/lib/mongoid/persistable/multipliable.rb +36 -0
  319. data/lib/mongoid/persistable/poppable.rb +1 -5
  320. data/lib/mongoid/persistable/pullable.rb +1 -7
  321. data/lib/mongoid/persistable/pushable.rb +1 -7
  322. data/lib/mongoid/persistable/renamable.rb +1 -5
  323. data/lib/mongoid/persistable/savable.rb +14 -8
  324. data/lib/mongoid/persistable/settable.rb +1 -5
  325. data/lib/mongoid/persistable/unsettable.rb +3 -7
  326. data/lib/mongoid/persistable/updatable.rb +114 -28
  327. data/lib/mongoid/persistable/upsertable.rb +33 -8
  328. data/lib/mongoid/persistable.rb +17 -27
  329. data/lib/mongoid/persistence_context.rb +111 -43
  330. data/lib/mongoid/positional.rb +1 -5
  331. data/lib/mongoid/railtie.rb +23 -15
  332. data/lib/mongoid/railties/bson_object_id_serializer.rb +39 -0
  333. data/lib/mongoid/railties/console_sandbox.rb +42 -0
  334. data/lib/mongoid/railties/controller_runtime.rb +21 -6
  335. data/lib/mongoid/railties/database.rake +19 -2
  336. data/lib/mongoid/reloadable.rb +45 -42
  337. data/lib/mongoid/scopable.rb +25 -53
  338. data/lib/mongoid/search_indexable.rb +167 -0
  339. data/lib/mongoid/selectable.rb +6 -17
  340. data/lib/mongoid/serializable.rb +11 -21
  341. data/lib/mongoid/shardable.rb +50 -16
  342. data/lib/mongoid/stateful.rb +66 -22
  343. data/lib/mongoid/stringified_symbol.rb +19 -7
  344. data/lib/mongoid/tasks/database.rake +25 -0
  345. data/lib/mongoid/tasks/database.rb +84 -8
  346. data/lib/mongoid/tasks/encryption.rake +59 -0
  347. data/lib/mongoid/tasks/encryption.rb +108 -0
  348. data/lib/mongoid/threaded/lifecycle.rb +6 -26
  349. data/lib/mongoid/threaded.rb +131 -92
  350. data/lib/mongoid/timestamps/created/short.rb +1 -1
  351. data/lib/mongoid/timestamps/created.rb +4 -4
  352. data/lib/mongoid/timestamps/short.rb +1 -1
  353. data/lib/mongoid/timestamps/timeless.rb +29 -7
  354. data/lib/mongoid/timestamps/updated/short.rb +1 -1
  355. data/lib/mongoid/timestamps/updated.rb +3 -5
  356. data/lib/mongoid/timestamps.rb +1 -1
  357. data/lib/mongoid/touchable.rb +155 -29
  358. data/lib/mongoid/traversable.rb +180 -125
  359. data/lib/mongoid/utils.rb +52 -0
  360. data/lib/mongoid/validatable/associated.rb +97 -21
  361. data/lib/mongoid/validatable/format.rb +1 -1
  362. data/lib/mongoid/validatable/length.rb +1 -1
  363. data/lib/mongoid/validatable/localizable.rb +2 -4
  364. data/lib/mongoid/validatable/macros.rb +10 -14
  365. data/lib/mongoid/validatable/presence.rb +7 -13
  366. data/lib/mongoid/validatable/queryable.rb +9 -3
  367. data/lib/mongoid/validatable/uniqueness.rb +26 -39
  368. data/lib/mongoid/validatable.rb +20 -29
  369. data/lib/mongoid/version.rb +2 -2
  370. data/lib/mongoid/warnings.rb +37 -0
  371. data/lib/mongoid.rb +56 -22
  372. data/lib/rails/generators/mongoid/config/config_generator.rb +25 -5
  373. data/lib/rails/generators/mongoid/config/templates/mongoid.rb +25 -0
  374. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +44 -64
  375. data/lib/rails/generators/mongoid/model/model_generator.rb +4 -1
  376. data/lib/rails/generators/mongoid_generator.rb +13 -1
  377. data/lib/rails/mongoid.rb +4 -32
  378. data/spec/config/mongoid.yml +16 -1
  379. data/spec/config/mongoid_with_schema_map_uuid.yml +27 -0
  380. data/spec/integration/active_job_spec.rb +32 -0
  381. data/spec/integration/app_spec.rb +180 -89
  382. data/spec/integration/associations/belongs_to_spec.rb +19 -1
  383. data/spec/integration/associations/embedded_dirty_spec.rb +58 -0
  384. data/spec/integration/associations/embedded_spec.rb +90 -7
  385. data/spec/integration/associations/embeds_many_spec.rb +197 -1
  386. data/spec/integration/associations/embeds_one_spec.rb +19 -1
  387. data/spec/integration/associations/foreign_key_spec.rb +10 -1
  388. data/spec/integration/associations/foreign_key_spec_models.rb +1 -1
  389. data/spec/integration/associations/has_and_belongs_to_many_spec.rb +62 -0
  390. data/spec/integration/associations/has_many_spec.rb +1 -1
  391. data/spec/integration/associations/has_one_spec.rb +145 -1
  392. data/spec/integration/associations/nested_attributes_assignment_spec.rb +1 -1
  393. data/spec/integration/associations/reverse_population_spec.rb +1 -1
  394. data/spec/integration/associations/reverse_population_spec_models.rb +1 -1
  395. data/spec/integration/associations/scope_option_spec.rb +102 -0
  396. data/spec/integration/atomic/modifiers_spec.rb +1 -1
  397. data/spec/integration/bson_regexp_raw_spec.rb +1 -1
  398. data/spec/integration/callbacks_models.rb +147 -3
  399. data/spec/integration/callbacks_spec.rb +398 -8
  400. data/spec/integration/contextual/empty_spec.rb +142 -0
  401. data/spec/integration/criteria/alias_query_spec.rb +98 -0
  402. data/spec/integration/criteria/date_field_spec.rb +2 -2
  403. data/spec/integration/criteria/default_scope_spec.rb +52 -0
  404. data/spec/integration/criteria/logical_spec.rb +12 -0
  405. data/spec/integration/criteria/range_spec.rb +358 -0
  406. data/spec/integration/criteria/raw_value_spec.rb +525 -0
  407. data/spec/integration/criteria/time_with_zone_spec.rb +126 -15
  408. data/spec/integration/discriminator_key_spec.rb +119 -81
  409. data/spec/integration/discriminator_value_spec.rb +1 -1
  410. data/spec/integration/document_spec.rb +31 -1
  411. data/spec/integration/dots_and_dollars_spec.rb +278 -0
  412. data/spec/integration/encryption_spec.rb +100 -0
  413. data/spec/integration/i18n_fallbacks_spec.rb +10 -52
  414. data/spec/integration/matcher_examples_spec.rb +21 -14
  415. data/spec/integration/matcher_operator_data/bits_all_clear.yml +144 -0
  416. data/spec/integration/matcher_operator_data/bits_all_set.yml +144 -0
  417. data/spec/integration/matcher_operator_data/bits_any_clear.yml +144 -0
  418. data/spec/integration/matcher_operator_data/bits_any_set.yml +144 -0
  419. data/spec/integration/matcher_operator_data/comment.yml +22 -0
  420. data/spec/integration/matcher_operator_data/elem_match.yml +46 -0
  421. data/spec/integration/matcher_operator_data/implicit_traversal.yml +96 -0
  422. data/spec/integration/matcher_operator_data/in.yml +16 -0
  423. data/spec/integration/matcher_operator_data/mod.yml +55 -0
  424. data/spec/integration/matcher_operator_data/size.yml +0 -3
  425. data/spec/integration/matcher_operator_data/type.yml +64 -0
  426. data/spec/integration/matcher_operator_data/type_array.yml +15 -0
  427. data/spec/integration/matcher_operator_data/type_binary.yml +18 -0
  428. data/spec/integration/matcher_operator_data/type_boolean.yml +39 -0
  429. data/spec/integration/matcher_operator_data/type_code.yml +26 -0
  430. data/spec/integration/matcher_operator_data/type_code_with_scope.yml +26 -0
  431. data/spec/integration/matcher_operator_data/type_date.yml +39 -0
  432. data/spec/integration/matcher_operator_data/type_db_pointer.yml +19 -0
  433. data/spec/integration/matcher_operator_data/type_decimal.yml +37 -0
  434. data/spec/integration/matcher_operator_data/type_double.yml +15 -0
  435. data/spec/integration/matcher_operator_data/type_int32.yml +33 -0
  436. data/spec/integration/matcher_operator_data/type_int64.yml +33 -0
  437. data/spec/integration/matcher_operator_data/type_max_key.yml +17 -0
  438. data/spec/integration/matcher_operator_data/type_min_key.yml +17 -0
  439. data/spec/integration/matcher_operator_data/type_null.yml +23 -0
  440. data/spec/integration/matcher_operator_data/type_object.yml +23 -0
  441. data/spec/integration/matcher_operator_data/type_object_id.yml +25 -0
  442. data/spec/integration/matcher_operator_data/type_regex.yml +44 -0
  443. data/spec/integration/matcher_operator_data/type_string.yml +15 -0
  444. data/spec/integration/matcher_operator_data/type_symbol.yml +32 -0
  445. data/spec/integration/matcher_operator_data/type_timestamp.yml +25 -0
  446. data/spec/integration/matcher_operator_data/type_undefined.yml +17 -0
  447. data/spec/integration/matcher_operator_spec.rb +26 -3
  448. data/spec/integration/matcher_spec.rb +50 -1
  449. data/spec/integration/persistence/range_field_spec.rb +351 -0
  450. data/spec/integration/server_query_spec.rb +1 -1
  451. data/spec/integration/shardable_spec.rb +1 -1
  452. data/spec/integration/stringified_symbol_field_spec.rb +17 -3
  453. data/spec/lite_spec_helper.rb +47 -14
  454. data/spec/mongoid/association/accessors_spec.rb +31 -19
  455. data/spec/mongoid/association/auto_save_spec.rb +73 -34
  456. data/spec/mongoid/association/builders_spec.rb +2 -2
  457. data/spec/mongoid/association/constrainable_spec.rb +1 -1
  458. data/spec/mongoid/association/counter_cache_spec.rb +34 -34
  459. data/spec/mongoid/association/depending_spec.rb +397 -358
  460. data/spec/mongoid/association/eager_spec.rb +56 -6
  461. data/spec/mongoid/association/embedded/cyclic_spec.rb +3 -3
  462. data/spec/mongoid/association/embedded/dirty_spec.rb +3 -3
  463. data/spec/mongoid/association/embedded/embedded_in/binding_spec.rb +3 -2
  464. data/spec/mongoid/association/embedded/embedded_in/buildable_spec.rb +55 -1
  465. data/spec/mongoid/association/embedded/embedded_in/proxy_spec.rb +110 -23
  466. data/spec/mongoid/association/embedded/embedded_in_spec.rb +19 -8
  467. data/spec/mongoid/association/embedded/embeds_many/binding_spec.rb +1 -1
  468. data/spec/mongoid/association/embedded/embeds_many/buildable_spec.rb +113 -1
  469. data/spec/mongoid/association/embedded/embeds_many/proxy_spec.rb +712 -203
  470. data/spec/mongoid/association/embedded/embeds_many_models.rb +189 -1
  471. data/spec/mongoid/association/embedded/embeds_many_query_spec.rb +14 -2
  472. data/spec/mongoid/association/embedded/embeds_many_spec.rb +69 -1
  473. data/spec/mongoid/association/embedded/embeds_one/binding_spec.rb +1 -1
  474. data/spec/mongoid/association/embedded/embeds_one/buildable_spec.rb +26 -1
  475. data/spec/mongoid/association/embedded/embeds_one/proxy_spec.rb +37 -24
  476. data/spec/mongoid/association/embedded/embeds_one_dnl_models.rb +1 -1
  477. data/spec/mongoid/association/embedded/embeds_one_models.rb +25 -2
  478. data/spec/mongoid/association/embedded/embeds_one_query_spec.rb +2 -2
  479. data/spec/mongoid/association/embedded/embeds_one_spec.rb +29 -1
  480. data/spec/mongoid/association/macros_spec.rb +10 -10
  481. data/spec/mongoid/association/nested/many_spec.rb +1 -1
  482. data/spec/mongoid/association/nested/one_spec.rb +17 -13
  483. data/spec/mongoid/association/options_spec.rb +1 -1
  484. data/spec/mongoid/association/polymorphic_spec.rb +1 -1
  485. data/spec/mongoid/association/referenced/belongs_to/binding_spec.rb +3 -2
  486. data/spec/mongoid/association/referenced/belongs_to/buildable_spec.rb +110 -17
  487. data/spec/mongoid/association/referenced/belongs_to/eager_spec.rb +51 -15
  488. data/spec/mongoid/association/referenced/belongs_to/proxy_spec.rb +113 -59
  489. data/spec/mongoid/association/referenced/belongs_to_models.rb +12 -0
  490. data/spec/mongoid/association/referenced/belongs_to_query_spec.rb +22 -2
  491. data/spec/mongoid/association/referenced/belongs_to_spec.rb +27 -22
  492. data/spec/mongoid/association/referenced/has_and_belongs_to_many/binding_spec.rb +2 -2
  493. data/spec/mongoid/association/referenced/has_and_belongs_to_many/buildable_spec.rb +28 -3
  494. data/spec/mongoid/association/referenced/has_and_belongs_to_many/eager_spec.rb +32 -3
  495. data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_persistence_spec.rb +1 -1
  496. data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_spec.rb +386 -376
  497. data/spec/mongoid/association/referenced/has_and_belongs_to_many_models.rb +44 -1
  498. data/spec/mongoid/association/referenced/has_and_belongs_to_many_query_spec.rb +2 -2
  499. data/spec/mongoid/association/referenced/has_and_belongs_to_many_spec.rb +57 -3
  500. data/spec/mongoid/association/referenced/has_many/binding_spec.rb +2 -2
  501. data/spec/mongoid/association/referenced/has_many/buildable_spec.rb +131 -1
  502. data/spec/mongoid/association/referenced/has_many/eager_spec.rb +24 -7
  503. data/spec/mongoid/association/referenced/has_many/enumerable_spec.rb +313 -134
  504. data/spec/mongoid/association/referenced/has_many/proxy_query_spec.rb +1 -1
  505. data/spec/mongoid/association/referenced/has_many/proxy_spec.rb +1313 -2109
  506. data/spec/mongoid/association/referenced/has_many_models.rb +39 -2
  507. data/spec/mongoid/association/referenced/has_many_query_spec.rb +2 -2
  508. data/spec/mongoid/association/referenced/has_many_spec.rb +47 -1
  509. data/spec/mongoid/association/referenced/has_one/binding_spec.rb +1 -1
  510. data/spec/mongoid/association/referenced/has_one/buildable_spec.rb +54 -10
  511. data/spec/mongoid/association/referenced/has_one/eager_spec.rb +18 -2
  512. data/spec/mongoid/association/referenced/has_one/proxy_spec.rb +134 -28
  513. data/spec/mongoid/association/referenced/has_one_models.rb +43 -1
  514. data/spec/mongoid/association/referenced/has_one_query_spec.rb +2 -2
  515. data/spec/mongoid/association/referenced/has_one_spec.rb +22 -1
  516. data/spec/mongoid/association/reflections_spec.rb +1 -1
  517. data/spec/mongoid/association/syncable_spec.rb +47 -33
  518. data/spec/mongoid/association_spec.rb +1 -1
  519. data/spec/mongoid/atomic/modifiers_spec.rb +1 -1
  520. data/spec/mongoid/atomic/paths/embedded/many_spec.rb +1 -1
  521. data/spec/mongoid/atomic/paths/embedded/one_spec.rb +1 -1
  522. data/spec/mongoid/atomic/paths/root_spec.rb +1 -1
  523. data/spec/mongoid/atomic/paths_spec.rb +65 -27
  524. data/spec/mongoid/atomic_spec.rb +29 -7
  525. data/spec/mongoid/atomic_update_preparer_spec.rb +83 -0
  526. data/spec/mongoid/attributes/dynamic_spec.rb +1 -1
  527. data/spec/mongoid/attributes/embedded_spec.rb +118 -0
  528. data/spec/mongoid/attributes/nested_spec.rb +147 -78
  529. data/spec/mongoid/attributes/nested_spec_models.rb +49 -0
  530. data/spec/mongoid/attributes/projector_data/embedded.yml +105 -0
  531. data/spec/mongoid/attributes/projector_data/fields.yml +93 -0
  532. data/spec/mongoid/attributes/projector_spec.rb +41 -0
  533. data/spec/mongoid/attributes/readonly_spec.rb +23 -23
  534. data/spec/mongoid/attributes_spec.rb +921 -69
  535. data/spec/mongoid/cacheable_spec.rb +5 -5
  536. data/spec/mongoid/changeable_spec.rb +468 -76
  537. data/spec/mongoid/clients/factory_spec.rb +152 -30
  538. data/spec/mongoid/clients/options_spec.rb +24 -12
  539. data/spec/mongoid/clients/sessions_spec.rb +49 -71
  540. data/spec/mongoid/clients/transactions_spec.rb +971 -176
  541. data/spec/mongoid/clients/transactions_spec_models.rb +159 -0
  542. data/spec/mongoid/clients_spec.rb +230 -22
  543. data/spec/mongoid/collection_configurable_spec.rb +159 -0
  544. data/spec/mongoid/composable_spec.rb +1 -1
  545. data/spec/mongoid/config/defaults_spec.rb +99 -0
  546. data/spec/mongoid/config/encryption_spec.rb +152 -0
  547. data/spec/mongoid/config/environment_spec.rb +126 -39
  548. data/spec/mongoid/config/introspection_spec.rb +114 -0
  549. data/spec/mongoid/config/options_spec.rb +1 -1
  550. data/spec/mongoid/config_spec.rb +375 -43
  551. data/spec/mongoid/contextual/aggregable/memory_spec.rb +432 -154
  552. data/spec/mongoid/contextual/aggregable/memory_table.yml +88 -0
  553. data/spec/mongoid/contextual/aggregable/memory_table_spec.rb +63 -0
  554. data/spec/mongoid/contextual/aggregable/mongo_spec.rb +95 -20
  555. data/spec/mongoid/contextual/aggregable/none_spec.rb +49 -0
  556. data/spec/mongoid/contextual/atomic_spec.rb +329 -87
  557. data/spec/mongoid/contextual/map_reduce_spec.rb +5 -19
  558. data/spec/mongoid/contextual/memory_spec.rb +1479 -127
  559. data/spec/mongoid/contextual/mongo/documents_loader_spec.rb +194 -0
  560. data/spec/mongoid/contextual/mongo_spec.rb +3374 -1254
  561. data/spec/mongoid/contextual/none_spec.rb +79 -68
  562. data/spec/mongoid/copyable_spec.rb +465 -23
  563. data/spec/mongoid/copyable_spec_models.rb +1 -1
  564. data/spec/mongoid/criteria/findable_spec.rb +295 -229
  565. data/spec/mongoid/criteria/includable_spec.rb +1493 -0
  566. data/spec/mongoid/criteria/includable_spec_models.rb +55 -0
  567. data/spec/mongoid/criteria/inspectable_spec.rb +1 -1
  568. data/spec/mongoid/criteria/marshalable_spec.rb +19 -2
  569. data/spec/mongoid/criteria/modifiable_spec.rb +38 -38
  570. data/spec/mongoid/criteria/options_spec.rb +1 -1
  571. data/spec/mongoid/criteria/queryable/aggregable_spec.rb +2 -2
  572. data/spec/mongoid/criteria/queryable/expandable_spec.rb +1 -74
  573. data/spec/mongoid/criteria/queryable/extensions/array_spec.rb +8 -20
  574. data/spec/mongoid/criteria/queryable/extensions/big_decimal_spec.rb +135 -27
  575. data/spec/mongoid/criteria/queryable/extensions/boolean_spec.rb +2 -2
  576. data/spec/mongoid/criteria/queryable/extensions/date_spec.rb +32 -12
  577. data/spec/mongoid/criteria/queryable/extensions/date_time_spec.rb +12 -1
  578. data/spec/mongoid/criteria/queryable/extensions/float_spec.rb +1 -1
  579. data/spec/mongoid/criteria/queryable/extensions/hash_spec.rb +1 -16
  580. data/spec/mongoid/criteria/queryable/extensions/integer_spec.rb +1 -1
  581. data/spec/mongoid/criteria/queryable/extensions/nil_class_spec.rb +1 -1
  582. data/spec/mongoid/criteria/queryable/extensions/numeric_spec.rb +74 -8
  583. data/spec/mongoid/criteria/queryable/extensions/object_spec.rb +1 -1
  584. data/spec/mongoid/criteria/queryable/extensions/range_spec.rb +238 -179
  585. data/spec/mongoid/criteria/queryable/extensions/regexp_raw_spec.rb +1 -12
  586. data/spec/mongoid/criteria/queryable/extensions/regexp_spec.rb +1 -12
  587. data/spec/mongoid/criteria/queryable/extensions/set_spec.rb +1 -1
  588. data/spec/mongoid/criteria/queryable/extensions/string_spec.rb +48 -132
  589. data/spec/mongoid/criteria/queryable/extensions/symbol_spec.rb +5 -60
  590. data/spec/mongoid/criteria/queryable/extensions/time_spec.rb +12 -1
  591. data/spec/mongoid/criteria/queryable/extensions/time_with_zone_spec.rb +12 -1
  592. data/spec/mongoid/criteria/queryable/key_spec.rb +1 -1
  593. data/spec/mongoid/criteria/queryable/mergeable_spec.rb +106 -8
  594. data/spec/mongoid/criteria/queryable/optional_spec.rb +17 -486
  595. data/spec/mongoid/criteria/queryable/options_spec.rb +2 -2
  596. data/spec/mongoid/criteria/queryable/pipeline_spec.rb +1 -1
  597. data/spec/mongoid/criteria/queryable/queryable_spec.rb +2 -2
  598. data/spec/mongoid/criteria/queryable/selectable_logical_spec.rb +700 -26
  599. data/spec/mongoid/criteria/queryable/selectable_shared_examples.rb +39 -0
  600. data/spec/mongoid/criteria/queryable/selectable_spec.rb +149 -683
  601. data/spec/mongoid/criteria/queryable/selectable_where_spec.rb +590 -0
  602. data/spec/mongoid/criteria/queryable/selector_spec.rb +186 -6
  603. data/spec/mongoid/criteria/queryable/smash_spec.rb +1 -1
  604. data/spec/mongoid/criteria/queryable/storable_spec.rb +87 -1
  605. data/spec/mongoid/criteria/scopable_spec.rb +128 -1
  606. data/spec/mongoid/criteria/translator_spec.rb +133 -0
  607. data/spec/mongoid/criteria_projection_spec.rb +407 -0
  608. data/spec/mongoid/criteria_spec.rb +1029 -1806
  609. data/spec/mongoid/document_fields_spec.rb +180 -5
  610. data/spec/mongoid/document_persistence_context_spec.rb +77 -1
  611. data/spec/mongoid/document_query_spec.rb +55 -4
  612. data/spec/mongoid/document_spec.rb +43 -172
  613. data/spec/mongoid/equality_spec.rb +7 -8
  614. data/spec/mongoid/errors/ambiguous_relationship_spec.rb +1 -1
  615. data/spec/mongoid/errors/attribute_not_loaded_spec.rb +32 -0
  616. data/spec/mongoid/errors/callback_spec.rb +1 -1
  617. data/spec/mongoid/errors/delete_restriction_spec.rb +2 -2
  618. data/spec/mongoid/errors/document_not_destroyed_spec.rb +1 -1
  619. data/spec/mongoid/errors/document_not_found_spec.rb +77 -1
  620. data/spec/mongoid/errors/invalid_collection_spec.rb +1 -1
  621. data/spec/mongoid/errors/{eager_load_spec.rb → invalid_config_file_spec.rb} +6 -6
  622. data/spec/mongoid/errors/invalid_config_option_spec.rb +1 -1
  623. data/spec/mongoid/errors/invalid_field_option_spec.rb +1 -1
  624. data/spec/mongoid/errors/invalid_field_spec.rb +2 -2
  625. data/spec/mongoid/errors/invalid_field_type_spec.rb +56 -0
  626. data/spec/mongoid/errors/invalid_find_spec.rb +1 -1
  627. data/spec/mongoid/errors/invalid_includes_spec.rb +1 -1
  628. data/spec/mongoid/errors/invalid_index_spec.rb +1 -1
  629. data/spec/mongoid/errors/invalid_options_spec.rb +1 -1
  630. data/spec/mongoid/errors/invalid_path_spec.rb +1 -1
  631. data/spec/mongoid/errors/invalid_relation_spec.rb +1 -1
  632. data/spec/mongoid/errors/invalid_scope_spec.rb +2 -2
  633. data/spec/mongoid/errors/invalid_set_polymorphic_relation_spec.rb +1 -1
  634. data/spec/mongoid/errors/invalid_storage_options_spec.rb +1 -1
  635. data/spec/mongoid/errors/invalid_time_spec.rb +1 -1
  636. data/spec/mongoid/errors/inverse_not_found_spec.rb +1 -1
  637. data/spec/mongoid/errors/mixed_client_configuration_spec.rb +1 -1
  638. data/spec/mongoid/errors/mixed_relations_spec.rb +1 -1
  639. data/spec/mongoid/errors/mongoid_error_spec.rb +4 -4
  640. data/spec/mongoid/errors/nested_attributes_metadata_not_found_spec.rb +1 -1
  641. data/spec/mongoid/errors/no_client_config_spec.rb +1 -1
  642. data/spec/mongoid/errors/no_client_database_spec.rb +1 -1
  643. data/spec/mongoid/errors/no_client_hosts_spec.rb +1 -1
  644. data/spec/mongoid/errors/no_clients_config_spec.rb +1 -1
  645. data/spec/mongoid/errors/no_environment_spec.rb +4 -4
  646. data/spec/mongoid/errors/no_map_reduce_output_spec.rb +1 -1
  647. data/spec/mongoid/errors/no_metadata_spec.rb +1 -1
  648. data/spec/mongoid/errors/no_parent_spec.rb +1 -1
  649. data/spec/mongoid/errors/readonly_attribute_spec.rb +1 -1
  650. data/spec/mongoid/errors/readonly_document_spec.rb +3 -3
  651. data/spec/mongoid/errors/scope_overwrite_spec.rb +1 -1
  652. data/spec/mongoid/errors/too_many_nested_attribute_records_spec.rb +2 -2
  653. data/spec/mongoid/errors/unknown_attribute_spec.rb +3 -3
  654. data/spec/mongoid/errors/unsaved_document_spec.rb +1 -1
  655. data/spec/mongoid/errors/unsupported_javascript_spec.rb +1 -1
  656. data/spec/mongoid/errors/validations_spec.rb +1 -1
  657. data/spec/mongoid/extensions/array_spec.rb +19 -265
  658. data/spec/mongoid/extensions/big_decimal_spec.rb +713 -213
  659. data/spec/mongoid/extensions/binary_spec.rb +45 -10
  660. data/spec/mongoid/extensions/boolean_spec.rb +69 -83
  661. data/spec/mongoid/extensions/date_class_mongoize_spec.rb +15 -11
  662. data/spec/mongoid/extensions/date_spec.rb +74 -22
  663. data/spec/mongoid/extensions/date_time_spec.rb +18 -19
  664. data/spec/mongoid/extensions/decimal128_spec.rb +1 -1
  665. data/spec/mongoid/extensions/false_class_spec.rb +2 -9
  666. data/spec/mongoid/extensions/float_spec.rb +56 -84
  667. data/spec/mongoid/extensions/hash_spec.rb +45 -219
  668. data/spec/mongoid/extensions/integer_spec.rb +53 -73
  669. data/spec/mongoid/extensions/module_spec.rb +1 -1
  670. data/spec/mongoid/extensions/nil_class_spec.rb +1 -1
  671. data/spec/mongoid/extensions/object_id_spec.rb +1 -1
  672. data/spec/mongoid/extensions/object_spec.rb +1 -177
  673. data/spec/mongoid/extensions/range_spec.rb +254 -64
  674. data/spec/mongoid/extensions/raw_value_spec.rb +67 -0
  675. data/spec/mongoid/extensions/regexp_spec.rb +59 -34
  676. data/spec/mongoid/extensions/set_spec.rb +105 -1
  677. data/spec/mongoid/extensions/string_spec.rb +21 -104
  678. data/spec/mongoid/extensions/stringified_symbol_spec.rb +1 -1
  679. data/spec/mongoid/extensions/symbol_spec.rb +15 -53
  680. data/spec/mongoid/extensions/time_spec.rb +345 -131
  681. data/spec/mongoid/extensions/time_with_zone_spec.rb +34 -107
  682. data/spec/mongoid/extensions/true_class_spec.rb +2 -9
  683. data/spec/mongoid/factory_spec.rb +63 -2
  684. data/spec/mongoid/fields/foreign_key_spec.rb +282 -120
  685. data/spec/mongoid/fields/localized_spec.rb +85 -42
  686. data/spec/mongoid/fields/standard_spec.rb +1 -1
  687. data/spec/mongoid/fields_spec.rb +826 -121
  688. data/spec/mongoid/findable_spec.rb +442 -80
  689. data/spec/mongoid/indexable/specification_spec.rb +132 -14
  690. data/spec/mongoid/indexable_spec.rb +361 -23
  691. data/spec/mongoid/inspectable_spec.rb +93 -5
  692. data/spec/mongoid/interceptable_spec.rb +926 -116
  693. data/spec/mongoid/interceptable_spec_models.rb +236 -4
  694. data/spec/mongoid/loading_spec.rb +110 -0
  695. data/spec/mongoid/loggable_spec.rb +1 -1
  696. data/spec/mongoid/matcher/extract_attribute_data/numeric_keys.yml +104 -0
  697. data/spec/mongoid/matcher/extract_attribute_data/traversal.yml +68 -88
  698. data/spec/mongoid/matcher/extract_attribute_spec.rb +5 -15
  699. data/spec/mongoid/mongoizable_spec.rb +286 -0
  700. data/spec/mongoid/monkey_patches_spec.rb +211 -0
  701. data/spec/mongoid/persistable/creatable_spec.rb +5 -5
  702. data/spec/mongoid/persistable/deletable_spec.rb +267 -27
  703. data/spec/mongoid/persistable/destroyable_spec.rb +409 -24
  704. data/spec/mongoid/persistable/incrementable_spec.rb +46 -9
  705. data/spec/mongoid/persistable/logical_spec.rb +42 -5
  706. data/spec/mongoid/persistable/maxable_spec.rb +147 -0
  707. data/spec/mongoid/persistable/minable_spec.rb +147 -0
  708. data/spec/mongoid/persistable/multipliable_spec.rb +227 -0
  709. data/spec/mongoid/persistable/poppable_spec.rb +41 -5
  710. data/spec/mongoid/persistable/pullable_spec.rb +81 -9
  711. data/spec/mongoid/persistable/pushable_spec.rb +81 -9
  712. data/spec/mongoid/persistable/renamable_spec.rb +40 -4
  713. data/spec/mongoid/persistable/savable_spec.rb +114 -20
  714. data/spec/mongoid/persistable/settable_spec.rb +77 -10
  715. data/spec/mongoid/persistable/unsettable_spec.rb +41 -5
  716. data/spec/mongoid/persistable/updatable_spec.rb +64 -52
  717. data/spec/mongoid/persistable/upsertable_spec.rb +124 -4
  718. data/spec/mongoid/persistable_spec.rb +4 -4
  719. data/spec/mongoid/persistence_context_spec.rb +58 -59
  720. data/spec/mongoid/positional_spec.rb +1 -1
  721. data/spec/mongoid/railties/bson_object_id_serializer_spec.rb +24 -0
  722. data/spec/mongoid/railties/console_sandbox_spec.rb +44 -0
  723. data/spec/mongoid/relations/proxy_spec.rb +7 -7
  724. data/spec/mongoid/reloadable_spec.rb +255 -30
  725. data/spec/mongoid/scopable_spec.rb +198 -58
  726. data/spec/mongoid/search_indexable_spec.rb +147 -0
  727. data/spec/mongoid/selectable_spec.rb +7 -7
  728. data/spec/mongoid/serializable_spec.rb +19 -40
  729. data/spec/mongoid/shardable_models.rb +15 -0
  730. data/spec/mongoid/shardable_spec.rb +181 -31
  731. data/spec/mongoid/stateful_spec.rb +152 -10
  732. data/spec/mongoid/tasks/database_rake_spec.rb +193 -42
  733. data/spec/mongoid/tasks/database_spec.rb +175 -2
  734. data/spec/mongoid/tasks/encryption_spec.rb +187 -0
  735. data/spec/mongoid/threaded_spec.rb +40 -3
  736. data/spec/mongoid/timestamps/created/short_spec.rb +2 -2
  737. data/spec/mongoid/timestamps/created_spec.rb +2 -2
  738. data/spec/mongoid/timestamps/timeless_spec.rb +3 -3
  739. data/spec/mongoid/timestamps/updated/short_spec.rb +4 -4
  740. data/spec/mongoid/timestamps/updated_spec.rb +4 -4
  741. data/spec/mongoid/timestamps_spec.rb +399 -11
  742. data/spec/mongoid/timestamps_spec_models.rb +68 -0
  743. data/spec/mongoid/touchable_spec.rb +971 -54
  744. data/spec/mongoid/touchable_spec_models.rb +154 -0
  745. data/spec/mongoid/traversable_spec.rb +79 -37
  746. data/spec/mongoid/validatable/associated_spec.rb +14 -31
  747. data/spec/mongoid/validatable/format_spec.rb +1 -1
  748. data/spec/mongoid/validatable/length_spec.rb +1 -1
  749. data/spec/mongoid/validatable/numericality_spec.rb +1 -1
  750. data/spec/mongoid/validatable/presence_spec.rb +27 -23
  751. data/spec/mongoid/validatable/uniqueness_spec.rb +170 -99
  752. data/spec/mongoid/validatable_spec.rb +4 -4
  753. data/spec/mongoid/warnings_spec.rb +36 -0
  754. data/spec/mongoid_spec.rb +61 -11
  755. data/spec/rails/controller_extension/controller_runtime_spec.rb +3 -3
  756. data/spec/rails/mongoid_spec.rb +28 -132
  757. data/spec/shared/bin/get-mongodb-download-url +17 -0
  758. data/spec/shared/bin/s3-copy +45 -0
  759. data/spec/shared/bin/s3-upload +69 -0
  760. data/spec/shared/lib/mrss/cluster_config.rb +24 -4
  761. data/spec/shared/lib/mrss/constraints.rb +77 -29
  762. data/spec/shared/lib/mrss/docker_runner.rb +40 -4
  763. data/spec/shared/lib/mrss/eg_config_utils.rb +51 -0
  764. data/spec/shared/lib/mrss/event_subscriber.rb +210 -0
  765. data/spec/shared/lib/mrss/lite_constraints.rb +64 -1
  766. data/spec/shared/lib/mrss/server_version_registry.rb +78 -34
  767. data/spec/shared/lib/mrss/session_registry.rb +69 -0
  768. data/spec/shared/lib/mrss/session_registry_legacy.rb +60 -0
  769. data/spec/shared/lib/mrss/spec_organizer.rb +32 -2
  770. data/spec/shared/lib/mrss/utils.rb +37 -0
  771. data/spec/shared/share/Dockerfile.erb +123 -71
  772. data/spec/shared/share/haproxy-1.conf +16 -0
  773. data/spec/shared/share/haproxy-2.conf +17 -0
  774. data/spec/shared/shlib/config.sh +27 -0
  775. data/spec/shared/shlib/distro.sh +2 -1
  776. data/spec/shared/shlib/server.sh +187 -40
  777. data/spec/shared/shlib/set_env.sh +49 -31
  778. data/spec/spec_helper.rb +46 -49
  779. data/spec/support/authorization.rb +1 -1
  780. data/spec/support/client_registry.rb +10 -0
  781. data/spec/support/constraints.rb +25 -1
  782. data/spec/support/crypt/models.rb +50 -0
  783. data/spec/support/crypt.rb +80 -0
  784. data/spec/support/expectations.rb +1 -1
  785. data/spec/support/feature_sandbox.rb +72 -0
  786. data/spec/support/helpers.rb +1 -0
  787. data/spec/support/immutable_ids.rb +119 -0
  788. data/spec/support/macros.rb +107 -1
  789. data/spec/support/models/account.rb +2 -2
  790. data/spec/support/models/acolyte.rb +1 -1
  791. data/spec/support/models/actor.rb +1 -1
  792. data/spec/support/models/actress.rb +1 -1
  793. data/spec/support/models/address.rb +7 -1
  794. data/spec/support/models/address_component.rb +1 -1
  795. data/spec/support/models/address_number.rb +1 -1
  796. data/spec/support/models/agency.rb +1 -1
  797. data/spec/support/models/agent.rb +1 -1
  798. data/spec/support/models/album.rb +1 -1
  799. data/spec/support/models/alert.rb +1 -1
  800. data/spec/support/models/animal.rb +1 -1
  801. data/spec/support/models/answer.rb +1 -1
  802. data/spec/support/models/appointment.rb +1 -1
  803. data/spec/support/models/armrest.rb +1 -1
  804. data/spec/support/models/array_field.rb +1 -1
  805. data/spec/support/models/article.rb +1 -1
  806. data/spec/support/models/artist.rb +3 -2
  807. data/spec/support/models/artwork.rb +1 -1
  808. data/spec/support/models/audible_sound.rb +4 -0
  809. data/spec/support/models/audio.rb +1 -1
  810. data/spec/support/models/augmentation.rb +13 -1
  811. data/spec/support/models/author.rb +1 -1
  812. data/spec/support/models/baby.rb +1 -1
  813. data/spec/support/models/band.rb +13 -1
  814. data/spec/support/models/bar.rb +1 -1
  815. data/spec/support/models/basic.rb +1 -1
  816. data/spec/support/models/bed.rb +1 -1
  817. data/spec/support/models/big_palette.rb +1 -1
  818. data/spec/support/models/birthday.rb +1 -1
  819. data/spec/support/models/bolt.rb +8 -0
  820. data/spec/support/models/bomb.rb +1 -1
  821. data/spec/support/models/book.rb +2 -1
  822. data/spec/support/models/breed.rb +1 -1
  823. data/spec/support/models/browser.rb +1 -1
  824. data/spec/support/models/building.rb +3 -1
  825. data/spec/support/models/building_address.rb +1 -1
  826. data/spec/support/models/bus.rb +1 -1
  827. data/spec/support/models/business.rb +1 -1
  828. data/spec/support/models/callback_test.rb +1 -1
  829. data/spec/support/models/canvas.rb +1 -1
  830. data/spec/support/models/car.rb +1 -1
  831. data/spec/support/models/cat.rb +1 -1
  832. data/spec/support/models/catalog.rb +25 -0
  833. data/spec/support/models/category.rb +1 -1
  834. data/spec/support/models/child.rb +1 -1
  835. data/spec/support/models/child_doc.rb +4 -4
  836. data/spec/support/models/church.rb +1 -1
  837. data/spec/support/models/circle.rb +1 -1
  838. data/spec/support/models/circuit.rb +1 -1
  839. data/spec/support/models/circus.rb +4 -1
  840. data/spec/support/models/code.rb +3 -1
  841. data/spec/support/models/coding/pull_request.rb +1 -1
  842. data/spec/support/models/coding.rb +1 -1
  843. data/spec/support/models/comment.rb +1 -1
  844. data/spec/support/models/company.rb +1 -1
  845. data/spec/support/models/consumption_period.rb +1 -1
  846. data/spec/support/models/contextable_item.rb +1 -1
  847. data/spec/support/models/contractor.rb +1 -1
  848. data/spec/support/models/cookie.rb +1 -1
  849. data/spec/support/models/country_code.rb +3 -1
  850. data/spec/support/models/courier_job.rb +1 -1
  851. data/spec/support/models/cover.rb +11 -0
  852. data/spec/support/models/crate.rb +1 -1
  853. data/spec/support/models/customer.rb +1 -1
  854. data/spec/support/models/customer_address.rb +1 -1
  855. data/spec/support/models/deed.rb +1 -1
  856. data/spec/support/models/definition.rb +1 -1
  857. data/spec/support/models/delegating_patient.rb +1 -1
  858. data/spec/support/models/description.rb +1 -1
  859. data/spec/support/models/dictionary.rb +1 -1
  860. data/spec/support/models/division.rb +1 -1
  861. data/spec/support/models/doctor.rb +1 -1
  862. data/spec/support/models/dog.rb +1 -1
  863. data/spec/support/models/dokument.rb +1 -1
  864. data/spec/support/models/draft.rb +1 -1
  865. data/spec/support/models/dragon.rb +1 -1
  866. data/spec/support/models/driver.rb +1 -1
  867. data/spec/support/models/drug.rb +1 -1
  868. data/spec/support/models/dungeon.rb +1 -1
  869. data/spec/support/models/edit.rb +1 -1
  870. data/spec/support/models/email.rb +1 -1
  871. data/spec/support/models/employer.rb +1 -1
  872. data/spec/support/models/entry.rb +1 -1
  873. data/spec/support/models/eraser.rb +1 -1
  874. data/spec/support/models/even.rb +1 -1
  875. data/spec/support/models/event.rb +1 -1
  876. data/spec/support/models/exhibition.rb +1 -1
  877. data/spec/support/models/exhibitor.rb +1 -1
  878. data/spec/support/models/explosion.rb +1 -1
  879. data/spec/support/models/eye.rb +1 -1
  880. data/spec/support/models/eye_bowl.rb +1 -1
  881. data/spec/support/models/face.rb +1 -1
  882. data/spec/support/models/fanatic.rb +9 -0
  883. data/spec/support/models/favorite.rb +8 -2
  884. data/spec/support/models/filesystem.rb +1 -1
  885. data/spec/support/models/fire_hydrant.rb +1 -1
  886. data/spec/support/models/firefox.rb +1 -1
  887. data/spec/support/models/fish.rb +1 -1
  888. data/spec/support/models/folder.rb +1 -1
  889. data/spec/support/models/folder_item.rb +1 -1
  890. data/spec/support/models/fruits.rb +1 -1
  891. data/spec/support/models/game.rb +1 -1
  892. data/spec/support/models/ghost.rb +1 -1
  893. data/spec/support/models/guitar.rb +1 -1
  894. data/spec/support/models/hole.rb +13 -0
  895. data/spec/support/models/home.rb +1 -1
  896. data/spec/support/models/house.rb +1 -1
  897. data/spec/support/models/html_writer.rb +1 -1
  898. data/spec/support/models/id_key.rb +1 -1
  899. data/spec/support/models/idnodef.rb +1 -1
  900. data/spec/support/models/image.rb +1 -1
  901. data/spec/support/models/implant.rb +10 -1
  902. data/spec/support/models/instrument.rb +1 -1
  903. data/spec/support/models/item.rb +1 -1
  904. data/spec/support/models/jar.rb +1 -1
  905. data/spec/support/models/kaleidoscope.rb +1 -1
  906. data/spec/support/models/kangaroo.rb +1 -1
  907. data/spec/support/models/label.rb +5 -2
  908. data/spec/support/models/language.rb +1 -1
  909. data/spec/support/models/lat_lng.rb +1 -1
  910. data/spec/support/models/league.rb +1 -1
  911. data/spec/support/models/learner.rb +1 -1
  912. data/spec/support/models/line_item.rb +1 -1
  913. data/spec/support/models/location.rb +1 -1
  914. data/spec/support/models/login.rb +1 -1
  915. data/spec/support/models/manufacturer.rb +1 -1
  916. data/spec/support/models/meat.rb +1 -1
  917. data/spec/support/models/membership.rb +2 -1
  918. data/spec/support/models/message.rb +1 -1
  919. data/spec/support/models/minim.rb +1 -1
  920. data/spec/support/models/mixed_drink.rb +1 -1
  921. data/spec/support/models/mop.rb +10 -1
  922. data/spec/support/models/movie.rb +1 -1
  923. data/spec/support/models/my_hash.rb +1 -1
  924. data/spec/support/models/name.rb +11 -1
  925. data/spec/support/models/name_only.rb +1 -1
  926. data/spec/support/models/node.rb +1 -1
  927. data/spec/support/models/note.rb +1 -1
  928. data/spec/support/models/nut.rb +8 -0
  929. data/spec/support/models/odd.rb +1 -1
  930. data/spec/support/models/order.rb +3 -1
  931. data/spec/support/models/ordered_post.rb +2 -2
  932. data/spec/support/models/ordered_preference.rb +1 -1
  933. data/spec/support/models/oscar.rb +1 -1
  934. data/spec/support/models/other_owner_object.rb +1 -1
  935. data/spec/support/models/override.rb +1 -1
  936. data/spec/support/models/ownable.rb +1 -1
  937. data/spec/support/models/owner.rb +1 -1
  938. data/spec/support/models/pack.rb +1 -1
  939. data/spec/support/models/page.rb +1 -1
  940. data/spec/support/models/page_question.rb +1 -1
  941. data/spec/support/models/palette.rb +1 -1
  942. data/spec/support/models/parent.rb +1 -1
  943. data/spec/support/models/parent_doc.rb +1 -1
  944. data/spec/support/models/passport.rb +15 -1
  945. data/spec/support/models/patient.rb +1 -1
  946. data/spec/support/models/pdf_writer.rb +1 -1
  947. data/spec/support/models/pencil.rb +1 -1
  948. data/spec/support/models/person.rb +19 -1
  949. data/spec/support/models/pet.rb +1 -1
  950. data/spec/support/models/pet_owner.rb +1 -1
  951. data/spec/support/models/phone.rb +3 -2
  952. data/spec/support/models/piano.rb +1 -1
  953. data/spec/support/models/pizza.rb +1 -1
  954. data/spec/support/models/player.rb +3 -1
  955. data/spec/support/models/post.rb +1 -1
  956. data/spec/support/models/post_genre.rb +1 -1
  957. data/spec/support/models/powerup.rb +13 -1
  958. data/spec/support/models/preference.rb +1 -1
  959. data/spec/support/models/princess.rb +1 -1
  960. data/spec/support/models/product.rb +2 -1
  961. data/spec/support/models/profile.rb +1 -1
  962. data/spec/support/models/pronunciation.rb +1 -1
  963. data/spec/support/models/pub.rb +1 -1
  964. data/spec/support/models/publication/encyclopedia.rb +1 -1
  965. data/spec/support/models/publication/review.rb +1 -1
  966. data/spec/support/models/publication.rb +1 -1
  967. data/spec/support/models/purchase.rb +1 -1
  968. data/spec/support/models/purchased_item.rb +11 -0
  969. data/spec/support/models/purse.rb +9 -0
  970. data/spec/support/models/question.rb +1 -1
  971. data/spec/support/models/quiz.rb +1 -1
  972. data/spec/support/models/rating.rb +1 -1
  973. data/spec/support/models/record.rb +1 -1
  974. data/spec/support/models/registry.rb +2 -1
  975. data/spec/support/models/role.rb +1 -1
  976. data/spec/support/models/root_category.rb +1 -1
  977. data/spec/support/models/sandbox/app/models/app_models_message.rb +4 -0
  978. data/spec/support/models/sandbox/lib/models/lib_models_message.rb +4 -0
  979. data/spec/support/models/sandbox/sandbox_message.rb +4 -0
  980. data/spec/support/models/sandbox/sandbox_user.rb +4 -0
  981. data/spec/support/models/sandbox/subdir/sandbox_comment.rb +4 -0
  982. data/spec/support/models/sandwich.rb +1 -1
  983. data/spec/support/models/scheduler.rb +1 -1
  984. data/spec/support/models/school.rb +15 -0
  985. data/spec/support/models/scribe.rb +1 -1
  986. data/spec/support/models/sealer.rb +8 -0
  987. data/spec/support/models/seat.rb +1 -1
  988. data/spec/support/models/seo.rb +1 -1
  989. data/spec/support/models/series.rb +1 -1
  990. data/spec/support/models/server.rb +1 -1
  991. data/spec/support/models/service.rb +1 -1
  992. data/spec/support/models/shape.rb +1 -1
  993. data/spec/support/models/shelf.rb +1 -1
  994. data/spec/support/models/shield.rb +19 -0
  995. data/spec/support/models/shipment_address.rb +1 -1
  996. data/spec/support/models/shipping_container.rb +1 -1
  997. data/spec/support/models/shipping_pack.rb +1 -1
  998. data/spec/support/models/shirt.rb +12 -0
  999. data/spec/support/models/shop.rb +1 -1
  1000. data/spec/support/models/short_agent.rb +1 -1
  1001. data/spec/support/models/short_quiz.rb +1 -1
  1002. data/spec/support/models/simple.rb +1 -1
  1003. data/spec/support/models/slave.rb +1 -1
  1004. data/spec/support/models/song.rb +1 -1
  1005. data/spec/support/models/sound.rb +1 -1
  1006. data/spec/support/models/spacer.rb +8 -0
  1007. data/spec/support/models/square.rb +1 -1
  1008. data/spec/support/models/staff.rb +1 -1
  1009. data/spec/support/models/store_as_dup_test1.rb +1 -1
  1010. data/spec/support/models/store_as_dup_test2.rb +1 -1
  1011. data/spec/support/models/store_as_dup_test3.rb +1 -1
  1012. data/spec/support/models/store_as_dup_test4.rb +1 -1
  1013. data/spec/support/models/strategy.rb +1 -1
  1014. data/spec/support/models/student.rb +15 -0
  1015. data/spec/support/models/sub_item.rb +1 -1
  1016. data/spec/support/models/subscription.rb +1 -1
  1017. data/spec/support/models/survey.rb +1 -1
  1018. data/spec/support/models/symptom.rb +1 -1
  1019. data/spec/support/models/system_role.rb +1 -0
  1020. data/spec/support/models/tag.rb +1 -1
  1021. data/spec/support/models/target.rb +1 -1
  1022. data/spec/support/models/template.rb +1 -1
  1023. data/spec/support/models/thing.rb +1 -1
  1024. data/spec/support/models/threadlocker.rb +8 -0
  1025. data/spec/support/models/title.rb +1 -1
  1026. data/spec/support/models/tool.rb +1 -1
  1027. data/spec/support/models/topping.rb +1 -1
  1028. data/spec/support/models/toy.rb +1 -1
  1029. data/spec/support/models/track.rb +1 -1
  1030. data/spec/support/models/translation.rb +1 -1
  1031. data/spec/support/models/tree.rb +1 -1
  1032. data/spec/support/models/truck.rb +1 -1
  1033. data/spec/support/models/updatable.rb +1 -1
  1034. data/spec/support/models/user.rb +1 -1
  1035. data/spec/support/models/user_account.rb +1 -1
  1036. data/spec/support/models/validation_callback.rb +1 -1
  1037. data/spec/support/models/vehicle.rb +1 -1
  1038. data/spec/support/models/version.rb +1 -1
  1039. data/spec/support/models/vertex.rb +1 -1
  1040. data/spec/support/models/vet_visit.rb +1 -1
  1041. data/spec/support/models/video.rb +1 -1
  1042. data/spec/support/models/video_game.rb +1 -1
  1043. data/spec/support/models/washer.rb +8 -0
  1044. data/spec/support/models/weapon.rb +13 -1
  1045. data/spec/support/models/wiki_page.rb +1 -1
  1046. data/spec/support/models/word.rb +1 -1
  1047. data/spec/support/models/word_origin.rb +1 -1
  1048. data/spec/support/models/writer.rb +1 -1
  1049. data/spec/support/rails_mock.rb +32 -0
  1050. data/spec/support/schema_maps/schema_map_aws.json +17 -0
  1051. data/spec/support/schema_maps/schema_map_aws_key_alt_names.json +12 -0
  1052. data/spec/support/schema_maps/schema_map_azure.json +17 -0
  1053. data/spec/support/schema_maps/schema_map_azure_key_alt_names.json +12 -0
  1054. data/spec/support/schema_maps/schema_map_gcp.json +17 -0
  1055. data/spec/support/schema_maps/schema_map_gcp_key_alt_names.json +12 -0
  1056. data/spec/support/schema_maps/schema_map_kmip.json +17 -0
  1057. data/spec/support/schema_maps/schema_map_kmip_key_alt_names.json +12 -0
  1058. data/spec/support/schema_maps/schema_map_local.json +18 -0
  1059. data/spec/support/schema_maps/schema_map_local_key_alt_names.json +12 -0
  1060. data/spec/support/shared/time.rb +3 -22
  1061. data/spec/support/sinatra_mock.rb +7 -0
  1062. data/spec/support/spec_config.rb +42 -7
  1063. data.tar.gz.sig +0 -0
  1064. metadata +883 -562
  1065. metadata.gz.sig +0 -0
  1066. data/lib/mongoid/association/referenced/eager.rb +0 -184
  1067. data/lib/mongoid/association/referenced/has_one/nested_builder.rb +0 -128
  1068. data/lib/mongoid/contextual/geo_near.rb +0 -269
  1069. data/lib/mongoid/errors/eager_load.rb +0 -26
  1070. data/lib/mongoid/errors/invalid_session_use.rb +0 -26
  1071. data/lib/mongoid/errors/invalid_storage_parent.rb +0 -28
  1072. data/lib/mongoid/errors/invalid_value.rb +0 -18
  1073. data/lib/mongoid/query_cache.rb +0 -333
  1074. data/lib/support/ruby_version.rb +0 -29
  1075. data/spec/mongoid/contextual/geo_near_spec.rb +0 -472
  1076. data/spec/mongoid/criteria/queryable/extensions/bignum_spec.rb +0 -61
  1077. data/spec/mongoid/criteria/queryable/extensions/fixnum_spec.rb +0 -61
  1078. data/spec/mongoid/extensions_spec.rb +0 -32
  1079. data/spec/mongoid/query_cache_middleware_spec.rb +0 -61
  1080. data/spec/mongoid/query_cache_spec.rb +0 -978
  1081. data/spec/support/cluster_config.rb +0 -158
  1082. data/spec/support/session_registry.rb +0 -50
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
- # encoding: utf-8
2
+ # rubocop:todo all
3
3
 
4
4
  require "spec_helper"
5
5
 
@@ -41,7 +41,7 @@ describe Mongoid::Criteria do
41
41
  context "when the entries are the same" do
42
42
 
43
43
  let!(:band) do
44
- Band.create(name: "Depeche Mode")
44
+ Band.create!(name: "Depeche Mode")
45
45
  end
46
46
 
47
47
  let(:other) do
@@ -56,11 +56,11 @@ describe Mongoid::Criteria do
56
56
  context "when the entries are not the same" do
57
57
 
58
58
  let!(:band) do
59
- Band.create(name: "Depeche Mode")
59
+ Band.create!(name: "Depeche Mode")
60
60
  end
61
61
 
62
62
  let!(:other_band) do
63
- Band.create(name: "Tool")
63
+ Band.create!(name: "Tool")
64
64
  end
65
65
 
66
66
  let(:other) do
@@ -105,21 +105,21 @@ describe Mongoid::Criteria do
105
105
  describe "#asc" do
106
106
 
107
107
  let(:person) do
108
- Person.create
108
+ Person.create!
109
109
  end
110
110
 
111
111
  context "when the documents are embedded" do
112
112
 
113
113
  let!(:hobrecht) do
114
- person.addresses.create(street: "hobrecht", name: "hobrecht")
114
+ person.addresses.create!(street: "hobrecht", name: "hobrecht")
115
115
  end
116
116
 
117
117
  let!(:friedel) do
118
- person.addresses.create(street: "friedel", name: "friedel")
118
+ person.addresses.create!(street: "friedel", name: "friedel")
119
119
  end
120
120
 
121
121
  let!(:pfluger) do
122
- person.addresses.create(street: "pfluger", name: "pfluger")
122
+ person.addresses.create!(street: "pfluger", name: "pfluger")
123
123
  end
124
124
 
125
125
  let(:criteria) do
@@ -135,7 +135,7 @@ describe Mongoid::Criteria do
135
135
  describe "#batch_size" do
136
136
 
137
137
  let(:person) do
138
- Person.create
138
+ Person.create!
139
139
  end
140
140
 
141
141
  let(:criteria) do
@@ -154,7 +154,7 @@ describe Mongoid::Criteria do
154
154
  describe "#read" do
155
155
 
156
156
  let(:person) do
157
- Person.create
157
+ Person.create!
158
158
  end
159
159
 
160
160
  let(:criteria) do
@@ -171,11 +171,11 @@ describe Mongoid::Criteria do
171
171
  context "when provided a single field" do
172
172
 
173
173
  let!(:depeche) do
174
- Band.create(name: "Depeche Mode", likes: 1000)
174
+ Band.create!(name: "Depeche Mode", likes: 1000)
175
175
  end
176
176
 
177
177
  let!(:tool) do
178
- Band.create(name: "Tool", likes: 500)
178
+ Band.create!(name: "Tool", likes: 500)
179
179
  end
180
180
 
181
181
  let(:criteria) do
@@ -213,11 +213,11 @@ describe Mongoid::Criteria do
213
213
  context "when provided a single field" do
214
214
 
215
215
  let!(:depeche) do
216
- Band.create(name: "Depeche Mode", likes: 1000)
216
+ Band.create!(name: "Depeche Mode", likes: 1000)
217
217
  end
218
218
 
219
219
  let!(:tool) do
220
- Band.create(name: "Tool", likes: 500)
220
+ Band.create!(name: "Tool", likes: 500)
221
221
  end
222
222
 
223
223
  let(:criteria) do
@@ -239,11 +239,11 @@ describe Mongoid::Criteria do
239
239
  describe "\##{method}" do
240
240
 
241
241
  let!(:match) do
242
- Band.create(genres: [ "electro", "dub" ])
242
+ Band.create!(genres: [ "electro", "dub" ])
243
243
  end
244
244
 
245
245
  let!(:non_match) do
246
- Band.create(genres: [ "house" ])
246
+ Band.create!(genres: [ "house" ])
247
247
  end
248
248
 
249
249
  let(:criteria) do
@@ -261,11 +261,11 @@ describe Mongoid::Criteria do
261
261
  describe "\##{method}" do
262
262
 
263
263
  let!(:match) do
264
- Band.create(name: "Depeche Mode", genres: [ "electro" ])
264
+ Band.create!(name: "Depeche Mode", genres: [ "electro" ])
265
265
  end
266
266
 
267
267
  let!(:non_match) do
268
- Band.create(genres: [ "house" ])
268
+ Band.create!(genres: [ "house" ])
269
269
  end
270
270
 
271
271
  let(:criteria) do
@@ -281,41 +281,26 @@ describe Mongoid::Criteria do
281
281
  describe "#as_json" do
282
282
 
283
283
  let!(:band) do
284
- Band.create(name: "Depeche Mode")
284
+ Band.create!(name: "Depeche Mode")
285
285
  end
286
286
 
287
287
  let(:criteria) do
288
288
  Band.where(name: "Depeche Mode")
289
289
  end
290
290
 
291
- # as_json changed in rails 6 to call as_json on serializable_hash.
292
- # https://github.com/rails/rails/commit/2e5cb980a448e7f4ab00df6e9ad4c1cc456616aa
293
-
294
- context 'rails < 6' do
295
- max_rails_version '5.2'
296
-
297
- it "returns the criteria as a json hash" do
298
- expect(criteria.as_json).to eq([ band.serializable_hash ])
299
- end
300
- end
301
-
302
- context 'rails >= 6' do
303
- min_rails_version '6.0'
304
-
305
- it "returns the criteria as a json hash" do
306
- expect(criteria.as_json).to eq([ band.serializable_hash.as_json ])
307
- end
291
+ it "returns the criteria as a json hash" do
292
+ expect(criteria.as_json).to eq([ band.serializable_hash.as_json ])
308
293
  end
309
294
  end
310
295
 
311
296
  describe "#between" do
312
297
 
313
298
  let!(:match) do
314
- Band.create(member_count: 3)
299
+ Band.create!(member_count: 3)
315
300
  end
316
301
 
317
302
  let!(:non_match) do
318
- Band.create(member_count: 10)
303
+ Band.create!(member_count: 10)
319
304
  end
320
305
 
321
306
  let(:criteria) do
@@ -381,13 +366,14 @@ describe Mongoid::Criteria do
381
366
  describe "#cache" do
382
367
 
383
368
  let!(:person) do
384
- Person.create
369
+ Person.create!
385
370
  end
386
371
 
387
- context "when no eager loading is involved" do
372
+ context "when the query cache is enabled" do
373
+ query_cache_enabled
388
374
 
389
375
  let(:criteria) do
390
- Person.all.cache
376
+ Person.all
391
377
  end
392
378
 
393
379
  before do
@@ -395,17 +381,19 @@ describe Mongoid::Criteria do
395
381
  end
396
382
 
397
383
  it "does not hit the database after first iteration" do
398
- expect(criteria.context.view).to receive(:each).never
399
- criteria.each do |doc|
400
- expect(doc).to eq(person)
384
+ expect_no_queries do
385
+ criteria.each do |doc|
386
+ expect(doc).to eq(person)
387
+ end
401
388
  end
402
389
  end
403
390
  end
404
391
 
405
392
  context "when the criteria is eager loading" do
393
+ query_cache_enabled
406
394
 
407
395
  let(:criteria) do
408
- Person.includes(:posts).cache
396
+ Person.includes(:posts)
409
397
  end
410
398
 
411
399
  before do
@@ -413,9 +401,10 @@ describe Mongoid::Criteria do
413
401
  end
414
402
 
415
403
  it "does not hit the database after first iteration" do
416
- expect(criteria.context.view).to receive(:each).never
417
- criteria.each do |doc|
418
- expect(doc).to eq(person)
404
+ expect_no_queries do
405
+ criteria.each do |doc|
406
+ expect(doc).to eq(person)
407
+ end
419
408
  end
420
409
  end
421
410
  end
@@ -492,17 +481,6 @@ describe Mongoid::Criteria do
492
481
  end
493
482
  end
494
483
 
495
- describe "#cache" do
496
-
497
- let(:criteria) do
498
- Band.where(name: "Depeche Mode")
499
- end
500
-
501
- it "sets the cache option to true" do
502
- expect(criteria.cache).to be_cached
503
- end
504
- end
505
-
506
484
  describe "#context" do
507
485
 
508
486
  context "when the model is embedded" do
@@ -533,11 +511,11 @@ describe Mongoid::Criteria do
533
511
  describe "#delete" do
534
512
 
535
513
  let(:depeche) do
536
- Band.create(name: "Depeche Mode")
514
+ Band.create!(name: "Depeche Mode")
537
515
  end
538
516
 
539
517
  let(:tool) do
540
- Band.create(name: "Tool")
518
+ Band.create!(name: "Tool")
541
519
  end
542
520
 
543
521
  context "when no selector is provided" do
@@ -591,7 +569,7 @@ describe Mongoid::Criteria do
591
569
  describe "#each" do
592
570
 
593
571
  let!(:band) do
594
- Band.create(name: "Depeche Mode")
572
+ Band.create!(name: "Depeche Mode")
595
573
  end
596
574
 
597
575
  context "when provided a block" do
@@ -611,14 +589,14 @@ describe Mongoid::Criteria do
611
589
  describe "#elem_match" do
612
590
 
613
591
  let!(:match) do
614
- Band.create(name: "Depeche Mode").tap do |band|
592
+ Band.create!(name: "Depeche Mode").tap do |band|
615
593
  r = band.records
616
- r.create(name: "101")
594
+ r.create!(name: "101")
617
595
  end
618
596
  end
619
597
 
620
598
  let!(:non_match) do
621
- Band.create(genres: [ "house" ])
599
+ Band.create!(genres: [ "house" ])
622
600
  end
623
601
 
624
602
  let(:criteria) do
@@ -664,7 +642,7 @@ describe Mongoid::Criteria do
664
642
  context "when matching documents exist" do
665
643
 
666
644
  let!(:match) do
667
- Band.create(name: "Depeche Mode")
645
+ Band.create!(name: "Depeche Mode")
668
646
  end
669
647
 
670
648
  let(:criteria) do
@@ -679,7 +657,7 @@ describe Mongoid::Criteria do
679
657
  context "when no matching documents exist" do
680
658
 
681
659
  let!(:nonmatch) do
682
- Band.create(name: "New Order")
660
+ Band.create!(name: "New Order")
683
661
  end
684
662
 
685
663
  let(:criteria) do
@@ -695,11 +673,11 @@ describe Mongoid::Criteria do
695
673
  describe "#exists" do
696
674
 
697
675
  let!(:match) do
698
- Band.create(name: "Depeche Mode")
676
+ Band.create!(name: "Depeche Mode")
699
677
  end
700
678
 
701
679
  let!(:non_match) do
702
- Band.create
680
+ Band.create!
703
681
  end
704
682
 
705
683
  let(:criteria) do
@@ -716,7 +694,7 @@ describe Mongoid::Criteria do
716
694
  context "when matching documents exist" do
717
695
 
718
696
  let!(:match) do
719
- Band.create(name: "Depeche Mode")
697
+ Band.create!(name: "Depeche Mode")
720
698
  end
721
699
 
722
700
  let(:criteria) do
@@ -838,8 +816,8 @@ describe Mongoid::Criteria do
838
816
  end
839
817
  end
840
818
 
841
- context "when given a Proc" do
842
- it "behaves as Enumerable" do
819
+ context "when given a Proc without a block" do
820
+ it "raises an error" do
843
821
  lambda do
844
822
  criteria.find(-> {"default"})
845
823
  # Proc is not serializable to a BSON type
@@ -858,11 +836,11 @@ describe Mongoid::Criteria do
858
836
  describe "#find_one_and_update" do
859
837
 
860
838
  let!(:depeche) do
861
- Band.create(name: "Depeche Mode")
839
+ Band.create!(name: "Depeche Mode")
862
840
  end
863
841
 
864
842
  let!(:tool) do
865
- Band.create(name: "Tool")
843
+ Band.create!(name: "Tool")
866
844
  end
867
845
 
868
846
  context "when the selector matches" do
@@ -1001,7 +979,7 @@ describe Mongoid::Criteria do
1001
979
  it "deletes the document from the database" do
1002
980
  expect {
1003
981
  depeche.reload
1004
- }.to raise_error(Mongoid::Errors::DocumentNotFound)
982
+ }.to raise_error(Mongoid::Errors::DocumentNotFound, /Document\(s\) not found for class Band with id\(s\)/)
1005
983
  end
1006
984
  end
1007
985
  end
@@ -1052,19 +1030,18 @@ describe Mongoid::Criteria do
1052
1030
  end
1053
1031
  end
1054
1032
 
1055
- describe "#geo_near" do
1056
- max_server_version '4.0'
1033
+ describe "#eq" do
1057
1034
 
1058
- before do
1059
- Bar.create_indexes
1035
+ let!(:match) do
1036
+ Band.create(member_count: 5)
1060
1037
  end
1061
1038
 
1062
- let!(:match) do
1063
- Bar.create(location: [ 52.30, 13.25 ])
1039
+ let!(:non_match) do
1040
+ Band.create(member_count: 1)
1064
1041
  end
1065
1042
 
1066
1043
  let(:criteria) do
1067
- Bar.geo_near([ 52, 13 ]).max_distance(10).spherical
1044
+ Band.eq(member_count: 5)
1068
1045
  end
1069
1046
 
1070
1047
  it "returns the matching documents" do
@@ -1075,11 +1052,11 @@ describe Mongoid::Criteria do
1075
1052
  describe "#gt" do
1076
1053
 
1077
1054
  let!(:match) do
1078
- Band.create(member_count: 5)
1055
+ Band.create!(member_count: 5)
1079
1056
  end
1080
1057
 
1081
1058
  let!(:non_match) do
1082
- Band.create(member_count: 1)
1059
+ Band.create!(member_count: 1)
1083
1060
  end
1084
1061
 
1085
1062
  let(:criteria) do
@@ -1094,11 +1071,11 @@ describe Mongoid::Criteria do
1094
1071
  describe "#gte" do
1095
1072
 
1096
1073
  let!(:match) do
1097
- Band.create(member_count: 5)
1074
+ Band.create!(member_count: 5)
1098
1075
  end
1099
1076
 
1100
1077
  let!(:non_match) do
1101
- Band.create(member_count: 1)
1078
+ Band.create!(member_count: 1)
1102
1079
  end
1103
1080
 
1104
1081
  let(:criteria) do
@@ -1117,11 +1094,11 @@ describe Mongoid::Criteria do
1117
1094
  context "when querying on a normal field" do
1118
1095
 
1119
1096
  let!(:match) do
1120
- Band.create(genres: [ "electro", "dub" ])
1097
+ Band.create!(genres: [ "electro", "dub" ])
1121
1098
  end
1122
1099
 
1123
1100
  let!(:non_match) do
1124
- Band.create(genres: [ "house" ])
1101
+ Band.create!(genres: [ "house" ])
1125
1102
  end
1126
1103
 
1127
1104
  let(:criteria) do
@@ -1140,7 +1117,7 @@ describe Mongoid::Criteria do
1140
1117
  end
1141
1118
 
1142
1119
  let!(:match_one) do
1143
- Person.create(preference_ids: [ id ])
1120
+ Person.create!(preference_ids: [ id ])
1144
1121
  end
1145
1122
 
1146
1123
  context "when providing valid ids" do
@@ -1181,7 +1158,7 @@ describe Mongoid::Criteria do
1181
1158
  context "when the relation is a one to one" do
1182
1159
 
1183
1160
  let!(:game) do
1184
- Game.create
1161
+ Game.create!
1185
1162
  end
1186
1163
 
1187
1164
  let(:criteria) do
@@ -1216,1276 +1193,207 @@ describe Mongoid::Criteria do
1216
1193
  end
1217
1194
  end
1218
1195
 
1219
- describe "#includes" do
1196
+ describe "#lt" do
1220
1197
 
1221
- let!(:person) do
1222
- Person.create(age: 1)
1198
+ let!(:match) do
1199
+ Band.create!(member_count: 1)
1223
1200
  end
1224
1201
 
1225
- context "when providing a name that is not a relation" do
1226
-
1227
- it "raises an error" do
1228
- expect {
1229
- Person.includes(:members)
1230
- }.to raise_error(Mongoid::Errors::InvalidIncludes)
1231
- end
1202
+ let!(:non_match) do
1203
+ Band.create!(member_count: 5)
1232
1204
  end
1233
1205
 
1234
- context "when providing one association" do
1235
-
1236
- let!(:user) do
1237
- User.create(posts: [ post1 ])
1238
- end
1239
-
1240
- let!(:post1) do
1241
- Post.create
1242
- end
1243
-
1244
- let(:result) do
1245
- User.includes(:posts).first
1246
- end
1247
-
1248
- it "executes the query" do
1249
- expect(result).to eq(user)
1250
- end
1251
-
1252
- it "includes the related objects" do
1253
- expect(result.posts).to eq([ post1 ])
1254
- end
1206
+ let(:criteria) do
1207
+ Band.lt(member_count: 4)
1255
1208
  end
1256
1209
 
1257
- context "when providing a list of associations" do
1258
-
1259
- let!(:user) do
1260
- User.create(posts: [ post1 ], descriptions: [ description1 ])
1261
- end
1262
-
1263
- let!(:post1) do
1264
- Post.create
1265
- end
1266
-
1267
- let!(:description1) do
1268
- Description.create(details: 1)
1269
- end
1210
+ it "returns the matching documents" do
1211
+ expect(criteria).to eq([ match ])
1212
+ end
1213
+ end
1270
1214
 
1271
- let(:result) do
1272
- User.includes(:posts, :descriptions).first
1273
- end
1215
+ describe "#lte" do
1274
1216
 
1275
- it "executes the query" do
1276
- expect(result).to eq(user)
1277
- end
1217
+ let!(:match) do
1218
+ Band.create!(member_count: 4)
1219
+ end
1278
1220
 
1279
- it "includes the related objects" do
1280
- expect(result.posts).to eq([ post1 ])
1281
- expect(result.descriptions).to eq([ description1 ])
1282
- end
1221
+ let!(:non_match) do
1222
+ Band.create!(member_count: 5)
1283
1223
  end
1284
1224
 
1285
- context "when providing a nested association" do
1225
+ let(:criteria) do
1226
+ Band.lte(member_count: 4)
1227
+ end
1286
1228
 
1287
- let!(:user) do
1288
- User.create
1289
- end
1229
+ it "returns the matching documents" do
1230
+ expect(criteria).to eq([ match ])
1231
+ end
1232
+ end
1290
1233
 
1291
- before do
1292
- p = Post.create(alerts: [ Alert.create ])
1293
- user.posts = [ p ]
1294
- user.save
1295
- end
1234
+ describe "#map_reduce" do
1296
1235
 
1297
- let(:result) do
1298
- User.includes(:posts => [:alerts]).first
1299
- end
1236
+ let(:map) do
1237
+ %Q{
1238
+ function() {
1239
+ emit(this.name, { likes: this.likes });
1240
+ }}
1241
+ end
1300
1242
 
1301
- it "executes the query" do
1302
- expect(result).to eq(user)
1303
- end
1243
+ let(:reduce) do
1244
+ %Q{
1245
+ function(key, values) {
1246
+ var result = { likes: 0 };
1247
+ values.forEach(function(value) {
1248
+ result.likes += value.likes;
1249
+ });
1250
+ return result;
1251
+ }}
1252
+ end
1304
1253
 
1305
- it "includes the related objects" do
1306
- expect(result.posts.size).to eq(1)
1307
- expect(result.posts.first.alerts.size).to eq(1)
1308
- end
1254
+ let!(:depeche_mode) do
1255
+ Band.create!(name: "Depeche Mode", likes: 200)
1309
1256
  end
1310
1257
 
1311
- context "when providing a deeply nested association" do
1258
+ let!(:tool) do
1259
+ Band.create!(name: "Tool", likes: 100)
1260
+ end
1312
1261
 
1313
- let!(:user) do
1314
- User.create
1315
- end
1262
+ context "when no timeout options are provided" do
1316
1263
 
1317
- let(:results) do
1318
- User.includes(:posts => [{ :alerts => :items }]).to_a
1264
+ let(:map_reduce) do
1265
+ Band.limit(2).map_reduce(map, reduce).out(inline: 1)
1319
1266
  end
1320
1267
 
1321
- it "executes the query" do
1322
- expect(results.first).to eq(user)
1268
+ it "returns the map/reduce results" do
1269
+ expect(map_reduce.sort_by { |doc| doc['_id'] }).to eq([
1270
+ { "_id" => "Depeche Mode", "value" => { "likes" => 200 }},
1271
+ { "_id" => "Tool", "value" => { "likes" => 100 }}
1272
+ ])
1323
1273
  end
1324
1274
  end
1275
+ end
1325
1276
 
1326
- context "when the models are inherited" do
1277
+ describe "#max" do
1327
1278
 
1328
- before(:all) do
1329
- class A
1330
- include Mongoid::Document
1331
- end
1279
+ context "when provided a single field" do
1332
1280
 
1333
- class B < A
1334
- belongs_to :c
1335
- end
1281
+ let!(:depeche) do
1282
+ Band.create!(name: "Depeche Mode", likes: 1000)
1283
+ end
1336
1284
 
1337
- class C
1338
- include Mongoid::Document
1339
- has_one :b
1340
- end
1285
+ let!(:tool) do
1286
+ Band.create!(name: "Tool", likes: 500)
1341
1287
  end
1342
1288
 
1343
- after(:all) do
1344
- Object.send(:remove_const, :A)
1345
- Object.send(:remove_const, :B)
1346
- Object.send(:remove_const, :C)
1289
+ let(:criteria) do
1290
+ Band.all
1347
1291
  end
1348
1292
 
1349
- context "when the includes is on the subclass" do
1293
+ context "when provided a symbol" do
1350
1294
 
1351
- let!(:c_one) do
1352
- C.create
1295
+ let(:max) do
1296
+ criteria.max(:likes)
1353
1297
  end
1354
1298
 
1355
- let!(:c_two) do
1356
- C.create
1299
+ it "returns the max of the provided field" do
1300
+ expect(max).to eq(1000)
1357
1301
  end
1302
+ end
1358
1303
 
1359
- let!(:b) do
1360
- B.create(c: c_two)
1361
- end
1304
+ context "when provided a block" do
1362
1305
 
1363
- let!(:results) do
1364
- C.includes(:b).to_a.detect do |c|
1365
- c.id == c_two.id
1306
+ let(:max) do
1307
+ criteria.max do |a, b|
1308
+ a.likes <=> b.likes
1366
1309
  end
1367
1310
  end
1368
1311
 
1369
- it "returns the correct documents" do
1370
- expect(results).to eq(c_two)
1371
- end
1372
-
1373
- it "does not query the db" do
1374
- expect_query(0) do
1375
- results.b
1376
- end
1312
+ it "returns the document with the max value for the field" do
1313
+ expect(max).to eq(depeche)
1377
1314
  end
1378
1315
  end
1379
1316
  end
1317
+ end
1380
1318
 
1381
- context "when the models are inherited from another one model" do
1382
-
1383
- context "when the relation is a has_one" do
1384
-
1385
- before(:all) do
1386
- class A
1387
- include Mongoid::Document
1388
- end
1389
-
1390
- class B < A
1391
- belongs_to :d
1392
- end
1393
-
1394
- class C < A
1395
- belongs_to :d
1396
- end
1397
-
1398
- class D
1399
- include Mongoid::Document
1400
- has_one :b
1401
- has_one :c
1402
- end
1403
- end
1319
+ describe "#max_distance" do
1404
1320
 
1405
- after(:all) do
1406
- Object.send(:remove_const, :A)
1407
- Object.send(:remove_const, :B)
1408
- Object.send(:remove_const, :C)
1409
- Object.send(:remove_const, :D)
1410
- end
1321
+ before do
1322
+ Bar.create_indexes
1323
+ end
1411
1324
 
1412
- context "when the includes is on the several relations" do
1325
+ let!(:match) do
1326
+ Bar.create!(location: [ 52.30, 13.25 ])
1327
+ end
1413
1328
 
1414
- let!(:d_one) do
1415
- D.create
1416
- end
1329
+ let!(:non_match) do
1330
+ Bar.create!(location: [ 19.26, 99.70 ])
1331
+ end
1417
1332
 
1418
- let!(:d_two) do
1419
- D.create
1420
- end
1333
+ let(:criteria) do
1334
+ Bar.near(location: [ 52, 13 ]).max_distance(location: 5)
1335
+ end
1421
1336
 
1422
- let!(:b) do
1423
- B.create(d: d_two)
1424
- end
1337
+ it "returns the matching documents" do
1338
+ expect(criteria).to eq([ match ])
1339
+ end
1340
+ end
1425
1341
 
1426
- let!(:c) do
1427
- C.create(d: d_two)
1428
- end
1342
+ describe "#merge" do
1429
1343
 
1430
- let!(:results) do
1431
- D.includes(:b, :c).entries.detect do |d|
1432
- d.id == d_two.id
1433
- end
1434
- end
1344
+ let(:band) do
1345
+ Band.new
1346
+ end
1435
1347
 
1436
- it "returns the correct documents" do
1437
- expect(results).to eq(d_two)
1438
- end
1348
+ let(:criteria) do
1349
+ Band.scoped.where(name: "Depeche Mode").asc(:name)
1350
+ end
1439
1351
 
1440
- it "does not query the db on b" do
1441
- expect_query(0) do
1442
- results.b
1443
- end
1444
- end
1352
+ context "when merging with another criteria" do
1445
1353
 
1446
- it "does not query the db on c" do
1447
- expect_query(0) do
1448
- results.b
1449
- end
1450
- end
1354
+ let(:mergeable) do
1355
+ Band.includes(:records).tap do |crit|
1356
+ crit.documents = [ band ]
1451
1357
  end
1452
1358
  end
1453
1359
 
1454
- context "when the relation is a has_many" do
1455
-
1456
- before(:all) do
1457
- class A
1458
- include Mongoid::Document
1459
- end
1460
-
1461
- class B < A
1462
- belongs_to :d
1463
- end
1464
-
1465
- class C < A
1466
- belongs_to :d
1467
- end
1468
-
1469
- class D
1470
- include Mongoid::Document
1471
- has_many :b
1472
- has_many :c
1473
- end
1474
- end
1475
-
1476
- after(:all) do
1477
- Object.send(:remove_const, :A)
1478
- Object.send(:remove_const, :B)
1479
- Object.send(:remove_const, :C)
1480
- Object.send(:remove_const, :D)
1481
- end
1482
-
1483
- context "when the includes is on the several relations" do
1484
-
1485
- let!(:d_one) do
1486
- D.create
1487
- end
1488
-
1489
- let!(:d_two) do
1490
- D.create
1491
- end
1492
-
1493
- let!(:bs) do
1494
- 2.times.map { B.create(d: d_two) }
1495
- end
1496
-
1497
- let!(:cs) do
1498
- 2.times.map { C.create(d: d_two) }
1499
- end
1500
-
1501
- let!(:results) do
1502
- D.includes(:b, :c).entries.detect do |d|
1503
- d.id == d_two.id
1504
- end
1505
- end
1506
-
1507
- it "returns the correct documents" do
1508
- expect(results).to eq(d_two)
1509
- end
1510
-
1511
- it "does not query the db on b" do
1512
- expect_query(0) do
1513
- results.b
1514
- end
1515
- end
1516
-
1517
- it "does not query the db on c" do
1518
- expect_query(0) do
1519
- results.b
1520
- end
1521
- end
1522
- end
1360
+ let(:association) do
1361
+ Band.relations["records"]
1523
1362
  end
1524
- end
1525
-
1526
- context "when including the same association multiple times" do
1527
1363
 
1528
- let(:criteria) do
1529
- Person.all.includes(:posts, :posts).includes(:posts)
1364
+ let(:merged) do
1365
+ criteria.merge(mergeable)
1530
1366
  end
1531
1367
 
1532
- let(:association) do
1533
- Person.reflect_on_association(:posts)
1368
+ it "merges the selector" do
1369
+ expect(merged.selector).to eq({ "name" => "Depeche Mode" })
1534
1370
  end
1535
1371
 
1536
- it "does not duplicate the association in the inclusions" do
1537
- expect(criteria.inclusions).to eq([ association ])
1372
+ it "merges the options" do
1373
+ expect(merged.options).to eq({ sort: { "name" => 1 }})
1538
1374
  end
1539
- end
1540
-
1541
- context "when mapping the results more than once" do
1542
1375
 
1543
- let!(:post) do
1544
- person.posts.create(title: "one")
1376
+ it "merges the documents" do
1377
+ expect(merged.documents).to eq([ band ])
1545
1378
  end
1546
1379
 
1547
- let(:criteria) do
1548
- Post.includes(:person)
1380
+ it "merges the scoping options" do
1381
+ expect(merged.scoping_options).to eq([ nil, nil ])
1549
1382
  end
1550
1383
 
1551
- let!(:results) do
1552
- criteria.map { |doc| doc }
1553
- criteria.map { |doc| doc }
1384
+ it "merges the inclusions" do
1385
+ expect(merged.inclusions).to eq([ association ])
1554
1386
  end
1555
1387
 
1556
- it "returns the proper results" do
1557
- expect(results.first.title).to eq("one")
1388
+ it "returns a new criteria" do
1389
+ expect(merged).to_not equal(criteria)
1558
1390
  end
1559
1391
  end
1560
1392
 
1561
- context "when including a belongs to relation" do
1562
-
1563
- context "when the criteria is from the root" do
1564
-
1565
- let!(:person_two) do
1566
- Person.create(age: 2)
1567
- end
1568
-
1569
- let!(:post_one) do
1570
- person.posts.create(title: "one")
1571
- end
1572
-
1573
- let!(:post_two) do
1574
- person_two.posts.create(title: "two")
1575
- end
1576
-
1577
- context "when calling first" do
1578
-
1579
- let(:criteria) do
1580
- Post.includes(:person)
1581
- end
1582
-
1583
- let!(:document) do
1584
- criteria.first
1585
- end
1586
-
1587
- it "eager loads the first document" do
1588
- expect_query(0) do
1589
- expect(document.person).to eq(person)
1590
- end
1591
- end
1592
-
1593
- it "returns the first document" do
1594
- expect(document).to eq(post_one)
1595
- end
1596
- end
1597
-
1598
- context "when calling last" do
1599
-
1600
- let!(:criteria) do
1601
- Post.asc(:_id).includes(:person)
1602
- end
1603
-
1604
- let!(:document) do
1605
- criteria.last
1606
- end
1607
-
1608
- it "eager loads the last document" do
1609
- expect_query(0) do
1610
- expect(document.person).to eq(person_two)
1611
- end
1612
- end
1613
-
1614
- it "returns the last document" do
1615
- expect(document).to eq(post_two)
1616
- end
1617
- end
1618
- end
1619
-
1620
- context "when the criteria is from an embedded relation" do
1621
-
1622
- let(:peep) do
1623
- Person.create
1624
- end
1625
-
1626
- let!(:address_one) do
1627
- peep.addresses.create(street: "rosenthaler")
1628
- end
1629
-
1630
- let!(:address_two) do
1631
- peep.addresses.create(street: "weinmeister")
1632
- end
1633
-
1634
- let!(:depeche) do
1635
- Band.create!(name: "Depeche Mode")
1636
- end
1637
-
1638
- let!(:tool) do
1639
- Band.create!(name: "Tool")
1640
- end
1641
-
1642
- before do
1643
- address_one.band = depeche
1644
- address_two.band = tool
1645
- address_one.save
1646
- address_two.save
1647
- end
1648
-
1649
- context "when calling first" do
1650
-
1651
- let(:criteria) do
1652
- peep.reload.addresses.includes(:band)
1653
- end
1654
-
1655
- let(:context) do
1656
- criteria.context
1657
- end
1658
-
1659
- let!(:document) do
1660
- criteria.first
1661
- end
1662
-
1663
- it "eager loads the first document" do
1664
- expect_query(0) do
1665
- expect(document.band).to eq(depeche)
1666
- end
1667
- end
1668
-
1669
- it "returns the document" do
1670
- expect(document).to eq(address_one)
1671
- end
1672
- end
1673
-
1674
- context "when calling last" do
1675
-
1676
- let(:criteria) do
1677
- peep.reload.addresses.includes(:band)
1678
- end
1679
-
1680
- let(:context) do
1681
- criteria.context
1682
- end
1683
-
1684
- let!(:document) do
1685
- criteria.last
1686
- end
1687
-
1688
- it "eager loads the last document" do
1689
- expect_query(0) do
1690
- expect(document.band).to eq(tool)
1691
- end
1692
- end
1693
-
1694
- it "returns the document" do
1695
- expect(document).to eq(address_two)
1696
- end
1697
- end
1698
-
1699
- context "when iterating all documents" do
1700
-
1701
- let(:criteria) do
1702
- peep.reload.addresses.includes(:band)
1703
- end
1704
-
1705
- let(:context) do
1706
- criteria.context
1707
- end
1708
-
1709
- let!(:documents) do
1710
- criteria.to_a
1711
- end
1712
-
1713
- it "eager loads the first document" do
1714
- expect_query(0) do
1715
- expect(documents.first.band).to eq(depeche)
1716
- end
1717
- end
1718
-
1719
- it "eager loads the last document" do
1720
- expect_query(0) do
1721
- expect(documents.last.band).to eq(tool)
1722
- end
1723
- end
1724
-
1725
- it "returns the documents" do
1726
- expect(documents).to eq([ address_one, address_two ])
1727
- end
1728
- end
1729
- end
1730
- end
1731
-
1732
- context "when providing inclusions to the default scope" do
1733
-
1734
- before do
1735
- Person.default_scope(->{ Person.includes(:posts) })
1736
- end
1737
-
1738
- after do
1739
- Person.default_scoping = nil
1740
- end
1741
-
1742
- let!(:post_one) do
1743
- person.posts.create(title: "one")
1744
- end
1745
-
1746
- let!(:post_two) do
1747
- person.posts.create(title: "two")
1748
- end
1749
-
1750
- context "when the criteria has no options" do
1751
-
1752
- let!(:criteria) do
1753
- Person.asc(:age).all
1754
- end
1755
-
1756
- let!(:documents) do
1757
- criteria.entries
1758
- end
1759
-
1760
- it "returns the correct documents" do
1761
- expect(documents).to eq([ person ])
1762
- end
1763
-
1764
- it "eager loads the first document" do
1765
- expect_query(0) do
1766
- expect(documents.first.posts.first).to eq(post_one)
1767
- end
1768
- end
1769
-
1770
- it "eager loads the last document" do
1771
- expect_query(0) do
1772
- expect(documents.first.posts.last).to eq(post_two)
1773
- end
1774
- end
1775
-
1776
- context "when executing the query twice" do
1777
-
1778
- let!(:new_criteria) do
1779
- Person.where(id: person.id)
1780
- end
1781
-
1782
- let!(:new_context) do
1783
- new_criteria.context
1784
- end
1785
-
1786
- before do
1787
- expect(new_context).to receive(:eager_load).with([person]).once.and_call_original
1788
- end
1789
-
1790
- let!(:from_db) do
1791
- new_criteria.first
1792
- end
1793
-
1794
- it "does not duplicate documents in the relation" do
1795
- expect(person.posts.size).to eq(2)
1796
- end
1797
- end
1798
- end
1799
-
1800
- context "when calling first on the criteria" do
1801
-
1802
- let(:criteria) do
1803
- Person.asc(:age).all
1804
- end
1805
-
1806
- let!(:from_db) do
1807
- criteria.first
1808
- end
1809
-
1810
- it "returns the correct documents" do
1811
- expect(from_db).to eq(person)
1812
- end
1813
-
1814
- it "eager loads the first document" do
1815
- expect_query(0) do
1816
- expect(from_db.posts.first).to eq(post_one)
1817
- end
1818
- end
1819
-
1820
- it "eager loads the last document" do
1821
- expect_query(0) do
1822
- expect(from_db.posts.last).to eq(post_two)
1823
- end
1824
- end
1825
- end
1826
-
1827
- context "when calling last on the criteria" do
1828
-
1829
- let(:criteria) do
1830
- Person.asc(:age).all
1831
- end
1832
-
1833
- let!(:context) do
1834
- criteria.context
1835
- end
1836
-
1837
- before do
1838
- expect(context).to receive(:eager_load).with([person]).once.and_call_original
1839
- end
1840
-
1841
- let!(:from_db) do
1842
- criteria.last
1843
- end
1844
-
1845
- it "returns the correct documents" do
1846
- expect(from_db).to eq(person)
1847
- end
1848
-
1849
- it "eager loads the first document" do
1850
- expect_query(0) do
1851
- expect(from_db.posts.first).to eq(post_one)
1852
- end
1853
- end
1854
-
1855
- it "eager loads the last document" do
1856
- expect_query(0) do
1857
- expect(from_db.posts.last).to eq(post_two)
1858
- end
1859
- end
1860
- end
1861
-
1862
- context "when the criteria has limiting options" do
1863
-
1864
- let!(:person_two) do
1865
- Person.create
1866
- end
1867
-
1868
- let!(:post_three) do
1869
- person_two.posts.create(title: "three")
1870
- end
1871
-
1872
- let!(:criteria) do
1873
- Person.asc(:age).limit(1)
1874
- end
1875
-
1876
- let!(:documents) do
1877
- criteria.entries
1878
- end
1879
-
1880
- it "returns the correct documents" do
1881
- expect(criteria).to eq([ person ])
1882
- end
1883
-
1884
- it "eager loads the first document" do
1885
- expect_query(0) do
1886
- expect(documents.first.posts.first).to eq(post_one)
1887
- end
1888
- end
1889
-
1890
- it "eager loads the second document" do
1891
- expect_query(0) do
1892
- expect(documents.first.posts.last).to eq(post_two)
1893
- end
1894
- end
1895
- end
1896
- end
1897
-
1898
- context "when including a has and belongs to many" do
1899
-
1900
- let!(:preference_one) do
1901
- person.preferences.create(name: "one")
1902
- end
1903
-
1904
- let!(:preference_two) do
1905
- person.preferences.create(name: "two")
1906
- end
1907
-
1908
- context "when one of the related items is deleted" do
1909
-
1910
- before do
1911
- person.preferences = [ preference_one, preference_two ]
1912
- preference_two.delete
1913
- end
1914
-
1915
- let(:criteria) do
1916
- Person.where(id: person.id).includes(:preferences)
1917
- end
1918
-
1919
- it "only loads the existing related items" do
1920
- expect(criteria.entries.first.preferences).to eq([ preference_one ])
1921
- end
1922
- end
1923
-
1924
- context "when the criteria has no options" do
1925
-
1926
- let!(:criteria) do
1927
- Person.asc(:age).includes(:preferences)
1928
- end
1929
-
1930
- let!(:documents) do
1931
- criteria.entries
1932
- end
1933
-
1934
- it "returns the correct documents" do
1935
- expect(documents).to eq([ person ])
1936
- end
1937
-
1938
- it "eager loads the first document" do
1939
- expect_query(0) do
1940
- expect(documents.first.preferences.first).to eq(preference_one)
1941
- end
1942
- end
1943
-
1944
- it "eager loads the last document" do
1945
- expect_query(0) do
1946
- expect(documents.first.preferences.last).to eq(preference_two)
1947
- end
1948
- end
1949
- end
1950
-
1951
- context "when calling first on the criteria" do
1952
-
1953
- let!(:criteria) do
1954
- Person.asc(:age).includes(:preferences)
1955
- end
1956
-
1957
- let!(:from_db) do
1958
- criteria.first
1959
- end
1960
-
1961
- it "returns the correct documents" do
1962
- expect(from_db).to eq(person)
1963
- end
1964
-
1965
- it "eager loads the first document" do
1966
- expect_query(0) do
1967
- expect(from_db.preferences.first).to eq(preference_one)
1968
- end
1969
- end
1970
-
1971
- it "eager loads the last document" do
1972
- expect_query(0) do
1973
- expect(from_db.preferences.last).to eq(preference_two)
1974
- end
1975
- end
1976
- end
1977
-
1978
- context "when calling last on the criteria" do
1979
-
1980
- let!(:criteria) do
1981
- Person.asc(:age).includes(:preferences)
1982
- end
1983
-
1984
- let!(:from_db) do
1985
- criteria.last
1986
- end
1987
-
1988
- it "returns the correct documents" do
1989
- expect(from_db).to eq(person)
1990
- end
1991
-
1992
- it "eager loads the first document" do
1993
- expect_query(0) do
1994
- expect(from_db.preferences.first).to eq(preference_one)
1995
- end
1996
- end
1997
-
1998
- it "eager loads the last document" do
1999
- expect_query(0) do
2000
- expect(from_db.preferences.last).to eq(preference_two)
2001
- end
2002
- end
2003
- end
2004
- end
2005
-
2006
- context "when including a has many" do
2007
-
2008
- let!(:post_one) do
2009
- person.posts.create(title: "one")
2010
- end
2011
-
2012
- let!(:post_two) do
2013
- person.posts.create(title: "two")
2014
- end
2015
-
2016
- context "when the criteria has no options" do
2017
-
2018
- let!(:criteria) do
2019
- Person.asc(:age).includes(:posts)
2020
- end
2021
-
2022
- let!(:documents) do
2023
- criteria.entries
2024
- end
2025
-
2026
- it "returns the correct documents" do
2027
- expect(documents).to eq([ person ])
2028
- end
2029
-
2030
- it "eager loads the first document" do
2031
- expect_query(0) do
2032
- expect(documents.first.posts.first).to eq(post_one)
2033
- end
2034
- end
2035
-
2036
- it "eager loads the last document" do
2037
- expect_query(0) do
2038
- expect(documents.first.posts.last).to eq(post_two)
2039
- end
2040
- end
2041
- end
2042
-
2043
- context "when calling first on the criteria" do
2044
-
2045
- let!(:criteria) do
2046
- Person.asc(:age).includes(:posts)
2047
- end
2048
-
2049
- let!(:from_db) do
2050
- criteria.first
2051
- end
2052
-
2053
- it "returns the correct documents" do
2054
- expect(from_db).to eq(person)
2055
- end
2056
-
2057
- context "when subsequently getting all documents" do
2058
-
2059
- let!(:documents) do
2060
- criteria.entries
2061
- end
2062
-
2063
- it "returns the correct documents" do
2064
- expect(documents).to eq([ person ])
2065
- end
2066
- end
2067
- end
2068
-
2069
- context "when calling last on the criteria" do
2070
-
2071
- let!(:criteria) do
2072
- Person.asc(:age).includes(:posts)
2073
- end
2074
-
2075
- let!(:from_db) do
2076
- criteria.last
2077
- end
2078
-
2079
- it "returns the correct documents" do
2080
- expect(from_db).to eq(person)
2081
- end
2082
-
2083
- context "when subsequently getting all documents" do
2084
-
2085
- let!(:documents) do
2086
- criteria.entries
2087
- end
2088
-
2089
- it "returns the correct documents" do
2090
- expect(documents).to eq([ person ])
2091
- end
2092
- end
2093
- end
2094
-
2095
- context "when the criteria has limiting options" do
2096
-
2097
- let!(:person_two) do
2098
- Person.create
2099
- end
2100
-
2101
- let!(:post_three) do
2102
- person_two.posts.create(title: "three")
2103
- end
2104
-
2105
- let!(:criteria) do
2106
- Person.includes(:posts).asc(:age).limit(1)
2107
- end
2108
-
2109
- let(:context) do
2110
- criteria.context
2111
- end
2112
-
2113
- before do
2114
- expect(context).to receive(:eager_load).with([ person ]).once.and_call_original
2115
- end
2116
-
2117
- let!(:documents) do
2118
- criteria.entries
2119
- end
2120
-
2121
- it "returns the correct documents" do
2122
- expect(documents).to eq([ person ])
2123
- end
2124
- end
2125
- end
2126
-
2127
- context "when including a has one" do
2128
-
2129
- let!(:game_one) do
2130
- person.create_game(name: "one")
2131
- end
2132
-
2133
- let!(:game_two) do
2134
- person.create_game(name: "two")
2135
- end
2136
-
2137
- context "when the criteria has no options" do
2138
-
2139
- let!(:criteria) do
2140
- Person.asc(:age).includes(:game)
2141
- end
2142
-
2143
- let(:context) do
2144
- criteria.context
2145
- end
2146
-
2147
- before do
2148
- expect(context).to receive(:eager_load).with([ person ]).once.and_call_original
2149
- end
2150
-
2151
- let!(:documents) do
2152
- criteria.entries
2153
- end
2154
-
2155
- it "returns the correct documents" do
2156
- expect(documents).to eq([ person ])
2157
- end
2158
- end
2159
-
2160
- context "when the criteria has limiting options" do
2161
-
2162
- let!(:person_two) do
2163
- Person.create(age: 2)
2164
- end
2165
-
2166
- let!(:game_three) do
2167
- person_two.create_game(name: "Skyrim")
2168
- end
2169
-
2170
- let!(:criteria) do
2171
- Person.where(id: person.id).includes(:game).asc(:age).limit(1)
2172
- end
2173
-
2174
- let(:context) do
2175
- criteria.context
2176
- end
2177
-
2178
- before do
2179
- expect(context).to receive(:eager_load).with([ person ]).once.and_call_original
2180
- end
2181
-
2182
- let!(:documents) do
2183
- criteria.entries
2184
- end
2185
-
2186
- it "returns the correct documents" do
2187
- expect(documents).to eq([ person ])
2188
- end
2189
- end
2190
- end
2191
-
2192
- context "when including a belongs to" do
2193
-
2194
- let(:person_two) do
2195
- Person.create(age: 2)
2196
- end
2197
-
2198
- let!(:game_one) do
2199
- person.create_game(name: "one")
2200
- end
2201
-
2202
- let!(:game_two) do
2203
- person_two.create_game(name: "two")
2204
- end
2205
-
2206
- context "when providing no options" do
2207
-
2208
- let!(:criteria) do
2209
- Game.includes(:person)
2210
- end
2211
-
2212
- let(:context) do
2213
- criteria.context
2214
- end
2215
-
2216
- before do
2217
- expect(context).to receive(:preload).twice.and_call_original
2218
- end
2219
-
2220
- let!(:documents) do
2221
- criteria.entries
2222
- end
2223
-
2224
- it "returns the correct documents" do
2225
- expect(criteria).to eq([ game_one, game_two ])
2226
- end
2227
- end
2228
-
2229
- context "when the criteria has limiting options" do
2230
-
2231
- let!(:criteria) do
2232
- Game.where(id: game_one.id).includes(:person).asc(:_id).limit(1)
2233
- end
2234
-
2235
- let(:context) do
2236
- criteria.context
2237
- end
2238
-
2239
- before do
2240
- expect(context).to receive(:eager_load).with([ game_one ]).once.and_call_original
2241
- end
2242
-
2243
- let!(:documents) do
2244
- criteria.entries
2245
- end
2246
-
2247
- it "returns the correct documents" do
2248
- expect(documents).to eq([ game_one ])
2249
- end
2250
- end
2251
- end
2252
-
2253
- context "when including multiples in the same criteria" do
2254
-
2255
- let!(:post_one) do
2256
- person.posts.create(title: "one")
2257
- end
2258
-
2259
- let!(:post_two) do
2260
- person.posts.create(title: "two")
2261
- end
2262
-
2263
- let!(:game_one) do
2264
- person.create_game(name: "one")
2265
- end
2266
-
2267
- let!(:game_two) do
2268
- person.create_game(name: "two")
2269
- end
2270
-
2271
- let!(:criteria) do
2272
- Person.includes(:posts, :game).asc(:age)
2273
- end
2274
-
2275
- let(:context) do
2276
- criteria.context
2277
- end
2278
-
2279
- before do
2280
- expect(context).to receive(:preload).twice.and_call_original
2281
- end
2282
-
2283
- let!(:documents) do
2284
- criteria.entries
2285
- end
2286
-
2287
- it "returns the correct documents" do
2288
- expect(criteria).to eq([ person ])
2289
- end
2290
- end
2291
- end
2292
-
2293
- describe "#inclusions" do
2294
-
2295
- let(:criteria) do
2296
- Band.includes(:records)
2297
- end
2298
-
2299
- let(:association) do
2300
- Band.relations["records"]
2301
- end
2302
-
2303
- it "returns the inclusions" do
2304
- expect(criteria.inclusions).to eq([ association ])
2305
- end
2306
- end
2307
-
2308
- describe "#inclusions=" do
2309
-
2310
- let(:criteria) do
2311
- Band.all
2312
- end
2313
-
2314
- let(:association) do
2315
- Band.relations["records"]
2316
- end
2317
-
2318
- before do
2319
- criteria.inclusions = [ association ]
2320
- end
2321
-
2322
- it "sets the inclusions" do
2323
- expect(criteria.inclusions).to eq([ association ])
2324
- end
2325
- end
2326
-
2327
- describe "#lt" do
2328
-
2329
- let!(:match) do
2330
- Band.create(member_count: 1)
2331
- end
2332
-
2333
- let!(:non_match) do
2334
- Band.create(member_count: 5)
2335
- end
2336
-
2337
- let(:criteria) do
2338
- Band.lt(member_count: 4)
2339
- end
2340
-
2341
- it "returns the matching documents" do
2342
- expect(criteria).to eq([ match ])
2343
- end
2344
- end
2345
-
2346
- describe "#lte" do
2347
-
2348
- let!(:match) do
2349
- Band.create(member_count: 4)
2350
- end
2351
-
2352
- let!(:non_match) do
2353
- Band.create(member_count: 5)
2354
- end
2355
-
2356
- let(:criteria) do
2357
- Band.lte(member_count: 4)
2358
- end
2359
-
2360
- it "returns the matching documents" do
2361
- expect(criteria).to eq([ match ])
2362
- end
2363
- end
2364
-
2365
- describe "#map_reduce" do
2366
-
2367
- let(:map) do
2368
- %Q{
2369
- function() {
2370
- emit(this.name, { likes: this.likes });
2371
- }}
2372
- end
2373
-
2374
- let(:reduce) do
2375
- %Q{
2376
- function(key, values) {
2377
- var result = { likes: 0 };
2378
- values.forEach(function(value) {
2379
- result.likes += value.likes;
2380
- });
2381
- return result;
2382
- }}
2383
- end
2384
-
2385
- let!(:depeche_mode) do
2386
- Band.create(name: "Depeche Mode", likes: 200)
2387
- end
2388
-
2389
- let!(:tool) do
2390
- Band.create(name: "Tool", likes: 100)
2391
- end
2392
-
2393
- context "when no timeout options are provided" do
2394
-
2395
- let(:map_reduce) do
2396
- Band.limit(2).map_reduce(map, reduce).out(inline: 1)
2397
- end
2398
-
2399
- it "returns the map/reduce results" do
2400
- expect(map_reduce.sort_by { |doc| doc['_id'] }).to eq([
2401
- { "_id" => "Depeche Mode", "value" => { "likes" => 200 }},
2402
- { "_id" => "Tool", "value" => { "likes" => 100 }}
2403
- ])
2404
- end
2405
- end
2406
- end
2407
-
2408
- describe "#max" do
2409
-
2410
- context "when provided a single field" do
2411
-
2412
- let!(:depeche) do
2413
- Band.create(name: "Depeche Mode", likes: 1000)
2414
- end
2415
-
2416
- let!(:tool) do
2417
- Band.create(name: "Tool", likes: 500)
2418
- end
2419
-
2420
- let(:criteria) do
2421
- Band.all
2422
- end
2423
-
2424
- context "when provided a symbol" do
2425
-
2426
- let(:max) do
2427
- criteria.max(:likes)
2428
- end
2429
-
2430
- it "returns the max of the provided field" do
2431
- expect(max).to eq(1000)
2432
- end
2433
- end
2434
-
2435
- context "when provided a block" do
2436
-
2437
- let(:max) do
2438
- criteria.max do |a, b|
2439
- a.likes <=> b.likes
2440
- end
2441
- end
2442
-
2443
- it "returns the document with the max value for the field" do
2444
- expect(max).to eq(depeche)
2445
- end
2446
- end
2447
- end
2448
- end
2449
-
2450
- describe "#max_distance" do
2451
-
2452
- before do
2453
- Bar.create_indexes
2454
- end
2455
-
2456
- let!(:match) do
2457
- Bar.create(location: [ 52.30, 13.25 ])
2458
- end
2459
-
2460
- let!(:non_match) do
2461
- Bar.create(location: [ 19.26, 99.70 ])
2462
- end
2463
-
2464
- let(:criteria) do
2465
- Bar.near(location: [ 52, 13 ]).max_distance(location: 5)
2466
- end
2467
-
2468
- it "returns the matching documents" do
2469
- expect(criteria).to eq([ match ])
2470
- end
2471
- end
2472
-
2473
- describe "#merge" do
2474
-
2475
- let(:band) do
2476
- Band.new
2477
- end
2478
-
2479
- let(:criteria) do
2480
- Band.scoped.where(name: "Depeche Mode").asc(:name)
2481
- end
2482
-
2483
- context "when merging with another criteria" do
1393
+ context "when merging with a hash" do
2484
1394
 
2485
1395
  let(:mergeable) do
2486
- Band.includes(:records).tap do |crit|
2487
- crit.documents = [ band ]
2488
- end
1396
+ { klass: Band, includes: [ :records ] }
2489
1397
  end
2490
1398
 
2491
1399
  let(:association) do
@@ -2504,10 +1412,6 @@ describe Mongoid::Criteria do
2504
1412
  expect(merged.options).to eq({ sort: { "name" => 1 }})
2505
1413
  end
2506
1414
 
2507
- it "merges the documents" do
2508
- expect(merged.documents).to eq([ band ])
2509
- end
2510
-
2511
1415
  it "merges the scoping options" do
2512
1416
  expect(merged.scoping_options).to eq([ nil, nil ])
2513
1417
  end
@@ -2520,89 +1424,70 @@ describe Mongoid::Criteria do
2520
1424
  expect(merged).to_not equal(criteria)
2521
1425
  end
2522
1426
  end
1427
+ end
2523
1428
 
2524
- context "when merging with a hash" do
2525
-
2526
- let(:mergeable) do
2527
- { klass: Band, includes: [ :records ] }
2528
- end
2529
-
2530
- let(:association) do
2531
- Band.relations["records"]
2532
- end
1429
+ describe '#merge!' do
1430
+ let(:band) { Band.new }
1431
+ let(:criteria) { Band.scoped.where(name: 'Depeche Mode').asc(:name) }
1432
+ let(:association) { Band.relations['records'] }
1433
+ subject(:merged) { criteria.merge!(other) }
2533
1434
 
2534
- let(:merged) do
2535
- criteria.merge(mergeable)
1435
+ context 'when merging a Criteria' do
1436
+ let(:other) do
1437
+ { klass: Band, includes: [:records] }
2536
1438
  end
2537
1439
 
2538
- it "merges the selector" do
2539
- expect(merged.selector).to eq({ "name" => "Depeche Mode" })
1440
+ it 'merges the selector' do
1441
+ expect(merged.selector).to eq({ 'name' => 'Depeche Mode' })
2540
1442
  end
2541
1443
 
2542
- it "merges the options" do
2543
- expect(merged.options).to eq({ sort: { "name" => 1 }})
1444
+ it 'merges the options' do
1445
+ expect(merged.options).to eq({ sort: { 'name' => 1 }})
2544
1446
  end
2545
1447
 
2546
- it "merges the scoping options" do
1448
+ it 'merges the scoping options' do
2547
1449
  expect(merged.scoping_options).to eq([ nil, nil ])
2548
1450
  end
2549
1451
 
2550
- it "merges the inclusions" do
1452
+ it 'merges the inclusions' do
2551
1453
  expect(merged.inclusions).to eq([ association ])
2552
1454
  end
2553
1455
 
2554
- it "returns a new criteria" do
2555
- expect(merged).to_not equal(criteria)
1456
+ it 'returns the same criteria' do
1457
+ expect(merged).to equal(criteria)
2556
1458
  end
2557
1459
  end
2558
- end
2559
-
2560
- describe "#merge!" do
2561
-
2562
- let(:band) do
2563
- Band.new
2564
- end
2565
-
2566
- let(:criteria) do
2567
- Band.scoped.where(name: "Depeche Mode").asc(:name)
2568
- end
2569
1460
 
2570
- let(:mergeable) do
2571
- Band.includes(:records).tap do |crit|
2572
- crit.documents = [ band ]
1461
+ context 'when merging a Hash' do
1462
+ let(:other) do
1463
+ Band.includes(:records).tap do |crit|
1464
+ crit.documents = [ band ]
1465
+ end
2573
1466
  end
2574
- end
2575
-
2576
- let(:association) do
2577
- Band.relations["records"]
2578
- end
2579
1467
 
2580
- let(:merged) do
2581
- criteria.merge!(mergeable)
2582
- end
2583
-
2584
- it "merges the selector" do
2585
- expect(merged.selector).to eq({ "name" => "Depeche Mode" })
2586
- end
1468
+ it 'merges the selector' do
1469
+ expect(merged.selector).to eq({ 'name' => 'Depeche Mode' })
1470
+ end
2587
1471
 
2588
- it "merges the options" do
2589
- expect(merged.options).to eq({ sort: { "name" => 1 }})
2590
- end
1472
+ it 'merges the options' do
1473
+ expect(merged.options).to eq({ sort: { 'name' => 1 }})
1474
+ end
2591
1475
 
2592
- it "merges the documents" do
2593
- expect(merged.documents).to eq([ band ])
2594
- end
1476
+ it 'merges the documents' do
1477
+ expect(merged.documents).to eq([ band ])
1478
+ end
2595
1479
 
2596
- it "merges the scoping options" do
2597
- expect(merged.scoping_options).to eq([ nil, nil ])
2598
- end
1480
+ it 'merges the scoping options' do
1481
+ expect(merged.scoping_options).to eq([ nil, nil ])
1482
+ end
2599
1483
 
2600
- it "merges the inclusions" do
2601
- expect(merged.inclusions).to eq([ association ])
2602
- end
1484
+ it 'merges the inclusions' do
1485
+ expect(merged.inclusions).to eq([ association ])
1486
+ end
2603
1487
 
2604
- it "returns the same criteria" do
2605
- expect(merged).to equal(criteria)
1488
+ it 'returns the same criteria' do
1489
+ expect(merged).to equal(criteria)
1490
+ end
2606
1491
  end
2607
1492
  end
2608
1493
 
@@ -2611,391 +1496,154 @@ describe Mongoid::Criteria do
2611
1496
  context "when provided a single field" do
2612
1497
 
2613
1498
  let!(:depeche) do
2614
- Band.create(name: "Depeche Mode", likes: 1000)
1499
+ Band.create!(name: "Depeche Mode", likes: 1000)
2615
1500
  end
2616
1501
 
2617
1502
  let!(:tool) do
2618
- Band.create(name: "Tool", likes: 500)
1503
+ Band.create!(name: "Tool", likes: 500)
2619
1504
  end
2620
1505
 
2621
1506
  let(:criteria) do
2622
1507
  Band.all
2623
1508
  end
2624
1509
 
2625
- context "when provided a symbol" do
2626
-
2627
- let(:min) do
2628
- criteria.min(:likes)
2629
- end
2630
-
2631
- it "returns the min of the provided field" do
2632
- expect(min).to eq(500)
2633
- end
2634
- end
2635
-
2636
- context "when provided a block" do
2637
-
2638
- let(:min) do
2639
- criteria.min do |a, b|
2640
- a.likes <=> b.likes
2641
- end
2642
- end
2643
-
2644
- it "returns the document with the min value for the field" do
2645
- expect(min).to eq(tool)
2646
- end
2647
- end
2648
- end
2649
- end
2650
-
2651
- describe "#mod" do
2652
-
2653
- let!(:match) do
2654
- Band.create(member_count: 5)
2655
- end
2656
-
2657
- let!(:non_match) do
2658
- Band.create(member_count: 2)
2659
- end
2660
-
2661
- let(:criteria) do
2662
- Band.mod(member_count: [ 4, 1 ])
2663
- end
2664
-
2665
- it "returns the matching documents" do
2666
- expect(criteria).to eq([ match ])
2667
- end
2668
- end
2669
-
2670
- describe "#ne" do
2671
-
2672
- let!(:match) do
2673
- Band.create(name: "Depeche Mode")
2674
- end
2675
-
2676
- let!(:non_match) do
2677
- Band.create(name: "Tool")
2678
- end
2679
-
2680
- let(:criteria) do
2681
- Band.ne(name: "Tool")
2682
- end
2683
-
2684
- it "returns the matching documents" do
2685
- expect(criteria).to eq([ match ])
2686
- end
2687
- end
2688
-
2689
- describe "#near" do
2690
-
2691
- before do
2692
- Bar.create_indexes
2693
- end
2694
-
2695
- let!(:match) do
2696
- Bar.create(location: [ 52.30, 13.25 ])
2697
- end
2698
-
2699
- let(:criteria) do
2700
- Bar.near(location: [ 52, 13 ])
2701
- end
2702
-
2703
- it "returns the matching documents" do
2704
- expect(criteria).to eq([ match ])
2705
- end
2706
- end
2707
-
2708
- describe "#near_sphere" do
2709
-
2710
- before do
2711
- Bar.create_indexes
2712
- end
2713
-
2714
- let!(:match) do
2715
- Bar.create(location: [ 52.30, 13.25 ])
2716
- end
2717
-
2718
- let(:criteria) do
2719
- Bar.near_sphere(location: [ 52, 13 ])
2720
- end
2721
-
2722
- it "returns the matching documents" do
2723
- expect(criteria).to eq([ match ])
2724
- end
2725
- end
2726
-
2727
- describe "#nin" do
2728
-
2729
- let!(:match) do
2730
- Band.create(name: "Depeche Mode")
2731
- end
2732
-
2733
- let!(:non_match) do
2734
- Band.create(name: "Tool")
2735
- end
2736
-
2737
- let(:criteria) do
2738
- Band.nin(name: [ "Tool" ])
2739
- end
2740
-
2741
- it "returns the matching documents" do
2742
- expect(criteria).to eq([ match ])
2743
- end
2744
- end
2745
-
2746
- describe "#nor" do
2747
-
2748
- let!(:match) do
2749
- Band.create(name: "Depeche Mode")
2750
- end
2751
-
2752
- let!(:non_match) do
2753
- Band.create(name: "Tool")
2754
- end
2755
-
2756
- let(:criteria) do
2757
- Band.nor({ name: "Tool" }, { name: "New Order" })
2758
- end
2759
-
2760
- it "returns the matching documents" do
2761
- expect(criteria).to eq([ match ])
2762
- end
2763
- end
2764
-
2765
- describe "#only" do
2766
-
2767
- let!(:band) do
2768
- Band.create(name: "Depeche Mode", likes: 3, views: 10)
2769
- end
2770
-
2771
- context "when not using inheritance" do
2772
-
2773
- context "when passing splat args" do
2774
-
2775
- let(:criteria) do
2776
- Band.only(:_id)
2777
- end
2778
-
2779
- it "limits the returned fields" do
2780
- expect {
2781
- criteria.first.name
2782
- }.to raise_error(ActiveModel::MissingAttributeError)
2783
- end
2784
-
2785
- it "does not add _type to the fields" do
2786
- expect(criteria.options[:fields]["_type"]).to be_nil
2787
- end
2788
- end
2789
-
2790
- context "when not including id" do
2791
-
2792
- let(:criteria) do
2793
- Band.only(:name)
2794
- end
2795
-
2796
- it "responds to id anyway" do
2797
- expect {
2798
- criteria.first.id
2799
- }.to_not raise_error
2800
- end
2801
- end
2802
-
2803
- context "when passing an array" do
2804
-
2805
- let(:criteria) do
2806
- Band.only([ :name, :likes ])
2807
- end
2808
-
2809
- it "includes the limited fields" do
2810
- expect(criteria.first.name).to_not be_nil
2811
- end
2812
-
2813
- it "excludes the non included fields" do
2814
- expect {
2815
- criteria.first.active
2816
- }.to raise_error(ActiveModel::MissingAttributeError)
2817
- end
2818
-
2819
- it "does not add _type to the fields" do
2820
- expect(criteria.options[:fields]["_type"]).to be_nil
2821
- end
2822
- end
2823
-
2824
- context "when instantiating a class of another type inside the iteration" do
2825
-
2826
- let(:criteria) do
2827
- Band.only(:name)
2828
- end
2829
-
2830
- it "only limits the fields on the correct model" do
2831
- criteria.each do |band|
2832
- expect(Person.new.age).to eq(100)
2833
- end
2834
- end
2835
- end
2836
-
2837
- context "when instantiating a document not in the result set" do
2838
-
2839
- let(:criteria) do
2840
- Band.only(:name)
2841
- end
2842
-
2843
- it "only limits the fields on the correct criteria" do
2844
- criteria.each do |band|
2845
- expect(Band.new.active).to be true
2846
- end
2847
- end
2848
- end
2849
-
2850
- context "when nesting a criteria within a criteria" do
1510
+ context "when provided a symbol" do
2851
1511
 
2852
- let(:criteria) do
2853
- Band.only(:name)
1512
+ let(:min) do
1513
+ criteria.min(:likes)
2854
1514
  end
2855
1515
 
2856
- it "only limits the fields on the correct criteria" do
2857
- criteria.each do |band|
2858
- Band.all.each do |b|
2859
- expect(b.active).to be true
2860
- end
2861
- end
1516
+ it "returns the min of the provided field" do
1517
+ expect(min).to eq(500)
2862
1518
  end
2863
1519
  end
2864
- end
2865
1520
 
2866
- context "when using inheritance" do
2867
- context "when using the default discriminator key" do
2868
- let(:criteria) do
2869
- Doctor.only(:_id)
1521
+ context "when provided a block" do
1522
+
1523
+ let(:min) do
1524
+ criteria.min do |a, b|
1525
+ a.likes <=> b.likes
1526
+ end
2870
1527
  end
2871
1528
 
2872
- it "adds _type to the fields" do
2873
- expect(criteria.options[:fields]).to include("_type")
1529
+ it "returns the document with the min value for the field" do
1530
+ expect(min).to eq(tool)
2874
1531
  end
2875
1532
  end
1533
+ end
1534
+ end
2876
1535
 
2877
- context "when setting a custom discriminator key" do
2878
- before do
2879
- Person.discriminator_key = "dkey"
2880
- end
1536
+ describe "#mod" do
2881
1537
 
2882
- after do
2883
- Person.discriminator_key = nil
2884
- end
1538
+ let!(:match) do
1539
+ Band.create!(member_count: 5)
1540
+ end
2885
1541
 
2886
- let(:criteria) do
2887
- Doctor.only(:_id)
2888
- end
1542
+ let!(:non_match) do
1543
+ Band.create!(member_count: 2)
1544
+ end
2889
1545
 
2890
- it "adds custom discriminator key to the fields" do
2891
- expect(criteria.options[:fields]).to include("dkey")
2892
- end
1546
+ let(:criteria) do
1547
+ Band.mod(member_count: [ 4, 1 ])
1548
+ end
2893
1549
 
2894
- it "does not add _type to the fields" do
2895
- expect(criteria.options[:fields]).to_not include("_type")
2896
- end
2897
- end
1550
+ it "returns the matching documents" do
1551
+ expect(criteria).to eq([ match ])
2898
1552
  end
1553
+ end
2899
1554
 
2900
- context "when limiting to embedded documents" do
1555
+ describe "#ne" do
2901
1556
 
2902
- context "when the embedded documents are aliased" do
1557
+ let!(:match) do
1558
+ Band.create!(name: "Depeche Mode")
1559
+ end
2903
1560
 
2904
- let(:criteria) do
2905
- Person.only(:phones)
2906
- end
1561
+ let!(:non_match) do
1562
+ Band.create!(name: "Tool")
1563
+ end
2907
1564
 
2908
- it "properly uses the database field name" do
2909
- expect(criteria.options).to eq(fields: { "_id" => 1, "mobile_phones" => 1 })
2910
- end
2911
- end
1565
+ let(:criteria) do
1566
+ Band.ne(name: "Tool")
2912
1567
  end
2913
1568
 
2914
- context 'when the field is localized' do
1569
+ it "returns the matching documents" do
1570
+ expect(criteria).to eq([ match ])
1571
+ end
1572
+ end
2915
1573
 
2916
- before do
2917
- I18n.locale = :en
2918
- d = Dictionary.create(description: 'english-text')
2919
- I18n.locale = :de
2920
- d.description = 'deutsch-text'
2921
- d.save
2922
- end
1574
+ describe "#near" do
2923
1575
 
2924
- after do
2925
- I18n.locale = :en
2926
- end
1576
+ before do
1577
+ Bar.create_indexes
1578
+ end
2927
1579
 
2928
- context 'when entire field is included' do
1580
+ let!(:match) do
1581
+ Bar.create!(location: [ 52.30, 13.25 ])
1582
+ end
2929
1583
 
2930
- let(:dictionary) do
2931
- Dictionary.only(:description).first
1584
+ let(:criteria) do
1585
+ Bar.near(location: [ 52, 13 ])
1586
+ end
2932
1587
 
2933
- end
1588
+ it "returns the matching documents" do
1589
+ expect(criteria).to eq([ match ])
1590
+ end
1591
+ end
2934
1592
 
2935
- it 'loads all translations' do
2936
- expect(dictionary.description_translations.keys).to include('de', 'en')
2937
- end
1593
+ describe "#near_sphere" do
2938
1594
 
2939
- it 'returns the field value for the current locale' do
2940
- I18n.locale = :en
2941
- expect(dictionary.description).to eq('english-text')
2942
- I18n.locale = :de
2943
- expect(dictionary.description).to eq('deutsch-text')
2944
- end
2945
- end
1595
+ before do
1596
+ Bar.create_indexes
1597
+ end
2946
1598
 
2947
- context 'when a specific locale is included' do
1599
+ let!(:match) do
1600
+ Bar.create!(location: [ 52.30, 13.25 ])
1601
+ end
2948
1602
 
2949
- let(:dictionary) do
2950
- Dictionary.only(:'description.de').first
2951
- end
1603
+ let(:criteria) do
1604
+ Bar.near_sphere(location: [ 52, 13 ])
1605
+ end
2952
1606
 
2953
- it 'loads translations only for the included locale' do
2954
- expect(dictionary.description_translations.keys).to include('de')
2955
- expect(dictionary.description_translations.keys).to_not include('en')
2956
- end
1607
+ it "returns the matching documents" do
1608
+ expect(criteria).to eq([ match ])
1609
+ end
1610
+ end
2957
1611
 
2958
- it 'returns the field value for the included locale' do
2959
- I18n.locale = :en
2960
- expect(dictionary.description).to be_nil
2961
- I18n.locale = :de
2962
- expect(dictionary.description).to eq('deutsch-text')
2963
- end
2964
- end
1612
+ describe "#nin" do
2965
1613
 
2966
- context 'when entire field is excluded' do
1614
+ let!(:match) do
1615
+ Band.create!(name: "Depeche Mode")
1616
+ end
2967
1617
 
2968
- let(:dictionary) do
2969
- Dictionary.without(:description).first
2970
- end
1618
+ let!(:non_match) do
1619
+ Band.create!(name: "Tool")
1620
+ end
2971
1621
 
2972
- it 'does not load all translations' do
2973
- expect(dictionary.description_translations.keys).to_not include('de', 'en')
2974
- end
1622
+ let(:criteria) do
1623
+ Band.nin(name: [ "Tool" ])
1624
+ end
2975
1625
 
2976
- it 'raises an ActiveModel::MissingAttributeError when attempting to access the field' do
2977
- expect{dictionary.description}.to raise_error ActiveModel::MissingAttributeError
2978
- end
2979
- end
1626
+ it "returns the matching documents" do
1627
+ expect(criteria).to eq([ match ])
1628
+ end
1629
+ end
2980
1630
 
2981
- context 'when a specific locale is excluded' do
1631
+ describe "#nor" do
2982
1632
 
2983
- let(:dictionary) do
2984
- Dictionary.without(:'description.de').first
2985
- end
1633
+ let!(:match) do
1634
+ Band.create!(name: "Depeche Mode")
1635
+ end
2986
1636
 
2987
- it 'does not load excluded translations' do
2988
- expect(dictionary.description_translations.keys).to_not include('de')
2989
- expect(dictionary.description_translations.keys).to include('en')
2990
- end
1637
+ let!(:non_match) do
1638
+ Band.create!(name: "Tool")
1639
+ end
2991
1640
 
2992
- it 'returns nil for excluded translations' do
2993
- I18n.locale = :en
2994
- expect(dictionary.description).to eq('english-text')
2995
- I18n.locale = :de
2996
- expect(dictionary.description).to be_nil
2997
- end
2998
- end
1641
+ let(:criteria) do
1642
+ Band.nor({ name: "Tool" }, { name: "New Order" })
1643
+ end
1644
+
1645
+ it "returns the matching documents" do
1646
+ expect(criteria).to eq([ match ])
2999
1647
  end
3000
1648
  end
3001
1649
 
@@ -3004,11 +1652,11 @@ describe Mongoid::Criteria do
3004
1652
  describe "\##{method}" do
3005
1653
 
3006
1654
  let!(:match) do
3007
- Band.create(name: "Depeche Mode")
1655
+ Band.create!(name: "Depeche Mode")
3008
1656
  end
3009
1657
 
3010
1658
  let!(:non_match) do
3011
- Band.create(name: "Tool")
1659
+ Band.create!(name: "Tool")
3012
1660
  end
3013
1661
 
3014
1662
  context "when sending a normal $or criterion" do
@@ -3038,25 +1686,29 @@ describe Mongoid::Criteria do
3038
1686
  describe "#pluck" do
3039
1687
 
3040
1688
  let!(:depeche) do
3041
- Band.create(name: "Depeche Mode", likes: 3)
1689
+ Band.create!(name: "Depeche Mode", likes: 3)
3042
1690
  end
3043
1691
 
3044
1692
  let!(:tool) do
3045
- Band.create(name: "Tool", likes: 3)
1693
+ Band.create!(name: "Tool", likes: 3)
3046
1694
  end
3047
1695
 
3048
1696
  let!(:photek) do
3049
- Band.create(name: "Photek", likes: 1)
1697
+ Band.create!(name: "Photek", likes: 1)
1698
+ end
1699
+
1700
+ let(:maniacs) do
1701
+ Band.create!(name: "10,000 Maniacs", likes: 1, sales: "1E2")
3050
1702
  end
3051
1703
 
3052
1704
  context "when the field is aliased" do
3053
1705
 
3054
1706
  let!(:expensive) do
3055
- Product.create(price: 100000)
1707
+ Product.create!(price: 100000)
3056
1708
  end
3057
1709
 
3058
1710
  let!(:cheap) do
3059
- Product.create(price: 1)
1711
+ Product.create!(price: 1)
3060
1712
  end
3061
1713
 
3062
1714
  context "when using alias_attribute" do
@@ -3088,7 +1740,6 @@ describe Mongoid::Criteria do
3088
1740
  end
3089
1741
 
3090
1742
  context "when subsequently executing the criteria without a pluck" do
3091
-
3092
1743
  it "does not limit the fields" do
3093
1744
  expect(criteria.first.likes).to eq(3)
3094
1745
  end
@@ -3101,10 +1752,9 @@ describe Mongoid::Criteria do
3101
1752
  end
3102
1753
 
3103
1754
  context 'when a top-level field and a subdocument field are plucked' do
3104
-
3105
1755
  before do
3106
- Band.create(name: 'FKA Twigs')
3107
- Band.create(name: 'FKA Twigs', records: [ Record.new(name: 'LP1') ])
1756
+ Band.create!(name: 'FKA Twigs')
1757
+ Band.create!(name: 'FKA Twigs', records: [ Record.new(name: 'LP1') ])
3108
1758
  end
3109
1759
 
3110
1760
  let(:embedded_pluck) do
@@ -3114,20 +1764,20 @@ describe Mongoid::Criteria do
3114
1764
  let(:expected) do
3115
1765
  [
3116
1766
  ["FKA Twigs", nil],
3117
- ['FKA Twigs', [{ "name" => "LP1" }]]
1767
+ ['FKA Twigs', ["LP1"]]
3118
1768
  ]
3119
1769
  end
3120
1770
 
3121
1771
  it 'returns the list of top-level field and subdocument values' do
3122
- expect(embedded_pluck). to eq(expected)
1772
+ expect(embedded_pluck).to eq(expected)
3123
1773
  end
3124
1774
  end
3125
1775
 
3126
1776
  context 'when only a subdocument field is plucked' do
3127
1777
 
3128
1778
  before do
3129
- Band.create(name: 'FKA Twigs')
3130
- Band.create(name: 'FKA Twigs', records: [ Record.new(name: 'LP1') ])
1779
+ Band.create!(name: 'FKA Twigs')
1780
+ Band.create!(name: 'FKA Twigs', records: [ Record.new(name: 'LP1') ])
3131
1781
  end
3132
1782
 
3133
1783
  let(:embedded_pluck) do
@@ -3137,15 +1787,14 @@ describe Mongoid::Criteria do
3137
1787
  let(:expected) do
3138
1788
  [
3139
1789
  nil,
3140
- [{ "name" => "LP1" }]
1790
+ ["LP1"]
3141
1791
  ]
3142
1792
  end
3143
1793
 
3144
1794
  it 'returns the list of subdocument values' do
3145
- expect(embedded_pluck). to eq(expected)
1795
+ expect(embedded_pluck).to eq(expected)
3146
1796
  end
3147
1797
  end
3148
-
3149
1798
  end
3150
1799
  end
3151
1800
 
@@ -3213,7 +1862,7 @@ describe Mongoid::Criteria do
3213
1862
  Band.all.pluck(:foo)
3214
1863
  end
3215
1864
 
3216
- it "returns a array with nil values" do
1865
+ it "returns an array with nil values" do
3217
1866
  expect(plucked).to eq([nil, nil, nil])
3218
1867
  end
3219
1868
  end
@@ -3224,46 +1873,244 @@ describe Mongoid::Criteria do
3224
1873
  Band.all.pluck(:foo, :bar)
3225
1874
  end
3226
1875
 
3227
- it "returns a nil arrays" do
1876
+ it "returns an array of arrays with nil values" do
3228
1877
  expect(plucked).to eq([[nil, nil], [nil, nil], [nil, nil]])
3229
1878
  end
3230
1879
  end
3231
1880
  end
3232
1881
 
3233
- context 'when plucking a localized field' do
1882
+ context 'when plucking a localized field' do
1883
+ with_default_i18n_configs
1884
+
1885
+ before do
1886
+ I18n.locale = :en
1887
+ d = Dictionary.create!(description: 'english-text')
1888
+ I18n.locale = :de
1889
+ d.description = 'deutsch-text'
1890
+ d.save!
1891
+ end
1892
+
1893
+ context 'when plucking the entire field' do
1894
+ let(:plucked) do
1895
+ Dictionary.all.pluck(:description)
1896
+ end
1897
+
1898
+ let(:plucked_translations) do
1899
+ Dictionary.all.pluck(:description_translations)
1900
+ end
1901
+
1902
+ let(:plucked_translations_both) do
1903
+ Dictionary.all.pluck(:description_translations, :description)
1904
+ end
1905
+
1906
+ it 'returns the demongoized translations' do
1907
+ expect(plucked.first).to eq('deutsch-text')
1908
+ end
1909
+
1910
+ it 'returns the full translations hash to _translations' do
1911
+ expect(plucked_translations.first).to eq({"de"=>"deutsch-text", "en"=>"english-text"})
1912
+ end
1913
+
1914
+ it 'returns both' do
1915
+ expect(plucked_translations_both.first).to eq([{"de"=>"deutsch-text", "en"=>"english-text"}, "deutsch-text"])
1916
+ end
1917
+ end
1918
+
1919
+ context 'when plucking a specific locale' do
1920
+
1921
+ let(:plucked) do
1922
+ Dictionary.all.pluck(:'description.de')
1923
+ end
1924
+
1925
+ it 'returns the specific translations' do
1926
+ expect(plucked.first).to eq('deutsch-text')
1927
+ end
1928
+ end
1929
+
1930
+ context 'when plucking a specific locale from _translations field' do
1931
+
1932
+ let(:plucked) do
1933
+ Dictionary.all.pluck(:'description_translations.de')
1934
+ end
1935
+
1936
+ it 'returns the specific translations' do
1937
+ expect(plucked.first).to eq('deutsch-text')
1938
+ end
1939
+ end
1940
+
1941
+ context 'when fallbacks are enabled with a locale list' do
1942
+ require_fallbacks
1943
+
1944
+ before do
1945
+ I18n.fallbacks[:he] = [ :en ]
1946
+ end
1947
+
1948
+ let(:plucked) do
1949
+ Dictionary.all.pluck(:description).first
1950
+ end
1951
+
1952
+ it "correctly uses the fallback" do
1953
+ I18n.locale = :en
1954
+ d = Dictionary.create!(description: 'english-text')
1955
+ I18n.locale = :he
1956
+ plucked.should == "english-text"
1957
+ end
1958
+ end
1959
+
1960
+ context "when the localized field is embedded" do
1961
+ with_default_i18n_configs
1962
+
1963
+ before do
1964
+ p = Passport.new
1965
+ I18n.locale = :en
1966
+ p.name = "Neil"
1967
+ I18n.locale = :he
1968
+ p.name = "Nissim"
1969
+
1970
+ Person.create!(passport: p, employer_id: 12345)
1971
+ end
1972
+
1973
+ let(:plucked) do
1974
+ Person.where(employer_id: 12345).pluck("pass.name").first
1975
+ end
1976
+
1977
+ let(:plucked_translations) do
1978
+ Person.where(employer_id: 12345).pluck("pass.name_translations").first
1979
+ end
1980
+
1981
+ let(:plucked_translations_field) do
1982
+ Person.where(employer_id: 12345).pluck("pass.name_translations.en").first
1983
+ end
1984
+
1985
+ it "returns the translation for the current locale" do
1986
+ expect(plucked).to eq("Nissim")
1987
+ end
1988
+
1989
+ it "returns the full _translation hash" do
1990
+ expect(plucked_translations).to eq({ "en" => "Neil", "he" => "Nissim" })
1991
+ end
1992
+
1993
+ it "returns the translation for the requested locale" do
1994
+ expect(plucked_translations_field).to eq("Neil")
1995
+ end
1996
+ end
1997
+ end
1998
+
1999
+ context 'when plucking a field to be demongoized' do
2000
+
2001
+ let(:plucked) do
2002
+ Band.where(name: maniacs.name).pluck(:sales)
2003
+ end
2004
+
2005
+ context 'when value is stored as string' do
2006
+ config_override :map_big_decimal_to_decimal128, false
2007
+
2008
+ it "demongoizes the field" do
2009
+ expect(plucked.first).to be_a(BigDecimal)
2010
+ expect(plucked.first).to eq(BigDecimal("1E2"))
2011
+ end
2012
+ end
2013
+
2014
+ context 'when value is stored as decimal128' do
2015
+ config_override :map_big_decimal_to_decimal128, true
2016
+
2017
+ it "demongoizes the field" do
2018
+ expect(plucked.first).to be_a(BigDecimal)
2019
+ expect(plucked.first).to eq(BigDecimal("1E2"))
2020
+ end
2021
+ end
2022
+ end
2023
+
2024
+ context "when plucking an embedded field" do
2025
+ let(:label) { Label.new(sales: "1E2") }
2026
+ let!(:band) { Band.create!(label: label) }
2027
+
2028
+ let(:plucked) { Band.where(_id: band.id).pluck("label.sales") }
2029
+
2030
+ it "demongoizes the field" do
2031
+ expect(plucked).to eq([ BigDecimal("1E2") ])
2032
+ end
2033
+ end
2034
+
2035
+ context "when plucking an embeds_many field" do
2036
+ let(:label) { Label.new(sales: "1E2") }
2037
+ let!(:band) { Band.create!(labels: [label]) }
2038
+
2039
+ let(:plucked) { Band.where(_id: band.id).pluck("labels.sales") }
2040
+
2041
+ it "demongoizes the field" do
2042
+ expect(plucked.first).to eq([ BigDecimal("1E2") ])
2043
+ end
2044
+ end
2045
+
2046
+ context "when plucking a nonexistent embedded field" do
2047
+ let(:label) { Label.new(sales: "1E2") }
2048
+ let!(:band) { Band.create!(label: label) }
2049
+
2050
+ let(:plucked) { Band.where(_id: band.id).pluck("label.qwerty") }
2051
+
2052
+ it "returns nil" do
2053
+ expect(plucked.first).to eq(nil)
2054
+ end
2055
+ end
2056
+
2057
+ context "when tallying deeply nested arrays/embedded associations" do
2058
+
2059
+ before do
2060
+ Person.create!(addresses: [ Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 2 } } ]))) ])
2061
+ Person.create!(addresses: [ Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 2 } } ]))) ])
2062
+ Person.create!(addresses: [ Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 3 } } ]))) ])
2063
+ end
2064
+
2065
+ let(:plucked) do
2066
+ Person.pluck("addresses.code.deepest.array.y.z")
2067
+ end
2068
+
2069
+ it "returns the correct hash" do
2070
+ expect(plucked).to eq([
2071
+ [ [ 1, 2 ] ], [ [ 1, 2 ] ], [ [ 1, 3 ] ]
2072
+ ])
2073
+ end
2074
+ end
2075
+ end
2076
+
2077
+ describe "#pick" do
2078
+
2079
+ let!(:depeche) do
2080
+ Band.create!(name: "Depeche Mode", likes: 3)
2081
+ end
2082
+
2083
+ let!(:tool) do
2084
+ Band.create!(name: "Tool", likes: 3)
2085
+ end
3234
2086
 
3235
- before do
3236
- I18n.locale = :en
3237
- d = Dictionary.create(description: 'english-text')
3238
- I18n.locale = :de
3239
- d.description = 'deutsch-text'
3240
- d.save
2087
+ context "when picking a field" do
2088
+
2089
+ let(:criteria) do
2090
+ Band.all
3241
2091
  end
3242
2092
 
3243
- after do
3244
- I18n.locale = :en
2093
+ let(:picked) do
2094
+ criteria.pick(:name)
3245
2095
  end
3246
2096
 
3247
- context 'when plucking the entire field' do
2097
+ it "returns one element" do
2098
+ expect(picked).to eq("Depeche Mode")
2099
+ end
2100
+ end
3248
2101
 
3249
- let(:plucked) do
3250
- Dictionary.all.pluck(:description)
3251
- end
2102
+ context "when picking multiple fields" do
3252
2103
 
3253
- it 'returns all translations' do
3254
- expect(plucked.first).to eq({'en' => 'english-text', 'de' => 'deutsch-text'})
3255
- end
2104
+ let(:criteria) do
2105
+ Band.all
3256
2106
  end
3257
2107
 
3258
- context 'when plucking a specific locale' do
3259
-
3260
- let(:plucked) do
3261
- Dictionary.all.pluck(:'description.de')
3262
- end
2108
+ let(:picked) do
2109
+ criteria.pick(:name, :likes)
2110
+ end
3263
2111
 
3264
- it 'returns the specific translations' do
3265
- expect(plucked.first).to eq({'de' => 'deutsch-text'})
3266
- end
2112
+ it "returns an array" do
2113
+ expect(picked).to eq([ "Depeche Mode", 3 ])
3267
2114
  end
3268
2115
  end
3269
2116
  end
@@ -3349,11 +2196,11 @@ describe Mongoid::Criteria do
3349
2196
  describe "#sort" do
3350
2197
 
3351
2198
  let!(:depeche) do
3352
- Band.create(name: "Depeche Mode", likes: 1000)
2199
+ Band.create!(name: "Depeche Mode", likes: 1000)
3353
2200
  end
3354
2201
 
3355
2202
  let!(:tool) do
3356
- Band.create(name: "Tool", likes: 500)
2203
+ Band.create!(name: "Tool", likes: 500)
3357
2204
  end
3358
2205
 
3359
2206
  let(:sorted) do
@@ -3372,11 +2219,11 @@ describe Mongoid::Criteria do
3372
2219
  context "when provided a single field" do
3373
2220
 
3374
2221
  let!(:depeche) do
3375
- Band.create(name: "Depeche Mode", likes: 1000)
2222
+ Band.create!(name: "Depeche Mode", likes: 1000)
3376
2223
  end
3377
2224
 
3378
2225
  let!(:tool) do
3379
- Band.create(name: "Tool", likes: 500)
2226
+ Band.create!(name: "Tool", likes: 500)
3380
2227
  end
3381
2228
 
3382
2229
  let(:criteria) do
@@ -3410,7 +2257,7 @@ describe Mongoid::Criteria do
3410
2257
  describe "#to_ary" do
3411
2258
 
3412
2259
  let!(:band) do
3413
- Band.create(name: "Depeche Mode")
2260
+ Band.create!(name: "Depeche Mode")
3414
2261
  end
3415
2262
 
3416
2263
  let(:criteria) do
@@ -3426,11 +2273,11 @@ describe Mongoid::Criteria do
3426
2273
  max_server_version '4.0'
3427
2274
 
3428
2275
  let!(:band) do
3429
- Band.create(name: "Depeche Mode")
2276
+ Band.create!(name: "Depeche Mode")
3430
2277
  end
3431
2278
 
3432
2279
  let!(:band2) do
3433
- Band.create(name: "Tool")
2280
+ Band.create!(name: "Tool")
3434
2281
  end
3435
2282
 
3436
2283
  let(:criteria) do
@@ -3442,17 +2289,6 @@ describe Mongoid::Criteria do
3442
2289
  end
3443
2290
  end
3444
2291
 
3445
- describe "#to_criteria" do
3446
-
3447
- let(:criteria) do
3448
- Band.all
3449
- end
3450
-
3451
- it "returns self" do
3452
- expect(criteria.to_criteria).to eq(criteria)
3453
- end
3454
- end
3455
-
3456
2292
  describe "#to_proc" do
3457
2293
 
3458
2294
  let(:criteria) do
@@ -3473,7 +2309,7 @@ describe Mongoid::Criteria do
3473
2309
  context "when the type is a string" do
3474
2310
 
3475
2311
  let!(:browser) do
3476
- Browser.create
2312
+ Browser.create!
3477
2313
  end
3478
2314
 
3479
2315
  let(:criteria) do
@@ -3488,7 +2324,7 @@ describe Mongoid::Criteria do
3488
2324
  context "when the type is an Array of type" do
3489
2325
 
3490
2326
  let!(:browser) do
3491
- Firefox.create
2327
+ Firefox.create!
3492
2328
  end
3493
2329
 
3494
2330
  let(:criteria) do
@@ -3513,7 +2349,7 @@ describe Mongoid::Criteria do
3513
2349
  context "when the type is a string" do
3514
2350
 
3515
2351
  let!(:browser) do
3516
- Browser.create
2352
+ Browser.create!
3517
2353
  end
3518
2354
 
3519
2355
  let(:criteria) do
@@ -3528,7 +2364,7 @@ describe Mongoid::Criteria do
3528
2364
  context "when the type is an Array of type" do
3529
2365
 
3530
2366
  let!(:browser) do
3531
- Firefox.create
2367
+ Firefox.create!
3532
2368
  end
3533
2369
 
3534
2370
  let(:criteria) do
@@ -3545,11 +2381,11 @@ describe Mongoid::Criteria do
3545
2381
  describe "#where" do
3546
2382
 
3547
2383
  let!(:match) do
3548
- Band.create(name: "Depeche Mode")
2384
+ Band.create!(name: "Depeche Mode")
3549
2385
  end
3550
2386
 
3551
2387
  let!(:non_match) do
3552
- Band.create(name: "Tool")
2388
+ Band.create!(name: "Tool")
3553
2389
  end
3554
2390
 
3555
2391
  context 'when provided no arguments' do
@@ -3641,32 +2477,140 @@ describe Mongoid::Criteria do
3641
2477
 
3642
2478
  context "when querying on a big decimal" do
3643
2479
 
3644
- let(:sales) do
3645
- BigDecimal('0.1')
2480
+ context 'when map_big_decimal_to_decimal128 is false' do
2481
+ config_override :map_big_decimal_to_decimal128, false
2482
+
2483
+ let(:sales) do
2484
+ BigDecimal('0.1')
2485
+ end
2486
+
2487
+ let!(:band) do
2488
+ Band.create!(name: "Boards of Canada", sales: sales)
2489
+ end
2490
+
2491
+ let(:from_db) do
2492
+ Band.where(sales: sales).first
2493
+ end
2494
+
2495
+ it "finds the document by the big decimal value" do
2496
+ expect(from_db).to eq(band)
2497
+ end
3646
2498
  end
3647
2499
 
3648
- let!(:band) do
3649
- Band.create(name: "Boards of Canada", sales: sales)
2500
+ context 'when map_big_decimal_to_decimal128 is true' do
2501
+ config_override :map_big_decimal_to_decimal128, true
2502
+
2503
+ let(:sales) do
2504
+ BigDecimal('0.1')
2505
+ end
2506
+
2507
+ let!(:band) do
2508
+ Band.create!(name: "Boards of Canada", sales: sales)
2509
+ end
2510
+
2511
+ let(:from_db) do
2512
+ Band.where(sales: sales).first
2513
+ end
2514
+
2515
+ it "finds the document by the big decimal value" do
2516
+ expect(from_db).to eq(band)
2517
+ end
3650
2518
  end
3651
2519
 
3652
- let(:from_db) do
3653
- Band.where(sales: sales).first
2520
+ context 'when map_big_decimal_to_decimal128 was false and is now true' do
2521
+ config_override :map_big_decimal_to_decimal128, false
2522
+
2523
+ let(:sales) do
2524
+ BigDecimal('0.1')
2525
+ end
2526
+
2527
+ let!(:band) do
2528
+ Mongoid.map_big_decimal_to_decimal128 = false
2529
+ Band.create!(name: "Boards of Canada", sales: sales)
2530
+ end
2531
+
2532
+ it "cannot find values when querying using a BigDecimal value" do
2533
+ Mongoid.map_big_decimal_to_decimal128 = true
2534
+ from_db = Band.where(sales: sales).first
2535
+ expect(from_db).to eq(nil)
2536
+ end
2537
+
2538
+ it "cannot find values when querying using a string value" do
2539
+ Mongoid.map_big_decimal_to_decimal128 = true
2540
+ from_db = Band.where(sales: sales.to_s).first
2541
+ expect(from_db).to eq(nil)
2542
+ end
2543
+
2544
+ context "after converting value" do
2545
+ before do
2546
+ Mongoid.map_big_decimal_to_decimal128 = true
2547
+ band.set(sales: band.sales)
2548
+ end
2549
+
2550
+ it "can find values when querying using a BigDecimal value" do
2551
+ from_db = Band.where(sales: sales).first
2552
+ expect(from_db).to eq(band)
2553
+ end
2554
+
2555
+ it "can find values when querying using a string value" do
2556
+ from_db = Band.where(sales: sales.to_s).first
2557
+ expect(from_db).to eq(band)
2558
+ end
2559
+ end
3654
2560
  end
2561
+ end
3655
2562
 
3656
- it "finds the document by the big decimal value" do
3657
- expect(from_db).to eq(band)
2563
+ context "when querying on a big decimal from a dynamic field" do
2564
+
2565
+ context 'when map_big_decimal_to_decimal128 is false' do
2566
+ config_override :map_big_decimal_to_decimal128, false
2567
+
2568
+ let(:fans) do
2569
+ BigDecimal('139432.0002')
2570
+ end
2571
+
2572
+ let!(:band) do
2573
+ Band.create!(name: "Boards of Canada", fans: fans)
2574
+ end
2575
+
2576
+ let(:from_db) do
2577
+ Band.where(fans: fans.to_s).first
2578
+ end
2579
+
2580
+ it "finds the document by the big decimal value" do
2581
+ expect(from_db).to eq(band)
2582
+ end
2583
+ end
2584
+
2585
+ context 'when map_big_decimal_to_decimal128 is true' do
2586
+ config_override :map_big_decimal_to_decimal128, true
2587
+
2588
+ let(:fans) do
2589
+ BigDecimal('139432.0002')
2590
+ end
2591
+
2592
+ let!(:band) do
2593
+ Band.create!(name: "Boards of Canada", fans: fans)
2594
+ end
2595
+
2596
+ let(:from_db) do
2597
+ Band.where(fans: fans).first
2598
+ end
2599
+
2600
+ it "only finds the document by the string value" do
2601
+ expect(from_db).to eq(band)
2602
+ end
3658
2603
  end
3659
2604
  end
3660
2605
 
3661
2606
  context "when querying on a BSON::Decimal128" do
3662
- min_server_version '3.4'
3663
2607
 
3664
2608
  let(:decimal) do
3665
2609
  BSON::Decimal128.new("0.0005")
3666
2610
  end
3667
2611
 
3668
2612
  let!(:band) do
3669
- Band.create(name: "Boards of Canada", decimal: decimal)
2613
+ Band.create!(name: "Boards of Canada", decimal: decimal)
3670
2614
  end
3671
2615
 
3672
2616
  let(:from_db) do
@@ -3681,7 +2625,7 @@ describe Mongoid::Criteria do
3681
2625
  context 'when querying on a polymorphic relation' do
3682
2626
 
3683
2627
  let(:movie) do
3684
- Movie.create
2628
+ Movie.create!
3685
2629
  end
3686
2630
 
3687
2631
  let(:selector) do
@@ -3692,6 +2636,17 @@ describe Mongoid::Criteria do
3692
2636
  expect(selector['ratable_id']).to eq(movie.id)
3693
2637
  end
3694
2638
  end
2639
+
2640
+ context "when querying an embedded document with aliases" do
2641
+
2642
+ let(:criteria) do
2643
+ Person.where("phones.extension" => "123")
2644
+ end
2645
+
2646
+ it "expands the aliases" do
2647
+ expect(criteria.selector).to eq("mobile_phones.ext" => "123")
2648
+ end
2649
+ end
3695
2650
  end
3696
2651
 
3697
2652
  context 'when given multiple keys in separate calls' do
@@ -3727,12 +2682,274 @@ describe Mongoid::Criteria do
3727
2682
  'foo' => 1, '$and' => [{'foo' => 2}], 'bar' => 3)
3728
2683
  end
3729
2684
  end
2685
+
2686
+ context "when duplicating where conditions" do
2687
+ let(:criteria) { Sound.where(active: true).where(active: true) }
2688
+
2689
+ it 'does not duplicate criteria' do
2690
+ expect(criteria.selector).to eq('active' => true)
2691
+ end
2692
+ end
2693
+
2694
+ context "when duplicating where conditions with different values" do
2695
+ let(:criteria) { Sound.where(active: true).where(active: false).where(active: true).where(active: false) }
2696
+
2697
+ it 'does not duplicate criteria' do
2698
+ expect(criteria.selector).to eq(
2699
+ 'active' => true, '$and' => [{'active' => false}])
2700
+ end
2701
+ end
2702
+
2703
+ # Used to test MONGOID-5251 where the find command was adding unnecessary
2704
+ # and clauses. Since the find command creates the criteria and executes it,
2705
+ # it is difficult to analyze the criteria used. For this reason, I have
2706
+ # extracted the crux of the issue, adding an _id to the the criteria twice,
2707
+ # and used that for the test case.
2708
+ context "when searching by _id twice" do
2709
+ let(:_id) { BSON::ObjectId.new }
2710
+ let(:criteria) { Band.where(_id: _id) }
2711
+ let(:dup_criteria) { criteria.where(_id: _id)}
2712
+
2713
+ it "does not duplicate the criteria" do
2714
+ expect(dup_criteria.selector).to eq({ "_id" => _id })
2715
+ end
2716
+ end
2717
+
2718
+ context "when querying an embedded field" do
2719
+ let(:criteria) { Band.where("label.name": 12345) }
2720
+
2721
+ it "mongoizes the embedded field in the selector" do
2722
+ expect(criteria.selector).to eq("label.name" => "12345")
2723
+ end
2724
+ end
2725
+
2726
+ context "when querying with a range" do
2727
+
2728
+ context "when querying an embeds_many association" do
2729
+ let(:criteria) do
2730
+ Band.where("labels" => 10..15)
2731
+ end
2732
+
2733
+ it "correctly uses elemMatch without an inner key" do
2734
+ expect(criteria.selector).to eq(
2735
+ "labels" => {
2736
+ "$elemMatch" => { "$gte" => 10, "$lte" => 15 }
2737
+ }
2738
+ )
2739
+ end
2740
+ end
2741
+
2742
+ context "when querying an element in an embeds_many association" do
2743
+ let(:criteria) do
2744
+ Band.where("labels.age" => 10..15)
2745
+ end
2746
+
2747
+ it "correctly uses elemMatch" do
2748
+ expect(criteria.selector).to eq(
2749
+ "labels" => {
2750
+ "$elemMatch" => {
2751
+ "age" => { "$gte" => 10, "$lte" => 15 }
2752
+ }
2753
+ }
2754
+ )
2755
+ end
2756
+ end
2757
+
2758
+ context "when querying a field of type array" do
2759
+ let(:criteria) do
2760
+ Band.where("genres" => 10..15)
2761
+ end
2762
+
2763
+ it "correctly uses elemMatch without an inner key" do
2764
+ expect(criteria.selector).to eq(
2765
+ "genres" => {
2766
+ "$elemMatch" => { "$gte" => 10, "$lte" => 15 }
2767
+ }
2768
+ )
2769
+ end
2770
+ end
2771
+
2772
+ context "when querying an aliased field of type array" do
2773
+ let(:criteria) do
2774
+ Person.where("array" => 10..15)
2775
+ end
2776
+
2777
+ it "correctly uses the aliased field and elemMatch" do
2778
+ expect(criteria.selector).to eq(
2779
+ "a" => {
2780
+ "$elemMatch" => { "$gte" => 10, "$lte" => 15 }
2781
+ }
2782
+ )
2783
+ end
2784
+ end
2785
+
2786
+ context "when querying a field inside an array" do
2787
+ let(:criteria) do
2788
+ Band.where("genres.age" => 10..15)
2789
+ end
2790
+
2791
+ it "correctly uses elemMatch" do
2792
+ expect(criteria.selector).to eq(
2793
+ "genres" => {
2794
+ "$elemMatch" => {
2795
+ "age" => { "$gte" => 10, "$lte" => 15 }
2796
+ }
2797
+ }
2798
+ )
2799
+ end
2800
+ end
2801
+
2802
+ context "when there are no embeds_manys or Arrays" do
2803
+ let(:criteria) do
2804
+ Band.where("fans.info.age" => 10..15)
2805
+ end
2806
+
2807
+ it "does not use elemMatch" do
2808
+ expect(criteria.selector).to eq(
2809
+ "fans.info.age" => { "$gte" => 10, "$lte" => 15 }
2810
+ )
2811
+ end
2812
+ end
2813
+
2814
+ context "when querying a nested element in an embeds_many association" do
2815
+ let(:criteria) do
2816
+ Band.where("labels.age.number" => 10..15)
2817
+ end
2818
+
2819
+ it "correctly uses elemMatch" do
2820
+ expect(criteria.selector).to eq(
2821
+ "labels" => {
2822
+ "$elemMatch" => {
2823
+ "age.number" => { "$gte" => 10, "$lte" => 15 }
2824
+ }
2825
+ }
2826
+ )
2827
+ end
2828
+ end
2829
+
2830
+ context "when querying a nested element in an Array" do
2831
+ let(:criteria) do
2832
+ Band.where("genres.name.length" => 10..15)
2833
+ end
2834
+
2835
+ it "correctly uses elemMatch" do
2836
+ expect(criteria.selector).to eq(
2837
+ "genres" => {
2838
+ "$elemMatch" => {
2839
+ "name.length" => { "$gte" => 10, "$lte" => 15 }
2840
+ }
2841
+ }
2842
+ )
2843
+ end
2844
+ end
2845
+
2846
+ context "when querying a nested element in a nested embeds_many association" do
2847
+ context "when the outer association is an embeds_many" do
2848
+ let(:criteria) do
2849
+ Band.where("records.tracks.name.length" => 10..15)
2850
+ end
2851
+
2852
+ it "correctly uses elemMatch" do
2853
+ expect(criteria.selector).to eq(
2854
+ "records.tracks" => {
2855
+ "$elemMatch" => {
2856
+ "name.length" => { "$gte" => 10, "$lte" => 15 }
2857
+ }
2858
+ }
2859
+ )
2860
+ end
2861
+ end
2862
+
2863
+ context "when the outer association is an embeds_one" do
2864
+ let(:criteria) do
2865
+ Person.where("name.translations.language.length" => 10..15)
2866
+ end
2867
+
2868
+ it "correctly uses elemMatch" do
2869
+ expect(criteria.selector).to eq(
2870
+ "name.translations" => {
2871
+ "$elemMatch" => {
2872
+ "language.length" => { "$gte" => 10, "$lte" => 15 }
2873
+ }
2874
+ }
2875
+ )
2876
+ end
2877
+ end
2878
+ end
2879
+
2880
+ context "when querying a deeply nested array" do
2881
+ let(:criteria) do
2882
+ Person.where("addresses.code.deepest.array.element.item" => 10..15)
2883
+ end
2884
+
2885
+ it "correctly uses elemMatch" do
2886
+ expect(criteria.selector).to eq(
2887
+ "addresses.code.deepest.array" => {
2888
+ "$elemMatch" => {
2889
+ "element.item" => { "$gte" => 10, "$lte" => 15 }
2890
+ }
2891
+ }
2892
+ )
2893
+ end
2894
+ end
2895
+
2896
+ context "when there are multiple conditions" do
2897
+ let(:criteria) do
2898
+ Band.where("$or" => [{"labels.age" => 10..15}, {labels: 8}])
2899
+ end
2900
+
2901
+ it "correctly combines the conditions" do
2902
+ expect(criteria.selector).to eq("$or" => [
2903
+ { "labels" => {
2904
+ "$elemMatch" => {
2905
+ "age" => { "$gte" => 10, "$lte" => 15 }
2906
+ } } },
2907
+ { "labels" => 8 }
2908
+ ])
2909
+ end
2910
+ end
2911
+
2912
+ context "when the association is aliased" do
2913
+ let(:criteria) do
2914
+ Person.where("passport.passport_pages.num_stamps" => 10..18)
2915
+ end
2916
+
2917
+ it "correctly uses the aliased association" do
2918
+ expect(criteria.selector).to eq(
2919
+ "pass.passport_pages" => {
2920
+ "$elemMatch" => {
2921
+ "num_stamps" => { "$gte" => 10, "$lte" => 18 }
2922
+ }
2923
+ }
2924
+ )
2925
+ end
2926
+ end
2927
+ end
2928
+
2929
+ context "when searching for a regex on a symbol field" do
2930
+ let!(:person) { Person.create!(species: :hello)}
2931
+ let(:criteria) { Person.where(species: /ell/) }
2932
+
2933
+ it "creates the correct criteria" do
2934
+ expect(criteria.selector).to eq({ "species" => /ell/ })
2935
+ end
2936
+
2937
+ it "finds the document" do
2938
+ expect(criteria.first).to eq(person)
2939
+ end
2940
+ end
3730
2941
  end
3731
2942
 
3732
2943
  describe "#for_js" do
3733
2944
 
3734
2945
  let!(:match) do
3735
- Band.create(name: "Depeche Mode")
2946
+ Band.create!(name: "Depeche Mode")
2947
+ end
2948
+
2949
+ it 'is deprecated' do
2950
+ expect(Mongoid.logger).to receive(:warn).with(/for_js is deprecated/).and_call_original
2951
+
2952
+ Band.for_js("this.name == 'Depeche Mode'")
3736
2953
  end
3737
2954
 
3738
2955
  context "when the code has no scope" do
@@ -3769,21 +2986,25 @@ describe Mongoid::Criteria do
3769
2986
 
3770
2987
  before do
3771
2988
  expect(Person).to receive(:minor).and_call_original
2989
+ expect(Person).to receive(:older_than).and_call_original
3772
2990
  end
3773
2991
 
3774
2992
  it "calls the method on the class" do
3775
2993
  expect(criteria.minor).to be_empty
2994
+ expect do
2995
+ criteria.older_than(age: 25)
2996
+ end.not_to raise_error
3776
2997
  end
3777
2998
  end
3778
2999
 
3779
3000
  context "when the method exists on the criteria" do
3780
3001
 
3781
3002
  before do
3782
- expect(criteria).to receive(:to_criteria).and_call_original
3003
+ expect(criteria).to receive(:only).and_call_original
3783
3004
  end
3784
3005
 
3785
3006
  it "calls the method on the criteria" do
3786
- expect(criteria.to_criteria).to eq(criteria)
3007
+ expect(criteria.only).to eq(criteria)
3787
3008
  end
3788
3009
  end
3789
3010
 
@@ -3815,11 +3036,11 @@ describe Mongoid::Criteria do
3815
3036
  describe "#uniq" do
3816
3037
 
3817
3038
  let!(:band_one) do
3818
- Band.create(name: "New Order")
3039
+ Band.create!(name: "New Order")
3819
3040
  end
3820
3041
 
3821
3042
  let!(:band_two) do
3822
- Band.create(name: "New Order")
3043
+ Band.create!(name: "New Order")
3823
3044
  end
3824
3045
 
3825
3046
  let(:criteria) do
@@ -3868,7 +3089,7 @@ describe Mongoid::Criteria do
3868
3089
  end
3869
3090
 
3870
3091
  let!(:match) do
3871
- Bar.create(location: [ 52.30, 13.25 ])
3092
+ Bar.create!(location: [ 52.30, 13.25 ])
3872
3093
  end
3873
3094
 
3874
3095
  let(:criteria) do
@@ -3886,11 +3107,11 @@ describe Mongoid::Criteria do
3886
3107
  describe "#with_size" do
3887
3108
 
3888
3109
  let!(:match) do
3889
- Band.create(genres: [ "electro", "dub" ])
3110
+ Band.create!(genres: [ "electro", "dub" ])
3890
3111
  end
3891
3112
 
3892
3113
  let!(:non_match) do
3893
- Band.create(genres: [ "house" ])
3114
+ Band.create!(genres: [ "house" ])
3894
3115
  end
3895
3116
 
3896
3117
  let(:criteria) do
@@ -3905,7 +3126,7 @@ describe Mongoid::Criteria do
3905
3126
  describe "#with_type" do
3906
3127
 
3907
3128
  let!(:match) do
3908
- Band.create(name: "Depeche Mode")
3129
+ Band.create!(name: "Depeche Mode")
3909
3130
  end
3910
3131
 
3911
3132
  let(:criteria) do
@@ -3917,44 +3138,6 @@ describe Mongoid::Criteria do
3917
3138
  end
3918
3139
  end
3919
3140
 
3920
- describe "#without" do
3921
-
3922
- let!(:person) do
3923
- Person.create!(username: "davinci", age: 50, pets: false)
3924
- end
3925
-
3926
- context "when omitting to embedded documents" do
3927
-
3928
- context "when the embedded documents are aliased" do
3929
-
3930
- let(:criteria) do
3931
- Person.without(:phones)
3932
- end
3933
-
3934
- it "properly uses the database field name" do
3935
- expect(criteria.options).to eq(fields: { "mobile_phones" => 0 })
3936
- end
3937
- end
3938
- end
3939
-
3940
- context "when excluding id" do
3941
-
3942
- let(:criteria) do
3943
- Person.without(:_id, :id, "_id", "id")
3944
- end
3945
-
3946
- it "does not raise error" do
3947
- expect {
3948
- criteria.first.id
3949
- }.to_not raise_error
3950
- end
3951
-
3952
- it "returns id anyway" do
3953
- expect(criteria.first.id).to_not be_nil
3954
- end
3955
- end
3956
- end
3957
-
3958
3141
  describe "#type_selection" do
3959
3142
  context "when using the default discriminator_key" do
3960
3143
  context "when only one subclass exists" do
@@ -4028,4 +3211,44 @@ describe Mongoid::Criteria do
4028
3211
  end
4029
3212
  end
4030
3213
  end
3214
+
3215
+ describe '.from_hash' do
3216
+ subject(:criteria) { described_class.from_hash(hash) }
3217
+
3218
+ context 'when klass is specified' do
3219
+ let(:hash) do
3220
+ { klass: Band, where: { name: 'Songs Ohia' } }
3221
+ end
3222
+
3223
+ it 'returns a criteria' do
3224
+ expect(criteria).to be_a(Mongoid::Criteria)
3225
+ end
3226
+
3227
+ it 'sets the klass' do
3228
+ expect(criteria.klass).to eq(Band)
3229
+ end
3230
+
3231
+ it 'sets the selector' do
3232
+ expect(criteria.selector).to eq({ 'name' => 'Songs Ohia' })
3233
+ end
3234
+ end
3235
+
3236
+ context 'when klass is missing' do
3237
+ let(:hash) do
3238
+ { where: { name: 'Songs Ohia' } }
3239
+ end
3240
+
3241
+ it 'returns a criteria' do
3242
+ expect(criteria).to be_a(Mongoid::Criteria)
3243
+ end
3244
+
3245
+ it 'has klass nil' do
3246
+ expect(criteria.klass).to be_nil
3247
+ end
3248
+
3249
+ it 'sets the selector' do
3250
+ expect(criteria.selector).to eq({ 'name' => 'Songs Ohia' })
3251
+ end
3252
+ end
3253
+ end
4031
3254
  end