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