mongoid 7.0.2 → 8.1.1

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