mongoid 6.4.8 → 7.5.4

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 (1372) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/CHANGELOG.md +30 -30
  4. data/LICENSE +1 -0
  5. data/README.md +34 -20
  6. data/Rakefile +75 -6
  7. data/lib/config/locales/en.yml +149 -66
  8. data/lib/mongoid/association/accessors.rb +402 -0
  9. data/lib/mongoid/association/bindable.rb +179 -0
  10. data/lib/mongoid/association/builders.rb +84 -0
  11. data/lib/mongoid/association/constrainable.rb +43 -0
  12. data/lib/mongoid/association/depending.rb +128 -0
  13. data/lib/mongoid/association/eager_loadable.rb +35 -0
  14. data/lib/mongoid/association/embedded/batchable.rb +375 -0
  15. data/lib/mongoid/association/embedded/cyclic.rb +102 -0
  16. data/lib/mongoid/association/embedded/embedded_in/binding.rb +52 -0
  17. data/lib/mongoid/association/embedded/embedded_in/buildable.rb +38 -0
  18. data/lib/mongoid/association/embedded/embedded_in/proxy.rb +111 -0
  19. data/lib/mongoid/association/embedded/embedded_in.rb +134 -0
  20. data/lib/mongoid/association/embedded/embeds_many/binding.rb +41 -0
  21. data/lib/mongoid/association/embedded/embeds_many/buildable.rb +45 -0
  22. data/lib/mongoid/association/embedded/embeds_many/proxy.rb +549 -0
  23. data/lib/mongoid/association/embedded/embeds_many.rb +183 -0
  24. data/lib/mongoid/association/embedded/embeds_one/binding.rb +43 -0
  25. data/lib/mongoid/association/embedded/embeds_one/buildable.rb +39 -0
  26. data/lib/mongoid/association/embedded/embeds_one/proxy.rb +145 -0
  27. data/lib/mongoid/association/embedded/embeds_one.rb +150 -0
  28. data/lib/mongoid/association/embedded.rb +6 -0
  29. data/lib/mongoid/association/macros.rb +227 -0
  30. data/lib/mongoid/association/many.rb +198 -0
  31. data/lib/mongoid/association/marshalable.rb +31 -0
  32. data/lib/mongoid/association/nested/many.rb +191 -0
  33. data/lib/mongoid/association/nested/nested_buildable.rb +66 -0
  34. data/lib/mongoid/association/nested/one.rb +116 -0
  35. data/lib/mongoid/association/nested.rb +15 -0
  36. data/lib/mongoid/association/one.rb +53 -0
  37. data/lib/mongoid/association/options.rb +122 -0
  38. data/lib/mongoid/association/proxy.rb +189 -0
  39. data/lib/mongoid/association/referenced/auto_save.rb +73 -0
  40. data/lib/mongoid/association/referenced/belongs_to/binding.rb +82 -0
  41. data/lib/mongoid/association/referenced/belongs_to/buildable.rb +48 -0
  42. data/lib/mongoid/association/referenced/belongs_to/eager.rb +73 -0
  43. data/lib/mongoid/association/referenced/belongs_to/proxy.rb +125 -0
  44. data/lib/mongoid/association/referenced/belongs_to.rb +226 -0
  45. data/lib/mongoid/association/referenced/counter_cache.rb +152 -0
  46. data/lib/mongoid/association/referenced/eager.rb +163 -0
  47. data/lib/mongoid/association/referenced/has_and_belongs_to_many/binding.rb +72 -0
  48. data/lib/mongoid/association/referenced/has_and_belongs_to_many/buildable.rb +40 -0
  49. data/lib/mongoid/association/referenced/has_and_belongs_to_many/eager.rb +53 -0
  50. data/lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb +292 -0
  51. data/lib/mongoid/association/referenced/has_and_belongs_to_many.rb +270 -0
  52. data/lib/mongoid/association/referenced/has_many/binding.rb +36 -0
  53. data/lib/mongoid/association/referenced/has_many/buildable.rb +38 -0
  54. data/lib/mongoid/association/referenced/has_many/eager.rb +44 -0
  55. data/lib/mongoid/association/referenced/has_many/enumerable.rb +502 -0
  56. data/lib/mongoid/association/referenced/has_many/proxy.rb +545 -0
  57. data/lib/mongoid/association/referenced/has_many.rb +251 -0
  58. data/lib/mongoid/association/referenced/has_one/binding.rb +42 -0
  59. data/lib/mongoid/association/referenced/has_one/buildable.rb +74 -0
  60. data/lib/mongoid/association/referenced/has_one/eager.rb +36 -0
  61. data/lib/mongoid/association/referenced/has_one/nested_builder.rb +113 -0
  62. data/lib/mongoid/association/referenced/has_one/proxy.rb +111 -0
  63. data/lib/mongoid/association/referenced/has_one.rb +184 -0
  64. data/lib/mongoid/association/referenced/syncable.rb +155 -0
  65. data/lib/mongoid/association/referenced.rb +9 -0
  66. data/lib/mongoid/association/reflections.rb +69 -0
  67. data/lib/mongoid/association/relatable.rb +455 -0
  68. data/lib/mongoid/association.rb +135 -0
  69. data/lib/mongoid/atomic/modifiers.rb +27 -51
  70. data/lib/mongoid/atomic/paths/embedded/many.rb +24 -8
  71. data/lib/mongoid/atomic/paths/embedded/one.rb +5 -8
  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 +43 -48
  76. data/lib/mongoid/attributes/dynamic.rb +19 -33
  77. data/lib/mongoid/attributes/nested.rb +29 -21
  78. data/lib/mongoid/attributes/processing.rb +11 -26
  79. data/lib/mongoid/attributes/projector.rb +119 -0
  80. data/lib/mongoid/attributes/readonly.rb +5 -10
  81. data/lib/mongoid/attributes.rb +94 -91
  82. data/lib/mongoid/cacheable.rb +7 -10
  83. data/lib/mongoid/changeable.rb +7 -61
  84. data/lib/mongoid/clients/factory.rb +42 -17
  85. data/lib/mongoid/clients/options.rb +17 -18
  86. data/lib/mongoid/clients/sessions.rb +22 -10
  87. data/lib/mongoid/clients/storage_options.rb +7 -12
  88. data/lib/mongoid/clients/validators/storage.rb +2 -9
  89. data/lib/mongoid/clients/validators.rb +2 -1
  90. data/lib/mongoid/clients.rb +3 -10
  91. data/lib/mongoid/composable.rb +9 -13
  92. data/lib/mongoid/config/environment.rb +51 -13
  93. data/lib/mongoid/config/options.rb +20 -23
  94. data/lib/mongoid/config/validators/client.rb +2 -17
  95. data/lib/mongoid/config/validators/option.rb +2 -3
  96. data/lib/mongoid/config/validators.rb +2 -1
  97. data/lib/mongoid/config.rb +123 -40
  98. data/lib/mongoid/contextual/aggregable/memory.rb +17 -12
  99. data/lib/mongoid/contextual/aggregable/mongo.rb +25 -26
  100. data/lib/mongoid/contextual/aggregable/none.rb +65 -0
  101. data/lib/mongoid/contextual/aggregable.rb +17 -0
  102. data/lib/mongoid/contextual/atomic.rb +29 -31
  103. data/lib/mongoid/contextual/command.rb +2 -5
  104. data/lib/mongoid/contextual/geo_near.rb +7 -38
  105. data/lib/mongoid/contextual/map_reduce.rb +5 -33
  106. data/lib/mongoid/contextual/memory.rb +167 -70
  107. data/lib/mongoid/contextual/mongo.rb +295 -106
  108. data/lib/mongoid/contextual/none.rb +88 -28
  109. data/lib/mongoid/contextual/queryable.rb +2 -3
  110. data/lib/mongoid/contextual.rb +7 -9
  111. data/lib/mongoid/copyable.rb +20 -14
  112. data/lib/mongoid/criteria/findable.rb +12 -15
  113. data/lib/mongoid/criteria/includable.rb +21 -28
  114. data/lib/mongoid/criteria/inspectable.rb +2 -3
  115. data/lib/mongoid/criteria/marshalable.rb +2 -5
  116. data/lib/mongoid/criteria/modifiable.rb +10 -22
  117. data/lib/mongoid/criteria/options.rb +4 -5
  118. data/lib/mongoid/criteria/permission.rb +2 -1
  119. data/lib/mongoid/criteria/queryable/aggregable.rb +2 -13
  120. data/lib/mongoid/criteria/queryable/expandable.rb +68 -0
  121. data/lib/mongoid/criteria/queryable/extensions/array.rb +5 -26
  122. data/lib/mongoid/criteria/queryable/extensions/big_decimal.rb +3 -4
  123. data/lib/mongoid/criteria/queryable/extensions/boolean.rb +3 -4
  124. data/lib/mongoid/criteria/queryable/extensions/date.rb +3 -8
  125. data/lib/mongoid/criteria/queryable/extensions/date_time.rb +5 -11
  126. data/lib/mongoid/criteria/queryable/extensions/hash.rb +4 -25
  127. data/lib/mongoid/criteria/queryable/extensions/nil_class.rb +3 -14
  128. data/lib/mongoid/criteria/queryable/extensions/numeric.rb +4 -13
  129. data/lib/mongoid/criteria/queryable/extensions/object.rb +4 -29
  130. data/lib/mongoid/criteria/queryable/extensions/range.rb +41 -17
  131. data/lib/mongoid/criteria/queryable/extensions/regexp.rb +9 -16
  132. data/lib/mongoid/criteria/queryable/extensions/set.rb +3 -4
  133. data/lib/mongoid/criteria/queryable/extensions/string.rb +4 -19
  134. data/lib/mongoid/criteria/queryable/extensions/symbol.rb +3 -10
  135. data/lib/mongoid/criteria/queryable/extensions/time.rb +4 -9
  136. data/lib/mongoid/criteria/queryable/extensions/time_with_zone.rb +13 -6
  137. data/lib/mongoid/criteria/queryable/extensions.rb +1 -4
  138. data/lib/mongoid/criteria/queryable/key.rb +101 -27
  139. data/lib/mongoid/criteria/queryable/macroable.rb +3 -4
  140. data/lib/mongoid/criteria/queryable/mergeable.rb +205 -44
  141. data/lib/mongoid/criteria/queryable/optional.rb +5 -48
  142. data/lib/mongoid/criteria/queryable/options.rb +2 -19
  143. data/lib/mongoid/criteria/queryable/pipeline.rb +14 -19
  144. data/lib/mongoid/criteria/queryable/selectable.rb +436 -166
  145. data/lib/mongoid/criteria/queryable/selector.rb +45 -55
  146. data/lib/mongoid/criteria/queryable/smash.rb +2 -11
  147. data/lib/mongoid/criteria/queryable/storable.rb +237 -0
  148. data/lib/mongoid/criteria/queryable.rb +7 -9
  149. data/lib/mongoid/criteria/scopable.rb +27 -19
  150. data/lib/mongoid/criteria.rb +90 -75
  151. data/lib/mongoid/document.rb +43 -74
  152. data/lib/mongoid/equality.rb +29 -12
  153. data/lib/mongoid/errors/ambiguous_relationship.rb +4 -5
  154. data/lib/mongoid/errors/callback.rb +2 -3
  155. data/lib/mongoid/errors/criteria_argument_required.rb +18 -0
  156. data/lib/mongoid/errors/delete_restriction.rb +10 -13
  157. data/lib/mongoid/errors/document_not_destroyed.rb +4 -7
  158. data/lib/mongoid/errors/document_not_found.rb +25 -15
  159. data/lib/mongoid/errors/eager_load.rb +6 -5
  160. data/lib/mongoid/errors/empty_config_file.rb +25 -0
  161. data/lib/mongoid/errors/in_memory_collation_not_supported.rb +2 -3
  162. data/lib/mongoid/errors/invalid_collection.rb +2 -1
  163. data/lib/mongoid/errors/invalid_config_file.rb +25 -0
  164. data/lib/mongoid/errors/invalid_config_option.rb +2 -3
  165. data/lib/mongoid/errors/invalid_dependent_strategy.rb +31 -0
  166. data/lib/mongoid/errors/invalid_discriminator_key_target.rb +24 -0
  167. data/lib/mongoid/errors/invalid_elem_match_operator.rb +32 -0
  168. data/lib/mongoid/errors/invalid_estimated_count_criteria.rb +25 -0
  169. data/lib/mongoid/errors/invalid_expression_operator.rb +27 -0
  170. data/lib/mongoid/errors/invalid_field.rb +2 -5
  171. data/lib/mongoid/errors/invalid_field_operator.rb +32 -0
  172. data/lib/mongoid/errors/invalid_field_option.rb +2 -3
  173. data/lib/mongoid/errors/invalid_find.rb +2 -3
  174. data/lib/mongoid/errors/invalid_includes.rb +2 -3
  175. data/lib/mongoid/errors/invalid_index.rb +2 -3
  176. data/lib/mongoid/errors/invalid_options.rb +4 -5
  177. data/lib/mongoid/errors/invalid_path.rb +2 -3
  178. data/lib/mongoid/errors/invalid_persistence_option.rb +2 -5
  179. data/lib/mongoid/errors/invalid_query.rb +40 -0
  180. data/lib/mongoid/errors/invalid_relation.rb +4 -9
  181. data/lib/mongoid/errors/invalid_relation_option.rb +28 -0
  182. data/lib/mongoid/errors/invalid_scope.rb +2 -3
  183. data/lib/mongoid/errors/invalid_session_use.rb +3 -6
  184. data/lib/mongoid/errors/invalid_set_polymorphic_relation.rb +6 -5
  185. data/lib/mongoid/errors/invalid_storage_options.rb +2 -3
  186. data/lib/mongoid/errors/invalid_storage_parent.rb +2 -3
  187. data/lib/mongoid/errors/invalid_time.rb +2 -3
  188. data/lib/mongoid/errors/invalid_value.rb +2 -1
  189. data/lib/mongoid/errors/inverse_not_found.rb +3 -4
  190. data/lib/mongoid/errors/mixed_client_configuration.rb +2 -3
  191. data/lib/mongoid/errors/mixed_relations.rb +2 -3
  192. data/lib/mongoid/errors/mongoid_error.rb +3 -10
  193. data/lib/mongoid/errors/nested_attributes_metadata_not_found.rb +3 -4
  194. data/lib/mongoid/errors/no_client_config.rb +4 -5
  195. data/lib/mongoid/errors/no_client_database.rb +2 -3
  196. data/lib/mongoid/errors/no_client_hosts.rb +2 -3
  197. data/lib/mongoid/errors/no_clients_config.rb +2 -3
  198. data/lib/mongoid/errors/no_default_client.rb +3 -4
  199. data/lib/mongoid/errors/no_environment.rb +2 -3
  200. data/lib/mongoid/errors/no_map_reduce_output.rb +2 -3
  201. data/lib/mongoid/errors/no_metadata.rb +2 -3
  202. data/lib/mongoid/errors/no_parent.rb +2 -3
  203. data/lib/mongoid/errors/readonly_attribute.rb +2 -3
  204. data/lib/mongoid/errors/readonly_document.rb +3 -6
  205. data/lib/mongoid/errors/scope_overwrite.rb +2 -1
  206. data/lib/mongoid/errors/too_many_nested_attribute_records.rb +2 -0
  207. data/lib/mongoid/errors/unknown_attribute.rb +2 -3
  208. data/lib/mongoid/errors/unknown_model.rb +24 -0
  209. data/lib/mongoid/errors/unsaved_document.rb +3 -2
  210. data/lib/mongoid/errors/unsupported_javascript.rb +2 -3
  211. data/lib/mongoid/errors/validations.rb +2 -1
  212. data/lib/mongoid/errors.rb +15 -1
  213. data/lib/mongoid/evolvable.rb +4 -5
  214. data/lib/mongoid/extensions/array.rb +33 -42
  215. data/lib/mongoid/extensions/big_decimal.rb +2 -11
  216. data/lib/mongoid/extensions/boolean.rb +3 -5
  217. data/lib/mongoid/extensions/date.rb +13 -12
  218. data/lib/mongoid/extensions/date_time.rb +4 -12
  219. data/lib/mongoid/extensions/decimal128.rb +2 -5
  220. data/lib/mongoid/extensions/false_class.rb +4 -7
  221. data/lib/mongoid/extensions/float.rb +5 -10
  222. data/lib/mongoid/extensions/hash.rb +56 -38
  223. data/lib/mongoid/extensions/integer.rb +5 -12
  224. data/lib/mongoid/extensions/module.rb +2 -3
  225. data/lib/mongoid/extensions/nil_class.rb +2 -5
  226. data/lib/mongoid/extensions/object.rb +21 -48
  227. data/lib/mongoid/extensions/object_id.rb +2 -7
  228. data/lib/mongoid/extensions/range.rb +3 -11
  229. data/lib/mongoid/extensions/regexp.rb +3 -4
  230. data/lib/mongoid/extensions/set.rb +2 -7
  231. data/lib/mongoid/extensions/string.rb +21 -41
  232. data/lib/mongoid/extensions/symbol.rb +2 -7
  233. data/lib/mongoid/extensions/time.rb +12 -9
  234. data/lib/mongoid/extensions/time_with_zone.rb +25 -7
  235. data/lib/mongoid/extensions/true_class.rb +4 -7
  236. data/lib/mongoid/extensions.rb +18 -7
  237. data/lib/mongoid/factory.rb +59 -10
  238. data/lib/mongoid/fields/foreign_key.rb +8 -27
  239. data/lib/mongoid/fields/localized.rb +2 -11
  240. data/lib/mongoid/fields/standard.rb +8 -50
  241. data/lib/mongoid/fields/validators/macro.rb +37 -19
  242. data/lib/mongoid/fields/validators.rb +2 -1
  243. data/lib/mongoid/fields.rb +245 -70
  244. data/lib/mongoid/findable.rb +78 -27
  245. data/lib/mongoid/indexable/specification.rb +3 -16
  246. data/lib/mongoid/indexable/validators/options.rb +2 -7
  247. data/lib/mongoid/indexable.rb +10 -22
  248. data/lib/mongoid/inspectable.rb +4 -11
  249. data/lib/mongoid/interceptable.rb +18 -35
  250. data/lib/mongoid/loggable.rb +13 -16
  251. data/lib/mongoid/matchable.rb +3 -153
  252. data/lib/mongoid/matcher/all.rb +22 -0
  253. data/lib/mongoid/matcher/and.rb +21 -0
  254. data/lib/mongoid/matcher/bits.rb +41 -0
  255. data/lib/mongoid/matcher/bits_all_clear.rb +20 -0
  256. data/lib/mongoid/matcher/bits_all_set.rb +20 -0
  257. data/lib/mongoid/matcher/bits_any_clear.rb +20 -0
  258. data/lib/mongoid/matcher/bits_any_set.rb +20 -0
  259. data/lib/mongoid/matcher/elem_match.rb +36 -0
  260. data/lib/mongoid/matcher/elem_match_expression.rb +20 -0
  261. data/lib/mongoid/matcher/eq.rb +11 -0
  262. data/lib/mongoid/matcher/eq_impl.rb +67 -0
  263. data/lib/mongoid/matcher/eq_impl_with_regexp.rb +26 -0
  264. data/lib/mongoid/matcher/exists.rb +15 -0
  265. data/lib/mongoid/matcher/expression.rb +35 -0
  266. data/lib/mongoid/matcher/expression_operator.rb +19 -0
  267. data/lib/mongoid/matcher/field_expression.rb +62 -0
  268. data/lib/mongoid/matcher/field_operator.rb +54 -0
  269. data/lib/mongoid/matcher/gt.rb +17 -0
  270. data/lib/mongoid/matcher/gte.rb +17 -0
  271. data/lib/mongoid/matcher/in.rb +25 -0
  272. data/lib/mongoid/matcher/lt.rb +17 -0
  273. data/lib/mongoid/matcher/lte.rb +17 -0
  274. data/lib/mongoid/matcher/mod.rb +17 -0
  275. data/lib/mongoid/matcher/ne.rb +16 -0
  276. data/lib/mongoid/matcher/nin.rb +11 -0
  277. data/lib/mongoid/matcher/nor.rb +25 -0
  278. data/lib/mongoid/matcher/not.rb +29 -0
  279. data/lib/mongoid/matcher/or.rb +21 -0
  280. data/lib/mongoid/matcher/regex.rb +41 -0
  281. data/lib/mongoid/matcher/size.rb +26 -0
  282. data/lib/mongoid/matcher/type.rb +99 -0
  283. data/lib/mongoid/matcher.rb +110 -0
  284. data/lib/mongoid/persistable/creatable.rb +4 -21
  285. data/lib/mongoid/persistable/deletable.rb +11 -26
  286. data/lib/mongoid/persistable/destroyable.rb +11 -10
  287. data/lib/mongoid/persistable/incrementable.rb +7 -8
  288. data/lib/mongoid/persistable/logical.rb +5 -7
  289. data/lib/mongoid/persistable/poppable.rb +3 -6
  290. data/lib/mongoid/persistable/pullable.rb +3 -8
  291. data/lib/mongoid/persistable/pushable.rb +14 -10
  292. data/lib/mongoid/persistable/renamable.rb +10 -8
  293. data/lib/mongoid/persistable/savable.rb +3 -8
  294. data/lib/mongoid/persistable/settable.rb +60 -18
  295. data/lib/mongoid/persistable/unsettable.rb +8 -8
  296. data/lib/mongoid/persistable/updatable.rb +32 -20
  297. data/lib/mongoid/persistable/upsertable.rb +4 -9
  298. data/lib/mongoid/persistable.rb +136 -42
  299. data/lib/mongoid/persistence_context.rb +101 -48
  300. data/lib/mongoid/positional.rb +3 -6
  301. data/lib/mongoid/query_cache.rb +117 -130
  302. data/lib/mongoid/railtie.rb +3 -16
  303. data/lib/mongoid/railties/controller_runtime.rb +3 -1
  304. data/lib/mongoid/railties/database.rake +9 -0
  305. data/lib/mongoid/reloadable.rb +14 -19
  306. data/lib/mongoid/scopable.rb +19 -44
  307. data/lib/mongoid/selectable.rb +8 -17
  308. data/lib/mongoid/serializable.rb +28 -33
  309. data/lib/mongoid/shardable.rb +108 -21
  310. data/lib/mongoid/stateful.rb +3 -10
  311. data/lib/mongoid/stringified_symbol.rb +52 -0
  312. data/lib/mongoid/tasks/database.rake +12 -5
  313. data/lib/mongoid/tasks/database.rb +85 -5
  314. data/lib/mongoid/threaded/lifecycle.rb +2 -21
  315. data/lib/mongoid/threaded.rb +2 -55
  316. data/lib/mongoid/timestamps/created/short.rb +2 -1
  317. data/lib/mongoid/timestamps/created.rb +3 -2
  318. data/lib/mongoid/timestamps/short.rb +2 -1
  319. data/lib/mongoid/timestamps/timeless.rb +6 -9
  320. data/lib/mongoid/timestamps/updated/short.rb +2 -1
  321. data/lib/mongoid/timestamps/updated.rb +3 -4
  322. data/lib/mongoid/timestamps.rb +3 -2
  323. data/lib/mongoid/touchable.rb +132 -0
  324. data/lib/mongoid/traversable.rb +183 -60
  325. data/lib/mongoid/validatable/associated.rb +5 -6
  326. data/lib/mongoid/validatable/format.rb +2 -1
  327. data/lib/mongoid/validatable/length.rb +2 -1
  328. data/lib/mongoid/validatable/localizable.rb +2 -3
  329. data/lib/mongoid/validatable/macros.rb +3 -8
  330. data/lib/mongoid/validatable/presence.rb +10 -15
  331. data/lib/mongoid/validatable/queryable.rb +2 -3
  332. data/lib/mongoid/validatable/uniqueness.rb +25 -38
  333. data/lib/mongoid/validatable.rb +16 -35
  334. data/lib/mongoid/version.rb +3 -2
  335. data/lib/mongoid/warnings.rb +29 -0
  336. data/lib/mongoid.rb +34 -15
  337. data/lib/rails/generators/mongoid/config/config_generator.rb +10 -2
  338. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +53 -29
  339. data/lib/rails/generators/mongoid/model/model_generator.rb +3 -2
  340. data/lib/rails/generators/mongoid/model/templates/model.rb.tt +1 -1
  341. data/lib/rails/generators/mongoid_generator.rb +2 -1
  342. data/lib/rails/mongoid.rb +4 -5
  343. data/spec/README.md +33 -0
  344. data/spec/config/mongoid.yml +14 -3
  345. data/spec/config/mongoid_with_schema_map_uuid.yml +27 -0
  346. data/spec/integration/app_spec.rb +349 -0
  347. data/spec/integration/associations/belongs_to_spec.rb +15 -0
  348. data/spec/integration/associations/embedded_dirty_spec.rb +57 -0
  349. data/spec/integration/associations/embedded_spec.rb +268 -0
  350. data/spec/integration/associations/embeds_many_spec.rb +206 -0
  351. data/spec/integration/associations/embeds_one_spec.rb +23 -0
  352. data/spec/integration/associations/foreign_key_spec.rb +98 -0
  353. data/spec/integration/associations/foreign_key_spec_models.rb +64 -0
  354. data/spec/integration/associations/has_many_spec.rb +128 -0
  355. data/spec/integration/associations/has_one_spec.rb +176 -0
  356. data/spec/integration/associations/nested_attributes_assignment_spec.rb +115 -0
  357. data/spec/integration/associations/reverse_population_spec.rb +34 -0
  358. data/spec/integration/associations/reverse_population_spec_models.rb +36 -0
  359. data/spec/integration/associations/scope_option_spec.rb +101 -0
  360. data/spec/integration/atomic/modifiers_spec.rb +116 -0
  361. data/spec/integration/bson_regexp_raw_spec.rb +19 -0
  362. data/spec/integration/callbacks_models.rb +61 -0
  363. data/spec/integration/callbacks_spec.rb +228 -0
  364. data/spec/integration/contextual/empty_spec.rb +141 -0
  365. data/spec/integration/criteria/alias_query_spec.rb +161 -0
  366. data/spec/integration/criteria/date_field_spec.rb +40 -0
  367. data/spec/integration/criteria/default_scope_spec.rb +72 -0
  368. data/spec/integration/criteria/logical_spec.rb +124 -0
  369. data/spec/integration/criteria/range_spec.rb +265 -0
  370. data/spec/integration/criteria/time_with_zone_spec.rb +142 -0
  371. data/spec/integration/discriminator_key_spec.rb +353 -0
  372. data/spec/integration/discriminator_value_spec.rb +206 -0
  373. data/spec/integration/document_spec.rb +30 -1
  374. data/spec/integration/i18n_fallbacks_spec.rb +103 -0
  375. data/spec/integration/matcher_examples_spec.rb +758 -0
  376. data/spec/integration/matcher_operator_data/all.yml +140 -0
  377. data/spec/integration/matcher_operator_data/and.yml +93 -0
  378. data/spec/integration/matcher_operator_data/bits_all_clear.yml +159 -0
  379. data/spec/integration/matcher_operator_data/bits_all_set.yml +159 -0
  380. data/spec/integration/matcher_operator_data/bits_any_clear.yml +159 -0
  381. data/spec/integration/matcher_operator_data/bits_any_set.yml +159 -0
  382. data/spec/integration/matcher_operator_data/comment.yml +22 -0
  383. data/spec/integration/matcher_operator_data/elem_match.yml +409 -0
  384. data/spec/integration/matcher_operator_data/elem_match_expr.yml +213 -0
  385. data/spec/integration/matcher_operator_data/eq.yml +191 -0
  386. data/spec/integration/matcher_operator_data/exists.yml +213 -0
  387. data/spec/integration/matcher_operator_data/generic_op.yml +17 -0
  388. data/spec/integration/matcher_operator_data/gt.yml +132 -0
  389. data/spec/integration/matcher_operator_data/gt_types.yml +63 -0
  390. data/spec/integration/matcher_operator_data/gte.yml +132 -0
  391. data/spec/integration/matcher_operator_data/gte_types.yml +15 -0
  392. data/spec/integration/matcher_operator_data/implicit.yml +331 -0
  393. data/spec/integration/matcher_operator_data/implicit_traversal.yml +112 -0
  394. data/spec/integration/matcher_operator_data/in.yml +210 -0
  395. data/spec/integration/matcher_operator_data/invalid_op.yml +59 -0
  396. data/spec/integration/matcher_operator_data/invalid_syntax.yml +39 -0
  397. data/spec/integration/matcher_operator_data/lt.yml +132 -0
  398. data/spec/integration/matcher_operator_data/lt_types.yml +15 -0
  399. data/spec/integration/matcher_operator_data/lte.yml +132 -0
  400. data/spec/integration/matcher_operator_data/lte_types.yml +15 -0
  401. data/spec/integration/matcher_operator_data/mod.yml +55 -0
  402. data/spec/integration/matcher_operator_data/multiple.yml +29 -0
  403. data/spec/integration/matcher_operator_data/ne.yml +150 -0
  404. data/spec/integration/matcher_operator_data/ne_types.yml +15 -0
  405. data/spec/integration/matcher_operator_data/nin.yml +114 -0
  406. data/spec/integration/matcher_operator_data/nor.yml +126 -0
  407. data/spec/integration/matcher_operator_data/not.yml +196 -0
  408. data/spec/integration/matcher_operator_data/or.yml +137 -0
  409. data/spec/integration/matcher_operator_data/regex.yml +174 -0
  410. data/spec/integration/matcher_operator_data/regex_options.yml +72 -0
  411. data/spec/integration/matcher_operator_data/size.yml +174 -0
  412. data/spec/integration/matcher_operator_data/type.yml +70 -0
  413. data/spec/integration/matcher_operator_data/type_array.yml +16 -0
  414. data/spec/integration/matcher_operator_data/type_binary.yml +18 -0
  415. data/spec/integration/matcher_operator_data/type_boolean.yml +39 -0
  416. data/spec/integration/matcher_operator_data/type_code.yml +26 -0
  417. data/spec/integration/matcher_operator_data/type_code_with_scope.yml +26 -0
  418. data/spec/integration/matcher_operator_data/type_date.yml +39 -0
  419. data/spec/integration/matcher_operator_data/type_db_pointer.yml +19 -0
  420. data/spec/integration/matcher_operator_data/type_decimal.yml +40 -0
  421. data/spec/integration/matcher_operator_data/type_double.yml +15 -0
  422. data/spec/integration/matcher_operator_data/type_int32.yml +33 -0
  423. data/spec/integration/matcher_operator_data/type_int64.yml +33 -0
  424. data/spec/integration/matcher_operator_data/type_max_key.yml +17 -0
  425. data/spec/integration/matcher_operator_data/type_min_key.yml +17 -0
  426. data/spec/integration/matcher_operator_data/type_null.yml +23 -0
  427. data/spec/integration/matcher_operator_data/type_object.yml +23 -0
  428. data/spec/integration/matcher_operator_data/type_object_id.yml +25 -0
  429. data/spec/integration/matcher_operator_data/type_regex.yml +44 -0
  430. data/spec/integration/matcher_operator_data/type_string.yml +15 -0
  431. data/spec/integration/matcher_operator_data/type_symbol.yml +32 -0
  432. data/spec/integration/matcher_operator_data/type_timestamp.yml +25 -0
  433. data/spec/integration/matcher_operator_data/type_undefined.yml +17 -0
  434. data/spec/integration/matcher_operator_spec.rb +124 -0
  435. data/spec/integration/matcher_spec.rb +283 -0
  436. data/spec/integration/server_query_spec.rb +141 -0
  437. data/spec/integration/shardable_spec.rb +148 -0
  438. data/spec/integration/stringified_symbol_field_spec.rb +203 -0
  439. data/spec/lite_spec_helper.rb +83 -0
  440. data/spec/mongoid/association/accessors_spec.rb +1067 -0
  441. data/spec/mongoid/association/auto_save_spec.rb +403 -0
  442. data/spec/mongoid/association/builders_spec.rb +255 -0
  443. data/spec/mongoid/association/constrainable_spec.rb +117 -0
  444. data/spec/mongoid/association/counter_cache_spec.rb +452 -0
  445. data/spec/mongoid/association/depending_spec.rb +959 -0
  446. data/spec/mongoid/association/eager_spec.rb +281 -0
  447. data/spec/mongoid/association/embedded/cyclic_spec.rb +180 -0
  448. data/spec/mongoid/association/embedded/dirty_spec.rb +67 -0
  449. data/spec/mongoid/association/embedded/embedded_in/binding_spec.rb +173 -0
  450. data/spec/mongoid/association/embedded/embedded_in/buildable_spec.rb +36 -0
  451. data/spec/mongoid/association/embedded/embedded_in/proxy_spec.rb +559 -0
  452. data/spec/mongoid/association/embedded/embedded_in_spec.rb +903 -0
  453. data/spec/mongoid/association/embedded/embeds_many/binding_spec.rb +56 -0
  454. data/spec/mongoid/association/embedded/embeds_many/buildable_spec.rb +106 -0
  455. data/spec/mongoid/association/embedded/embeds_many/proxy_spec.rb +4673 -0
  456. data/spec/mongoid/association/embedded/embeds_many_models.rb +190 -0
  457. data/spec/mongoid/association/embedded/embeds_many_query_spec.rb +51 -0
  458. data/spec/mongoid/association/embedded/embeds_many_spec.rb +864 -0
  459. data/spec/mongoid/association/embedded/embeds_one/binding_spec.rb +79 -0
  460. data/spec/mongoid/association/embedded/embeds_one/buildable_spec.rb +81 -0
  461. data/spec/mongoid/association/embedded/embeds_one/proxy_spec.rb +1025 -0
  462. data/spec/mongoid/association/embedded/embeds_one_dnl_models.rb +8 -0
  463. data/spec/mongoid/association/embedded/embeds_one_models.rb +54 -0
  464. data/spec/mongoid/association/embedded/embeds_one_query_spec.rb +28 -0
  465. data/spec/mongoid/association/embedded/embeds_one_spec.rb +956 -0
  466. data/spec/mongoid/association/macros_spec.rb +1116 -0
  467. data/spec/mongoid/association/nested/many_spec.rb +232 -0
  468. data/spec/mongoid/association/nested/one_spec.rb +253 -0
  469. data/spec/mongoid/association/options_spec.rb +1323 -0
  470. data/spec/mongoid/association/polymorphic_spec.rb +162 -0
  471. data/spec/mongoid/association/referenced/belongs_to/binding_spec.rb +243 -0
  472. data/spec/mongoid/association/referenced/belongs_to/buildable_spec.rb +238 -0
  473. data/spec/mongoid/association/referenced/belongs_to/eager_spec.rb +412 -0
  474. data/spec/mongoid/association/referenced/belongs_to/proxy_spec.rb +1373 -0
  475. data/spec/mongoid/association/referenced/belongs_to_query_spec.rb +57 -0
  476. data/spec/mongoid/association/referenced/belongs_to_spec.rb +2046 -0
  477. data/spec/mongoid/association/referenced/has_and_belongs_to_many/binding_spec.rb +180 -0
  478. data/spec/mongoid/association/referenced/has_and_belongs_to_many/buildable_spec.rb +148 -0
  479. data/spec/mongoid/association/referenced/has_and_belongs_to_many/eager_spec.rb +196 -0
  480. data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_persistence_spec.rb +76 -0
  481. data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_spec.rb +3803 -0
  482. data/spec/mongoid/association/referenced/has_and_belongs_to_many_models.rb +67 -0
  483. data/spec/mongoid/association/referenced/has_and_belongs_to_many_query_spec.rb +39 -0
  484. data/spec/mongoid/association/referenced/has_and_belongs_to_many_spec.rb +1071 -0
  485. data/spec/mongoid/association/referenced/has_many/binding_spec.rb +155 -0
  486. data/spec/mongoid/association/referenced/has_many/buildable_spec.rb +142 -0
  487. data/spec/mongoid/association/referenced/has_many/eager_spec.rb +290 -0
  488. data/spec/mongoid/association/referenced/has_many/enumerable_spec.rb +2286 -0
  489. data/spec/mongoid/association/referenced/has_many/proxy_query_spec.rb +23 -0
  490. data/spec/mongoid/association/referenced/has_many/proxy_spec.rb +4112 -0
  491. data/spec/mongoid/association/referenced/has_many_models.rb +95 -0
  492. data/spec/mongoid/association/referenced/has_many_query_spec.rb +37 -0
  493. data/spec/mongoid/association/referenced/has_many_spec.rb +1248 -0
  494. data/spec/mongoid/association/referenced/has_one/binding_spec.rb +133 -0
  495. data/spec/mongoid/association/referenced/has_one/buildable_spec.rb +159 -0
  496. data/spec/mongoid/association/referenced/has_one/eager_spec.rb +193 -0
  497. data/spec/mongoid/association/referenced/has_one/proxy_spec.rb +1142 -0
  498. data/spec/mongoid/association/referenced/has_one_models.rb +97 -0
  499. data/spec/mongoid/association/referenced/has_one_query_spec.rb +37 -0
  500. data/spec/mongoid/association/referenced/has_one_spec.rb +1383 -0
  501. data/spec/mongoid/association/reflections_spec.rb +92 -0
  502. data/spec/mongoid/association/syncable_spec.rb +499 -0
  503. data/spec/mongoid/association_spec.rb +191 -0
  504. data/spec/mongoid/atomic/modifiers_spec.rb +51 -2
  505. data/spec/mongoid/atomic/paths/embedded/many_spec.rb +2 -0
  506. data/spec/mongoid/atomic/paths/embedded/one_spec.rb +2 -0
  507. data/spec/mongoid/atomic/paths/root_spec.rb +2 -0
  508. data/spec/mongoid/atomic/paths_spec.rb +107 -12
  509. data/spec/mongoid/atomic_spec.rb +57 -10
  510. data/spec/mongoid/attributes/dynamic_spec.rb +152 -0
  511. data/spec/mongoid/attributes/nested_spec.rb +98 -78
  512. data/spec/mongoid/attributes/projector_data/embedded.yml +105 -0
  513. data/spec/mongoid/attributes/projector_data/fields.yml +93 -0
  514. data/spec/mongoid/attributes/projector_spec.rb +44 -0
  515. data/spec/mongoid/attributes/readonly_spec.rb +84 -127
  516. data/spec/mongoid/attributes_spec.rb +461 -34
  517. data/spec/mongoid/cacheable_spec.rb +6 -4
  518. data/spec/mongoid/changeable_spec.rb +60 -35
  519. data/spec/mongoid/clients/factory_spec.rb +98 -9
  520. data/spec/mongoid/clients/options_spec.rb +93 -60
  521. data/spec/mongoid/clients/sessions_spec.rb +34 -33
  522. data/spec/mongoid/clients/transactions_spec.rb +415 -0
  523. data/spec/mongoid/clients_spec.rb +108 -16
  524. data/spec/mongoid/composable_spec.rb +2 -0
  525. data/spec/mongoid/config/environment_spec.rb +126 -8
  526. data/spec/mongoid/config/options_spec.rb +22 -3
  527. data/spec/mongoid/config_spec.rb +357 -2
  528. data/spec/mongoid/contextual/aggregable/memory_spec.rb +53 -11
  529. data/spec/mongoid/contextual/aggregable/mongo_spec.rb +122 -20
  530. data/spec/mongoid/contextual/aggregable/none_spec.rb +60 -0
  531. data/spec/mongoid/contextual/atomic_spec.rb +242 -81
  532. data/spec/mongoid/contextual/geo_near_spec.rb +30 -19
  533. data/spec/mongoid/contextual/map_reduce_spec.rb +24 -7
  534. data/spec/mongoid/contextual/memory_spec.rb +870 -88
  535. data/spec/mongoid/contextual/mongo_spec.rb +1339 -184
  536. data/spec/mongoid/contextual/none_spec.rb +45 -71
  537. data/spec/mongoid/copyable_spec.rb +294 -29
  538. data/spec/mongoid/copyable_spec_models.rb +47 -0
  539. data/spec/mongoid/criteria/findable_spec.rb +77 -20
  540. data/spec/mongoid/criteria/inspectable_spec.rb +2 -0
  541. data/spec/mongoid/criteria/marshalable_spec.rb +2 -0
  542. data/spec/mongoid/criteria/modifiable_spec.rb +215 -40
  543. data/spec/mongoid/criteria/options_spec.rb +2 -0
  544. data/spec/mongoid/criteria/queryable/aggregable_spec.rb +3 -1
  545. data/spec/mongoid/criteria/queryable/expandable_spec.rb +61 -0
  546. data/spec/mongoid/criteria/queryable/extensions/array_spec.rb +2 -0
  547. data/spec/mongoid/criteria/queryable/extensions/big_decimal_spec.rb +2 -0
  548. data/spec/mongoid/criteria/queryable/extensions/bignum_spec.rb +2 -0
  549. data/spec/mongoid/criteria/queryable/extensions/boolean_spec.rb +3 -1
  550. data/spec/mongoid/criteria/queryable/extensions/date_spec.rb +2 -0
  551. data/spec/mongoid/criteria/queryable/extensions/date_time_spec.rb +35 -17
  552. data/spec/mongoid/criteria/queryable/extensions/fixnum_spec.rb +2 -0
  553. data/spec/mongoid/criteria/queryable/extensions/float_spec.rb +2 -0
  554. data/spec/mongoid/criteria/queryable/extensions/hash_spec.rb +2 -0
  555. data/spec/mongoid/criteria/queryable/extensions/integer_spec.rb +2 -0
  556. data/spec/mongoid/criteria/queryable/extensions/nil_class_spec.rb +2 -0
  557. data/spec/mongoid/criteria/queryable/extensions/numeric_spec.rb +53 -0
  558. data/spec/mongoid/criteria/queryable/extensions/object_spec.rb +2 -0
  559. data/spec/mongoid/criteria/queryable/extensions/range_spec.rb +239 -178
  560. data/spec/mongoid/criteria/queryable/extensions/regexp_raw_spec.rb +3 -1
  561. data/spec/mongoid/criteria/queryable/extensions/regexp_spec.rb +9 -7
  562. data/spec/mongoid/criteria/queryable/extensions/set_spec.rb +2 -0
  563. data/spec/mongoid/criteria/queryable/extensions/string_spec.rb +46 -1
  564. data/spec/mongoid/criteria/queryable/extensions/symbol_spec.rb +2 -0
  565. data/spec/mongoid/criteria/queryable/extensions/time_spec.rb +42 -23
  566. data/spec/mongoid/criteria/queryable/extensions/time_with_zone_spec.rb +30 -1
  567. data/spec/mongoid/criteria/queryable/key_spec.rb +50 -6
  568. data/spec/mongoid/criteria/queryable/mergeable_spec.rb +145 -12
  569. data/spec/mongoid/criteria/queryable/optional_spec.rb +3 -1
  570. data/spec/mongoid/criteria/queryable/options_spec.rb +2 -0
  571. data/spec/mongoid/criteria/queryable/pipeline_spec.rb +14 -0
  572. data/spec/mongoid/criteria/queryable/queryable_spec.rb +3 -1
  573. data/spec/mongoid/criteria/queryable/selectable_logical_spec.rb +2069 -0
  574. data/spec/mongoid/criteria/queryable/selectable_shared_examples.rb +38 -0
  575. data/spec/mongoid/criteria/queryable/selectable_spec.rb +1155 -2927
  576. data/spec/mongoid/criteria/queryable/selectable_where_spec.rb +589 -0
  577. data/spec/mongoid/criteria/queryable/selector_spec.rb +114 -2
  578. data/spec/mongoid/criteria/queryable/smash_spec.rb +2 -0
  579. data/spec/mongoid/criteria/queryable/storable_spec.rb +298 -0
  580. data/spec/mongoid/criteria/scopable_spec.rb +129 -0
  581. data/spec/mongoid/criteria_projection_spec.rb +410 -0
  582. data/spec/mongoid/criteria_spec.rb +826 -478
  583. data/spec/mongoid/document_fields_spec.rb +113 -0
  584. data/spec/mongoid/document_persistence_context_spec.rb +32 -0
  585. data/spec/mongoid/document_query_spec.rb +89 -0
  586. data/spec/mongoid/document_spec.rb +131 -31
  587. data/spec/mongoid/equality_spec.rb +144 -41
  588. data/spec/mongoid/errors/ambiguous_relationship_spec.rb +5 -3
  589. data/spec/mongoid/errors/callback_spec.rb +2 -0
  590. data/spec/mongoid/errors/delete_restriction_spec.rb +4 -2
  591. data/spec/mongoid/errors/document_not_destroyed_spec.rb +2 -0
  592. data/spec/mongoid/errors/document_not_found_spec.rb +51 -0
  593. data/spec/mongoid/errors/eager_load_spec.rb +2 -0
  594. data/spec/mongoid/errors/invalid_collection_spec.rb +2 -0
  595. data/spec/mongoid/errors/invalid_config_file_spec.rb +31 -0
  596. data/spec/mongoid/errors/invalid_config_option_spec.rb +2 -0
  597. data/spec/mongoid/errors/invalid_field_option_spec.rb +2 -0
  598. data/spec/mongoid/errors/invalid_field_spec.rb +2 -0
  599. data/spec/mongoid/errors/invalid_find_spec.rb +2 -0
  600. data/spec/mongoid/errors/invalid_includes_spec.rb +2 -0
  601. data/spec/mongoid/errors/invalid_index_spec.rb +2 -0
  602. data/spec/mongoid/errors/invalid_options_spec.rb +4 -2
  603. data/spec/mongoid/errors/invalid_path_spec.rb +2 -0
  604. data/spec/mongoid/errors/invalid_relation_spec.rb +4 -2
  605. data/spec/mongoid/errors/invalid_scope_spec.rb +3 -1
  606. data/spec/mongoid/errors/invalid_set_polymorphic_relation_spec.rb +2 -0
  607. data/spec/mongoid/errors/invalid_storage_options_spec.rb +2 -0
  608. data/spec/mongoid/errors/invalid_time_spec.rb +2 -0
  609. data/spec/mongoid/errors/inverse_not_found_spec.rb +3 -1
  610. data/spec/mongoid/errors/mixed_client_configuration_spec.rb +2 -0
  611. data/spec/mongoid/errors/mixed_relations_spec.rb +2 -0
  612. data/spec/mongoid/errors/mongoid_error_spec.rb +22 -8
  613. data/spec/mongoid/errors/nested_attributes_metadata_not_found_spec.rb +5 -3
  614. data/spec/mongoid/errors/no_client_config_spec.rb +4 -2
  615. data/spec/mongoid/errors/no_client_database_spec.rb +5 -3
  616. data/spec/mongoid/errors/no_client_hosts_spec.rb +5 -3
  617. data/spec/mongoid/errors/no_clients_config_spec.rb +2 -0
  618. data/spec/mongoid/errors/no_environment_spec.rb +2 -0
  619. data/spec/mongoid/errors/no_map_reduce_output_spec.rb +2 -0
  620. data/spec/mongoid/errors/no_metadata_spec.rb +4 -2
  621. data/spec/mongoid/errors/no_parent_spec.rb +3 -1
  622. data/spec/mongoid/errors/readonly_attribute_spec.rb +2 -0
  623. data/spec/mongoid/errors/readonly_document_spec.rb +2 -0
  624. data/spec/mongoid/errors/scope_overwrite_spec.rb +2 -0
  625. data/spec/mongoid/errors/too_many_nested_attribute_records_spec.rb +2 -0
  626. data/spec/mongoid/errors/unknown_attribute_spec.rb +4 -2
  627. data/spec/mongoid/errors/unsaved_document_spec.rb +3 -1
  628. data/spec/mongoid/errors/unsupported_javascript_spec.rb +2 -0
  629. data/spec/mongoid/errors/validations_spec.rb +2 -0
  630. data/spec/mongoid/extensions/array_spec.rb +36 -58
  631. data/spec/mongoid/extensions/big_decimal_spec.rb +2 -0
  632. data/spec/mongoid/extensions/binary_spec.rb +2 -0
  633. data/spec/mongoid/extensions/boolean_spec.rb +2 -0
  634. data/spec/mongoid/extensions/date_class_mongoize_spec.rb +335 -0
  635. data/spec/mongoid/extensions/date_spec.rb +8 -160
  636. data/spec/mongoid/extensions/date_time_spec.rb +17 -60
  637. data/spec/mongoid/extensions/decimal128_spec.rb +2 -0
  638. data/spec/mongoid/extensions/false_class_spec.rb +3 -1
  639. data/spec/mongoid/extensions/float_spec.rb +17 -3
  640. data/spec/mongoid/extensions/hash_spec.rb +123 -1
  641. data/spec/mongoid/extensions/integer_spec.rb +14 -2
  642. data/spec/mongoid/extensions/module_spec.rb +2 -0
  643. data/spec/mongoid/extensions/nil_class_spec.rb +2 -0
  644. data/spec/mongoid/extensions/object_id_spec.rb +2 -0
  645. data/spec/mongoid/extensions/object_spec.rb +20 -35
  646. data/spec/mongoid/extensions/range_spec.rb +9 -0
  647. data/spec/mongoid/extensions/regexp_spec.rb +2 -0
  648. data/spec/mongoid/extensions/set_spec.rb +2 -0
  649. data/spec/mongoid/extensions/string_spec.rb +60 -27
  650. data/spec/mongoid/extensions/stringified_symbol_spec.rb +84 -0
  651. data/spec/mongoid/extensions/symbol_spec.rb +2 -0
  652. data/spec/mongoid/extensions/time_spec.rb +29 -0
  653. data/spec/mongoid/extensions/time_with_zone_spec.rb +33 -0
  654. data/spec/mongoid/extensions/true_class_spec.rb +3 -1
  655. data/spec/mongoid/extensions_spec.rb +16 -2
  656. data/spec/mongoid/factory_spec.rb +301 -23
  657. data/spec/mongoid/fields/foreign_key_spec.rb +26 -32
  658. data/spec/mongoid/fields/localized_spec.rb +6 -4
  659. data/spec/mongoid/fields/standard_spec.rb +2 -0
  660. data/spec/mongoid/fields_spec.rb +419 -37
  661. data/spec/mongoid/findable_spec.rb +83 -19
  662. data/spec/mongoid/indexable/specification_spec.rb +2 -0
  663. data/spec/mongoid/indexable_spec.rb +54 -14
  664. data/spec/mongoid/inspectable_spec.rb +39 -2
  665. data/spec/mongoid/interceptable_spec.rb +189 -96
  666. data/spec/mongoid/interceptable_spec_models.rb +76 -0
  667. data/spec/mongoid/loggable_spec.rb +2 -0
  668. data/spec/mongoid/matcher/extract_attribute_data/numeric_keys.yml +104 -0
  669. data/spec/mongoid/matcher/extract_attribute_data/traversal.yml +239 -0
  670. data/spec/mongoid/matcher/extract_attribute_spec.rb +40 -0
  671. data/spec/mongoid/persistable/creatable_spec.rb +112 -27
  672. data/spec/mongoid/persistable/deletable_spec.rb +273 -11
  673. data/spec/mongoid/persistable/destroyable_spec.rb +201 -11
  674. data/spec/mongoid/persistable/incrementable_spec.rb +23 -7
  675. data/spec/mongoid/persistable/logical_spec.rb +19 -3
  676. data/spec/mongoid/persistable/poppable_spec.rb +19 -3
  677. data/spec/mongoid/persistable/pullable_spec.rb +36 -6
  678. data/spec/mongoid/persistable/pushable_spec.rb +91 -7
  679. data/spec/mongoid/persistable/renamable_spec.rb +18 -2
  680. data/spec/mongoid/persistable/savable_spec.rb +189 -26
  681. data/spec/mongoid/persistable/settable_spec.rb +149 -18
  682. data/spec/mongoid/persistable/unsettable_spec.rb +19 -3
  683. data/spec/mongoid/persistable/updatable_spec.rb +45 -23
  684. data/spec/mongoid/persistable/upsertable_spec.rb +4 -2
  685. data/spec/mongoid/persistable_spec.rb +106 -15
  686. data/spec/mongoid/persistence_context_spec.rb +29 -2
  687. data/spec/mongoid/positional_spec.rb +2 -0
  688. data/spec/mongoid/query_cache_middleware_spec.rb +68 -0
  689. data/spec/mongoid/query_cache_spec.rb +529 -85
  690. data/spec/mongoid/relations/proxy_spec.rb +126 -124
  691. data/spec/mongoid/reloadable_spec.rb +298 -20
  692. data/spec/mongoid/scopable_spec.rb +102 -37
  693. data/spec/mongoid/selectable_spec.rb +8 -6
  694. data/spec/mongoid/serializable_spec.rb +160 -29
  695. data/spec/mongoid/shardable_models.rb +75 -0
  696. data/spec/mongoid/shardable_spec.rb +251 -26
  697. data/spec/mongoid/stateful_spec.rb +3 -1
  698. data/spec/mongoid/tasks/database_rake_spec.rb +15 -13
  699. data/spec/mongoid/tasks/database_spec.rb +3 -1
  700. data/spec/mongoid/threaded_spec.rb +4 -2
  701. data/spec/mongoid/timestamps/created/short_spec.rb +3 -1
  702. data/spec/mongoid/timestamps/created_spec.rb +3 -1
  703. data/spec/mongoid/timestamps/timeless_spec.rb +4 -2
  704. data/spec/mongoid/timestamps/updated/short_spec.rb +5 -3
  705. data/spec/mongoid/timestamps/updated_spec.rb +5 -3
  706. data/spec/mongoid/timestamps_spec.rb +8 -6
  707. data/spec/mongoid/touchable_spec.rb +588 -0
  708. data/spec/mongoid/touchable_spec_models.rb +53 -0
  709. data/spec/mongoid/traversable_spec.rb +1167 -1
  710. data/spec/mongoid/validatable/associated_spec.rb +3 -1
  711. data/spec/mongoid/validatable/format_spec.rb +2 -0
  712. data/spec/mongoid/validatable/length_spec.rb +2 -0
  713. data/spec/mongoid/validatable/numericality_spec.rb +2 -0
  714. data/spec/mongoid/validatable/presence_spec.rb +33 -26
  715. data/spec/mongoid/validatable/uniqueness_spec.rb +102 -73
  716. data/spec/mongoid/validatable_spec.rb +5 -3
  717. data/spec/mongoid_spec.rb +9 -1
  718. data/spec/rails/controller_extension/controller_runtime_spec.rb +3 -1
  719. data/spec/rails/mongoid_spec.rb +4 -2
  720. data/spec/shared/LICENSE +20 -0
  721. data/spec/shared/bin/get-mongodb-download-url +17 -0
  722. data/spec/shared/bin/s3-copy +45 -0
  723. data/spec/shared/bin/s3-upload +69 -0
  724. data/spec/shared/lib/mrss/child_process_helper.rb +80 -0
  725. data/spec/shared/lib/mrss/cluster_config.rb +231 -0
  726. data/spec/shared/lib/mrss/constraints.rb +378 -0
  727. data/spec/shared/lib/mrss/docker_runner.rb +291 -0
  728. data/spec/shared/lib/mrss/eg_config_utils.rb +51 -0
  729. data/spec/shared/lib/mrss/event_subscriber.rb +210 -0
  730. data/spec/shared/lib/mrss/lite_constraints.rb +238 -0
  731. data/spec/shared/lib/mrss/server_version_registry.rb +120 -0
  732. data/spec/shared/lib/mrss/session_registry.rb +69 -0
  733. data/spec/shared/lib/mrss/session_registry_legacy.rb +60 -0
  734. data/spec/shared/lib/mrss/spec_organizer.rb +179 -0
  735. data/spec/shared/lib/mrss/utils.rb +15 -0
  736. data/spec/shared/share/Dockerfile.erb +325 -0
  737. data/spec/shared/share/haproxy-1.conf +16 -0
  738. data/spec/shared/share/haproxy-2.conf +17 -0
  739. data/spec/shared/shlib/config.sh +27 -0
  740. data/spec/shared/shlib/distro.sh +74 -0
  741. data/spec/shared/shlib/server.sh +392 -0
  742. data/spec/shared/shlib/set_env.sh +169 -0
  743. data/spec/spec_helper.rb +70 -83
  744. data/spec/support/authorization.rb +2 -0
  745. data/spec/support/client_registry.rb +9 -0
  746. data/spec/support/constraints.rb +27 -75
  747. data/spec/support/expectations.rb +21 -3
  748. data/spec/support/helpers.rb +11 -0
  749. data/spec/support/macros.rb +31 -0
  750. data/spec/support/models/account.rb +38 -0
  751. data/spec/support/models/acolyte.rb +19 -0
  752. data/spec/support/models/actor.rb +20 -0
  753. data/spec/support/models/actress.rb +4 -0
  754. data/spec/support/models/address.rb +85 -0
  755. data/spec/support/models/address_component.rb +7 -0
  756. data/spec/support/models/address_number.rb +8 -0
  757. data/spec/support/models/agency.rb +7 -0
  758. data/spec/support/models/agent.rb +18 -0
  759. data/spec/support/models/album.rb +20 -0
  760. data/spec/support/models/alert.rb +9 -0
  761. data/spec/support/models/animal.rb +28 -0
  762. data/spec/support/models/answer.rb +8 -0
  763. data/spec/support/models/appointment.rb +9 -0
  764. data/spec/support/models/armrest.rb +9 -0
  765. data/spec/support/models/article.rb +14 -0
  766. data/spec/support/models/artist.rb +91 -0
  767. data/spec/support/models/artwork.rb +6 -0
  768. data/spec/support/models/audible_sound.rb +3 -0
  769. data/spec/support/models/audio.rb +7 -0
  770. data/spec/support/models/augmentation.rb +13 -0
  771. data/spec/support/models/author.rb +8 -0
  772. data/spec/support/models/baby.rb +6 -0
  773. data/spec/support/models/band.rb +37 -0
  774. data/spec/support/models/bar.rb +12 -0
  775. data/spec/support/models/basic.rb +8 -0
  776. data/spec/support/models/bed.rb +3 -0
  777. data/spec/support/models/big_palette.rb +4 -0
  778. data/spec/support/models/birthday.rb +15 -0
  779. data/spec/support/models/bolt.rb +7 -0
  780. data/spec/support/models/bomb.rb +6 -0
  781. data/spec/support/models/book.rb +18 -0
  782. data/spec/support/models/breed.rb +6 -0
  783. data/spec/support/models/browser.rb +8 -0
  784. data/spec/support/models/building.rb +8 -0
  785. data/spec/support/models/building_address.rb +9 -0
  786. data/spec/support/models/bus.rb +9 -0
  787. data/spec/support/models/business.rb +7 -0
  788. data/spec/support/models/callback_test.rb +11 -0
  789. data/spec/support/models/canvas.rb +27 -0
  790. data/spec/support/models/car.rb +3 -0
  791. data/spec/support/models/cat.rb +10 -0
  792. data/spec/support/models/category.rb +10 -0
  793. data/spec/support/models/child.rb +6 -0
  794. data/spec/support/models/child_doc.rb +24 -0
  795. data/spec/support/models/church.rb +8 -0
  796. data/spec/support/models/circle.rb +5 -0
  797. data/spec/support/models/circuit.rb +6 -0
  798. data/spec/support/models/circus.rb +9 -0
  799. data/spec/support/models/code.rb +15 -0
  800. data/spec/support/models/coding/pull_request.rb +11 -0
  801. data/spec/support/models/coding.rb +3 -0
  802. data/spec/support/models/comment.rb +18 -0
  803. data/spec/support/models/company.rb +7 -0
  804. data/spec/support/models/consumption_period.rb +9 -0
  805. data/spec/support/models/contextable_item.rb +7 -0
  806. data/spec/support/models/contractor.rb +7 -0
  807. data/spec/support/models/cookie.rb +8 -0
  808. data/spec/support/models/country_code.rb +12 -0
  809. data/spec/support/models/courier_job.rb +6 -0
  810. data/spec/support/models/crate.rb +12 -0
  811. data/spec/support/models/customer.rb +10 -0
  812. data/spec/support/models/customer_address.rb +11 -0
  813. data/spec/support/models/deed.rb +7 -0
  814. data/spec/support/models/definition.rb +11 -0
  815. data/spec/support/models/delegating_patient.rb +15 -0
  816. data/spec/support/models/description.rb +13 -0
  817. data/spec/support/models/dictionary.rb +18 -0
  818. data/spec/support/models/division.rb +12 -0
  819. data/spec/support/models/doctor.rb +14 -0
  820. data/spec/support/models/dog.rb +9 -0
  821. data/spec/support/models/dokument.rb +8 -0
  822. data/spec/support/models/draft.rb +11 -0
  823. data/spec/support/models/dragon.rb +6 -0
  824. data/spec/support/models/driver.rb +9 -0
  825. data/spec/support/models/drug.rb +8 -0
  826. data/spec/support/models/dungeon.rb +6 -0
  827. data/spec/support/models/edit.rb +7 -0
  828. data/spec/support/models/email.rb +8 -0
  829. data/spec/support/models/employer.rb +7 -0
  830. data/spec/support/models/entry.rb +8 -0
  831. data/spec/support/models/eraser.rb +3 -0
  832. data/spec/support/models/even.rb +9 -0
  833. data/spec/support/models/event.rb +24 -0
  834. data/spec/support/models/exhibition.rb +6 -0
  835. data/spec/support/models/exhibitor.rb +8 -0
  836. data/spec/support/models/explosion.rb +6 -0
  837. data/spec/support/models/eye.rb +11 -0
  838. data/spec/support/models/eye_bowl.rb +11 -0
  839. data/spec/support/models/face.rb +10 -0
  840. data/spec/support/models/favorite.rb +8 -0
  841. data/spec/support/models/filesystem.rb +7 -0
  842. data/spec/support/models/fire_hydrant.rb +8 -0
  843. data/spec/support/models/firefox.rb +6 -0
  844. data/spec/support/models/fish.rb +9 -0
  845. data/spec/support/models/folder.rb +9 -0
  846. data/spec/support/models/folder_item.rb +11 -0
  847. data/spec/support/models/fruits.rb +36 -0
  848. data/spec/support/models/game.rb +21 -0
  849. data/spec/support/models/ghost.rb +9 -0
  850. data/spec/support/models/guitar.rb +4 -0
  851. data/spec/support/models/hole.rb +12 -0
  852. data/spec/support/models/home.rb +6 -0
  853. data/spec/support/models/house.rb +8 -0
  854. data/spec/support/models/html_writer.rb +5 -0
  855. data/spec/support/models/id_key.rb +8 -0
  856. data/spec/support/models/idnodef.rb +7 -0
  857. data/spec/support/models/image.rb +24 -0
  858. data/spec/support/models/implant.rb +18 -0
  859. data/spec/support/models/instrument.rb +8 -0
  860. data/spec/support/models/item.rb +10 -0
  861. data/spec/support/models/jar.rb +9 -0
  862. data/spec/support/models/kaleidoscope.rb +8 -0
  863. data/spec/support/models/kangaroo.rb +6 -0
  864. data/spec/support/models/label.rb +50 -0
  865. data/spec/support/models/language.rb +7 -0
  866. data/spec/support/models/lat_lng.rb +17 -0
  867. data/spec/support/models/league.rb +13 -0
  868. data/spec/support/models/learner.rb +4 -0
  869. data/spec/support/models/line_item.rb +8 -0
  870. data/spec/support/models/location.rb +10 -0
  871. data/spec/support/models/login.rb +10 -0
  872. data/spec/support/models/manufacturer.rb +9 -0
  873. data/spec/support/models/meat.rb +6 -0
  874. data/spec/support/models/membership.rb +7 -0
  875. data/spec/support/models/message.rb +13 -0
  876. data/spec/support/models/minim.rb +6 -0
  877. data/spec/support/models/mixed_drink.rb +6 -0
  878. data/spec/support/models/mop.rb +24 -0
  879. data/spec/support/models/movie.rb +15 -0
  880. data/spec/support/models/my_hash.rb +4 -0
  881. data/spec/support/models/name.rb +26 -0
  882. data/spec/support/models/name_only.rb +8 -0
  883. data/spec/support/models/node.rb +7 -0
  884. data/spec/support/models/note.rb +19 -0
  885. data/spec/support/models/nut.rb +7 -0
  886. data/spec/support/models/odd.rb +9 -0
  887. data/spec/support/models/order.rb +12 -0
  888. data/spec/support/models/ordered_post.rb +13 -0
  889. data/spec/support/models/ordered_preference.rb +8 -0
  890. data/spec/support/models/oscar.rb +16 -0
  891. data/spec/support/models/other_owner_object.rb +4 -0
  892. data/spec/support/models/override.rb +18 -0
  893. data/spec/support/models/ownable.rb +8 -0
  894. data/spec/support/models/owner.rb +10 -0
  895. data/spec/support/models/pack.rb +5 -0
  896. data/spec/support/models/page.rb +18 -0
  897. data/spec/support/models/page_question.rb +6 -0
  898. data/spec/support/models/palette.rb +9 -0
  899. data/spec/support/models/parent.rb +7 -0
  900. data/spec/support/models/parent_doc.rb +8 -0
  901. data/spec/support/models/passport.rb +13 -0
  902. data/spec/support/models/patient.rb +11 -0
  903. data/spec/support/models/pdf_writer.rb +5 -0
  904. data/spec/support/models/pencil.rb +3 -0
  905. data/spec/support/models/person.rb +230 -0
  906. data/spec/support/models/pet.rb +25 -0
  907. data/spec/support/models/pet_owner.rb +8 -0
  908. data/spec/support/models/phone.rb +13 -0
  909. data/spec/support/models/piano.rb +4 -0
  910. data/spec/support/models/pizza.rb +9 -0
  911. data/spec/support/models/player.rb +37 -0
  912. data/spec/support/models/post.rb +52 -0
  913. data/spec/support/models/post_genre.rb +8 -0
  914. data/spec/support/models/powerup.rb +13 -0
  915. data/spec/support/models/preference.rb +11 -0
  916. data/spec/support/models/princess.rb +12 -0
  917. data/spec/support/models/product.rb +19 -0
  918. data/spec/support/models/profile.rb +17 -0
  919. data/spec/support/models/pronunciation.rb +7 -0
  920. data/spec/support/models/pub.rb +8 -0
  921. data/spec/support/models/publication/encyclopedia.rb +11 -0
  922. data/spec/support/models/publication/review.rb +13 -0
  923. data/spec/support/models/publication.rb +4 -0
  924. data/spec/support/models/purchase.rb +6 -0
  925. data/spec/support/models/purchased_item.rb +10 -0
  926. data/spec/support/models/question.rb +10 -0
  927. data/spec/support/models/quiz.rb +9 -0
  928. data/spec/support/models/rating.rb +10 -0
  929. data/spec/support/models/record.rb +54 -0
  930. data/spec/support/models/registry.rb +6 -0
  931. data/spec/support/models/role.rb +9 -0
  932. data/spec/support/models/root_category.rb +6 -0
  933. data/spec/support/models/sandwich.rb +11 -0
  934. data/spec/support/models/scheduler.rb +9 -0
  935. data/spec/support/models/scribe.rb +7 -0
  936. data/spec/support/models/sealer.rb +7 -0
  937. data/spec/support/models/seat.rb +24 -0
  938. data/spec/support/models/seo.rb +9 -0
  939. data/spec/support/models/series.rb +7 -0
  940. data/spec/support/models/server.rb +15 -0
  941. data/spec/support/models/service.rb +24 -0
  942. data/spec/support/models/shape.rb +14 -0
  943. data/spec/support/models/shelf.rb +7 -0
  944. data/spec/support/models/shipment_address.rb +5 -0
  945. data/spec/support/models/shipping_container.rb +7 -0
  946. data/spec/support/models/shipping_pack.rb +5 -0
  947. data/spec/support/models/shirt.rb +11 -0
  948. data/spec/support/models/shop.rb +8 -0
  949. data/spec/support/models/short_agent.rb +6 -0
  950. data/spec/support/models/short_quiz.rb +7 -0
  951. data/spec/support/models/simple.rb +7 -0
  952. data/spec/support/models/slave.rb +8 -0
  953. data/spec/support/models/song.rb +10 -0
  954. data/spec/support/models/sound.rb +7 -0
  955. data/spec/support/models/spacer.rb +7 -0
  956. data/spec/support/models/square.rb +6 -0
  957. data/spec/support/models/staff.rb +9 -0
  958. data/spec/support/models/store_as_dup_test1.rb +7 -0
  959. data/spec/support/models/store_as_dup_test2.rb +7 -0
  960. data/spec/support/models/store_as_dup_test3.rb +7 -0
  961. data/spec/support/models/store_as_dup_test4.rb +7 -0
  962. data/spec/support/models/strategy.rb +5 -0
  963. data/spec/support/models/sub_item.rb +5 -0
  964. data/spec/support/models/subscription.rb +7 -0
  965. data/spec/support/models/survey.rb +7 -0
  966. data/spec/support/models/symptom.rb +8 -0
  967. data/spec/support/models/system_role.rb +7 -0
  968. data/spec/support/models/tag.rb +10 -0
  969. data/spec/support/models/target.rb +7 -0
  970. data/spec/support/models/template.rb +7 -0
  971. data/spec/support/models/thing.rb +11 -0
  972. data/spec/support/models/threadlocker.rb +7 -0
  973. data/spec/support/models/title.rb +5 -0
  974. data/spec/support/models/tool.rb +10 -0
  975. data/spec/support/models/topping.rb +7 -0
  976. data/spec/support/models/toy.rb +9 -0
  977. data/spec/support/models/track.rb +40 -0
  978. data/spec/support/models/translation.rb +7 -0
  979. data/spec/support/models/tree.rb +11 -0
  980. data/spec/support/models/truck.rb +7 -0
  981. data/spec/support/models/updatable.rb +7 -0
  982. data/spec/support/models/user.rb +23 -0
  983. data/spec/support/models/user_account.rb +12 -0
  984. data/spec/support/models/validation_callback.rb +12 -0
  985. data/spec/support/models/vehicle.rb +18 -0
  986. data/spec/support/models/version.rb +7 -0
  987. data/spec/support/models/vertex.rb +8 -0
  988. data/spec/support/models/vet_visit.rb +7 -0
  989. data/spec/support/models/video.rb +15 -0
  990. data/spec/support/models/video_game.rb +3 -0
  991. data/spec/support/models/washer.rb +7 -0
  992. data/spec/support/models/weapon.rb +13 -0
  993. data/spec/support/models/wiki_page.rb +17 -0
  994. data/spec/support/models/word.rb +17 -0
  995. data/spec/support/models/word_origin.rb +13 -0
  996. data/spec/support/models/writer.rb +13 -0
  997. data/spec/support/schema_maps/schema_map_aws.json +17 -0
  998. data/spec/support/schema_maps/schema_map_aws_key_alt_names.json +12 -0
  999. data/spec/support/schema_maps/schema_map_azure.json +17 -0
  1000. data/spec/support/schema_maps/schema_map_azure_key_alt_names.json +12 -0
  1001. data/spec/support/schema_maps/schema_map_gcp.json +17 -0
  1002. data/spec/support/schema_maps/schema_map_gcp_key_alt_names.json +12 -0
  1003. data/spec/support/schema_maps/schema_map_kmip.json +17 -0
  1004. data/spec/support/schema_maps/schema_map_kmip_key_alt_names.json +12 -0
  1005. data/spec/support/schema_maps/schema_map_local.json +18 -0
  1006. data/spec/support/schema_maps/schema_map_local_key_alt_names.json +12 -0
  1007. data/spec/support/shared/time.rb +53 -0
  1008. data/spec/support/spec_config.rb +28 -6
  1009. data.tar.gz.sig +0 -0
  1010. metadata +1304 -843
  1011. metadata.gz.sig +3 -5
  1012. data/lib/mongoid/criteria/queryable/forwardable.rb +0 -65
  1013. data/lib/mongoid/matchable/all.rb +0 -27
  1014. data/lib/mongoid/matchable/and.rb +0 -30
  1015. data/lib/mongoid/matchable/default.rb +0 -72
  1016. data/lib/mongoid/matchable/elem_match.rb +0 -28
  1017. data/lib/mongoid/matchable/exists.rb +0 -23
  1018. data/lib/mongoid/matchable/gt.rb +0 -23
  1019. data/lib/mongoid/matchable/gte.rb +0 -23
  1020. data/lib/mongoid/matchable/in.rb +0 -24
  1021. data/lib/mongoid/matchable/lt.rb +0 -23
  1022. data/lib/mongoid/matchable/lte.rb +0 -23
  1023. data/lib/mongoid/matchable/ne.rb +0 -21
  1024. data/lib/mongoid/matchable/nin.rb +0 -22
  1025. data/lib/mongoid/matchable/nor.rb +0 -37
  1026. data/lib/mongoid/matchable/or.rb +0 -33
  1027. data/lib/mongoid/matchable/regexp.rb +0 -27
  1028. data/lib/mongoid/matchable/size.rb +0 -21
  1029. data/lib/mongoid/relations/accessors.rb +0 -267
  1030. data/lib/mongoid/relations/auto_save.rb +0 -94
  1031. data/lib/mongoid/relations/binding.rb +0 -218
  1032. data/lib/mongoid/relations/bindings/embedded/in.rb +0 -59
  1033. data/lib/mongoid/relations/bindings/embedded/many.rb +0 -43
  1034. data/lib/mongoid/relations/bindings/embedded/one.rb +0 -45
  1035. data/lib/mongoid/relations/bindings/referenced/in.rb +0 -65
  1036. data/lib/mongoid/relations/bindings/referenced/many.rb +0 -38
  1037. data/lib/mongoid/relations/bindings/referenced/many_to_many.rb +0 -70
  1038. data/lib/mongoid/relations/bindings/referenced/one.rb +0 -44
  1039. data/lib/mongoid/relations/bindings.rb +0 -9
  1040. data/lib/mongoid/relations/builder.rb +0 -57
  1041. data/lib/mongoid/relations/builders/embedded/in.rb +0 -29
  1042. data/lib/mongoid/relations/builders/embedded/many.rb +0 -36
  1043. data/lib/mongoid/relations/builders/embedded/one.rb +0 -30
  1044. data/lib/mongoid/relations/builders/nested_attributes/many.rb +0 -199
  1045. data/lib/mongoid/relations/builders/nested_attributes/one.rb +0 -126
  1046. data/lib/mongoid/relations/builders/referenced/in.rb +0 -26
  1047. data/lib/mongoid/relations/builders/referenced/many.rb +0 -26
  1048. data/lib/mongoid/relations/builders/referenced/many_to_many.rb +0 -39
  1049. data/lib/mongoid/relations/builders/referenced/one.rb +0 -26
  1050. data/lib/mongoid/relations/builders.rb +0 -106
  1051. data/lib/mongoid/relations/cascading/delete.rb +0 -44
  1052. data/lib/mongoid/relations/cascading/destroy.rb +0 -43
  1053. data/lib/mongoid/relations/cascading/nullify.rb +0 -35
  1054. data/lib/mongoid/relations/cascading/restrict.rb +0 -39
  1055. data/lib/mongoid/relations/cascading.rb +0 -56
  1056. data/lib/mongoid/relations/constraint.rb +0 -55
  1057. data/lib/mongoid/relations/conversions.rb +0 -34
  1058. data/lib/mongoid/relations/counter_cache.rb +0 -160
  1059. data/lib/mongoid/relations/cyclic.rb +0 -107
  1060. data/lib/mongoid/relations/eager/base.rb +0 -153
  1061. data/lib/mongoid/relations/eager/belongs_to.rb +0 -31
  1062. data/lib/mongoid/relations/eager/has_and_belongs_to_many.rb +0 -47
  1063. data/lib/mongoid/relations/eager/has_many.rb +0 -38
  1064. data/lib/mongoid/relations/eager/has_one.rb +0 -30
  1065. data/lib/mongoid/relations/eager.rb +0 -36
  1066. data/lib/mongoid/relations/embedded/batchable.rb +0 -384
  1067. data/lib/mongoid/relations/embedded/in.rb +0 -241
  1068. data/lib/mongoid/relations/embedded/many.rb +0 -683
  1069. data/lib/mongoid/relations/embedded/one.rb +0 -235
  1070. data/lib/mongoid/relations/macros.rb +0 -367
  1071. data/lib/mongoid/relations/many.rb +0 -242
  1072. data/lib/mongoid/relations/marshalable.rb +0 -32
  1073. data/lib/mongoid/relations/metadata.rb +0 -1179
  1074. data/lib/mongoid/relations/nested_builder.rb +0 -74
  1075. data/lib/mongoid/relations/one.rb +0 -60
  1076. data/lib/mongoid/relations/options.rb +0 -49
  1077. data/lib/mongoid/relations/polymorphic.rb +0 -39
  1078. data/lib/mongoid/relations/proxy.rb +0 -215
  1079. data/lib/mongoid/relations/referenced/in.rb +0 -304
  1080. data/lib/mongoid/relations/referenced/many.rb +0 -812
  1081. data/lib/mongoid/relations/referenced/many_to_many.rb +0 -479
  1082. data/lib/mongoid/relations/referenced/one.rb +0 -290
  1083. data/lib/mongoid/relations/reflections.rb +0 -64
  1084. data/lib/mongoid/relations/synchronization.rb +0 -169
  1085. data/lib/mongoid/relations/targets/enumerable.rb +0 -493
  1086. data/lib/mongoid/relations/targets.rb +0 -2
  1087. data/lib/mongoid/relations/touchable.rb +0 -97
  1088. data/lib/mongoid/relations.rb +0 -148
  1089. data/lib/support/ruby_version.rb +0 -26
  1090. data/spec/app/models/account.rb +0 -36
  1091. data/spec/app/models/acolyte.rb +0 -17
  1092. data/spec/app/models/actor.rb +0 -18
  1093. data/spec/app/models/actress.rb +0 -2
  1094. data/spec/app/models/address.rb +0 -79
  1095. data/spec/app/models/address_component.rb +0 -5
  1096. data/spec/app/models/address_number.rb +0 -6
  1097. data/spec/app/models/agency.rb +0 -5
  1098. data/spec/app/models/agent.rb +0 -16
  1099. data/spec/app/models/album.rb +0 -18
  1100. data/spec/app/models/alert.rb +0 -7
  1101. data/spec/app/models/animal.rb +0 -25
  1102. data/spec/app/models/answer.rb +0 -6
  1103. data/spec/app/models/appointment.rb +0 -7
  1104. data/spec/app/models/article.rb +0 -12
  1105. data/spec/app/models/artist.rb +0 -87
  1106. data/spec/app/models/artwork.rb +0 -4
  1107. data/spec/app/models/audio.rb +0 -5
  1108. data/spec/app/models/augmentation.rb +0 -11
  1109. data/spec/app/models/author.rb +0 -6
  1110. data/spec/app/models/baby.rb +0 -4
  1111. data/spec/app/models/band.rb +0 -31
  1112. data/spec/app/models/bar.rb +0 -10
  1113. data/spec/app/models/basic.rb +0 -6
  1114. data/spec/app/models/bed.rb +0 -1
  1115. data/spec/app/models/big_palette.rb +0 -2
  1116. data/spec/app/models/birthday.rb +0 -13
  1117. data/spec/app/models/bomb.rb +0 -4
  1118. data/spec/app/models/book.rb +0 -16
  1119. data/spec/app/models/breed.rb +0 -4
  1120. data/spec/app/models/browser.rb +0 -6
  1121. data/spec/app/models/building.rb +0 -6
  1122. data/spec/app/models/building_address.rb +0 -7
  1123. data/spec/app/models/bus.rb +0 -7
  1124. data/spec/app/models/business.rb +0 -5
  1125. data/spec/app/models/callback_test.rb +0 -9
  1126. data/spec/app/models/canvas.rb +0 -25
  1127. data/spec/app/models/car.rb +0 -1
  1128. data/spec/app/models/cat.rb +0 -8
  1129. data/spec/app/models/category.rb +0 -8
  1130. data/spec/app/models/child.rb +0 -4
  1131. data/spec/app/models/child_doc.rb +0 -22
  1132. data/spec/app/models/church.rb +0 -6
  1133. data/spec/app/models/circle.rb +0 -3
  1134. data/spec/app/models/circuit.rb +0 -4
  1135. data/spec/app/models/circus.rb +0 -7
  1136. data/spec/app/models/code.rb +0 -11
  1137. data/spec/app/models/comment.rb +0 -16
  1138. data/spec/app/models/company.rb +0 -5
  1139. data/spec/app/models/consumption_period.rb +0 -7
  1140. data/spec/app/models/contextable_item.rb +0 -5
  1141. data/spec/app/models/contractor.rb +0 -5
  1142. data/spec/app/models/cookie.rb +0 -6
  1143. data/spec/app/models/country_code.rb +0 -8
  1144. data/spec/app/models/courier_job.rb +0 -4
  1145. data/spec/app/models/definition.rb +0 -9
  1146. data/spec/app/models/delegating_patient.rb +0 -16
  1147. data/spec/app/models/description.rb +0 -11
  1148. data/spec/app/models/dictionary.rb +0 -10
  1149. data/spec/app/models/division.rb +0 -10
  1150. data/spec/app/models/doctor.rb +0 -12
  1151. data/spec/app/models/dog.rb +0 -7
  1152. data/spec/app/models/dokument.rb +0 -6
  1153. data/spec/app/models/draft.rb +0 -9
  1154. data/spec/app/models/dragon.rb +0 -4
  1155. data/spec/app/models/driver.rb +0 -7
  1156. data/spec/app/models/drug.rb +0 -6
  1157. data/spec/app/models/dungeon.rb +0 -4
  1158. data/spec/app/models/edit.rb +0 -5
  1159. data/spec/app/models/email.rb +0 -6
  1160. data/spec/app/models/employer.rb +0 -5
  1161. data/spec/app/models/entry.rb +0 -6
  1162. data/spec/app/models/eraser.rb +0 -1
  1163. data/spec/app/models/even.rb +0 -7
  1164. data/spec/app/models/event.rb +0 -22
  1165. data/spec/app/models/exhibition.rb +0 -4
  1166. data/spec/app/models/exhibitor.rb +0 -6
  1167. data/spec/app/models/explosion.rb +0 -4
  1168. data/spec/app/models/eye.rb +0 -9
  1169. data/spec/app/models/eye_bowl.rb +0 -9
  1170. data/spec/app/models/face.rb +0 -8
  1171. data/spec/app/models/favorite.rb +0 -6
  1172. data/spec/app/models/filesystem.rb +0 -5
  1173. data/spec/app/models/fire_hydrant.rb +0 -6
  1174. data/spec/app/models/firefox.rb +0 -4
  1175. data/spec/app/models/fish.rb +0 -7
  1176. data/spec/app/models/folder.rb +0 -7
  1177. data/spec/app/models/folder_item.rb +0 -9
  1178. data/spec/app/models/fruits.rb +0 -34
  1179. data/spec/app/models/game.rb +0 -19
  1180. data/spec/app/models/ghost.rb +0 -7
  1181. data/spec/app/models/home.rb +0 -4
  1182. data/spec/app/models/house.rb +0 -6
  1183. data/spec/app/models/html_writer.rb +0 -3
  1184. data/spec/app/models/id_key.rb +0 -6
  1185. data/spec/app/models/image.rb +0 -22
  1186. data/spec/app/models/implant.rb +0 -16
  1187. data/spec/app/models/item.rb +0 -8
  1188. data/spec/app/models/jar.rb +0 -7
  1189. data/spec/app/models/kaleidoscope.rb +0 -6
  1190. data/spec/app/models/kangaroo.rb +0 -4
  1191. data/spec/app/models/label.rb +0 -47
  1192. data/spec/app/models/language.rb +0 -5
  1193. data/spec/app/models/lat_lng.rb +0 -15
  1194. data/spec/app/models/league.rb +0 -11
  1195. data/spec/app/models/learner.rb +0 -2
  1196. data/spec/app/models/line_item.rb +0 -6
  1197. data/spec/app/models/location.rb +0 -8
  1198. data/spec/app/models/login.rb +0 -8
  1199. data/spec/app/models/manufacturer.rb +0 -7
  1200. data/spec/app/models/meat.rb +0 -4
  1201. data/spec/app/models/membership.rb +0 -4
  1202. data/spec/app/models/message.rb +0 -11
  1203. data/spec/app/models/mixed_drink.rb +0 -4
  1204. data/spec/app/models/movie.rb +0 -13
  1205. data/spec/app/models/my_hash.rb +0 -2
  1206. data/spec/app/models/name.rb +0 -24
  1207. data/spec/app/models/node.rb +0 -5
  1208. data/spec/app/models/note.rb +0 -17
  1209. data/spec/app/models/odd.rb +0 -7
  1210. data/spec/app/models/ordered_post.rb +0 -11
  1211. data/spec/app/models/ordered_preference.rb +0 -6
  1212. data/spec/app/models/oscar.rb +0 -14
  1213. data/spec/app/models/override.rb +0 -16
  1214. data/spec/app/models/ownable.rb +0 -6
  1215. data/spec/app/models/owner.rb +0 -6
  1216. data/spec/app/models/pack.rb +0 -3
  1217. data/spec/app/models/page.rb +0 -16
  1218. data/spec/app/models/page_question.rb +0 -4
  1219. data/spec/app/models/palette.rb +0 -7
  1220. data/spec/app/models/parent.rb +0 -5
  1221. data/spec/app/models/parent_doc.rb +0 -6
  1222. data/spec/app/models/passport.rb +0 -5
  1223. data/spec/app/models/patient.rb +0 -9
  1224. data/spec/app/models/pdf_writer.rb +0 -3
  1225. data/spec/app/models/pencil.rb +0 -1
  1226. data/spec/app/models/person.rb +0 -207
  1227. data/spec/app/models/pet.rb +0 -23
  1228. data/spec/app/models/pet_owner.rb +0 -6
  1229. data/spec/app/models/phone.rb +0 -9
  1230. data/spec/app/models/pizza.rb +0 -7
  1231. data/spec/app/models/player.rb +0 -35
  1232. data/spec/app/models/post.rb +0 -50
  1233. data/spec/app/models/post_genre.rb +0 -6
  1234. data/spec/app/models/powerup.rb +0 -11
  1235. data/spec/app/models/preference.rb +0 -9
  1236. data/spec/app/models/princess.rb +0 -10
  1237. data/spec/app/models/product.rb +0 -17
  1238. data/spec/app/models/profile.rb +0 -5
  1239. data/spec/app/models/pronunciation.rb +0 -5
  1240. data/spec/app/models/pub.rb +0 -6
  1241. data/spec/app/models/purchase.rb +0 -4
  1242. data/spec/app/models/question.rb +0 -8
  1243. data/spec/app/models/quiz.rb +0 -7
  1244. data/spec/app/models/rating.rb +0 -8
  1245. data/spec/app/models/record.rb +0 -52
  1246. data/spec/app/models/registry.rb +0 -4
  1247. data/spec/app/models/role.rb +0 -7
  1248. data/spec/app/models/root_category.rb +0 -4
  1249. data/spec/app/models/sandwich.rb +0 -9
  1250. data/spec/app/models/scheduler.rb +0 -7
  1251. data/spec/app/models/seo.rb +0 -7
  1252. data/spec/app/models/series.rb +0 -4
  1253. data/spec/app/models/server.rb +0 -13
  1254. data/spec/app/models/service.rb +0 -22
  1255. data/spec/app/models/shape.rb +0 -12
  1256. data/spec/app/models/shelf.rb +0 -5
  1257. data/spec/app/models/shipment_address.rb +0 -2
  1258. data/spec/app/models/shipping_container.rb +0 -5
  1259. data/spec/app/models/shipping_pack.rb +0 -3
  1260. data/spec/app/models/shop.rb +0 -6
  1261. data/spec/app/models/short_agent.rb +0 -4
  1262. data/spec/app/models/short_quiz.rb +0 -5
  1263. data/spec/app/models/simple.rb +0 -5
  1264. data/spec/app/models/slave.rb +0 -6
  1265. data/spec/app/models/song.rb +0 -8
  1266. data/spec/app/models/sound.rb +0 -5
  1267. data/spec/app/models/square.rb +0 -4
  1268. data/spec/app/models/staff.rb +0 -7
  1269. data/spec/app/models/store_as_dup_test1.rb +0 -5
  1270. data/spec/app/models/store_as_dup_test2.rb +0 -5
  1271. data/spec/app/models/strategy.rb +0 -3
  1272. data/spec/app/models/sub_item.rb +0 -3
  1273. data/spec/app/models/subscription.rb +0 -5
  1274. data/spec/app/models/survey.rb +0 -5
  1275. data/spec/app/models/symptom.rb +0 -6
  1276. data/spec/app/models/tag.rb +0 -8
  1277. data/spec/app/models/target.rb +0 -5
  1278. data/spec/app/models/template.rb +0 -5
  1279. data/spec/app/models/thing.rb +0 -9
  1280. data/spec/app/models/title.rb +0 -3
  1281. data/spec/app/models/tool.rb +0 -8
  1282. data/spec/app/models/topping.rb +0 -5
  1283. data/spec/app/models/track.rb +0 -38
  1284. data/spec/app/models/translation.rb +0 -5
  1285. data/spec/app/models/tree.rb +0 -9
  1286. data/spec/app/models/truck.rb +0 -3
  1287. data/spec/app/models/user.rb +0 -21
  1288. data/spec/app/models/user_account.rb +0 -10
  1289. data/spec/app/models/validation_callback.rb +0 -10
  1290. data/spec/app/models/vehicle.rb +0 -11
  1291. data/spec/app/models/version.rb +0 -5
  1292. data/spec/app/models/vet_visit.rb +0 -5
  1293. data/spec/app/models/video.rb +0 -13
  1294. data/spec/app/models/video_game.rb +0 -1
  1295. data/spec/app/models/weapon.rb +0 -11
  1296. data/spec/app/models/wiki_page.rb +0 -14
  1297. data/spec/app/models/word.rb +0 -15
  1298. data/spec/app/models/word_origin.rb +0 -11
  1299. data/spec/app/models/writer.rb +0 -11
  1300. data/spec/mongoid/criteria/queryable/forwardable_spec.rb +0 -87
  1301. data/spec/mongoid/fields/internal/foreign_keys/array_spec.rb +0 -184
  1302. data/spec/mongoid/fields/internal/foreign_keys/object_spec.rb +0 -201
  1303. data/spec/mongoid/matchable/all_spec.rb +0 -31
  1304. data/spec/mongoid/matchable/and_spec.rb +0 -187
  1305. data/spec/mongoid/matchable/default_spec.rb +0 -130
  1306. data/spec/mongoid/matchable/elem_match_spec.rb +0 -86
  1307. data/spec/mongoid/matchable/exists_spec.rb +0 -57
  1308. data/spec/mongoid/matchable/gt_spec.rb +0 -86
  1309. data/spec/mongoid/matchable/gte_spec.rb +0 -84
  1310. data/spec/mongoid/matchable/in_spec.rb +0 -49
  1311. data/spec/mongoid/matchable/lt_spec.rb +0 -85
  1312. data/spec/mongoid/matchable/lte_spec.rb +0 -85
  1313. data/spec/mongoid/matchable/ne_spec.rb +0 -46
  1314. data/spec/mongoid/matchable/nin_spec.rb +0 -48
  1315. data/spec/mongoid/matchable/nor_spec.rb +0 -209
  1316. data/spec/mongoid/matchable/or_spec.rb +0 -131
  1317. data/spec/mongoid/matchable/regexp_spec.rb +0 -59
  1318. data/spec/mongoid/matchable/size_spec.rb +0 -25
  1319. data/spec/mongoid/matchable_spec.rb +0 -853
  1320. data/spec/mongoid/relations/accessors_spec.rb +0 -821
  1321. data/spec/mongoid/relations/auto_save_spec.rb +0 -314
  1322. data/spec/mongoid/relations/bindings/embedded/in_spec.rb +0 -171
  1323. data/spec/mongoid/relations/bindings/embedded/many_spec.rb +0 -54
  1324. data/spec/mongoid/relations/bindings/embedded/one_spec.rb +0 -77
  1325. data/spec/mongoid/relations/bindings/referenced/in_spec.rb +0 -241
  1326. data/spec/mongoid/relations/bindings/referenced/many_spec.rb +0 -153
  1327. data/spec/mongoid/relations/bindings/referenced/many_to_many_spec.rb +0 -178
  1328. data/spec/mongoid/relations/bindings/referenced/one_spec.rb +0 -131
  1329. data/spec/mongoid/relations/builders/embedded/in_spec.rb +0 -34
  1330. data/spec/mongoid/relations/builders/embedded/many_spec.rb +0 -132
  1331. data/spec/mongoid/relations/builders/embedded/one_spec.rb +0 -99
  1332. data/spec/mongoid/relations/builders/nested_attributes/many_spec.rb +0 -233
  1333. data/spec/mongoid/relations/builders/nested_attributes/one_spec.rb +0 -250
  1334. data/spec/mongoid/relations/builders/referenced/in_spec.rb +0 -230
  1335. data/spec/mongoid/relations/builders/referenced/many_spec.rb +0 -137
  1336. data/spec/mongoid/relations/builders/referenced/many_to_many_spec.rb +0 -178
  1337. data/spec/mongoid/relations/builders/referenced/one_spec.rb +0 -111
  1338. data/spec/mongoid/relations/builders_spec.rb +0 -253
  1339. data/spec/mongoid/relations/cascading/delete_spec.rb +0 -101
  1340. data/spec/mongoid/relations/cascading/destroy_spec.rb +0 -47
  1341. data/spec/mongoid/relations/cascading/nullify_spec.rb +0 -32
  1342. data/spec/mongoid/relations/cascading/restrict_spec.rb +0 -68
  1343. data/spec/mongoid/relations/cascading_spec.rb +0 -355
  1344. data/spec/mongoid/relations/constraint_spec.rb +0 -75
  1345. data/spec/mongoid/relations/conversions_spec.rb +0 -128
  1346. data/spec/mongoid/relations/counter_cache_spec.rb +0 -450
  1347. data/spec/mongoid/relations/cyclic_spec.rb +0 -178
  1348. data/spec/mongoid/relations/eager/belongs_to_spec.rb +0 -163
  1349. data/spec/mongoid/relations/eager/has_and_belongs_to_many_spec.rb +0 -133
  1350. data/spec/mongoid/relations/eager/has_many_spec.rb +0 -244
  1351. data/spec/mongoid/relations/eager/has_one_spec.rb +0 -163
  1352. data/spec/mongoid/relations/eager_spec.rb +0 -279
  1353. data/spec/mongoid/relations/embedded/dirty_spec.rb +0 -65
  1354. data/spec/mongoid/relations/embedded/in_spec.rb +0 -579
  1355. data/spec/mongoid/relations/embedded/many_spec.rb +0 -4412
  1356. data/spec/mongoid/relations/embedded/one_spec.rb +0 -1068
  1357. data/spec/mongoid/relations/macros_spec.rb +0 -1039
  1358. data/spec/mongoid/relations/metadata_spec.rb +0 -1985
  1359. data/spec/mongoid/relations/options_spec.rb +0 -35
  1360. data/spec/mongoid/relations/polymorphic_spec.rb +0 -128
  1361. data/spec/mongoid/relations/referenced/in_spec.rb +0 -1366
  1362. data/spec/mongoid/relations/referenced/many_spec.rb +0 -3816
  1363. data/spec/mongoid/relations/referenced/many_to_many_spec.rb +0 -3577
  1364. data/spec/mongoid/relations/referenced/one_spec.rb +0 -1240
  1365. data/spec/mongoid/relations/reflections_spec.rb +0 -101
  1366. data/spec/mongoid/relations/synchronization_spec.rb +0 -495
  1367. data/spec/mongoid/relations/targets/enumerable_spec.rb +0 -1825
  1368. data/spec/mongoid/relations/touchable_spec.rb +0 -402
  1369. data/spec/mongoid/relations_spec.rb +0 -189
  1370. data/spec/support/cluster_config.rb +0 -158
  1371. data/spec/support/session_registry.rb +0 -50
  1372. /data/spec/{app → support}/models/array_field.rb +0 -0
@@ -1,43 +1,262 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "spec_helper"
4
+ require_relative './selectable_shared_examples'
5
+
6
+ class FieldWithSerializer
7
+ def evolve(object)
8
+ Integer.evolve(object)
9
+ end
10
+
11
+ def localized?
12
+ false
13
+ end
14
+ end
2
15
 
3
16
  describe Mongoid::Criteria::Queryable::Selectable do
4
17
 
5
18
  let(:query) do
6
- Mongoid::Query.new("id" => "_id")
19
+ Mongoid::Query.new("id" => "_id")
7
20
  end
8
21
 
9
- shared_examples_for "a cloning selection" do
22
+ shared_examples_for 'supports merge strategies' do
23
+
24
+ context 'when the field is not aliased' do
25
+
26
+ context "when the strategy is not set" do
27
+
28
+ let(:selection) do
29
+ query.send(query_method, first: [ 1, 2 ]).send(query_method, first: [ 3, 4 ])
30
+ end
31
+
32
+ it "combines the conditions with $and" do
33
+ expect(selection.selector).to eq({
34
+ "first" => { operator => [ 1, 2 ] },
35
+ '$and' => [{'first' => {operator => [3, 4]}}],
36
+ })
37
+ end
38
+
39
+ it_behaves_like "returns a cloned query"
40
+ end
41
+
42
+ context "when the strategy is intersect" do
43
+
44
+ let(:selection) do
45
+ query.send(query_method, first: [ 1, 2 ]).intersect.send(query_method, first: [ 2, 3 ])
46
+ end
47
+
48
+ it "intersects the conditions" do
49
+ expect(selection.selector).to eq({
50
+ "first" => { operator => [ 2 ] }
51
+ })
52
+ end
53
+
54
+ it_behaves_like "returns a cloned query"
55
+ end
56
+
57
+ context "when the strategy is override" do
58
+
59
+ let(:selection) do
60
+ query.send(query_method, first: [ 1, 2 ]).override.send(query_method, first: [ 3, 4 ])
61
+ end
62
+
63
+ it "overwrites the first condition" do
64
+ expect(selection.selector).to eq({
65
+ "first" => { operator => [ 3, 4 ] }
66
+ })
67
+ end
68
+
69
+ it_behaves_like "returns a cloned query"
70
+ end
71
+
72
+ context "when the strategy is union" do
73
+
74
+ let(:selection) do
75
+ query.send(query_method, first: [ 1, 2 ]).union.send(query_method, first: [ 3, 4 ])
76
+ end
77
+
78
+ it "unions the conditions" do
79
+ expect(selection.selector).to eq({
80
+ "first" => { operator => [ 1, 2, 3, 4 ] }
81
+ })
82
+ end
10
83
 
11
- it "returns a cloned query" do
12
- expect(selection).to_not equal(query)
84
+ it_behaves_like "returns a cloned query"
85
+ end
13
86
  end
14
- end
15
87
 
16
- describe "#all" do
88
+ context 'when the field is aliased' do
17
89
 
18
- context "when provided no criterion" do
90
+ context "when the strategy is not set" do
19
91
 
20
- let(:selection) do
21
- query.all
92
+ let(:selection) do
93
+ query.send(query_method, id: [ 1, 2 ]).send(query_method, _id: [ 3, 4 ])
94
+ end
95
+
96
+ it "combines the conditions with $and" do
97
+ expect(selection.selector).to eq({
98
+ "_id" => { operator => [ 1, 2 ] },
99
+ '$and' => [{'_id' => {operator => [3, 4]}}],
100
+ })
101
+ end
102
+
103
+ it_behaves_like "returns a cloned query"
22
104
  end
23
105
 
24
- it "does not add any criterion" do
25
- expect(selection.selector).to eq({})
106
+ context "when the strategy is intersect" do
107
+
108
+ let(:selection) do
109
+ query.send(query_method, id: [ 1, 2 ]).intersect.send(query_method, _id: [ 2, 3 ])
110
+ end
111
+
112
+ it "intersects the conditions" do
113
+ expect(selection.selector).to eq({
114
+ "_id" => { operator => [ 2 ] }
115
+ })
116
+ end
117
+
118
+ it_behaves_like "returns a cloned query"
26
119
  end
27
120
 
28
- it "returns the query" do
29
- expect(selection).to eq(query)
121
+ context "when the strategy is override" do
122
+
123
+ let(:selection) do
124
+ query.send(query_method, _id: [ 1, 2 ]).override.send(query_method, id: [ 3, 4 ])
125
+ end
126
+
127
+ it "overwrites the first condition" do
128
+ expect(selection.selector).to eq({
129
+ "_id" => { operator => [ 3, 4 ] }
130
+ })
131
+ end
132
+
133
+ it_behaves_like "returns a cloned query"
30
134
  end
31
135
 
32
- it "returns a cloned query" do
33
- expect(selection).to_not equal(query)
136
+ context "when the strategy is union" do
137
+
138
+ let(:selection) do
139
+ query.send(query_method, _id: [ 1, 2 ]).union.send(query_method, id: [ 3, 4 ])
140
+ end
141
+
142
+ it "unions the conditions" do
143
+ expect(selection.selector).to eq({
144
+ "_id" => { operator => [ 1, 2, 3, 4 ] }
145
+ })
146
+ end
147
+
148
+ it_behaves_like "returns a cloned query"
149
+ end
150
+ end
151
+
152
+ context 'when the field uses a serializer' do
153
+
154
+ let(:query) do
155
+ Mongoid::Query.new({}, { "field" => FieldWithSerializer.new })
156
+ end
157
+
158
+
159
+ context "when the strategy is not set" do
160
+
161
+ let(:selection) do
162
+ query.send(query_method, field: [ '1', '2' ]).send(query_method, field: [ '3', '4' ])
163
+ end
164
+
165
+ it "combines the conditions with $and" do
166
+ expect(selection.selector).to eq({
167
+ "field" => { operator => [ 1, 2 ] },
168
+ '$and' => [{'field' => {operator => [3, 4]}}],
169
+ })
170
+ end
171
+
172
+ it_behaves_like "returns a cloned query"
173
+ end
174
+
175
+ context "when the strategy is set" do
176
+
177
+ let(:selection) do
178
+ query.send(query_method, field: [ '1', '2' ]).intersect.send(query_method, field: [ '2', '3' ])
179
+ end
180
+
181
+ it "intersects the conditions" do
182
+ expect(selection.selector).to eq({
183
+ "field" => { operator => [ 2 ] }
184
+ })
185
+ end
186
+
187
+ it_behaves_like "returns a cloned query"
188
+ end
189
+ end
190
+
191
+ context 'when operator value is a Range' do
192
+
193
+ context "when there is no existing condition and strategy is not specified" do
194
+
195
+ let(:selection) do
196
+ query.send(query_method, foo: 2..4)
197
+ end
198
+
199
+ it 'expands range to array' do
200
+ expect(selection.selector).to eq({
201
+ "foo" => { operator => [ 2, 3, 4 ] }
202
+ })
203
+
204
+ end
205
+ end
206
+
207
+ context "when there is no existing condition and strategy is specified" do
208
+
209
+ let(:selection) do
210
+ query.union.send(query_method, foo: 2..4)
211
+ end
212
+
213
+ it 'expands range to array' do
214
+ expect(selection.selector).to eq({
215
+ "foo" => { operator => [ 2, 3, 4 ] }
216
+ })
217
+
218
+ end
219
+ end
220
+
221
+ context "when existing condition has Array value" do
222
+
223
+ let(:selection) do
224
+ query.send(query_method, foo: [ 1, 2 ]).union.send(query_method, foo: 2..4)
225
+ end
226
+
227
+ it 'expands range to array' do
228
+ expect(selection.selector).to eq({
229
+ "foo" => { operator => [ 1, 2, 3, 4 ] }
230
+ })
231
+
232
+ end
233
+ end
234
+
235
+ context "when existing condition has Range value" do
236
+
237
+ let(:selection) do
238
+ query.send(query_method, foo: 1..2).union.send(query_method, foo: 2..4)
239
+ end
240
+
241
+ it 'expands range to array' do
242
+ expect(selection.selector).to eq({
243
+ "foo" => { operator => [ 1, 2, 3, 4 ] }
244
+ })
245
+
246
+ end
34
247
  end
35
248
  end
249
+ end
36
250
 
37
- context "when provided nil" do
251
+ describe "#all" do
252
+
253
+ let(:query_method) { :all }
254
+ let(:operator) { '$all' }
255
+
256
+ context "when provided no criterion" do
38
257
 
39
258
  let(:selection) do
40
- query.all(nil)
259
+ query.all
41
260
  end
42
261
 
43
262
  it "does not add any criterion" do
@@ -53,6 +272,8 @@ describe Mongoid::Criteria::Queryable::Selectable do
53
272
  end
54
273
  end
55
274
 
275
+ it_behaves_like 'requires a non-nil argument'
276
+
56
277
  context "when provided a single criterion" do
57
278
 
58
279
  context "when no serializers are provided" do
@@ -74,23 +295,6 @@ describe Mongoid::Criteria::Queryable::Selectable do
74
295
  end
75
296
  end
76
297
 
77
- context "when providing a range" do
78
-
79
- let(:selection) do
80
- query.all(field: 1..3)
81
- end
82
-
83
- it "adds the $all selector with converted range" do
84
- expect(selection.selector).to eq({
85
- "field" => { "$all" => [ 1, 2, 3 ] }
86
- })
87
- end
88
-
89
- it "returns a cloned query" do
90
- expect(selection).to_not equal(query)
91
- end
92
- end
93
-
94
298
  context "when providing a single value" do
95
299
 
96
300
  let(:selection) do
@@ -147,23 +351,6 @@ describe Mongoid::Criteria::Queryable::Selectable do
147
351
  end
148
352
  end
149
353
 
150
- context "when providing a range" do
151
-
152
- let(:selection) do
153
- query.all(field: "1".."3")
154
- end
155
-
156
- it "adds the $all selector with converted range" do
157
- expect(selection.selector).to eq({
158
- "field" => { "$all" => [ 1, 2, 3 ] }
159
- })
160
- end
161
-
162
- it "returns a cloned query" do
163
- expect(selection).to_not equal(query)
164
- end
165
- end
166
-
167
354
  context "when providing a single value" do
168
355
 
169
356
  let(:selection) do
@@ -226,257 +413,249 @@ describe Mongoid::Criteria::Queryable::Selectable do
226
413
 
227
414
  context "when the criterion are on the same field" do
228
415
 
229
- context "when no serializers are provided" do
416
+ it_behaves_like 'supports merge strategies'
417
+ end
418
+ end
419
+ end
230
420
 
231
- context "when the strategy is the default (union)" do
421
+ describe "#between" do
232
422
 
233
- let(:selection) do
234
- query.all(first: [ 1, 2 ]).all(first: [ 3, 4 ])
235
- end
423
+ let(:query_method) { :between }
236
424
 
237
- it "overwrites the first $all selector" do
238
- expect(selection.selector).to eq({
239
- "first" => { "$all" => [ 1, 2, 3, 4 ] }
240
- })
241
- end
425
+ it_behaves_like 'requires an argument'
426
+ it_behaves_like 'requires a non-nil argument'
242
427
 
243
- it "returns a cloned query" do
244
- expect(selection).to_not equal(query)
245
- end
246
- end
428
+ context "when provided a single range" do
247
429
 
248
- context "when the strategy is intersect" do
430
+ let(:selection) do
431
+ query.between(field: 1..10)
432
+ end
249
433
 
250
- let(:selection) do
251
- query.all(first: [ 1, 2 ]).intersect.all(first: [ 2, 3 ])
252
- end
434
+ it "adds the $gte and $lte selectors" do
435
+ expect(selection.selector).to eq({
436
+ "field" => { "$gte" => 1, "$lte" => 10 }
437
+ })
438
+ end
253
439
 
254
- it "intersects the $all selectors" do
255
- expect(selection.selector).to eq({
256
- "first" => { "$all" => [ 2 ] }
257
- })
258
- end
440
+ it "returns a cloned query" do
441
+ expect(selection).to_not equal(query)
442
+ end
443
+ end
259
444
 
260
- it "returns a cloned query" do
261
- expect(selection).to_not equal(query)
262
- end
263
- end
445
+ context "when provided multiple ranges" do
264
446
 
265
- context "when the strategy is override" do
447
+ context "when the ranges are on different fields" do
266
448
 
267
- let(:selection) do
268
- query.all(first: [ 1, 2 ]).override.all(first: [ 3, 4 ])
269
- end
449
+ let(:selection) do
450
+ query.between(field: 1..10, key: 5..7)
451
+ end
270
452
 
271
- it "overwrites the first $all selector" do
272
- expect(selection.selector).to eq({
273
- "first" => { "$all" => [ 3, 4 ] }
274
- })
275
- end
453
+ it "adds the $gte and $lte selectors" do
454
+ expect(selection.selector).to eq({
455
+ "field" => { "$gte" => 1, "$lte" => 10 },
456
+ "key" => { "$gte" => 5, "$lte" => 7 }
457
+ })
458
+ end
276
459
 
277
- it "returns a cloned query" do
278
- expect(selection).to_not equal(query)
279
- end
280
- end
460
+ it "returns a cloned query" do
461
+ expect(selection).to_not equal(query)
462
+ end
463
+ end
464
+ end
465
+ end
281
466
 
282
- context "when the strategy is union" do
467
+ describe "#elem_match" do
283
468
 
284
- let(:selection) do
285
- query.all(first: [ 1, 2 ]).union.all(first: [ 3, 4 ])
286
- end
469
+ let(:query_method) { :elem_match }
287
470
 
288
- it "unions the $all selectors" do
289
- expect(selection.selector).to eq({
290
- "first" => { "$all" => [ 1, 2, 3, 4 ] }
291
- })
292
- end
471
+ it_behaves_like 'requires an argument'
472
+ it_behaves_like 'requires a non-nil argument'
293
473
 
294
- it "returns a cloned query" do
295
- expect(selection).to_not equal(query)
296
- end
297
- end
298
- end
474
+ context "when provided a criterion" do
299
475
 
300
- context "when serializers are provided" do
476
+ context "when there are no nested complex keys" do
301
477
 
302
- before(:all) do
303
- class Field
304
- def evolve(object)
305
- Integer.evolve(object)
306
- end
307
- def localized?
308
- false
309
- end
310
- end
311
- end
478
+ let(:selection) do
479
+ query.elem_match(users: { name: "value" })
480
+ end
312
481
 
313
- after(:all) do
314
- Object.send(:remove_const, :Field)
315
- end
482
+ context "when overwrite_chained_operators is false" do
483
+ config_override :overwrite_chained_operators, false
316
484
 
317
- let!(:query) do
318
- Mongoid::Query.new({}, { "field" => Field.new })
485
+ it "adds the $elemMatch expression" do
486
+ expect(selection.selector).to eq({
487
+ "users" => { "$elemMatch" => { "name" => "value" }}
488
+ })
319
489
  end
490
+ end
320
491
 
321
- context "when the strategy is the default (union)" do
322
-
323
- let(:selection) do
324
- query.all(field: [ "1", "2" ]).all(field: [ "3", "4" ])
325
- end
326
-
327
- it "overwrites the field $all selector" do
328
- expect(selection.selector).to eq({
329
- "field" => { "$all" => [ 1, 2, 3, 4 ] }
330
- })
331
- end
492
+ context "when overwrite_chained_operators is true" do
493
+ config_override :overwrite_chained_operators, true
332
494
 
333
- it "returns a cloned query" do
334
- expect(selection).to_not equal(query)
335
- end
495
+ it "adds the $elemMatch expression" do
496
+ expect(selection.selector).to eq({
497
+ "users" => { "$elemMatch" => { name: "value" }}
498
+ })
336
499
  end
500
+ end
337
501
 
338
- context "when the strategy is intersect" do
502
+ it "returns a cloned query" do
503
+ expect(selection).to_not equal(query)
504
+ end
505
+ end
339
506
 
340
- let(:selection) do
341
- query.all(field: [ "1", "2" ]).intersect.all(field: [ "2", "3" ])
342
- end
507
+ context "when there are nested complex keys" do
343
508
 
344
- it "intersects the $all selectors" do
345
- expect(selection.selector).to eq({
346
- "field" => { "$all" => [ 2 ] }
347
- })
348
- end
509
+ let(:time) do
510
+ Time.now
511
+ end
349
512
 
350
- it "returns a cloned query" do
351
- expect(selection).to_not equal(query)
352
- end
353
- end
513
+ let(:selection) do
514
+ query.elem_match(users: { :time.gt => time })
515
+ end
354
516
 
355
- context "when the strategy is override" do
517
+ it "adds the $elemMatch expression" do
518
+ expect(selection.selector).to eq({
519
+ "users" => { "$elemMatch" => { "time" => { "$gt" => time }}}
520
+ })
521
+ end
356
522
 
357
- let(:selection) do
358
- query.all(field: [ "1", "2" ]).override.all(field: [ "3", "4" ])
359
- end
523
+ it "returns a cloned query" do
524
+ expect(selection).to_not equal(query)
525
+ end
526
+ end
527
+ end
360
528
 
361
- it "overwrites the field $all selector" do
362
- expect(selection.selector).to eq({
363
- "field" => { "$all" => [ 3, 4 ] }
364
- })
365
- end
529
+ context "when providing multiple criteria" do
366
530
 
367
- it "returns a cloned query" do
368
- expect(selection).to_not equal(query)
369
- end
370
- end
531
+ context "when the fields differ" do
371
532
 
372
- context "when the strategy is union" do
533
+ let(:selection) do
534
+ query.elem_match(
535
+ users: { name: "value" },
536
+ comments: { text: "value" }
537
+ )
538
+ end
373
539
 
374
- let(:selection) do
375
- query.all(field: [ "1", "2" ]).union.all(field: [ "3", "4" ])
376
- end
540
+ context "when overwrite_chained_operators is false" do
541
+ config_override :overwrite_chained_operators, false
377
542
 
378
- it "unions the $all selectors" do
379
- expect(selection.selector).to eq({
380
- "field" => { "$all" => [ 1, 2, 3, 4 ] }
381
- })
382
- end
543
+ it "adds the $elemMatch expression" do
544
+ expect(selection.selector).to eq({
545
+ "users" => { "$elemMatch" => { "name" => "value" }},
546
+ "comments" => { "$elemMatch" => { "text" => "value" }}
547
+ })
548
+ end
549
+ end
383
550
 
384
- it "returns a cloned query" do
385
- expect(selection).to_not equal(query)
386
- end
551
+ context "when overwrite_chained_operators is true" do
552
+ config_override :overwrite_chained_operators, true
553
+
554
+ it "adds the $elemMatch expression" do
555
+ expect(selection.selector).to eq({
556
+ "users" => { "$elemMatch" => { name: "value" }},
557
+ "comments" => { "$elemMatch" => { text: "value" }}
558
+ })
387
559
  end
388
560
  end
561
+
562
+ it "returns a cloned query" do
563
+ expect(selection).to_not equal(query)
564
+ end
389
565
  end
390
566
  end
391
- end
392
567
 
393
- describe "#and" do
568
+ context "when chaining multiple criteria" do
394
569
 
395
- context "when provided no criterion" do
570
+ context "when the fields differ" do
396
571
 
397
- let(:selection) do
398
- query.and
399
- end
572
+ let(:selection) do
573
+ query.
574
+ elem_match(users: { name: "value" }).
575
+ elem_match(comments: { text: "value" })
576
+ end
400
577
 
401
- it "does not add any criterion" do
402
- expect(selection.selector).to eq({})
403
- end
578
+ context "when overwrite_chained_operators is false" do
579
+ config_override :overwrite_chained_operators, false
404
580
 
405
- it "returns the query" do
406
- expect(selection).to eq(query)
407
- end
581
+ it "adds the $elemMatch expression" do
582
+ expect(selection.selector).to eq({
583
+ "users" => { "$elemMatch" => { "name" => "value" }},
584
+ "comments" => { "$elemMatch" => { "text" => "value" }}
585
+ })
586
+ end
587
+ end
408
588
 
409
- it "returns a cloned query" do
410
- expect(selection).to_not equal(query)
411
- end
412
- end
589
+ context "when overwrite_chained_operators is true" do
590
+ config_override :overwrite_chained_operators, true
413
591
 
414
- context "when provided nil" do
592
+ it "adds the $elemMatch expression" do
593
+ expect(selection.selector).to eq({
594
+ "users" => { "$elemMatch" => { name: "value" }},
595
+ "comments" => { "$elemMatch" => { text: "value" }}
596
+ })
597
+ end
598
+ end
415
599
 
416
- let(:selection) do
417
- query.and(nil)
600
+ it "returns a cloned query" do
601
+ expect(selection).to_not equal(query)
602
+ end
418
603
  end
419
604
 
420
- it "does not add any criterion" do
421
- expect(selection.selector).to eq({})
422
- end
605
+ context "when the fields are the same" do
423
606
 
424
- it "returns the query" do
425
- expect(selection).to eq(query)
426
- end
607
+ let(:selection) do
608
+ query.
609
+ elem_match(users: { name: "value" }).
610
+ elem_match(users: { state: "new" })
611
+ end
427
612
 
428
- it "returns a cloned query" do
429
- expect(selection).to_not equal(query)
430
- end
431
- end
613
+ context "when overwrite_chained_operators is false" do
614
+ config_override :overwrite_chained_operators, false
432
615
 
433
- context "when provided a single criterion" do
616
+ it "adds an $elemMatch expression" do
617
+ expect(selection.selector).to eq({
618
+ "users" => { "$elemMatch" => { "name" => "value" } },
619
+ "$and" => [ { "users" => { "$elemMatch" => { "state" => "new" } } } ],
620
+ })
621
+ end
622
+ end
434
623
 
435
- let(:selection) do
436
- query.and(field: [ 1, 2 ])
437
- end
624
+ context "when overwrite_chained_operators is true" do
625
+ config_override :overwrite_chained_operators, true
438
626
 
439
- it "adds the $and selector" do
440
- expect(selection.selector).to eq({
441
- "$and" => [{ "field" => [ 1, 2 ] }]
442
- })
443
- end
627
+ it "overrides the $elemMatch expression" do
628
+ expect(selection.selector).to eq({
629
+ "users" => { "$elemMatch" => { state: "new" }}
630
+ })
631
+ end
632
+ end
444
633
 
445
- it "returns a cloned query" do
446
- expect(selection).to_not equal(query)
634
+ it "returns a cloned query" do
635
+ expect(selection).to_not equal(query)
636
+ end
447
637
  end
448
638
  end
639
+ end
449
640
 
450
- context "when provided a nested criterion" do
451
-
452
- let(:selection) do
453
- query.and(:test.elem_match => { :field.in => [ 1, 2 ] })
454
- end
641
+ describe "#exists" do
455
642
 
456
- it "adds the $and selector" do
457
- expect(selection.selector).to eq({
458
- "$and" => [{ "test" => { "$elemMatch" => { "field" => { "$in" => [ 1, 2 ] }}}}]
459
- })
460
- end
643
+ let(:query_method) { :exists }
461
644
 
462
- it "returns a cloned query" do
463
- expect(selection).to_not equal(query)
464
- end
465
- end
645
+ it_behaves_like 'requires an argument'
646
+ it_behaves_like 'requires a non-nil argument'
466
647
 
467
- context "when provided multiple criterion" do
648
+ context "when provided a criterion" do
468
649
 
469
- context "when the criterion is already included" do
650
+ context "when provided a boolean" do
470
651
 
471
652
  let(:selection) do
472
- query.and({ first: [ 1, 2 ] }).and({ first: [ 1, 2 ] })
653
+ query.exists(users: true)
473
654
  end
474
655
 
475
- it "does not duplicate the $and selector" do
656
+ it "adds the $exists expression" do
476
657
  expect(selection.selector).to eq({
477
- "$and" => [
478
- { "first" => [ 1, 2 ] }
479
- ]
658
+ "users" => { "$exists" => true }
480
659
  })
481
660
  end
482
661
 
@@ -485,18 +664,15 @@ describe Mongoid::Criteria::Queryable::Selectable do
485
664
  end
486
665
  end
487
666
 
488
- context "when the criterion are for different fields" do
667
+ context "when provided a string" do
489
668
 
490
669
  let(:selection) do
491
- query.and({ first: [ 1, 2 ] }, { second: [ 3, 4 ] })
670
+ query.exists(users: "yes")
492
671
  end
493
672
 
494
- it "adds the $and selector" do
673
+ it "adds the $exists expression" do
495
674
  expect(selection.selector).to eq({
496
- "$and" => [
497
- { "first" => [ 1, 2 ] },
498
- { "second" => [ 3, 4 ] }
499
- ]
675
+ "users" => { "$exists" => true }
500
676
  })
501
677
  end
502
678
 
@@ -504,62 +680,70 @@ describe Mongoid::Criteria::Queryable::Selectable do
504
680
  expect(selection).to_not equal(query)
505
681
  end
506
682
  end
683
+ end
507
684
 
508
- context "when the criterion are on the same field" do
509
-
510
- let(:selection) do
511
- query.and({ first: [ 1, 2 ] }, { first: [ 3, 4 ] })
512
- end
685
+ context "when providing multiple criteria" do
513
686
 
514
- it "appends both $and expressions" do
515
- expect(selection.selector).to eq({
516
- "$and" => [
517
- { "first" => [ 1, 2 ] },
518
- { "first" => [ 3, 4 ] }
519
- ]
520
- })
521
- end
687
+ context "when the fields differ" do
522
688
 
523
- it "returns a cloned query" do
524
- expect(selection).to_not equal(query)
525
- end
526
- end
527
- end
689
+ context "when providing boolean values" do
528
690
 
529
- context "when chaining the criterion" do
691
+ let(:selection) do
692
+ query.exists(
693
+ users: true,
694
+ comments: true
695
+ )
696
+ end
530
697
 
531
- context "when the criterion are for different fields" do
698
+ it "adds the $exists expression" do
699
+ expect(selection.selector).to eq({
700
+ "users" => { "$exists" => true },
701
+ "comments" => { "$exists" => true }
702
+ })
703
+ end
532
704
 
533
- let(:selection) do
534
- query.and(first: [ 1, 2 ]).and(second: [ 3, 4 ])
705
+ it "returns a cloned query" do
706
+ expect(selection).to_not equal(query)
707
+ end
535
708
  end
536
709
 
537
- it "adds the $and selectors" do
538
- expect(selection.selector).to eq({
539
- "$and" => [
540
- { "first" => [ 1, 2 ] },
541
- { "second" => [ 3, 4 ] }
542
- ]
543
- })
544
- end
710
+ context "when providing string values" do
545
711
 
546
- it "returns a cloned query" do
547
- expect(selection).to_not equal(query)
712
+ let(:selection) do
713
+ query.exists(
714
+ users: "y",
715
+ comments: "true"
716
+ )
717
+ end
718
+
719
+ it "adds the $exists expression" do
720
+ expect(selection.selector).to eq({
721
+ "users" => { "$exists" => true },
722
+ "comments" => { "$exists" => true }
723
+ })
724
+ end
725
+
726
+ it "returns a cloned query" do
727
+ expect(selection).to_not equal(query)
728
+ end
548
729
  end
549
730
  end
731
+ end
550
732
 
551
- context "when the criterion are on the same field" do
733
+ context "when chaining multiple criteria" do
734
+
735
+ context "when the fields differ" do
552
736
 
553
737
  let(:selection) do
554
- query.and(first: [ 1, 2 ]).and(first: [ 3, 4 ])
738
+ query.
739
+ exists(users: true).
740
+ exists(comments: true)
555
741
  end
556
742
 
557
- it "appends both $and expressions" do
743
+ it "adds the $exists expression" do
558
744
  expect(selection.selector).to eq({
559
- "$and" => [
560
- { "first" => [ 1, 2 ] },
561
- { "first" => [ 3, 4 ] }
562
- ]
745
+ "users" => { "$exists" => true },
746
+ "comments" => { "$exists" => true }
563
747
  })
564
748
  end
565
749
 
@@ -570,1840 +754,152 @@ describe Mongoid::Criteria::Queryable::Selectable do
570
754
  end
571
755
  end
572
756
 
573
- describe "#between" do
574
-
575
- context "when provided no criterion" do
757
+ %i(geo_spatial geo_spacial).each do |meth|
758
+ describe "#geo_spacial" do
576
759
 
577
- let(:selection) do
578
- query.between
579
- end
760
+ let(:query_method) { meth }
580
761
 
581
- it "does not add any criterion" do
582
- expect(selection.selector).to eq({})
583
- end
762
+ it_behaves_like 'requires an argument'
763
+ it_behaves_like 'requires a non-nil argument'
584
764
 
585
- it "returns the query" do
586
- expect(selection).to eq(query)
587
- end
765
+ context "when provided a criterion" do
588
766
 
589
- it "returns a cloned query" do
590
- expect(selection).to_not equal(query)
591
- end
592
- end
767
+ context "when the geometry is a point intersection" do
593
768
 
594
- context "when provided nil" do
769
+ let(:selection) do
770
+ query.public_send(query_method, :location.intersects_point => [ 1, 10 ])
771
+ end
595
772
 
596
- let(:selection) do
597
- query.between(nil)
598
- end
599
-
600
- it "does not add any criterion" do
601
- expect(selection.selector).to eq({})
602
- end
603
-
604
- it "returns the query" do
605
- expect(selection).to eq(query)
606
- end
607
-
608
- it "returns a cloned query" do
609
- expect(selection).to_not equal(query)
610
- end
611
- end
612
-
613
- context "when provided a single range" do
614
-
615
- let(:selection) do
616
- query.between(field: 1..10)
617
- end
618
-
619
- it "adds the $gte and $lte selectors" do
620
- expect(selection.selector).to eq({
621
- "field" => { "$gte" => 1, "$lte" => 10 }
622
- })
623
- end
624
-
625
- it "returns a cloned query" do
626
- expect(selection).to_not equal(query)
627
- end
628
- end
629
-
630
- context "when provided multiple ranges" do
631
-
632
- context "when the ranges are on different fields" do
633
-
634
- let(:selection) do
635
- query.between(field: 1..10, key: 5..7)
636
- end
637
-
638
- it "adds the $gte and $lte selectors" do
639
- expect(selection.selector).to eq({
640
- "field" => { "$gte" => 1, "$lte" => 10 },
641
- "key" => { "$gte" => 5, "$lte" => 7 }
642
- })
643
- end
644
-
645
- it "returns a cloned query" do
646
- expect(selection).to_not equal(query)
647
- end
648
- end
649
- end
650
- end
651
-
652
- describe "#elem_match" do
653
-
654
- context "when provided no criterion" do
655
-
656
- let(:selection) do
657
- query.elem_match
658
- end
659
-
660
- it "does not add any criterion" do
661
- expect(selection.selector).to eq({})
662
- end
663
-
664
- it "returns the query" do
665
- expect(selection).to eq(query)
666
- end
667
-
668
- it "returns a cloned query" do
669
- expect(selection).to_not equal(query)
670
- end
671
- end
672
-
673
- context "when provided nil" do
674
-
675
- let(:selection) do
676
- query.elem_match(nil)
677
- end
678
-
679
- it "does not add any criterion" do
680
- expect(selection.selector).to eq({})
681
- end
682
-
683
- it "returns the query" do
684
- expect(selection).to eq(query)
685
- end
686
-
687
- it "returns a cloned query" do
688
- expect(selection).to_not equal(query)
689
- end
690
- end
691
-
692
- context "when provided a criterion" do
693
-
694
- context "when there are no nested complex keys" do
695
-
696
- let(:selection) do
697
- query.elem_match(users: { name: "value" })
698
- end
699
-
700
- it "adds the $elemMatch expression" do
701
- expect(selection.selector).to eq({
702
- "users" => { "$elemMatch" => { name: "value" }}
703
- })
704
- end
705
-
706
- it "returns a cloned query" do
707
- expect(selection).to_not equal(query)
708
- end
709
- end
710
-
711
- context "when there are nested complex keys" do
712
-
713
- let(:time) do
714
- Time.now
715
- end
716
-
717
- let(:selection) do
718
- query.elem_match(users: { :time.gt => time })
719
- end
720
-
721
- it "adds the $elemMatch expression" do
722
- expect(selection.selector).to eq({
723
- "users" => { "$elemMatch" => { "time" => { "$gt" => time }}}
724
- })
725
- end
726
-
727
- it "returns a cloned query" do
728
- expect(selection).to_not equal(query)
729
- end
730
- end
731
- end
732
-
733
- context "when providing multiple criteria" do
734
-
735
- context "when the fields differ" do
736
-
737
- let(:selection) do
738
- query.elem_match(
739
- users: { name: "value" },
740
- comments: { text: "value" }
741
- )
742
- end
743
-
744
- it "adds the $elemMatch expression" do
745
- expect(selection.selector).to eq({
746
- "users" => { "$elemMatch" => { name: "value" }},
747
- "comments" => { "$elemMatch" => { text: "value" }}
748
- })
749
- end
750
-
751
- it "returns a cloned query" do
752
- expect(selection).to_not equal(query)
753
- end
754
- end
755
- end
756
-
757
- context "when chaining multiple criteria" do
758
-
759
- context "when the fields differ" do
760
-
761
- let(:selection) do
762
- query.
763
- elem_match(users: { name: "value" }).
764
- elem_match(comments: { text: "value" })
765
- end
766
-
767
- it "adds the $elemMatch expression" do
768
- expect(selection.selector).to eq({
769
- "users" => { "$elemMatch" => { name: "value" }},
770
- "comments" => { "$elemMatch" => { text: "value" }}
771
- })
772
- end
773
-
774
- it "returns a cloned query" do
775
- expect(selection).to_not equal(query)
776
- end
777
- end
778
-
779
- context "when the fields are the same" do
780
-
781
- let(:selection) do
782
- query.
783
- elem_match(users: { name: "value" }).
784
- elem_match(users: { state: "new" })
785
- end
786
-
787
- it "overrides the $elemMatch expression" do
788
- expect(selection.selector).to eq({
789
- "users" => { "$elemMatch" => { state: "new" }}
790
- })
791
- end
792
-
793
- it "returns a cloned query" do
794
- expect(selection).to_not equal(query)
795
- end
796
- end
797
- end
798
- end
799
-
800
- describe "#exists" do
801
-
802
- context "when provided no criterion" do
803
-
804
- let(:selection) do
805
- query.exists
806
- end
807
-
808
- it "does not add any criterion" do
809
- expect(selection.selector).to eq({})
810
- end
811
-
812
- it "returns the query" do
813
- expect(selection).to eq(query)
814
- end
815
-
816
- it "returns a cloned query" do
817
- expect(selection).to_not equal(query)
818
- end
819
- end
820
-
821
- context "when provided nil" do
822
-
823
- let(:selection) do
824
- query.exists(nil)
825
- end
826
-
827
- it "does not add any criterion" do
828
- expect(selection.selector).to eq({})
829
- end
830
-
831
- it "returns the query" do
832
- expect(selection).to eq(query)
833
- end
834
-
835
- it "returns a cloned query" do
836
- expect(selection).to_not equal(query)
837
- end
838
- end
839
-
840
- context "when provided a criterion" do
841
-
842
- context "when provided a boolean" do
843
-
844
- let(:selection) do
845
- query.exists(users: true)
846
- end
847
-
848
- it "adds the $exists expression" do
849
- expect(selection.selector).to eq({
850
- "users" => { "$exists" => true }
851
- })
852
- end
853
-
854
- it "returns a cloned query" do
855
- expect(selection).to_not equal(query)
856
- end
857
- end
858
-
859
- context "when provided a string" do
860
-
861
- let(:selection) do
862
- query.exists(users: "yes")
863
- end
864
-
865
- it "adds the $exists expression" do
866
- expect(selection.selector).to eq({
867
- "users" => { "$exists" => true }
868
- })
869
- end
870
-
871
- it "returns a cloned query" do
872
- expect(selection).to_not equal(query)
873
- end
874
- end
875
- end
876
-
877
- context "when providing multiple criteria" do
878
-
879
- context "when the fields differ" do
880
-
881
- context "when providing boolean values" do
882
-
883
- let(:selection) do
884
- query.exists(
885
- users: true,
886
- comments: true
887
- )
888
- end
889
-
890
- it "adds the $exists expression" do
891
- expect(selection.selector).to eq({
892
- "users" => { "$exists" => true },
893
- "comments" => { "$exists" => true }
894
- })
895
- end
896
-
897
- it "returns a cloned query" do
898
- expect(selection).to_not equal(query)
899
- end
900
- end
901
-
902
- context "when providing string values" do
903
-
904
- let(:selection) do
905
- query.exists(
906
- users: "y",
907
- comments: "true"
908
- )
909
- end
910
-
911
- it "adds the $exists expression" do
912
- expect(selection.selector).to eq({
913
- "users" => { "$exists" => true },
914
- "comments" => { "$exists" => true }
915
- })
916
- end
917
-
918
- it "returns a cloned query" do
919
- expect(selection).to_not equal(query)
920
- end
921
- end
922
- end
923
- end
924
-
925
- context "when chaining multiple criteria" do
926
-
927
- context "when the fields differ" do
928
-
929
- let(:selection) do
930
- query.
931
- exists(users: true).
932
- exists(comments: true)
933
- end
934
-
935
- it "adds the $exists expression" do
936
- expect(selection.selector).to eq({
937
- "users" => { "$exists" => true },
938
- "comments" => { "$exists" => true }
939
- })
940
- end
941
-
942
- it "returns a cloned query" do
943
- expect(selection).to_not equal(query)
944
- end
945
- end
946
- end
947
- end
948
-
949
- describe "#geo_spacial" do
950
-
951
- context "when provided no criterion" do
952
-
953
- let(:selection) do
954
- query.geo_spacial
955
- end
956
-
957
- it "does not add any criterion" do
958
- expect(selection.selector).to be_empty
959
- end
960
-
961
- it "returns the query" do
962
- expect(selection).to eq(query)
963
- end
964
-
965
- it_behaves_like "a cloning selection"
966
- end
967
-
968
- context "when provided nil" do
969
-
970
- let(:selection) do
971
- query.geo_spacial(nil)
972
- end
973
-
974
- it "does not add any criterion" do
975
- expect(selection.selector).to be_empty
976
- end
977
-
978
- it "returns the query" do
979
- expect(selection).to eq(query)
980
- end
981
-
982
- it_behaves_like "a cloning selection"
983
- end
984
-
985
- context "when provided a criterion" do
986
-
987
- context "when the geometry is a point intersection" do
988
-
989
- let(:selection) do
990
- query.geo_spacial(:location.intersects_point => [ 1, 10 ])
991
- end
992
-
993
- it "adds the $geoIntersects expression" do
994
- expect(selection.selector).to eq({
995
- "location" => {
996
- "$geoIntersects" => {
997
- "$geometry" => {
998
- "type" => "Point",
999
- "coordinates" => [ 1, 10 ]
1000
- }
1001
- }
1002
- }
1003
- })
1004
- end
1005
-
1006
- it_behaves_like "a cloning selection"
1007
- end
1008
-
1009
- context "when the geometry is a line intersection" do
1010
-
1011
- let(:selection) do
1012
- query.geo_spacial(:location.intersects_line => [[ 1, 10 ], [ 2, 10 ]])
1013
- end
1014
-
1015
- it "adds the $geoIntersects expression" do
1016
- expect(selection.selector).to eq({
1017
- "location" => {
1018
- "$geoIntersects" => {
1019
- "$geometry" => {
1020
- "type" => "LineString",
1021
- "coordinates" => [[ 1, 10 ], [ 2, 10 ]]
1022
- }
1023
- }
1024
- }
1025
- })
1026
- end
1027
-
1028
- it_behaves_like "a cloning selection"
1029
- end
1030
-
1031
- context "when the geometry is a polygon intersection" do
1032
-
1033
- let(:selection) do
1034
- query.geo_spacial(
1035
- :location.intersects_polygon => [[[ 1, 10 ], [ 2, 10 ], [ 1, 10 ]]]
1036
- )
1037
- end
1038
-
1039
- it "adds the $geoIntersects expression" do
1040
- expect(selection.selector).to eq({
1041
- "location" => {
1042
- "$geoIntersects" => {
1043
- "$geometry" => {
1044
- "type" => "Polygon",
1045
- "coordinates" => [[[ 1, 10 ], [ 2, 10 ], [ 1, 10 ]]]
1046
- }
1047
- }
1048
- }
1049
- })
1050
- end
1051
-
1052
- it_behaves_like "a cloning selection"
1053
- end
1054
-
1055
- context "when the geometry is within a polygon" do
1056
-
1057
- let(:selection) do
1058
- query.geo_spacial(
1059
- :location.within_polygon => [[[ 1, 10 ], [ 2, 10 ], [ 1, 10 ]]]
1060
- )
1061
- end
1062
-
1063
- it "adds the $geoIntersects expression" do
1064
- expect(selection.selector).to eq({
1065
- "location" => {
1066
- "$geoWithin" => {
1067
- "$geometry" => {
1068
- "type" => "Polygon",
1069
- "coordinates" => [[[ 1, 10 ], [ 2, 10 ], [ 1, 10 ]]]
1070
- }
1071
- }
1072
- }
1073
- })
1074
- end
1075
-
1076
- context "when used with the $box operator ($geoWithin query) " do
1077
- let(:selection) do
1078
- query.geo_spacial(
1079
- :location.within_box => [[ 1, 10 ], [ 2, 10 ]]
1080
- )
1081
- end
1082
-
1083
- it "adds the $geoIntersects expression" do
1084
- expect(selection.selector).to eq({
1085
- "location" => {
1086
- "$geoWithin" => {
1087
- "$box" => [
1088
- [ 1, 10 ], [ 2, 10 ]
1089
- ]
1090
- }
1091
- }
1092
- })
1093
- end
1094
- end
1095
-
1096
- it_behaves_like "a cloning selection"
1097
- end
1098
- end
1099
- end
1100
-
1101
- describe "#gt" do
1102
-
1103
- context "when provided no criterion" do
1104
-
1105
- let(:selection) do
1106
- query.gt
1107
- end
1108
-
1109
- it "does not add any criterion" do
1110
- expect(selection.selector).to eq({})
1111
- end
1112
-
1113
- it "returns the query" do
1114
- expect(selection).to eq(query)
1115
- end
1116
-
1117
- it "returns a cloned query" do
1118
- expect(selection).to_not equal(query)
1119
- end
1120
- end
1121
-
1122
- context "when provided nil" do
1123
-
1124
- let(:selection) do
1125
- query.gt(nil)
1126
- end
1127
-
1128
- it "does not add any criterion" do
1129
- expect(selection.selector).to eq({})
1130
- end
1131
-
1132
- it "returns the query" do
1133
- expect(selection).to eq(query)
1134
- end
1135
-
1136
- it "returns a cloned query" do
1137
- expect(selection).to_not equal(query)
1138
- end
1139
- end
1140
-
1141
- context "when provided a single criterion" do
1142
-
1143
- let(:selection) do
1144
- query.gt(field: 10)
1145
- end
1146
-
1147
- it "adds the $gt selector" do
1148
- expect(selection.selector).to eq({
1149
- "field" => { "$gt" => 10 }
1150
- })
1151
- end
1152
-
1153
- it "returns a cloned query" do
1154
- expect(selection).to_not equal(query)
1155
- end
1156
- end
1157
-
1158
- context "when provided multiple criterion" do
1159
-
1160
- context "when the criterion are for different fields" do
1161
-
1162
- let(:selection) do
1163
- query.gt(first: 10, second: 15)
1164
- end
1165
-
1166
- it "adds the $gt selectors" do
1167
- expect(selection.selector).to eq({
1168
- "first" => { "$gt" => 10 },
1169
- "second" => { "$gt" => 15 }
1170
- })
1171
- end
1172
-
1173
- it "returns a cloned query" do
1174
- expect(selection).to_not equal(query)
1175
- end
1176
- end
1177
- end
1178
-
1179
- context "when chaining the criterion" do
1180
-
1181
- context "when the criterion are for different fields" do
1182
-
1183
- let(:selection) do
1184
- query.gt(first: 10).gt(second: 15)
1185
- end
1186
-
1187
- it "adds the $gt selectors" do
1188
- expect(selection.selector).to eq({
1189
- "first" => { "$gt" => 10 },
1190
- "second" => { "$gt" => 15 }
1191
- })
1192
- end
1193
-
1194
- it "returns a cloned query" do
1195
- expect(selection).to_not equal(query)
1196
- end
1197
- end
1198
-
1199
- context "when the criterion are on the same field" do
1200
-
1201
- let(:selection) do
1202
- query.gt(first: 10).gt(first: 15)
1203
- end
1204
-
1205
- it "overwrites the first $gt selector" do
1206
- expect(selection.selector).to eq({
1207
- "first" => { "$gt" => 15 }
1208
- })
1209
- end
1210
-
1211
- it "returns a cloned query" do
1212
- expect(selection).to_not equal(query)
1213
- end
1214
- end
1215
- end
1216
- end
1217
-
1218
- describe "#gte" do
1219
-
1220
- context "when provided no criterion" do
1221
-
1222
- let(:selection) do
1223
- query.gte
1224
- end
1225
-
1226
- it "does not add any criterion" do
1227
- expect(selection.selector).to eq({})
1228
- end
1229
-
1230
- it "returns the query" do
1231
- expect(selection).to eq(query)
1232
- end
1233
-
1234
- it "returns a cloned query" do
1235
- expect(selection).to_not equal(query)
1236
- end
1237
- end
1238
-
1239
- context "when provided nil" do
1240
-
1241
- let(:selection) do
1242
- query.gte(nil)
1243
- end
1244
-
1245
- it "does not add any criterion" do
1246
- expect(selection.selector).to eq({})
1247
- end
1248
-
1249
- it "returns the query" do
1250
- expect(selection).to eq(query)
1251
- end
1252
-
1253
- it "returns a cloned query" do
1254
- expect(selection).to_not equal(query)
1255
- end
1256
- end
1257
-
1258
- context "when provided a single criterion" do
1259
-
1260
- let(:selection) do
1261
- query.gte(field: 10)
1262
- end
1263
-
1264
- it "adds the $gte selector" do
1265
- expect(selection.selector).to eq({
1266
- "field" => { "$gte" => 10 }
1267
- })
1268
- end
1269
-
1270
- it "returns a cloned query" do
1271
- expect(selection).to_not equal(query)
1272
- end
1273
- end
1274
-
1275
- context "when provided multiple criterion" do
1276
-
1277
- context "when the criterion are for different fields" do
1278
-
1279
- let(:selection) do
1280
- query.gte(first: 10, second: 15)
1281
- end
1282
-
1283
- it "adds the $gte selectors" do
1284
- expect(selection.selector).to eq({
1285
- "first" => { "$gte" => 10 },
1286
- "second" => { "$gte" => 15 }
1287
- })
1288
- end
1289
-
1290
- it "returns a cloned query" do
1291
- expect(selection).to_not equal(query)
1292
- end
1293
- end
1294
- end
1295
-
1296
- context "when chaining the criterion" do
1297
-
1298
- context "when the criterion are for different fields" do
1299
-
1300
- let(:selection) do
1301
- query.gte(first: 10).gte(second: 15)
1302
- end
1303
-
1304
- it "adds the $gte selectors" do
1305
- expect(selection.selector).to eq({
1306
- "first" => { "$gte" => 10 },
1307
- "second" => { "$gte" => 15 }
1308
- })
1309
- end
1310
-
1311
- it "returns a cloned query" do
1312
- expect(selection).to_not equal(query)
1313
- end
1314
- end
1315
-
1316
- context "when the criterion are on the same field" do
1317
-
1318
- let(:selection) do
1319
- query.gte(first: 10).gte(first: 15)
1320
- end
1321
-
1322
- it "overwrites the first $gte selector" do
1323
- expect(selection.selector).to eq({
1324
- "first" => { "$gte" => 15 }
1325
- })
1326
- end
1327
-
1328
- it "returns a cloned query" do
1329
- expect(selection).to_not equal(query)
1330
- end
1331
- end
1332
- end
1333
- end
1334
-
1335
- describe "#in" do
1336
-
1337
- context "when provided no criterion" do
1338
-
1339
- let(:selection) do
1340
- query.in
1341
- end
1342
-
1343
- it "does not add any criterion" do
1344
- expect(selection.selector).to eq({})
1345
- end
1346
-
1347
- it "returns the query" do
1348
- expect(selection).to eq(query)
1349
- end
1350
-
1351
- it "returns a cloned query" do
1352
- expect(selection).to_not equal(query)
1353
- end
1354
- end
1355
-
1356
- context "when provided nil" do
1357
-
1358
- let(:selection) do
1359
- query.in(nil)
1360
- end
1361
-
1362
- it "does not add any criterion" do
1363
- expect(selection.selector).to eq({})
1364
- end
1365
-
1366
- it "returns the query" do
1367
- expect(selection).to eq(query)
1368
- end
1369
-
1370
- it "returns a cloned query" do
1371
- expect(selection).to_not equal(query)
1372
- end
1373
- end
1374
-
1375
- context "when provided a single criterion" do
1376
-
1377
- context "when providing an array" do
1378
-
1379
- let(:selection) do
1380
- query.in(field: [ 1, 2 ])
1381
- end
1382
-
1383
- it "adds the $in selector" do
1384
- expect(selection.selector).to eq({
1385
- "field" => { "$in" => [ 1, 2 ] }
1386
- })
1387
- end
1388
-
1389
- it "returns a cloned query" do
1390
- expect(selection).to_not equal(query)
1391
- end
1392
- end
1393
-
1394
- context "when providing a range" do
1395
-
1396
- let(:selection) do
1397
- query.in(field: 1..3)
1398
- end
1399
-
1400
- it "adds the $in selector with converted range" do
1401
- expect(selection.selector).to eq({
1402
- "field" => { "$in" => [ 1, 2, 3 ] }
1403
- })
1404
- end
1405
-
1406
- it "returns a cloned query" do
1407
- expect(selection).to_not equal(query)
1408
- end
1409
- end
1410
-
1411
- context "when providing a single value" do
1412
-
1413
- let(:selection) do
1414
- query.in(field: 1)
1415
- end
1416
-
1417
- it "adds the $in selector with wrapped value" do
1418
- expect(selection.selector).to eq({
1419
- "field" => { "$in" => [ 1 ] }
1420
- })
1421
- end
1422
-
1423
- it "returns a cloned query" do
1424
- expect(selection).to_not equal(query)
1425
- end
1426
- end
1427
- end
1428
-
1429
- context "when provided multiple criterion" do
1430
-
1431
- context "when the criterion are for different fields" do
1432
-
1433
- let(:selection) do
1434
- query.in(first: [ 1, 2 ], second: 3..4)
1435
- end
1436
-
1437
- it "adds the $in selectors" do
1438
- expect(selection.selector).to eq({
1439
- "first" => { "$in" => [ 1, 2 ] },
1440
- "second" => { "$in" => [ 3, 4 ] }
1441
- })
1442
- end
1443
-
1444
- it "returns a cloned query" do
1445
- expect(selection).to_not equal(query)
1446
- end
1447
- end
1448
- end
1449
-
1450
- context "when chaining the criterion" do
1451
-
1452
- context "when the criterion are for different fields" do
1453
-
1454
- let(:selection) do
1455
- query.in(first: [ 1, 2 ]).in(second: [ 3, 4 ])
1456
- end
1457
-
1458
- it "adds the $in selectors" do
1459
- expect(selection.selector).to eq({
1460
- "first" => { "$in" => [ 1, 2 ] },
1461
- "second" => { "$in" => [ 3, 4 ] }
1462
- })
1463
- end
1464
-
1465
- it "returns a cloned query" do
1466
- expect(selection).to_not equal(query)
1467
- end
1468
- end
1469
-
1470
- context "when the criterion are on the same field" do
1471
-
1472
- context "when the strategy is the default (intersection)" do
1473
-
1474
- let(:selection) do
1475
- query.in(first: [ 1, 2 ].freeze).in(first: [ 2, 3 ])
1476
- end
1477
-
1478
- it "intersects the $in selectors" do
1479
- expect(selection.selector).to eq({
1480
- "first" => { "$in" => [ 2 ] }
1481
- })
1482
- end
1483
-
1484
- it "returns a cloned query" do
1485
- expect(selection).to_not equal(query)
1486
- end
1487
- end
1488
-
1489
- context 'when the field is aliased' do
1490
-
1491
- before(:all) do
1492
- class TestModel
1493
- include Mongoid::Document
1494
- end
1495
- end
1496
-
1497
- after(:all) do
1498
- Object.send(:remove_const, :TestModel)
1499
- end
1500
-
1501
- let(:bson_object_id) do
1502
- BSON::ObjectId.new
1503
- end
1504
-
1505
- let(:selection) do
1506
- TestModel.in(id: [bson_object_id.to_s]).in(id: [bson_object_id.to_s])
1507
- end
1508
-
1509
- it "intersects the $in selectors" do
1510
- expect(selection.selector).to eq("_id" => { "$in" => [ bson_object_id ] })
1511
- end
1512
-
1513
- it "returns a cloned query" do
1514
- expect(selection).to_not equal(query)
1515
- end
1516
- end
1517
-
1518
- context "when the stretegy is intersect" do
1519
-
1520
- let(:selection) do
1521
- query.in(first: [ 1, 2 ]).intersect.in(first: [ 2, 3 ])
1522
- end
1523
-
1524
- it "intersects the $in selectors" do
1525
- expect(selection.selector).to eq({
1526
- "first" => { "$in" => [ 2 ] }
1527
- })
1528
- end
1529
-
1530
- it "returns a cloned query" do
1531
- expect(selection).to_not equal(query)
1532
- end
1533
- end
1534
-
1535
- context "when the strategy is override" do
1536
-
1537
- let(:selection) do
1538
- query.in(first: [ 1, 2 ]).override.in(first: [ 3, 4 ])
1539
- end
1540
-
1541
- it "overwrites the first $in selector" do
1542
- expect(selection.selector).to eq({
1543
- "first" => { "$in" => [ 3, 4 ] }
1544
- })
1545
- end
1546
-
1547
- it "returns a cloned query" do
1548
- expect(selection).to_not equal(query)
1549
- end
1550
- end
1551
-
1552
- context "when the strategy is union" do
1553
-
1554
- let(:selection) do
1555
- query.in(first: [ 1, 2 ]).union.in(first: [ 3, 4 ])
1556
- end
1557
-
1558
- it "unions the $in selectors" do
1559
- expect(selection.selector).to eq({
1560
- "first" => { "$in" => [ 1, 2, 3, 4 ] }
1561
- })
1562
- end
1563
-
1564
- it "returns a cloned query" do
1565
- expect(selection).to_not equal(query)
1566
- end
1567
- end
1568
- end
1569
- end
1570
- end
1571
-
1572
- describe "#lt" do
1573
-
1574
- context "when provided no criterion" do
1575
-
1576
- let(:selection) do
1577
- query.lt
1578
- end
1579
-
1580
- it "does not add any criterion" do
1581
- expect(selection.selector).to eq({})
1582
- end
1583
-
1584
- it "returns the query" do
1585
- expect(selection).to eq(query)
1586
- end
1587
-
1588
- it "returns a cloned query" do
1589
- expect(selection).to_not equal(query)
1590
- end
1591
- end
1592
-
1593
- context "when provided nil" do
1594
-
1595
- let(:selection) do
1596
- query.lt(nil)
1597
- end
1598
-
1599
- it "does not add any criterion" do
1600
- expect(selection.selector).to eq({})
1601
- end
1602
-
1603
- it "returns the query" do
1604
- expect(selection).to eq(query)
1605
- end
1606
-
1607
- it "returns a cloned query" do
1608
- expect(selection).to_not equal(query)
1609
- end
1610
- end
1611
-
1612
- context "when provided a single criterion" do
1613
-
1614
- let(:selection) do
1615
- query.lt(field: 10)
1616
- end
1617
-
1618
- it "adds the $lt selector" do
1619
- expect(selection.selector).to eq({
1620
- "field" => { "$lt" => 10 }
1621
- })
1622
- end
1623
-
1624
- it "returns a cloned query" do
1625
- expect(selection).to_not equal(query)
1626
- end
1627
- end
1628
-
1629
- context "when provided multiple criterion" do
1630
-
1631
- context "when the criterion are for different fields" do
1632
-
1633
- let(:selection) do
1634
- query.lt(first: 10, second: 15)
1635
- end
1636
-
1637
- it "adds the $lt selectors" do
1638
- expect(selection.selector).to eq({
1639
- "first" => { "$lt" => 10 },
1640
- "second" => { "$lt" => 15 }
1641
- })
1642
- end
1643
-
1644
- it "returns a cloned query" do
1645
- expect(selection).to_not equal(query)
1646
- end
1647
- end
1648
- end
1649
-
1650
- context "when chaining the criterion" do
1651
-
1652
- context "when the criterion are for different fields" do
1653
-
1654
- let(:selection) do
1655
- query.lt(first: 10).lt(second: 15)
1656
- end
1657
-
1658
- it "adds the $lt selectors" do
1659
- expect(selection.selector).to eq({
1660
- "first" => { "$lt" => 10 },
1661
- "second" => { "$lt" => 15 }
1662
- })
1663
- end
1664
-
1665
- it "returns a cloned query" do
1666
- expect(selection).to_not equal(query)
1667
- end
1668
- end
1669
-
1670
- context "when the criterion are on the same field" do
1671
-
1672
- let(:selection) do
1673
- query.lt(first: 10).lt(first: 15)
1674
- end
1675
-
1676
- it "overwrites the first $lt selector" do
1677
- expect(selection.selector).to eq({
1678
- "first" => { "$lt" => 15 }
1679
- })
1680
- end
1681
-
1682
- it "returns a cloned query" do
1683
- expect(selection).to_not equal(query)
1684
- end
1685
- end
1686
- end
1687
- end
1688
-
1689
- describe "#lte" do
1690
-
1691
- context "when provided no criterion" do
1692
-
1693
- let(:selection) do
1694
- query.lte
1695
- end
1696
-
1697
- it "does not add any criterion" do
1698
- expect(selection.selector).to eq({})
1699
- end
1700
-
1701
- it "returns the query" do
1702
- expect(selection).to eq(query)
1703
- end
1704
-
1705
- it "returns a cloned query" do
1706
- expect(selection).to_not equal(query)
1707
- end
1708
- end
1709
-
1710
- context "when provided nil" do
1711
-
1712
- let(:selection) do
1713
- query.lte(nil)
1714
- end
1715
-
1716
- it "does not add any criterion" do
1717
- expect(selection.selector).to eq({})
1718
- end
1719
-
1720
- it "returns the query" do
1721
- expect(selection).to eq(query)
1722
- end
1723
-
1724
- it "returns a cloned query" do
1725
- expect(selection).to_not equal(query)
1726
- end
1727
- end
1728
-
1729
- context "when provided a single criterion" do
1730
-
1731
- let(:selection) do
1732
- query.lte(field: 10)
1733
- end
1734
-
1735
- it "adds the $lte selector" do
1736
- expect(selection.selector).to eq({
1737
- "field" => { "$lte" => 10 }
1738
- })
1739
- end
1740
-
1741
- it "returns a cloned query" do
1742
- expect(selection).to_not equal(query)
1743
- end
1744
- end
1745
-
1746
- context "when provided multiple criterion" do
1747
-
1748
- context "when the criterion are for different fields" do
1749
-
1750
- let(:selection) do
1751
- query.lte(first: 10, second: 15)
1752
- end
1753
-
1754
- it "adds the $lte selectors" do
1755
- expect(selection.selector).to eq({
1756
- "first" => { "$lte" => 10 },
1757
- "second" => { "$lte" => 15 }
1758
- })
1759
- end
1760
-
1761
- it "returns a cloned query" do
1762
- expect(selection).to_not equal(query)
1763
- end
1764
- end
1765
- end
1766
-
1767
- context "when chaining the criterion" do
1768
-
1769
- context "when the criterion are for different fields" do
1770
-
1771
- let(:selection) do
1772
- query.lte(first: 10).lte(second: 15)
1773
- end
1774
-
1775
- it "adds the $lte selectors" do
1776
- expect(selection.selector).to eq({
1777
- "first" => { "$lte" => 10 },
1778
- "second" => { "$lte" => 15 }
1779
- })
1780
- end
1781
-
1782
- it "returns a cloned query" do
1783
- expect(selection).to_not equal(query)
1784
- end
1785
- end
1786
-
1787
- context "when the criterion are on the same field" do
1788
-
1789
- let(:selection) do
1790
- query.lte(first: 10).lte(first: 15)
1791
- end
1792
-
1793
- it "overwrites the first $lte selector" do
1794
- expect(selection.selector).to eq({
1795
- "first" => { "$lte" => 15 }
1796
- })
1797
- end
1798
-
1799
- it "returns a cloned query" do
1800
- expect(selection).to_not equal(query)
1801
- end
1802
- end
1803
- end
1804
- end
1805
-
1806
- describe "#max_distance" do
1807
-
1808
- context "when provided no criterion" do
1809
-
1810
- let(:selection) do
1811
- query.max_distance
1812
- end
1813
-
1814
- it "does not add any criterion" do
1815
- expect(selection.selector).to eq({})
1816
- end
1817
-
1818
- it "returns the query" do
1819
- expect(selection).to eq(query)
1820
- end
1821
-
1822
- it "returns a cloned query" do
1823
- expect(selection).to_not equal(query)
1824
- end
1825
- end
1826
-
1827
- context "when provided nil" do
1828
-
1829
- let(:selection) do
1830
- query.max_distance(nil)
1831
- end
1832
-
1833
- it "does not add any criterion" do
1834
- expect(selection.selector).to eq({})
1835
- end
1836
-
1837
- it "returns the query" do
1838
- expect(selection).to eq(query)
1839
- end
1840
-
1841
- it "returns a cloned query" do
1842
- expect(selection).to_not equal(query)
1843
- end
1844
- end
1845
-
1846
- context "when provided a criterion" do
1847
-
1848
- context "when a $near criterion exists on the same field" do
1849
-
1850
- let(:selection) do
1851
- query.near(location: [ 1, 1 ]).max_distance(location: 50)
1852
- end
1853
-
1854
- it "adds the $maxDistance expression" do
1855
- expect(selection.selector).to eq({
1856
- "location" => { "$near" => [ 1, 1 ], "$maxDistance" => 50 }
1857
- })
1858
- end
1859
-
1860
- it "returns a cloned query" do
1861
- expect(selection).to_not equal(query)
1862
- end
1863
- end
1864
- end
1865
- end
1866
-
1867
- describe "#mod" do
1868
-
1869
- context "when provided no criterion" do
1870
-
1871
- let(:selection) do
1872
- query.mod
1873
- end
1874
-
1875
- it "does not add any criterion" do
1876
- expect(selection.selector).to eq({})
1877
- end
1878
-
1879
- it "returns the query" do
1880
- expect(selection).to eq(query)
1881
- end
1882
-
1883
- it "returns a cloned query" do
1884
- expect(selection).to_not equal(query)
1885
- end
1886
- end
1887
-
1888
- context "when provided nil" do
1889
-
1890
- let(:selection) do
1891
- query.mod(nil)
1892
- end
1893
-
1894
- it "does not add any criterion" do
1895
- expect(selection.selector).to eq({})
1896
- end
1897
-
1898
- it "returns the query" do
1899
- expect(selection).to eq(query)
1900
- end
1901
-
1902
- it "returns a cloned query" do
1903
- expect(selection).to_not equal(query)
1904
- end
1905
- end
1906
-
1907
- context "when provided a criterion" do
1908
-
1909
- let(:selection) do
1910
- query.mod(value: [ 10, 1 ])
1911
- end
1912
-
1913
- it "adds the $mod expression" do
1914
- expect(selection.selector).to eq({
1915
- "value" => { "$mod" => [ 10, 1 ] }
1916
- })
1917
- end
1918
-
1919
- it "returns a cloned query" do
1920
- expect(selection).to_not equal(query)
1921
- end
1922
- end
1923
-
1924
- context "when providing multiple criteria" do
1925
-
1926
- context "when the fields differ" do
1927
-
1928
- let(:selection) do
1929
- query.mod(
1930
- value: [ 10, 1 ],
1931
- comments: [ 10, 1 ]
1932
- )
1933
- end
1934
-
1935
- it "adds the $mod expression" do
1936
- expect(selection.selector).to eq({
1937
- "value" => { "$mod" => [ 10, 1 ] },
1938
- "comments" => { "$mod" => [ 10, 1 ] }
1939
- })
1940
- end
1941
-
1942
- it "returns a cloned query" do
1943
- expect(selection).to_not equal(query)
1944
- end
1945
- end
1946
- end
1947
-
1948
- context "when chaining multiple criteria" do
1949
-
1950
- context "when the fields differ" do
1951
-
1952
- let(:selection) do
1953
- query.
1954
- mod(value: [ 10, 1 ]).
1955
- mod(result: [ 10, 1 ])
1956
- end
1957
-
1958
- it "adds the $mod expression" do
1959
- expect(selection.selector).to eq({
1960
- "value" => { "$mod" => [ 10, 1 ] },
1961
- "result" => { "$mod" => [ 10, 1 ] }
1962
- })
1963
- end
1964
-
1965
- it "returns a cloned query" do
1966
- expect(selection).to_not equal(query)
1967
- end
1968
- end
1969
- end
1970
- end
1971
-
1972
- describe "#ne" do
1973
-
1974
- context "when provided no criterion" do
1975
-
1976
- let(:selection) do
1977
- query.ne
1978
- end
1979
-
1980
- it "does not add any criterion" do
1981
- expect(selection.selector).to eq({})
1982
- end
1983
-
1984
- it "returns the query" do
1985
- expect(selection).to eq(query)
1986
- end
1987
-
1988
- it "returns a cloned query" do
1989
- expect(selection).to_not equal(query)
1990
- end
1991
- end
1992
-
1993
- context "when provided nil" do
1994
-
1995
- let(:selection) do
1996
- query.ne(nil)
1997
- end
1998
-
1999
- it "does not add any criterion" do
2000
- expect(selection.selector).to eq({})
2001
- end
2002
-
2003
- it "returns the query" do
2004
- expect(selection).to eq(query)
2005
- end
2006
-
2007
- it "returns a cloned query" do
2008
- expect(selection).to_not equal(query)
2009
- end
2010
- end
2011
-
2012
- context "when provided a criterion" do
2013
-
2014
- let(:selection) do
2015
- query.ne(value: 10)
2016
- end
2017
-
2018
- it "adds the $ne expression" do
2019
- expect(selection.selector).to eq({
2020
- "value" => { "$ne" => 10 }
2021
- })
2022
- end
2023
-
2024
- it "returns a cloned query" do
2025
- expect(selection).to_not equal(query)
2026
- end
2027
- end
2028
-
2029
- context "when providing multiple criteria" do
2030
-
2031
- context "when the fields differ" do
2032
-
2033
- let(:selection) do
2034
- query.ne(
2035
- value: 10,
2036
- comments: 10
2037
- )
2038
- end
2039
-
2040
- it "adds the $ne expression" do
2041
- expect(selection.selector).to eq({
2042
- "value" => { "$ne" => 10 },
2043
- "comments" => { "$ne" => 10 }
2044
- })
2045
- end
2046
-
2047
- it "returns a cloned query" do
2048
- expect(selection).to_not equal(query)
2049
- end
2050
- end
2051
- end
2052
-
2053
- context "when chaining multiple criteria" do
2054
-
2055
- context "when the fields differ" do
2056
-
2057
- let(:selection) do
2058
- query.
2059
- ne(value: 10).
2060
- ne(result: 10)
2061
- end
2062
-
2063
- it "adds the $ne expression" do
2064
- expect(selection.selector).to eq({
2065
- "value" => { "$ne" => 10 },
2066
- "result" => { "$ne" => 10 }
2067
- })
2068
- end
2069
-
2070
- it "returns a cloned query" do
2071
- expect(selection).to_not equal(query)
2072
- end
2073
- end
2074
- end
2075
- end
2076
-
2077
- describe "#near" do
2078
-
2079
- context "when provided no criterion" do
2080
-
2081
- let(:selection) do
2082
- query.near
2083
- end
2084
-
2085
- it "does not add any criterion" do
2086
- expect(selection.selector).to eq({})
2087
- end
2088
-
2089
- it "returns the query" do
2090
- expect(selection).to eq(query)
2091
- end
2092
-
2093
- it "returns a cloned query" do
2094
- expect(selection).to_not equal(query)
2095
- end
2096
- end
2097
-
2098
- context "when provided nil" do
2099
-
2100
- let(:selection) do
2101
- query.near(nil)
2102
- end
2103
-
2104
- it "does not add any criterion" do
2105
- expect(selection.selector).to eq({})
2106
- end
2107
-
2108
- it "returns the query" do
2109
- expect(selection).to eq(query)
2110
- end
2111
-
2112
- it "returns a cloned query" do
2113
- expect(selection).to_not equal(query)
2114
- end
2115
- end
2116
-
2117
- context "when provided a criterion" do
2118
-
2119
- let(:selection) do
2120
- query.near(location: [ 20, 21 ])
2121
- end
2122
-
2123
- it "adds the $near expression" do
2124
- expect(selection.selector).to eq({
2125
- "location" => { "$near" => [ 20, 21 ] }
2126
- })
2127
- end
2128
-
2129
- it "returns a cloned query" do
2130
- expect(selection).to_not equal(query)
2131
- end
2132
- end
2133
-
2134
- context "when providing multiple criteria" do
2135
-
2136
- context "when the fields differ" do
2137
-
2138
- let(:selection) do
2139
- query.near(
2140
- location: [ 20, 21 ],
2141
- comments: [ 20, 21 ]
2142
- )
2143
- end
2144
-
2145
- it "adds the $near expression" do
2146
- expect(selection.selector).to eq({
2147
- "location" => { "$near" => [ 20, 21 ] },
2148
- "comments" => { "$near" => [ 20, 21 ] }
2149
- })
2150
- end
2151
-
2152
- it "returns a cloned query" do
2153
- expect(selection).to_not equal(query)
2154
- end
2155
- end
2156
- end
2157
-
2158
- context "when chaining multiple criteria" do
2159
-
2160
- context "when the fields differ" do
2161
-
2162
- let(:selection) do
2163
- query.
2164
- near(location: [ 20, 21 ]).
2165
- near(comments: [ 20, 21 ])
2166
- end
2167
-
2168
- it "adds the $near expression" do
2169
- expect(selection.selector).to eq({
2170
- "location" => { "$near" => [ 20, 21 ] },
2171
- "comments" => { "$near" => [ 20, 21 ] }
2172
- })
2173
- end
2174
-
2175
- it "returns a cloned query" do
2176
- expect(selection).to_not equal(query)
2177
- end
2178
- end
2179
- end
2180
- end
2181
-
2182
- describe "#near_sphere" do
2183
-
2184
- context "when provided no criterion" do
2185
-
2186
- let(:selection) do
2187
- query.near_sphere
2188
- end
2189
-
2190
- it "does not add any criterion" do
2191
- expect(selection.selector).to eq({})
2192
- end
2193
-
2194
- it "returns the query" do
2195
- expect(selection).to eq(query)
2196
- end
2197
-
2198
- it "returns a cloned query" do
2199
- expect(selection).to_not equal(query)
2200
- end
2201
- end
2202
-
2203
- context "when provided nil" do
2204
-
2205
- let(:selection) do
2206
- query.near_sphere(nil)
2207
- end
2208
-
2209
- it "does not add any criterion" do
2210
- expect(selection.selector).to eq({})
2211
- end
2212
-
2213
- it "returns the query" do
2214
- expect(selection).to eq(query)
2215
- end
2216
-
2217
- it "returns a cloned query" do
2218
- expect(selection).to_not equal(query)
2219
- end
2220
- end
2221
-
2222
- context "when provided a criterion" do
2223
-
2224
- let(:selection) do
2225
- query.near_sphere(location: [ 20, 21 ])
2226
- end
2227
-
2228
- it "adds the $nearSphere expression" do
2229
- expect(selection.selector).to eq({
2230
- "location" => { "$nearSphere" => [ 20, 21 ] }
2231
- })
2232
- end
2233
-
2234
- it "returns a cloned query" do
2235
- expect(selection).to_not equal(query)
2236
- end
2237
- end
2238
-
2239
- context "when providing multiple criteria" do
2240
-
2241
- context "when the fields differ" do
2242
-
2243
- let(:selection) do
2244
- query.near_sphere(
2245
- location: [ 20, 21 ],
2246
- comments: [ 20, 21 ]
2247
- )
2248
- end
2249
-
2250
- it "adds the $nearSphere expression" do
2251
- expect(selection.selector).to eq({
2252
- "location" => { "$nearSphere" => [ 20, 21 ] },
2253
- "comments" => { "$nearSphere" => [ 20, 21 ] }
2254
- })
2255
- end
2256
-
2257
- it "returns a cloned query" do
2258
- expect(selection).to_not equal(query)
2259
- end
2260
- end
2261
- end
2262
-
2263
- context "when chaining multiple criteria" do
2264
-
2265
- context "when the fields differ" do
2266
-
2267
- let(:selection) do
2268
- query.
2269
- near_sphere(location: [ 20, 21 ]).
2270
- near_sphere(comments: [ 20, 21 ])
2271
- end
2272
-
2273
- it "adds the $nearSphere expression" do
2274
- expect(selection.selector).to eq({
2275
- "location" => { "$nearSphere" => [ 20, 21 ] },
2276
- "comments" => { "$nearSphere" => [ 20, 21 ] }
2277
- })
2278
- end
773
+ it "adds the $geoIntersects expression" do
774
+ expect(selection.selector).to eq({
775
+ "location" => {
776
+ "$geoIntersects" => {
777
+ "$geometry" => {
778
+ "type" => "Point",
779
+ "coordinates" => [ 1, 10 ]
780
+ }
781
+ }
782
+ }
783
+ })
784
+ end
2279
785
 
2280
- it "returns a cloned query" do
2281
- expect(selection).to_not equal(query)
786
+ it_behaves_like "returns a cloned query"
2282
787
  end
2283
- end
2284
- end
2285
- end
2286
-
2287
- describe "#nin" do
2288
-
2289
- context "when provided no criterion" do
2290
-
2291
- let(:selection) do
2292
- query.nin
2293
- end
2294
-
2295
- it "does not add any criterion" do
2296
- expect(selection.selector).to eq({})
2297
- end
2298
-
2299
- it "returns the query" do
2300
- expect(selection).to eq(query)
2301
- end
2302
-
2303
- it "returns a cloned query" do
2304
- expect(selection).to_not equal(query)
2305
- end
2306
- end
2307
-
2308
- context "when provided nil" do
2309
-
2310
- let(:selection) do
2311
- query.nin(nil)
2312
- end
2313
-
2314
- it "does not add any criterion" do
2315
- expect(selection.selector).to eq({})
2316
- end
2317
-
2318
- it "returns the query" do
2319
- expect(selection).to eq(query)
2320
- end
2321
-
2322
- it "returns a cloned query" do
2323
- expect(selection).to_not equal(query)
2324
- end
2325
- end
2326
788
 
2327
- context "when provided a single criterion" do
789
+ context "when the geometry is a line intersection" do
2328
790
 
2329
- context "when providing an array" do
791
+ let(:selection) do
792
+ query.public_send(query_method, :location.intersects_line => [[ 1, 10 ], [ 2, 10 ]])
793
+ end
2330
794
 
2331
- let(:selection) do
2332
- query.nin(field: [ 1, 2 ])
2333
- end
795
+ it "adds the $geoIntersects expression" do
796
+ expect(selection.selector).to eq({
797
+ "location" => {
798
+ "$geoIntersects" => {
799
+ "$geometry" => {
800
+ "type" => "LineString",
801
+ "coordinates" => [[ 1, 10 ], [ 2, 10 ]]
802
+ }
803
+ }
804
+ }
805
+ })
806
+ end
2334
807
 
2335
- it "adds the $nin selector" do
2336
- expect(selection.selector).to eq({
2337
- "field" => { "$nin" => [ 1, 2 ] }
2338
- })
808
+ it_behaves_like "returns a cloned query"
2339
809
  end
2340
810
 
2341
- it "returns a cloned query" do
2342
- expect(selection).to_not equal(query)
2343
- end
2344
- end
811
+ context "when the geometry is a polygon intersection" do
2345
812
 
2346
- context "when providing a range" do
813
+ let(:selection) do
814
+ query.public_send(query_method,
815
+ :location.intersects_polygon => [[[ 1, 10 ], [ 2, 10 ], [ 1, 10 ]]]
816
+ )
817
+ end
2347
818
 
2348
- let(:selection) do
2349
- query.nin(field: 1..3)
2350
- end
819
+ it "adds the $geoIntersects expression" do
820
+ expect(selection.selector).to eq({
821
+ "location" => {
822
+ "$geoIntersects" => {
823
+ "$geometry" => {
824
+ "type" => "Polygon",
825
+ "coordinates" => [[[ 1, 10 ], [ 2, 10 ], [ 1, 10 ]]]
826
+ }
827
+ }
828
+ }
829
+ })
830
+ end
2351
831
 
2352
- it "adds the $nin selector with converted range" do
2353
- expect(selection.selector).to eq({
2354
- "field" => { "$nin" => [ 1, 2, 3 ] }
2355
- })
832
+ it_behaves_like "returns a cloned query"
2356
833
  end
2357
834
 
2358
- it "returns a cloned query" do
2359
- expect(selection).to_not equal(query)
2360
- end
2361
- end
835
+ context "when the geometry is within a polygon" do
2362
836
 
2363
- context "when providing a single value" do
837
+ let(:selection) do
838
+ query.public_send(query_method,
839
+ :location.within_polygon => [[[ 1, 10 ], [ 2, 10 ], [ 1, 10 ]]]
840
+ )
841
+ end
2364
842
 
2365
- let(:selection) do
2366
- query.nin(field: 1)
2367
- end
843
+ it "adds the $geoIntersects expression" do
844
+ expect(selection.selector).to eq({
845
+ "location" => {
846
+ "$geoWithin" => {
847
+ "$geometry" => {
848
+ "type" => "Polygon",
849
+ "coordinates" => [[[ 1, 10 ], [ 2, 10 ], [ 1, 10 ]]]
850
+ }
851
+ }
852
+ }
853
+ })
854
+ end
2368
855
 
2369
- it "adds the $nin selector with wrapped value" do
2370
- expect(selection.selector).to eq({
2371
- "field" => { "$nin" => [ 1 ] }
2372
- })
2373
- end
856
+ context "when used with the $box operator ($geoWithin query) " do
857
+ let(:selection) do
858
+ query.public_send(query_method,
859
+ :location.within_box => [[ 1, 10 ], [ 2, 10 ]]
860
+ )
861
+ end
2374
862
 
2375
- it "returns a cloned query" do
2376
- expect(selection).to_not equal(query)
863
+ it "adds the $geoIntersects expression" do
864
+ expect(selection.selector).to eq({
865
+ "location" => {
866
+ "$geoWithin" => {
867
+ "$box" => [
868
+ [ 1, 10 ], [ 2, 10 ]
869
+ ]
870
+ }
871
+ }
872
+ })
873
+ end
874
+ end
875
+
876
+ it_behaves_like "returns a cloned query"
2377
877
  end
2378
878
  end
2379
879
  end
880
+ end
2380
881
 
2381
- context "when unioning on the same field" do
882
+ describe "#gt" do
2382
883
 
2383
- context "when the field is not aliased" do
884
+ let(:query_method) { :gt }
2384
885
 
2385
- let(:selection) do
2386
- query.nin(first: [ 1, 2 ]).union.nin(first: [ 3, 4 ])
2387
- end
886
+ it_behaves_like 'requires an argument'
887
+ it_behaves_like 'requires a non-nil argument'
2388
888
 
2389
- it "unions the selection on the field" do
2390
- expect(selection.selector).to eq(
2391
- { "first" => { "$nin" => [ 1, 2, 3, 4 ]}}
2392
- )
2393
- end
2394
- end
889
+ context "when provided a single criterion" do
2395
890
 
2396
- context "when the field is aliased" do
891
+ let(:selection) do
892
+ query.gt(field: 10)
893
+ end
2397
894
 
2398
- let(:selection) do
2399
- query.nin(id: [ 1, 2 ]).union.nin(id: [ 3, 4 ])
2400
- end
895
+ it "adds the $gt selector" do
896
+ expect(selection.selector).to eq({
897
+ "field" => { "$gt" => 10 }
898
+ })
899
+ end
2401
900
 
2402
- it "unions the selection on the field" do
2403
- expect(selection.selector).to eq(
2404
- { "_id" => { "$nin" => [ 1, 2, 3, 4 ]}}
2405
- )
2406
- end
901
+ it "returns a cloned query" do
902
+ expect(selection).to_not equal(query)
2407
903
  end
2408
904
  end
2409
905
 
@@ -2412,13 +908,13 @@ describe Mongoid::Criteria::Queryable::Selectable do
2412
908
  context "when the criterion are for different fields" do
2413
909
 
2414
910
  let(:selection) do
2415
- query.nin(first: [ 1, 2 ], second: [ 3, 4 ])
911
+ query.gt(first: 10, second: 15)
2416
912
  end
2417
913
 
2418
- it "adds the $nin selectors" do
914
+ it "adds the $gt selectors" do
2419
915
  expect(selection.selector).to eq({
2420
- "first" => { "$nin" => [ 1, 2 ] },
2421
- "second" => { "$nin" => [ 3, 4 ] }
916
+ "first" => { "$gt" => 10 },
917
+ "second" => { "$gt" => 15 }
2422
918
  })
2423
919
  end
2424
920
 
@@ -2428,18 +924,18 @@ describe Mongoid::Criteria::Queryable::Selectable do
2428
924
  end
2429
925
  end
2430
926
 
2431
- context "when chaninning the criterion" do
927
+ context "when chaining the criterion" do
2432
928
 
2433
929
  context "when the criterion are for different fields" do
2434
930
 
2435
931
  let(:selection) do
2436
- query.nin(first: [ 1, 2 ]).nin(second: [ 3, 4 ])
932
+ query.gt(first: 10).gt(second: 15)
2437
933
  end
2438
934
 
2439
- it "adds the $nin selectors" do
935
+ it "adds the $gt selectors" do
2440
936
  expect(selection.selector).to eq({
2441
- "first" => { "$nin" => [ 1, 2 ] },
2442
- "second" => { "$nin" => [ 3, 4 ] }
937
+ "first" => { "$gt" => 10 },
938
+ "second" => { "$gt" => 15 }
2443
939
  })
2444
940
  end
2445
941
 
@@ -2450,50 +946,17 @@ describe Mongoid::Criteria::Queryable::Selectable do
2450
946
 
2451
947
  context "when the criterion are on the same field" do
2452
948
 
2453
- context "when the stretegy is the default (intersection)" do
2454
-
2455
- let(:selection) do
2456
- query.nin(first: [ 1, 2 ]).nin(first: [ 2, 3 ])
2457
- end
2458
-
2459
- it "intersects the $nin selectors" do
2460
- expect(selection.selector).to eq({
2461
- "first" => { "$nin" => [ 2 ] }
2462
- })
2463
- end
2464
-
2465
- it "returns a cloned query" do
2466
- expect(selection).to_not equal(query)
2467
- end
2468
- end
2469
-
2470
- context "when the stretegy is intersect" do
2471
-
2472
- let(:selection) do
2473
- query.nin(first: [ 1, 2 ]).intersect.nin(first: [ 2, 3 ])
2474
- end
2475
-
2476
- it "intersects the $nin selectors" do
2477
- expect(selection.selector).to eq({
2478
- "first" => { "$nin" => [ 2 ] }
2479
- })
2480
- end
2481
-
2482
- it "returns a cloned query" do
2483
- expect(selection).to_not equal(query)
2484
- end
2485
- end
2486
-
2487
- context "when the stretegy is override" do
949
+ context "when overwrite_chained_operators is true" do
950
+ config_override :overwrite_chained_operators, true
2488
951
 
2489
952
  let(:selection) do
2490
- query.nin(first: [ 1, 2 ]).override.nin(first: [ 3, 4 ])
953
+ query.gt(first: 10).gt(first: 15)
2491
954
  end
2492
955
 
2493
- it "overwrites the first $nin selector" do
956
+ it "overwrites the first $gt selector" do
2494
957
  expect(selection.selector).to eq({
2495
- "first" => { "$nin" => [ 3, 4 ] }
2496
- })
958
+ "first" => { "$gt" => 15 },
959
+ })
2497
960
  end
2498
961
 
2499
962
  it "returns a cloned query" do
@@ -2501,16 +964,17 @@ describe Mongoid::Criteria::Queryable::Selectable do
2501
964
  end
2502
965
  end
2503
966
 
2504
- context "when the stretegy is union" do
2505
-
967
+ context "when overwrite_chained_operators is false" do
968
+ config_override :overwrite_chained_operators, false
2506
969
  let(:selection) do
2507
- query.nin(first: [ 1, 2 ]).union.nin(first: [ 3, 4 ])
970
+ query.gt(first: 10).gt(first: 15)
2508
971
  end
2509
972
 
2510
- it "unions the $nin selectors" do
973
+ it "overwrites the first $gt selector" do
2511
974
  expect(selection.selector).to eq({
2512
- "first" => { "$nin" => [ 1, 2, 3, 4 ] }
2513
- })
975
+ "first" => { "$gt" => 10 },
976
+ "$and" => [{ "first" => { "$gt" => 15 } }]
977
+ })
2514
978
  end
2515
979
 
2516
980
  it "returns a cloned query" do
@@ -2521,55 +985,22 @@ describe Mongoid::Criteria::Queryable::Selectable do
2521
985
  end
2522
986
  end
2523
987
 
2524
- describe "#nor" do
2525
-
2526
- context "when provided no criterion" do
2527
-
2528
- let(:selection) do
2529
- query.nor
2530
- end
2531
-
2532
- it "does not add any criterion" do
2533
- expect(selection.selector).to eq({})
2534
- end
2535
-
2536
- it "returns the query" do
2537
- expect(selection).to eq(query)
2538
- end
2539
-
2540
- it "returns a cloned query" do
2541
- expect(selection).to_not equal(query)
2542
- end
2543
- end
2544
-
2545
- context "when provided nil" do
2546
-
2547
- let(:selection) do
2548
- query.nor(nil)
2549
- end
2550
-
2551
- it "does not add any criterion" do
2552
- expect(selection.selector).to eq({})
2553
- end
988
+ describe "#gte" do
2554
989
 
2555
- it "returns the query" do
2556
- expect(selection).to eq(query)
2557
- end
990
+ let(:query_method) { :gte }
2558
991
 
2559
- it "returns a cloned query" do
2560
- expect(selection).to_not equal(query)
2561
- end
2562
- end
992
+ it_behaves_like 'requires an argument'
993
+ it_behaves_like 'requires a non-nil argument'
2563
994
 
2564
995
  context "when provided a single criterion" do
2565
996
 
2566
997
  let(:selection) do
2567
- query.nor(field: [ 1, 2 ])
998
+ query.gte(field: 10)
2568
999
  end
2569
1000
 
2570
- it "adds the $nor selector" do
1001
+ it "adds the $gte selector" do
2571
1002
  expect(selection.selector).to eq({
2572
- "$nor" => [{"field" => [ 1, 2 ] }]
1003
+ "field" => { "$gte" => 10 }
2573
1004
  })
2574
1005
  end
2575
1006
 
@@ -2580,38 +1011,16 @@ describe Mongoid::Criteria::Queryable::Selectable do
2580
1011
 
2581
1012
  context "when provided multiple criterion" do
2582
1013
 
2583
- context "when the criterion are fnor different fields" do
2584
-
2585
- let(:selection) do
2586
- query.nor({ first: [ 1, 2 ] }, { second: [ 3, 4 ] })
2587
- end
2588
-
2589
- it "adds the $nor selector" do
2590
- expect(selection.selector).to eq({
2591
- "$nor" => [
2592
- { "first" => [ 1, 2 ] },
2593
- { "second" => [ 3, 4 ] }
2594
- ]
2595
- })
2596
- end
2597
-
2598
- it "returns a cloned query" do
2599
- expect(selection).to_not equal(query)
2600
- end
2601
- end
2602
-
2603
- context "when the criterion are on the same field" do
1014
+ context "when the criterion are for different fields" do
2604
1015
 
2605
1016
  let(:selection) do
2606
- query.nor({ first: [ 1, 2 ] }, { first: [ 3, 4 ] })
1017
+ query.gte(first: 10, second: 15)
2607
1018
  end
2608
1019
 
2609
- it "appends both $nor expressions" do
1020
+ it "adds the $gte selectors" do
2610
1021
  expect(selection.selector).to eq({
2611
- "$nor" => [
2612
- { "first" => [ 1, 2 ] },
2613
- { "first" => [ 3, 4 ] }
2614
- ]
1022
+ "first" => { "$gte" => 10 },
1023
+ "second" => { "$gte" => 15 }
2615
1024
  })
2616
1025
  end
2617
1026
 
@@ -2623,18 +1032,16 @@ describe Mongoid::Criteria::Queryable::Selectable do
2623
1032
 
2624
1033
  context "when chaining the criterion" do
2625
1034
 
2626
- context "when the criterion are fnor different fields" do
1035
+ context "when the criterion are for different fields" do
2627
1036
 
2628
1037
  let(:selection) do
2629
- query.nor(first: [ 1, 2 ]).nor(second: [ 3, 4 ])
1038
+ query.gte(first: 10).gte(second: 15)
2630
1039
  end
2631
1040
 
2632
- it "adds the $nor selectors" do
1041
+ it "adds the $gte selectors" do
2633
1042
  expect(selection.selector).to eq({
2634
- "$nor" => [
2635
- { "first" => [ 1, 2 ] },
2636
- { "second" => [ 3, 4 ] }
2637
- ]
1043
+ "first" => { "$gte" => 10 },
1044
+ "second" => { "$gte" => 15 }
2638
1045
  })
2639
1046
  end
2640
1047
 
@@ -2646,16 +1053,28 @@ describe Mongoid::Criteria::Queryable::Selectable do
2646
1053
  context "when the criterion are on the same field" do
2647
1054
 
2648
1055
  let(:selection) do
2649
- query.nor(first: [ 1, 2 ]).nor(first: [ 3, 4 ])
1056
+ query.gte(first: 10).gte(first: 15)
2650
1057
  end
2651
1058
 
2652
- it "appends both $nor expressions" do
2653
- expect(selection.selector).to eq({
2654
- "$nor" => [
2655
- { "first" => [ 1, 2 ] },
2656
- { "first" => [ 3, 4 ] }
2657
- ]
2658
- })
1059
+ context "when overwrite_chained_operators is false" do
1060
+ config_override :overwrite_chained_operators, false
1061
+
1062
+ it "adds a second $gte selector" do
1063
+ expect(selection.selector).to eq({
1064
+ "first" => { "$gte" => 10 },
1065
+ "$and" => [ { "first" => { "$gte" => 15 } } ]
1066
+ })
1067
+ end
1068
+ end
1069
+
1070
+ context "when overwrite_chained_operators is true" do
1071
+ config_override :overwrite_chained_operators, true
1072
+
1073
+ it "overwrites the first $gte selector" do
1074
+ expect(selection.selector).to eq({
1075
+ "first" => { "$gte" => 15 }
1076
+ })
1077
+ end
2659
1078
  end
2660
1079
 
2661
1080
  it "returns a cloned query" do
@@ -2665,140 +1084,115 @@ describe Mongoid::Criteria::Queryable::Selectable do
2665
1084
  end
2666
1085
  end
2667
1086
 
2668
- describe "#not" do
2669
-
2670
- context "when provided no criterion" do
2671
-
2672
- let(:selection) do
2673
- query.not
2674
- end
1087
+ describe "#in" do
2675
1088
 
2676
- it "does not add any criterion" do
2677
- expect(selection.selector).to eq({})
2678
- end
1089
+ let(:query_method) { :in }
1090
+ let(:operator) { '$in' }
2679
1091
 
2680
- it "returns the query" do
2681
- expect(selection).to eq(query)
2682
- end
1092
+ it_behaves_like 'requires an argument'
1093
+ it_behaves_like 'requires a non-nil argument'
2683
1094
 
2684
- it "returns a non cloned query" do
2685
- expect(selection).to equal(query)
2686
- end
1095
+ context "when provided a single criterion" do
2687
1096
 
2688
- context "when the following criteria is a query method" do
1097
+ context "when providing an array" do
2689
1098
 
2690
1099
  let(:selection) do
2691
- query.not.all(field: [ 1, 2 ])
1100
+ query.in(field: [ 1, 2 ])
2692
1101
  end
2693
1102
 
2694
- it "negates the all selection" do
2695
- expect(selection.selector).to eq(
2696
- { "field" => { "$not" => { "$all" => [ 1, 2 ] }}}
2697
- )
1103
+ it "adds the $in selector" do
1104
+ expect(selection.selector).to eq({
1105
+ "field" => { "$in" => [ 1, 2 ] }
1106
+ })
2698
1107
  end
2699
1108
 
2700
1109
  it "returns a cloned query" do
2701
1110
  expect(selection).to_not equal(query)
2702
1111
  end
2703
-
2704
- it "removes the negation on the clone" do
2705
- expect(selection).to_not be_negating
2706
- end
2707
1112
  end
2708
1113
 
2709
- context "when the following criteria is a gt method" do
1114
+ context "when providing a single value" do
2710
1115
 
2711
1116
  let(:selection) do
2712
- query.not.gt(age: 50)
2713
- end
2714
-
2715
- it "negates the gt selection" do
2716
- expect(selection.selector).to eq(
2717
- { "age" => { "$not" => { "$gt" => 50 }}}
2718
- )
1117
+ query.in(field: 1)
2719
1118
  end
2720
1119
 
2721
- it "returns a coned query" do
2722
- expect(selection).to_not eq(query)
1120
+ it "adds the $in selector with wrapped value" do
1121
+ expect(selection.selector).to eq({
1122
+ "field" => { "$in" => [ 1 ] }
1123
+ })
2723
1124
  end
2724
1125
 
2725
- it "removes the negation on the clone" do
2726
- expect(selection).to_not be_negating
1126
+ it "returns a cloned query" do
1127
+ expect(selection).to_not equal(query)
2727
1128
  end
2728
1129
  end
1130
+ end
1131
+
1132
+ context "when provided multiple criterion" do
2729
1133
 
2730
- context "when the following criteria is a where" do
1134
+ context "when the criterion are for different fields" do
2731
1135
 
2732
1136
  let(:selection) do
2733
- query.not.where(field: 1, :other.in => [ 1, 2 ])
1137
+ query.in(first: [ 1, 2 ], second: 3..4)
2734
1138
  end
2735
1139
 
2736
- it "negates the selection with an operator" do
2737
- expect(selection.selector).to eq(
2738
- { "field" => { "$ne" => 1 }, "other" => { "$not" => { "$in" => [ 1, 2 ] }}}
2739
- )
1140
+ it "adds the $in selectors" do
1141
+ expect(selection.selector).to eq({
1142
+ "first" => { "$in" => [ 1, 2 ] },
1143
+ "second" => { "$in" => [ 3, 4 ] }
1144
+ })
2740
1145
  end
2741
1146
 
2742
1147
  it "returns a cloned query" do
2743
1148
  expect(selection).to_not equal(query)
2744
1149
  end
2745
-
2746
- it "removes the negation on the clone" do
2747
- expect(selection).to_not be_negating
2748
- end
2749
1150
  end
1151
+ end
1152
+
1153
+ context "when chaining the criterion" do
2750
1154
 
2751
- context "when the following criteria is a where with a regexp" do
1155
+ context "when the criterion are for different fields" do
2752
1156
 
2753
1157
  let(:selection) do
2754
- query.not.where(field: 1, other: /test/)
1158
+ query.in(first: [ 1, 2 ]).in(second: [ 3, 4 ])
2755
1159
  end
2756
1160
 
2757
- it "negates the selection with an operator" do
2758
- expect(selection.selector).to eq(
2759
- { "field" => { "$ne" => 1 }, "other" => { "$not" => /test/ } }
2760
- )
1161
+ it "adds the $in selectors" do
1162
+ expect(selection.selector).to eq({
1163
+ "first" => { "$in" => [ 1, 2 ] },
1164
+ "second" => { "$in" => [ 3, 4 ] }
1165
+ })
2761
1166
  end
2762
1167
 
2763
1168
  it "returns a cloned query" do
2764
1169
  expect(selection).to_not equal(query)
2765
1170
  end
2766
-
2767
- it "removes the negation on the clone" do
2768
- expect(selection).to_not be_negating
2769
- end
2770
-
2771
1171
  end
2772
- end
2773
1172
 
2774
- context "when provided nil" do
1173
+ context "when the criterion are on the same field" do
2775
1174
 
2776
- let(:selection) do
2777
- query.not(nil)
1175
+ it_behaves_like 'supports merge strategies'
2778
1176
  end
1177
+ end
1178
+ end
2779
1179
 
2780
- it "does not add any criterion" do
2781
- expect(selection.selector).to eq({})
2782
- end
1180
+ describe "#lt" do
2783
1181
 
2784
- it "returns the query" do
2785
- expect(selection).to eq(query)
2786
- end
1182
+ let(:query_method) { :lt }
2787
1183
 
2788
- it "returns a cloned query" do
2789
- expect(selection).to_not equal(query)
2790
- end
2791
- end
1184
+ it_behaves_like 'requires an argument'
1185
+ it_behaves_like 'requires a non-nil argument'
2792
1186
 
2793
1187
  context "when provided a single criterion" do
2794
1188
 
2795
1189
  let(:selection) do
2796
- query.not(field: /test/)
1190
+ query.lt(field: 10)
2797
1191
  end
2798
1192
 
2799
- it "adds the $not selector" do
1193
+ it "adds the $lt selector" do
2800
1194
  expect(selection.selector).to eq({
2801
- "field" => { "$not" => /test/ }
1195
+ "field" => { "$lt" => 10 }
2802
1196
  })
2803
1197
  end
2804
1198
 
@@ -2812,13 +1206,13 @@ describe Mongoid::Criteria::Queryable::Selectable do
2812
1206
  context "when the criterion are for different fields" do
2813
1207
 
2814
1208
  let(:selection) do
2815
- query.not(first: /1/, second: /2/)
1209
+ query.lt(first: 10, second: 15)
2816
1210
  end
2817
1211
 
2818
- it "adds the $not selectors" do
1212
+ it "adds the $lt selectors" do
2819
1213
  expect(selection.selector).to eq({
2820
- "first" => { "$not" => /1/ },
2821
- "second" => { "$not" => /2/ }
1214
+ "first" => { "$lt" => 10 },
1215
+ "second" => { "$lt" => 15 }
2822
1216
  })
2823
1217
  end
2824
1218
 
@@ -2833,13 +1227,13 @@ describe Mongoid::Criteria::Queryable::Selectable do
2833
1227
  context "when the criterion are for different fields" do
2834
1228
 
2835
1229
  let(:selection) do
2836
- query.not(first: /1/).not(second: /2/)
1230
+ query.lt(first: 10).lt(second: 15)
2837
1231
  end
2838
1232
 
2839
- it "adds the $not selectors" do
1233
+ it "adds the $lt selectors" do
2840
1234
  expect(selection.selector).to eq({
2841
- "first" => { "$not" => /1/ },
2842
- "second" => { "$not" => /2/ }
1235
+ "first" => { "$lt" => 10 },
1236
+ "second" => { "$lt" => 15 }
2843
1237
  })
2844
1238
  end
2845
1239
 
@@ -2851,30 +1245,28 @@ describe Mongoid::Criteria::Queryable::Selectable do
2851
1245
  context "when the criterion are on the same field" do
2852
1246
 
2853
1247
  let(:selection) do
2854
- query.not(first: /1/).not(first: /2/)
2855
- end
2856
-
2857
- it "overwrites the first $not selector" do
2858
- expect(selection.selector).to eq({
2859
- "first" => { "$not" => /2/ }
2860
- })
2861
- end
2862
-
2863
- it "returns a cloned query" do
2864
- expect(selection).to_not equal(query)
1248
+ query.lt(first: 10).lt(first: 15)
2865
1249
  end
2866
- end
2867
1250
 
2868
- context "when the criterion are a double negative" do
1251
+ context "when overwrite_chained_operators is false" do
1252
+ config_override :overwrite_chained_operators, false
2869
1253
 
2870
- let(:selection) do
2871
- query.not.where(:first.not => /1/)
1254
+ it "adds a second $lt selector" do
1255
+ expect(selection.selector).to eq({
1256
+ "first" => { "$lt" => 10 },
1257
+ "$and" => [ { "first" => { "$lt" => 15 } } ]
1258
+ })
1259
+ end
2872
1260
  end
2873
1261
 
2874
- it "does not double the $not selector" do
2875
- expect(selection.selector).to eq({
2876
- "first" => { "$not" => /1/ }
2877
- })
1262
+ context "when overwrite_chained_operators is true" do
1263
+ config_override :overwrite_chained_operators, true
1264
+
1265
+ it "overwrites the first $lt selector" do
1266
+ expect(selection.selector).to eq({
1267
+ "first" => { "$lt" => 15 }
1268
+ })
1269
+ end
2878
1270
  end
2879
1271
 
2880
1272
  it "returns a cloned query" do
@@ -2884,55 +1276,22 @@ describe Mongoid::Criteria::Queryable::Selectable do
2884
1276
  end
2885
1277
  end
2886
1278
 
2887
- describe "#or" do
2888
-
2889
- context "when provided no criterion" do
2890
-
2891
- let(:selection) do
2892
- query.or
2893
- end
2894
-
2895
- it "does not add any criterion" do
2896
- expect(selection.selector).to eq({})
2897
- end
2898
-
2899
- it "returns the query" do
2900
- expect(selection).to eq(query)
2901
- end
2902
-
2903
- it "returns a cloned query" do
2904
- expect(selection).to_not equal(query)
2905
- end
2906
- end
2907
-
2908
- context "when provided nil" do
2909
-
2910
- let(:selection) do
2911
- query.or(nil)
2912
- end
2913
-
2914
- it "does not add any criterion" do
2915
- expect(selection.selector).to eq({})
2916
- end
1279
+ describe "#lte" do
2917
1280
 
2918
- it "returns the query" do
2919
- expect(selection).to eq(query)
2920
- end
1281
+ let(:query_method) { :lte }
2921
1282
 
2922
- it "returns a cloned query" do
2923
- expect(selection).to_not equal(query)
2924
- end
2925
- end
1283
+ it_behaves_like 'requires an argument'
1284
+ it_behaves_like 'requires a non-nil argument'
2926
1285
 
2927
1286
  context "when provided a single criterion" do
2928
1287
 
2929
1288
  let(:selection) do
2930
- query.or(field: [ 1, 2 ])
1289
+ query.lte(field: 10)
2931
1290
  end
2932
1291
 
2933
- it "adds the $or selector" do
1292
+ it "adds the $lte selector" do
2934
1293
  expect(selection.selector).to eq({
2935
- "$or" => [{ "field" => [ 1, 2 ] }]
1294
+ "field" => { "$lte" => 10 }
2936
1295
  })
2937
1296
  end
2938
1297
 
@@ -2946,15 +1305,13 @@ describe Mongoid::Criteria::Queryable::Selectable do
2946
1305
  context "when the criterion are for different fields" do
2947
1306
 
2948
1307
  let(:selection) do
2949
- query.or({ first: [ 1, 2 ] }, { second: [ 3, 4 ] })
1308
+ query.lte(first: 10, second: 15)
2950
1309
  end
2951
1310
 
2952
- it "adds the $or selector" do
1311
+ it "adds the $lte selectors" do
2953
1312
  expect(selection.selector).to eq({
2954
- "$or" => [
2955
- { "first" => [ 1, 2 ] },
2956
- { "second" => [ 3, 4 ] }
2957
- ]
1313
+ "first" => { "$lte" => 10 },
1314
+ "second" => { "$lte" => 15 }
2958
1315
  })
2959
1316
  end
2960
1317
 
@@ -2962,19 +1319,20 @@ describe Mongoid::Criteria::Queryable::Selectable do
2962
1319
  expect(selection).to_not equal(query)
2963
1320
  end
2964
1321
  end
1322
+ end
2965
1323
 
2966
- context "when a criterion has a selectable key" do
1324
+ context "when chaining the criterion" do
1325
+
1326
+ context "when the criterion are for different fields" do
2967
1327
 
2968
1328
  let(:selection) do
2969
- query.or({ first: [ 1, 2 ] }, { :second.gt => 3 })
1329
+ query.lte(first: 10).lte(second: 15)
2970
1330
  end
2971
1331
 
2972
- it "adds the $or selector" do
1332
+ it "adds the $lte selectors" do
2973
1333
  expect(selection.selector).to eq({
2974
- "$or" => [
2975
- { "first" => [ 1, 2 ] },
2976
- { "second" => { "$gt" => 3 }}
2977
- ]
1334
+ "first" => { "$lte" => 10 },
1335
+ "second" => { "$lte" => 15 }
2978
1336
  })
2979
1337
  end
2980
1338
 
@@ -2983,35 +1341,58 @@ describe Mongoid::Criteria::Queryable::Selectable do
2983
1341
  end
2984
1342
  end
2985
1343
 
2986
- context "when the criterion has an aliased field" do
1344
+ context "when the criterion are on the same field" do
2987
1345
 
2988
1346
  let(:selection) do
2989
- query.or({ id: 1 })
1347
+ query.lte(first: 10).lte(first: 15)
2990
1348
  end
2991
1349
 
2992
- it "adds the $or selector and aliases the field" do
2993
- expect(selection.selector).to eq({
2994
- "$or" => [ { "_id" => 1 } ]
2995
- })
1350
+ context "when overwrite_chained_operators is false" do
1351
+ config_override :overwrite_chained_operators, false
1352
+
1353
+ it "adds a second $lte selector" do
1354
+ expect(selection.selector).to eq({
1355
+ "first" => { "$lte" => 10 },
1356
+ "$and" => [ { "first" => { "$lte" => 15 } } ]
1357
+ })
1358
+ end
1359
+ end
1360
+
1361
+ context "when overwrite_chained_operators is true" do
1362
+ config_override :overwrite_chained_operators, true
1363
+
1364
+ it "overwrites the first $lte selector" do
1365
+ expect(selection.selector).to eq({
1366
+ "first" => { "$lte" => 15 }
1367
+ })
1368
+ end
2996
1369
  end
2997
1370
 
2998
1371
  it "returns a cloned query" do
2999
1372
  expect(selection).to_not equal(query)
3000
1373
  end
3001
1374
  end
1375
+ end
1376
+ end
1377
+
1378
+ describe "#max_distance" do
1379
+
1380
+ let(:query_method) { :max_distance }
1381
+
1382
+ it_behaves_like 'requires an argument'
1383
+ it_behaves_like 'requires a non-nil argument'
1384
+
1385
+ context "when provided a criterion" do
3002
1386
 
3003
- context "when a criterion is wrapped in an array" do
1387
+ context "when a $near criterion exists on the same field" do
3004
1388
 
3005
1389
  let(:selection) do
3006
- query.or([{ first: [ 1, 2 ] }, { :second.gt => 3 }])
1390
+ query.near(location: [ 1, 1 ]).max_distance(location: 50)
3007
1391
  end
3008
1392
 
3009
- it "adds the $or selector" do
1393
+ it "adds the $maxDistance expression" do
3010
1394
  expect(selection.selector).to eq({
3011
- "$or" => [
3012
- { "first" => [ 1, 2 ] },
3013
- { "second" => { "$gt" => 3 }}
3014
- ]
1395
+ "location" => { "$near" => [ 1, 1 ], "$maxDistance" => 50 }
3015
1396
  })
3016
1397
  end
3017
1398
 
@@ -3019,42 +1400,48 @@ describe Mongoid::Criteria::Queryable::Selectable do
3019
1400
  expect(selection).to_not equal(query)
3020
1401
  end
3021
1402
  end
1403
+ end
1404
+ end
3022
1405
 
3023
- context "when the criterion are on the same field" do
1406
+ describe "#mod" do
3024
1407
 
3025
- let(:selection) do
3026
- query.or({ first: [ 1, 2 ] }, { first: [ 3, 4 ] })
3027
- end
1408
+ let(:query_method) { :mod }
3028
1409
 
3029
- it "appends both $or expressions" do
3030
- expect(selection.selector).to eq({
3031
- "$or" => [
3032
- { "first" => [ 1, 2 ] },
3033
- { "first" => [ 3, 4 ] }
3034
- ]
3035
- })
3036
- end
1410
+ it_behaves_like 'requires an argument'
1411
+ it_behaves_like 'requires a non-nil argument'
3037
1412
 
3038
- it "returns a cloned query" do
3039
- expect(selection).to_not equal(query)
3040
- end
1413
+ context "when provided a criterion" do
1414
+
1415
+ let(:selection) do
1416
+ query.mod(value: [ 10, 1 ])
1417
+ end
1418
+
1419
+ it "adds the $mod expression" do
1420
+ expect(selection.selector).to eq({
1421
+ "value" => { "$mod" => [ 10, 1 ] }
1422
+ })
1423
+ end
1424
+
1425
+ it "returns a cloned query" do
1426
+ expect(selection).to_not equal(query)
3041
1427
  end
3042
1428
  end
3043
1429
 
3044
- context "when chaining the criterion" do
1430
+ context "when providing multiple criteria" do
3045
1431
 
3046
- context "when the criterion are for different fields" do
1432
+ context "when the fields differ" do
3047
1433
 
3048
1434
  let(:selection) do
3049
- query.or(first: [ 1, 2 ]).or(second: [ 3, 4 ])
1435
+ query.mod(
1436
+ value: [ 10, 1 ],
1437
+ comments: [ 10, 1 ]
1438
+ )
3050
1439
  end
3051
1440
 
3052
- it "adds the $or selectors" do
1441
+ it "adds the $mod expression" do
3053
1442
  expect(selection.selector).to eq({
3054
- "$or" => [
3055
- { "first" => [ 1, 2 ] },
3056
- { "second" => [ 3, 4 ] }
3057
- ]
1443
+ "value" => { "$mod" => [ 10, 1 ] },
1444
+ "comments" => { "$mod" => [ 10, 1 ] }
3058
1445
  })
3059
1446
  end
3060
1447
 
@@ -3062,19 +1449,22 @@ describe Mongoid::Criteria::Queryable::Selectable do
3062
1449
  expect(selection).to_not equal(query)
3063
1450
  end
3064
1451
  end
1452
+ end
3065
1453
 
3066
- context "when the criterion are on the same field" do
1454
+ context "when chaining multiple criteria" do
1455
+
1456
+ context "when the fields differ" do
3067
1457
 
3068
1458
  let(:selection) do
3069
- query.or(first: [ 1, 2 ]).or(first: [ 3, 4 ])
1459
+ query.
1460
+ mod(value: [ 10, 1 ]).
1461
+ mod(result: [ 10, 1 ])
3070
1462
  end
3071
1463
 
3072
- it "appends both $or expressions" do
1464
+ it "adds the $mod expression" do
3073
1465
  expect(selection.selector).to eq({
3074
- "$or" => [
3075
- { "first" => [ 1, 2 ] },
3076
- { "first" => [ 3, 4 ] }
3077
- ]
1466
+ "value" => { "$mod" => [ 10, 1 ] },
1467
+ "result" => { "$mod" => [ 10, 1 ] }
3078
1468
  })
3079
1469
  end
3080
1470
 
@@ -3085,39 +1475,23 @@ describe Mongoid::Criteria::Queryable::Selectable do
3085
1475
  end
3086
1476
  end
3087
1477
 
3088
- describe "#with_size" do
3089
-
3090
- context "when provided no criterion" do
3091
-
3092
- let(:selection) do
3093
- query.with_size
3094
- end
3095
-
3096
- it "does not add any criterion" do
3097
- expect(selection.selector).to eq({})
3098
- end
1478
+ describe "#ne" do
3099
1479
 
3100
- it "returns the query" do
3101
- expect(selection).to eq(query)
3102
- end
1480
+ let(:query_method) { :ne }
3103
1481
 
3104
- it "returns a cloned query" do
3105
- expect(selection).to_not equal(query)
3106
- end
3107
- end
1482
+ it_behaves_like 'requires an argument'
1483
+ it_behaves_like 'requires a non-nil argument'
3108
1484
 
3109
- context "when provided nil" do
1485
+ context "when provided a criterion" do
3110
1486
 
3111
1487
  let(:selection) do
3112
- query.with_size(nil)
3113
- end
3114
-
3115
- it "does not add any criterion" do
3116
- expect(selection.selector).to eq({})
1488
+ query.ne(value: 10)
3117
1489
  end
3118
1490
 
3119
- it "returns the query" do
3120
- expect(selection).to eq(query)
1491
+ it "adds the $ne expression" do
1492
+ expect(selection.selector).to eq({
1493
+ "value" => { "$ne" => 10 }
1494
+ })
3121
1495
  end
3122
1496
 
3123
1497
  it "returns a cloned query" do
@@ -3125,17 +1499,21 @@ describe Mongoid::Criteria::Queryable::Selectable do
3125
1499
  end
3126
1500
  end
3127
1501
 
3128
- context "when provided a single criterion" do
1502
+ context "when providing multiple criteria" do
3129
1503
 
3130
- context "when provided an integer" do
1504
+ context "when the fields differ" do
3131
1505
 
3132
1506
  let(:selection) do
3133
- query.with_size(field: 10)
1507
+ query.ne(
1508
+ value: 10,
1509
+ comments: 10
1510
+ )
3134
1511
  end
3135
1512
 
3136
- it "adds the $size selector" do
1513
+ it "adds the $ne expression" do
3137
1514
  expect(selection.selector).to eq({
3138
- "field" => { "$size" => 10 }
1515
+ "value" => { "$ne" => 10 },
1516
+ "comments" => { "$ne" => 10 }
3139
1517
  })
3140
1518
  end
3141
1519
 
@@ -3143,16 +1521,22 @@ describe Mongoid::Criteria::Queryable::Selectable do
3143
1521
  expect(selection).to_not equal(query)
3144
1522
  end
3145
1523
  end
1524
+ end
3146
1525
 
3147
- context "when provided a string" do
1526
+ context "when chaining multiple criteria" do
1527
+
1528
+ context "when the fields differ" do
3148
1529
 
3149
1530
  let(:selection) do
3150
- query.with_size(field: "10")
1531
+ query.
1532
+ ne(value: 10).
1533
+ ne(result: 10)
3151
1534
  end
3152
1535
 
3153
- it "adds the $size selector with an integer" do
1536
+ it "adds the $ne expression" do
3154
1537
  expect(selection.selector).to eq({
3155
- "field" => { "$size" => 10 }
1538
+ "value" => { "$ne" => 10 },
1539
+ "result" => { "$ne" => 10 }
3156
1540
  })
3157
1541
  end
3158
1542
 
@@ -3161,61 +1545,47 @@ describe Mongoid::Criteria::Queryable::Selectable do
3161
1545
  end
3162
1546
  end
3163
1547
  end
1548
+ end
3164
1549
 
3165
- context "when provided multiple criterion" do
3166
-
3167
- context "when the criterion are for different fields" do
3168
-
3169
- context "when provided integers" do
3170
-
3171
- let(:selection) do
3172
- query.with_size(first: 10, second: 15)
3173
- end
1550
+ describe "#near" do
3174
1551
 
3175
- it "adds the $size selectors" do
3176
- expect(selection.selector).to eq({
3177
- "first" => { "$size" => 10 },
3178
- "second" => { "$size" => 15 }
3179
- })
3180
- end
1552
+ let(:query_method) { :near }
3181
1553
 
3182
- it "returns a cloned query" do
3183
- expect(selection).to_not equal(query)
3184
- end
3185
- end
1554
+ it_behaves_like 'requires an argument'
1555
+ it_behaves_like 'requires a non-nil argument'
3186
1556
 
3187
- context "when provided strings" do
1557
+ context "when provided a criterion" do
3188
1558
 
3189
- let(:selection) do
3190
- query.with_size(first: "10", second: "15")
3191
- end
1559
+ let(:selection) do
1560
+ query.near(location: [ 20, 21 ])
1561
+ end
3192
1562
 
3193
- it "adds the $size selectors" do
3194
- expect(selection.selector).to eq({
3195
- "first" => { "$size" => 10 },
3196
- "second" => { "$size" => 15 }
3197
- })
3198
- end
1563
+ it "adds the $near expression" do
1564
+ expect(selection.selector).to eq({
1565
+ "location" => { "$near" => [ 20, 21 ] }
1566
+ })
1567
+ end
3199
1568
 
3200
- it "returns a cloned query" do
3201
- expect(selection).to_not equal(query)
3202
- end
3203
- end
1569
+ it "returns a cloned query" do
1570
+ expect(selection).to_not equal(query)
3204
1571
  end
3205
1572
  end
3206
1573
 
3207
- context "when chaining the criterion" do
1574
+ context "when providing multiple criteria" do
3208
1575
 
3209
- context "when the criterion are for different fields" do
1576
+ context "when the fields differ" do
3210
1577
 
3211
1578
  let(:selection) do
3212
- query.with_size(first: 10).with_size(second: 15)
1579
+ query.near(
1580
+ location: [ 20, 21 ],
1581
+ comments: [ 20, 21 ]
1582
+ )
3213
1583
  end
3214
1584
 
3215
- it "adds the $size selectors" do
1585
+ it "adds the $near expression" do
3216
1586
  expect(selection.selector).to eq({
3217
- "first" => { "$size" => 10 },
3218
- "second" => { "$size" => 15 }
1587
+ "location" => { "$near" => [ 20, 21 ] },
1588
+ "comments" => { "$near" => [ 20, 21 ] }
3219
1589
  })
3220
1590
  end
3221
1591
 
@@ -3223,16 +1593,22 @@ describe Mongoid::Criteria::Queryable::Selectable do
3223
1593
  expect(selection).to_not equal(query)
3224
1594
  end
3225
1595
  end
1596
+ end
3226
1597
 
3227
- context "when the criterion are on the same field" do
1598
+ context "when chaining multiple criteria" do
1599
+
1600
+ context "when the fields differ" do
3228
1601
 
3229
1602
  let(:selection) do
3230
- query.with_size(first: 10).with_size(first: 15)
1603
+ query.
1604
+ near(location: [ 20, 21 ]).
1605
+ near(comments: [ 20, 21 ])
3231
1606
  end
3232
1607
 
3233
- it "overwrites the first $size selector" do
1608
+ it "adds the $near expression" do
3234
1609
  expect(selection.selector).to eq({
3235
- "first" => { "$size" => 15 }
1610
+ "location" => { "$near" => [ 20, 21 ] },
1611
+ "comments" => { "$near" => [ 20, 21 ] }
3236
1612
  })
3237
1613
  end
3238
1614
 
@@ -3243,39 +1619,23 @@ describe Mongoid::Criteria::Queryable::Selectable do
3243
1619
  end
3244
1620
  end
3245
1621
 
3246
- describe "#type" do
3247
-
3248
- context "when provided no criterion" do
3249
-
3250
- let(:selection) do
3251
- query.with_type
3252
- end
3253
-
3254
- it "does not add any criterion" do
3255
- expect(selection.selector).to eq({})
3256
- end
1622
+ describe "#near_sphere" do
3257
1623
 
3258
- it "returns the query" do
3259
- expect(selection).to eq(query)
3260
- end
1624
+ let(:query_method) { :near_sphere }
3261
1625
 
3262
- it "returns a cloned query" do
3263
- expect(selection).to_not equal(query)
3264
- end
3265
- end
1626
+ it_behaves_like 'requires an argument'
1627
+ it_behaves_like 'requires a non-nil argument'
3266
1628
 
3267
- context "when provided nil" do
1629
+ context "when provided a criterion" do
3268
1630
 
3269
1631
  let(:selection) do
3270
- query.with_type(nil)
3271
- end
3272
-
3273
- it "does not add any criterion" do
3274
- expect(selection.selector).to eq({})
1632
+ query.near_sphere(location: [ 20, 21 ])
3275
1633
  end
3276
1634
 
3277
- it "returns the query" do
3278
- expect(selection).to eq(query)
1635
+ it "adds the $nearSphere expression" do
1636
+ expect(selection.selector).to eq({
1637
+ "location" => { "$nearSphere" => [ 20, 21 ] }
1638
+ })
3279
1639
  end
3280
1640
 
3281
1641
  it "returns a cloned query" do
@@ -3283,17 +1643,21 @@ describe Mongoid::Criteria::Queryable::Selectable do
3283
1643
  end
3284
1644
  end
3285
1645
 
3286
- context "when provided a single criterion" do
1646
+ context "when providing multiple criteria" do
3287
1647
 
3288
- context "when provided an integer" do
1648
+ context "when the fields differ" do
3289
1649
 
3290
1650
  let(:selection) do
3291
- query.with_type(field: 10)
1651
+ query.near_sphere(
1652
+ location: [ 20, 21 ],
1653
+ comments: [ 20, 21 ]
1654
+ )
3292
1655
  end
3293
1656
 
3294
- it "adds the $type selector" do
1657
+ it "adds the $nearSphere expression" do
3295
1658
  expect(selection.selector).to eq({
3296
- "field" => { "$type" => 10 }
1659
+ "location" => { "$nearSphere" => [ 20, 21 ] },
1660
+ "comments" => { "$nearSphere" => [ 20, 21 ] }
3297
1661
  })
3298
1662
  end
3299
1663
 
@@ -3301,16 +1665,22 @@ describe Mongoid::Criteria::Queryable::Selectable do
3301
1665
  expect(selection).to_not equal(query)
3302
1666
  end
3303
1667
  end
1668
+ end
3304
1669
 
3305
- context "when provided a string" do
1670
+ context "when chaining multiple criteria" do
1671
+
1672
+ context "when the fields differ" do
3306
1673
 
3307
1674
  let(:selection) do
3308
- query.with_type(field: "10")
1675
+ query.
1676
+ near_sphere(location: [ 20, 21 ]).
1677
+ near_sphere(comments: [ 20, 21 ])
3309
1678
  end
3310
1679
 
3311
- it "adds the $type selector" do
1680
+ it "adds the $nearSphere expression" do
3312
1681
  expect(selection.selector).to eq({
3313
- "field" => { "$type" => 10 }
1682
+ "location" => { "$nearSphere" => [ 20, 21 ] },
1683
+ "comments" => { "$nearSphere" => [ 20, 21 ] }
3314
1684
  })
3315
1685
  end
3316
1686
 
@@ -3319,19 +1689,27 @@ describe Mongoid::Criteria::Queryable::Selectable do
3319
1689
  end
3320
1690
  end
3321
1691
  end
1692
+ end
3322
1693
 
3323
- context "when provided multiple criterion" do
1694
+ describe "#nin" do
3324
1695
 
3325
- context "when the criterion are for different fields" do
1696
+ let(:query_method) { :nin }
1697
+ let(:operator) { '$nin' }
1698
+
1699
+ it_behaves_like 'requires an argument'
1700
+ it_behaves_like 'requires a non-nil argument'
1701
+
1702
+ context "when provided a single criterion" do
1703
+
1704
+ context "when providing an array" do
3326
1705
 
3327
1706
  let(:selection) do
3328
- query.with_type(first: 10, second: 15)
1707
+ query.nin(field: [ 1, 2 ])
3329
1708
  end
3330
1709
 
3331
- it "adds the $type selectors" do
1710
+ it "adds the $nin selector" do
3332
1711
  expect(selection.selector).to eq({
3333
- "first" => { "$type" => 10 },
3334
- "second" => { "$type" => 15 }
1712
+ "field" => { "$nin" => [ 1, 2 ] }
3335
1713
  })
3336
1714
  end
3337
1715
 
@@ -3339,20 +1717,16 @@ describe Mongoid::Criteria::Queryable::Selectable do
3339
1717
  expect(selection).to_not equal(query)
3340
1718
  end
3341
1719
  end
3342
- end
3343
1720
 
3344
- context "when chaining the criterion" do
3345
-
3346
- context "when the criterion are for different fields" do
1721
+ context "when providing a single value" do
3347
1722
 
3348
1723
  let(:selection) do
3349
- query.with_type(first: 10).with_type(second: 15)
1724
+ query.nin(field: 1)
3350
1725
  end
3351
1726
 
3352
- it "adds the $type selectors" do
1727
+ it "adds the $nin selector with wrapped value" do
3353
1728
  expect(selection.selector).to eq({
3354
- "first" => { "$type" => 10 },
3355
- "second" => { "$type" => 15 }
1729
+ "field" => { "$nin" => [ 1 ] }
3356
1730
  })
3357
1731
  end
3358
1732
 
@@ -3360,16 +1734,20 @@ describe Mongoid::Criteria::Queryable::Selectable do
3360
1734
  expect(selection).to_not equal(query)
3361
1735
  end
3362
1736
  end
1737
+ end
3363
1738
 
3364
- context "when the criterion are on the same field" do
1739
+ context "when provided multiple criterion" do
1740
+
1741
+ context "when the criterion are for different fields" do
3365
1742
 
3366
1743
  let(:selection) do
3367
- query.with_type(first: 10).with_type(first: 15)
1744
+ query.nin(first: [ 1, 2 ], second: [ 3, 4 ])
3368
1745
  end
3369
1746
 
3370
- it "overwrites the first $type selector" do
1747
+ it "adds the $nin selectors" do
3371
1748
  expect(selection.selector).to eq({
3372
- "first" => { "$type" => 15 }
1749
+ "first" => { "$nin" => [ 1, 2 ] },
1750
+ "second" => { "$nin" => [ 3, 4 ] }
3373
1751
  })
3374
1752
  end
3375
1753
 
@@ -3378,510 +1756,313 @@ describe Mongoid::Criteria::Queryable::Selectable do
3378
1756
  end
3379
1757
  end
3380
1758
  end
3381
- end
3382
-
3383
- describe "#text_search" do
3384
-
3385
- context "when providing a search string" do
3386
1759
 
3387
- let(:selection) do
3388
- query.text_search("testing")
3389
- end
3390
-
3391
- it "constructs a text search document" do
3392
- expect(selection.selector).to eq({ '$text' => { '$search' => "testing" }})
3393
- end
3394
-
3395
- it "returns the cloned selectable" do
3396
- expect(selection).to be_a(Mongoid::Criteria::Queryable::Selectable)
3397
- end
1760
+ context "when chaining the criterion" do
3398
1761
 
3399
- context "when providing text search options" do
1762
+ context "when the criterion are for different fields" do
3400
1763
 
3401
1764
  let(:selection) do
3402
- query.text_search("essais", { :$language => "fr" })
1765
+ query.nin(first: [ 1, 2 ]).nin(second: [ 3, 4 ])
3403
1766
  end
3404
1767
 
3405
- it "constructs a text search document" do
3406
- expect(selection.selector['$text']['$search']).to eq("essais")
1768
+ it "adds the $nin selectors" do
1769
+ expect(selection.selector).to eq({
1770
+ "first" => { "$nin" => [ 1, 2 ] },
1771
+ "second" => { "$nin" => [ 3, 4 ] }
1772
+ })
3407
1773
  end
3408
1774
 
3409
- it "add the options to the text search document" do
3410
- expect(selection.selector['$text'][:$language]).to eq("fr")
1775
+ it "returns a cloned query" do
1776
+ expect(selection).to_not equal(query)
3411
1777
  end
3412
-
3413
- it_behaves_like "a cloning selection"
3414
1778
  end
3415
- end
3416
1779
 
3417
- context 'when given more than once' do
3418
- let(:selection) do
3419
- query.text_search("one").text_search('two')
3420
- end
1780
+ context "when the criterion are on the same field" do
3421
1781
 
3422
- # MongoDB server can only handle one text expression at a time,
3423
- # per https://docs.mongodb.com/manual/reference/operator/query/text/.
3424
- # Nonetheless we test that the query is built correctly when
3425
- # a user supplies more than one text condition.
3426
- it 'merges conditions' do
3427
- expect(Mongoid.logger).to receive(:warn)
3428
- expect(selection.selector).to eq('$and' => [
3429
- {'$text' => {'$search' => 'one'}}
3430
- ],
3431
- '$text' => {'$search' => 'two'},
3432
- )
1782
+ it_behaves_like 'supports merge strategies'
3433
1783
  end
3434
1784
  end
3435
1785
  end
3436
1786
 
3437
- describe "#where" do
3438
-
3439
- context "when provided no criterion" do
3440
-
3441
- let(:selection) do
3442
- query.where
3443
- end
3444
-
3445
- it "does not add any criterion" do
3446
- expect(selection.selector).to eq({})
3447
- end
3448
-
3449
- it "returns the query" do
3450
- expect(selection).to eq(query)
3451
- end
3452
-
3453
- it "returns a cloned query" do
3454
- expect(selection).to_not equal(query)
3455
- end
3456
- end
3457
-
3458
- context "when provided nil" do
3459
-
3460
- let(:selection) do
3461
- query.where(nil)
3462
- end
3463
-
3464
- it "does not add any criterion" do
3465
- expect(selection.selector).to eq({})
3466
- end
3467
-
3468
- it "returns the query" do
3469
- expect(selection).to eq(query)
3470
- end
3471
-
3472
- it "returns a cloned query" do
3473
- expect(selection).to_not equal(query)
3474
- end
3475
- end
3476
-
3477
- context "when provided a string" do
3478
-
3479
- let(:selection) do
3480
- query.where("this.value = 10")
3481
- end
1787
+ describe "#with_size" do
3482
1788
 
3483
- it "adds the $where criterion" do
3484
- expect(selection.selector).to eq({ "$where" => "this.value = 10" })
3485
- end
1789
+ let(:query_method) { :with_size }
3486
1790
 
3487
- it "returns a cloned query" do
3488
- expect(selection).to_not equal(query)
3489
- end
3490
- end
1791
+ it_behaves_like 'requires an argument'
1792
+ it_behaves_like 'requires a non-nil argument'
3491
1793
 
3492
1794
  context "when provided a single criterion" do
3493
1795
 
3494
- context "when the value needs no evolution" do
3495
-
3496
- let(:selection) do
3497
- query.where(name: "Syd")
3498
- end
3499
-
3500
- it "adds the criterion to the selection" do
3501
- expect(selection.selector).to eq({ "name" => "Syd" })
3502
- end
3503
- end
3504
-
3505
- context "when the value must be evolved" do
3506
-
3507
- before(:all) do
3508
- class Document
3509
- def id
3510
- 13
3511
- end
3512
- def self.evolve(object)
3513
- object.id
3514
- end
3515
- end
3516
- end
3517
-
3518
- after(:all) do
3519
- Object.send(:remove_const, :Document)
3520
- end
3521
-
3522
- context "when the key needs evolution" do
3523
-
3524
- let(:query) do
3525
- Mongoid::Query.new({ "user" => "user_id" })
3526
- end
3527
-
3528
- let(:document) do
3529
- Document.new
3530
- end
3531
-
3532
- let(:selection) do
3533
- query.where(user: document)
3534
- end
3535
-
3536
- it "alters the key and value" do
3537
- expect(selection.selector).to eq({ "user_id" => document.id })
3538
- end
3539
- end
3540
-
3541
- context 'when the field is a String and the value is a BSON::Regexp::Raw' do
3542
-
3543
- let(:raw_regexp) do
3544
- BSON::Regexp::Raw.new('^Em')
3545
- end
3546
-
3547
- let(:selection) do
3548
- Login.where(_id: raw_regexp)
3549
- end
3550
-
3551
- it 'does not convert the bson raw regexp object to a String' do
3552
- expect(selection.selector).to eq({ "_id" => raw_regexp })
3553
- end
3554
- end
3555
- end
3556
- end
3557
-
3558
- context "when provided complex criterion" do
3559
-
3560
- context "when performing an $all" do
3561
-
3562
- context "when performing a single query" do
3563
-
3564
- let(:selection) do
3565
- query.where(:field.all => [ 1, 2 ])
3566
- end
3567
-
3568
- it "adds the $all criterion" do
3569
- expect(selection.selector).to eq({ "field" => { "$all" => [ 1, 2 ] }})
3570
- end
3571
-
3572
- it "returns a cloned query" do
3573
- expect(selection).to_not eq(query)
3574
- end
3575
- end
3576
- end
3577
-
3578
- context "when performing an $elemMatch" do
3579
-
3580
- context "when the value is not complex" do
1796
+ context "when provided an integer" do
3581
1797
 
3582
- let(:selection) do
3583
- query.where(:field.elem_match => { key: 1 })
3584
- end
1798
+ let(:selection) do
1799
+ query.with_size(field: 10)
1800
+ end
3585
1801
 
3586
- it "adds the $elemMatch criterion" do
3587
- expect(selection.selector).to eq(
3588
- { "field" => { "$elemMatch" => { key: 1 } }}
3589
- )
3590
- end
1802
+ it "adds the $size selector" do
1803
+ expect(selection.selector).to eq({
1804
+ "field" => { "$size" => 10 }
1805
+ })
1806
+ end
3591
1807
 
3592
- it "returns a cloned query" do
3593
- expect(selection).to_not eq(query)
3594
- end
1808
+ it "returns a cloned query" do
1809
+ expect(selection).to_not equal(query)
3595
1810
  end
1811
+ end
3596
1812
 
3597
- context "when the value is complex" do
1813
+ context "when provided a string" do
3598
1814
 
3599
- let(:selection) do
3600
- query.where(:field.elem_match => { :key.gt => 1 })
3601
- end
1815
+ let(:selection) do
1816
+ query.with_size(field: "10")
1817
+ end
3602
1818
 
3603
- it "adds the $elemMatch criterion" do
3604
- expect(selection.selector).to eq(
3605
- { "field" => { "$elemMatch" => { "key" => { "$gt" => 1 }}}}
3606
- )
3607
- end
1819
+ it "adds the $size selector with an integer" do
1820
+ expect(selection.selector).to eq({
1821
+ "field" => { "$size" => 10 }
1822
+ })
1823
+ end
3608
1824
 
3609
- it "returns a cloned query" do
3610
- expect(selection).to_not eq(query)
3611
- end
1825
+ it "returns a cloned query" do
1826
+ expect(selection).to_not equal(query)
3612
1827
  end
3613
1828
  end
1829
+ end
1830
+
1831
+ context "when provided multiple criterion" do
3614
1832
 
3615
- context "when performing an $exists" do
1833
+ context "when the criterion are for different fields" do
3616
1834
 
3617
- context "when providing boolean values" do
1835
+ context "when provided integers" do
3618
1836
 
3619
1837
  let(:selection) do
3620
- query.where(:field.exists => true)
1838
+ query.with_size(first: 10, second: 15)
3621
1839
  end
3622
1840
 
3623
- it "adds the $exists criterion" do
3624
- expect(selection.selector).to eq(
3625
- { "field" => { "$exists" => true }}
3626
- )
1841
+ it "adds the $size selectors" do
1842
+ expect(selection.selector).to eq({
1843
+ "first" => { "$size" => 10 },
1844
+ "second" => { "$size" => 15 }
1845
+ })
3627
1846
  end
3628
1847
 
3629
1848
  it "returns a cloned query" do
3630
- expect(selection).to_not eq(query)
1849
+ expect(selection).to_not equal(query)
3631
1850
  end
3632
1851
  end
3633
1852
 
3634
- context "when providing string values" do
1853
+ context "when provided strings" do
3635
1854
 
3636
1855
  let(:selection) do
3637
- query.where(:field.exists => "t")
1856
+ query.with_size(first: "10", second: "15")
3638
1857
  end
3639
1858
 
3640
- it "adds the $exists criterion" do
3641
- expect(selection.selector).to eq(
3642
- { "field" => { "$exists" => true }}
3643
- )
1859
+ it "adds the $size selectors" do
1860
+ expect(selection.selector).to eq({
1861
+ "first" => { "$size" => 10 },
1862
+ "second" => { "$size" => 15 }
1863
+ })
3644
1864
  end
3645
1865
 
3646
1866
  it "returns a cloned query" do
3647
- expect(selection).to_not eq(query)
1867
+ expect(selection).to_not equal(query)
3648
1868
  end
3649
1869
  end
3650
1870
  end
1871
+ end
1872
+
1873
+ context "when chaining the criterion" do
3651
1874
 
3652
- context "when performing a $gt" do
1875
+ context "when the criterion are for different fields" do
3653
1876
 
3654
1877
  let(:selection) do
3655
- query.where(:field.gt => 10)
1878
+ query.with_size(first: 10).with_size(second: 15)
3656
1879
  end
3657
1880
 
3658
- it "adds the $gt criterion" do
3659
- expect(selection.selector).to eq(
3660
- { "field" => { "$gt" => 10 }}
3661
- )
1881
+ it "adds the $size selectors" do
1882
+ expect(selection.selector).to eq({
1883
+ "first" => { "$size" => 10 },
1884
+ "second" => { "$size" => 15 }
1885
+ })
3662
1886
  end
3663
1887
 
3664
1888
  it "returns a cloned query" do
3665
- expect(selection).to_not eq(query)
1889
+ expect(selection).to_not equal(query)
3666
1890
  end
3667
1891
  end
3668
1892
 
3669
- context "when performing a $gte" do
1893
+ context "when the criterion are on the same field" do
3670
1894
 
3671
1895
  let(:selection) do
3672
- query.where(:field.gte => 10)
1896
+ query.with_size(first: 10).with_size(first: 15)
3673
1897
  end
3674
1898
 
3675
- it "adds the $gte criterion" do
3676
- expect(selection.selector).to eq(
3677
- { "field" => { "$gte" => 10 }}
3678
- )
1899
+ it "overwrites the first $size selector" do
1900
+ expect(selection.selector).to eq({
1901
+ "first" => { "$size" => 15 }
1902
+ })
3679
1903
  end
3680
1904
 
3681
1905
  it "returns a cloned query" do
3682
- expect(selection).to_not eq(query)
1906
+ expect(selection).to_not equal(query)
3683
1907
  end
3684
1908
  end
1909
+ end
1910
+ end
3685
1911
 
3686
- context "when performing an $in" do
1912
+ describe "#with_type" do
3687
1913
 
3688
- let(:selection) do
3689
- query.where(:field.in => [ 1, 2 ])
3690
- end
1914
+ let(:query_method) { :with_type }
3691
1915
 
3692
- it "adds the $in criterion" do
3693
- expect(selection.selector).to eq({ "field" => { "$in" => [ 1, 2 ] }})
3694
- end
1916
+ it_behaves_like 'requires an argument'
1917
+ it_behaves_like 'requires a non-nil argument'
3695
1918
 
3696
- it "returns a cloned query" do
3697
- expect(selection).to_not eq(query)
3698
- end
3699
- end
1919
+ context "when provided a single criterion" do
3700
1920
 
3701
- context "when performing a $lt" do
1921
+ context "when provided an integer" do
3702
1922
 
3703
1923
  let(:selection) do
3704
- query.where(:field.lt => 10)
1924
+ query.with_type(field: 10)
3705
1925
  end
3706
1926
 
3707
- it "adds the $lt criterion" do
3708
- expect(selection.selector).to eq(
3709
- { "field" => { "$lt" => 10 }}
3710
- )
1927
+ it "adds the $type selector" do
1928
+ expect(selection.selector).to eq({
1929
+ "field" => { "$type" => 10 }
1930
+ })
3711
1931
  end
3712
1932
 
3713
1933
  it "returns a cloned query" do
3714
- expect(selection).to_not eq(query)
1934
+ expect(selection).to_not equal(query)
3715
1935
  end
3716
1936
  end
3717
1937
 
3718
- context "when performing a $lte" do
1938
+ context "when provided a string" do
3719
1939
 
3720
1940
  let(:selection) do
3721
- query.where(:field.lte => 10)
1941
+ query.with_type(field: "10")
3722
1942
  end
3723
1943
 
3724
- it "adds the $lte criterion" do
3725
- expect(selection.selector).to eq(
3726
- { "field" => { "$lte" => 10 }}
3727
- )
1944
+ it "adds the $type selector" do
1945
+ expect(selection.selector).to eq({
1946
+ "field" => { "$type" => 10 }
1947
+ })
3728
1948
  end
3729
1949
 
3730
1950
  it "returns a cloned query" do
3731
- expect(selection).to_not eq(query)
1951
+ expect(selection).to_not equal(query)
3732
1952
  end
3733
1953
  end
1954
+ end
3734
1955
 
3735
- context "when performing a $mod" do
1956
+ context "when provided multiple criterion" do
1957
+
1958
+ context "when the criterion are for different fields" do
3736
1959
 
3737
1960
  let(:selection) do
3738
- query.where(:field.mod => [ 10, 1 ])
1961
+ query.with_type(first: 10, second: 15)
3739
1962
  end
3740
1963
 
3741
- it "adds the $lte criterion" do
3742
- expect(selection.selector).to eq(
3743
- { "field" => { "$mod" => [ 10, 1 ]}}
3744
- )
1964
+ it "adds the $type selectors" do
1965
+ expect(selection.selector).to eq({
1966
+ "first" => { "$type" => 10 },
1967
+ "second" => { "$type" => 15 }
1968
+ })
3745
1969
  end
3746
1970
 
3747
1971
  it "returns a cloned query" do
3748
- expect(selection).to_not eq(query)
1972
+ expect(selection).to_not equal(query)
3749
1973
  end
3750
1974
  end
1975
+ end
1976
+
1977
+ context "when chaining the criterion" do
3751
1978
 
3752
- context "when performing a $ne" do
1979
+ context "when the criterion are for different fields" do
3753
1980
 
3754
1981
  let(:selection) do
3755
- query.where(:field.ne => 10)
1982
+ query.with_type(first: 10).with_type(second: 15)
3756
1983
  end
3757
1984
 
3758
- it "adds the $ne criterion" do
3759
- expect(selection.selector).to eq(
3760
- { "field" => { "$ne" => 10 }}
3761
- )
1985
+ it "adds the $type selectors" do
1986
+ expect(selection.selector).to eq({
1987
+ "first" => { "$type" => 10 },
1988
+ "second" => { "$type" => 15 }
1989
+ })
3762
1990
  end
3763
1991
 
3764
1992
  it "returns a cloned query" do
3765
- expect(selection).to_not eq(query)
1993
+ expect(selection).to_not equal(query)
3766
1994
  end
3767
1995
  end
3768
1996
 
3769
- context "when performing a $near" do
1997
+ context "when the criterion are on the same field" do
3770
1998
 
3771
1999
  let(:selection) do
3772
- query.where(:field.near => [ 1, 1 ])
2000
+ query.with_type(first: 10).with_type(first: 15)
3773
2001
  end
3774
2002
 
3775
- it "adds the $near criterion" do
3776
- expect(selection.selector).to eq(
3777
- { "field" => { "$near" => [ 1, 1 ] }}
3778
- )
2003
+ it "overwrites the first $type selector" do
2004
+ expect(selection.selector).to eq({
2005
+ "first" => { "$type" => 15 }
2006
+ })
3779
2007
  end
3780
2008
 
3781
2009
  it "returns a cloned query" do
3782
- expect(selection).to_not eq(query)
2010
+ expect(selection).to_not equal(query)
3783
2011
  end
3784
2012
  end
2013
+ end
2014
+ end
3785
2015
 
3786
- context "when performing a $nearSphere" do
3787
-
3788
- let(:selection) do
3789
- query.where(:field.near_sphere => [ 1, 1 ])
3790
- end
2016
+ describe "#text_search" do
3791
2017
 
3792
- it "adds the $nearSphere criterion" do
3793
- expect(selection.selector).to eq(
3794
- { "field" => { "$nearSphere" => [ 1, 1 ] }}
3795
- )
3796
- end
2018
+ context "when providing a search string" do
3797
2019
 
3798
- it "returns a cloned query" do
3799
- expect(selection).to_not eq(query)
3800
- end
2020
+ let(:selection) do
2021
+ query.text_search("testing")
3801
2022
  end
3802
2023
 
3803
- context "when performing a $nin" do
3804
-
3805
- let(:selection) do
3806
- query.where(:field.nin => [ 1, 2 ])
3807
- end
3808
-
3809
- it "adds the $nin criterion" do
3810
- expect(selection.selector).to eq({ "field" => { "$nin" => [ 1, 2 ] }})
3811
- end
2024
+ it "constructs a text search document" do
2025
+ expect(selection.selector).to eq({ '$text' => { '$search' => "testing" }})
2026
+ end
3812
2027
 
3813
- it "returns a cloned query" do
3814
- expect(selection).to_not eq(query)
3815
- end
2028
+ it "returns the cloned selectable" do
2029
+ expect(selection).to be_a(Mongoid::Criteria::Queryable::Selectable)
3816
2030
  end
3817
2031
 
3818
- context "when performing a $not" do
2032
+ context "when providing text search options" do
3819
2033
 
3820
2034
  let(:selection) do
3821
- query.where(:field.not => /test/)
3822
- end
3823
-
3824
- it "adds the $not criterion" do
3825
- expect(selection.selector).to eq({ "field" => { "$not" => /test/ }})
2035
+ query.text_search("essais", { :$language => "fr" })
3826
2036
  end
3827
2037
 
3828
- it "returns a cloned query" do
3829
- expect(selection).to_not eq(query)
2038
+ it "constructs a text search document" do
2039
+ expect(selection.selector['$text']['$search']).to eq("essais")
3830
2040
  end
3831
- end
3832
2041
 
3833
- context "when performing a $size" do
3834
-
3835
- context "when providing an integer" do
3836
-
3837
- let(:selection) do
3838
- query.where(:field.with_size => 10)
3839
- end
3840
-
3841
- it "adds the $size criterion" do
3842
- expect(selection.selector).to eq(
3843
- { "field" => { "$size" => 10 }}
3844
- )
3845
- end
3846
-
3847
- it "returns a cloned query" do
3848
- expect(selection).to_not eq(query)
3849
- end
2042
+ it "add the options to the text search document" do
2043
+ expect(selection.selector['$text'][:$language]).to eq("fr")
3850
2044
  end
3851
2045
 
3852
- context "when providing a string" do
3853
-
3854
- let(:selection) do
3855
- query.where(:field.with_size => "10")
3856
- end
3857
-
3858
- it "adds the $size criterion" do
3859
- expect(selection.selector).to eq(
3860
- { "field" => { "$size" => 10 }}
3861
- )
3862
- end
3863
-
3864
- it "returns a cloned query" do
3865
- expect(selection).to_not eq(query)
3866
- end
3867
- end
2046
+ it_behaves_like "returns a cloned query"
3868
2047
  end
2048
+ end
3869
2049
 
3870
- context "when performing a $type" do
3871
-
3872
- let(:selection) do
3873
- query.where(:field.with_type => 10)
3874
- end
3875
-
3876
- it "adds the $type criterion" do
3877
- expect(selection.selector).to eq(
3878
- { "field" => { "$type" => 10 }}
3879
- )
3880
- end
2050
+ context 'when given more than once' do
2051
+ let(:selection) do
2052
+ query.text_search("one").text_search('two')
2053
+ end
3881
2054
 
3882
- it "returns a cloned query" do
3883
- expect(selection).to_not eq(query)
3884
- end
2055
+ # MongoDB server can only handle one text expression at a time,
2056
+ # per https://docs.mongodb.com/manual/reference/operator/query/text/.
2057
+ # Nonetheless we test that the query is built correctly when
2058
+ # a user supplies more than one text condition.
2059
+ it 'merges conditions' do
2060
+ expect(Mongoid.logger).to receive(:warn)
2061
+ expect(selection.selector).to eq('$and' => [
2062
+ {'$text' => {'$search' => 'one'}}
2063
+ ],
2064
+ '$text' => {'$search' => 'two'},
2065
+ )
3885
2066
  end
3886
2067
  end
3887
2068
  end
@@ -3894,7 +2075,7 @@ describe Mongoid::Criteria::Queryable::Selectable do
3894
2075
  :field.all
3895
2076
  end
3896
2077
 
3897
- it "returns a selecton key" do
2078
+ it "returns a selection key" do
3898
2079
  expect(key).to be_a(Mongoid::Criteria::Queryable::Key)
3899
2080
  end
3900
2081
 
@@ -3913,7 +2094,7 @@ describe Mongoid::Criteria::Queryable::Selectable do
3913
2094
  :field.elem_match
3914
2095
  end
3915
2096
 
3916
- it "returns a selecton key" do
2097
+ it "returns a selection key" do
3917
2098
  expect(key).to be_a(Mongoid::Criteria::Queryable::Key)
3918
2099
  end
3919
2100
 
@@ -3932,7 +2113,7 @@ describe Mongoid::Criteria::Queryable::Selectable do
3932
2113
  :field.exists
3933
2114
  end
3934
2115
 
3935
- it "returns a selecton key" do
2116
+ it "returns a selection key" do
3936
2117
  expect(key).to be_a(Mongoid::Criteria::Queryable::Key)
3937
2118
  end
3938
2119
 
@@ -3951,7 +2132,7 @@ describe Mongoid::Criteria::Queryable::Selectable do
3951
2132
  :field.gt
3952
2133
  end
3953
2134
 
3954
- it "returns a selecton key" do
2135
+ it "returns a selection key" do
3955
2136
  expect(key).to be_a(Mongoid::Criteria::Queryable::Key)
3956
2137
  end
3957
2138
 
@@ -3970,7 +2151,7 @@ describe Mongoid::Criteria::Queryable::Selectable do
3970
2151
  :field.gte
3971
2152
  end
3972
2153
 
3973
- it "returns a selecton key" do
2154
+ it "returns a selection key" do
3974
2155
  expect(key).to be_a(Mongoid::Criteria::Queryable::Key)
3975
2156
  end
3976
2157
 
@@ -3989,7 +2170,7 @@ describe Mongoid::Criteria::Queryable::Selectable do
3989
2170
  :field.in
3990
2171
  end
3991
2172
 
3992
- it "returns a selecton key" do
2173
+ it "returns a selection key" do
3993
2174
  expect(key).to be_a(Mongoid::Criteria::Queryable::Key)
3994
2175
  end
3995
2176
 
@@ -4008,7 +2189,7 @@ describe Mongoid::Criteria::Queryable::Selectable do
4008
2189
  :field.lt
4009
2190
  end
4010
2191
 
4011
- it "returns a selecton key" do
2192
+ it "returns a selection key" do
4012
2193
  expect(key).to be_a(Mongoid::Criteria::Queryable::Key)
4013
2194
  end
4014
2195
 
@@ -4027,7 +2208,7 @@ describe Mongoid::Criteria::Queryable::Selectable do
4027
2208
  :field.lte
4028
2209
  end
4029
2210
 
4030
- it "returns a selecton key" do
2211
+ it "returns a selection key" do
4031
2212
  expect(key).to be_a(Mongoid::Criteria::Queryable::Key)
4032
2213
  end
4033
2214
 
@@ -4046,7 +2227,7 @@ describe Mongoid::Criteria::Queryable::Selectable do
4046
2227
  :field.mod
4047
2228
  end
4048
2229
 
4049
- it "returns a selecton key" do
2230
+ it "returns a selection key" do
4050
2231
  expect(key).to be_a(Mongoid::Criteria::Queryable::Key)
4051
2232
  end
4052
2233
 
@@ -4065,7 +2246,7 @@ describe Mongoid::Criteria::Queryable::Selectable do
4065
2246
  :field.ne
4066
2247
  end
4067
2248
 
4068
- it "returns a selecton key" do
2249
+ it "returns a selection key" do
4069
2250
  expect(key).to be_a(Mongoid::Criteria::Queryable::Key)
4070
2251
  end
4071
2252
 
@@ -4084,7 +2265,7 @@ describe Mongoid::Criteria::Queryable::Selectable do
4084
2265
  :field.near
4085
2266
  end
4086
2267
 
4087
- it "returns a selecton key" do
2268
+ it "returns a selection key" do
4088
2269
  expect(key).to be_a(Mongoid::Criteria::Queryable::Key)
4089
2270
  end
4090
2271
 
@@ -4103,7 +2284,7 @@ describe Mongoid::Criteria::Queryable::Selectable do
4103
2284
  :field.near_sphere
4104
2285
  end
4105
2286
 
4106
- it "returns a selecton key" do
2287
+ it "returns a selection key" do
4107
2288
  expect(key).to be_a(Mongoid::Criteria::Queryable::Key)
4108
2289
  end
4109
2290
 
@@ -4122,7 +2303,7 @@ describe Mongoid::Criteria::Queryable::Selectable do
4122
2303
  :field.nin
4123
2304
  end
4124
2305
 
4125
- it "returns a selecton key" do
2306
+ it "returns a selection key" do
4126
2307
  expect(key).to be_a(Mongoid::Criteria::Queryable::Key)
4127
2308
  end
4128
2309
 
@@ -4161,7 +2342,7 @@ describe Mongoid::Criteria::Queryable::Selectable do
4161
2342
  :field.with_size
4162
2343
  end
4163
2344
 
4164
- it "returns a selecton key" do
2345
+ it "returns a selection key" do
4165
2346
  expect(key).to be_a(Mongoid::Criteria::Queryable::Key)
4166
2347
  end
4167
2348
 
@@ -4180,7 +2361,7 @@ describe Mongoid::Criteria::Queryable::Selectable do
4180
2361
  :field.with_type
4181
2362
  end
4182
2363
 
4183
- it "returns a selecton key" do
2364
+ it "returns a selection key" do
4184
2365
  expect(key).to be_a(Mongoid::Criteria::Queryable::Key)
4185
2366
  end
4186
2367
 
@@ -4198,7 +2379,7 @@ describe Mongoid::Criteria::Queryable::Selectable do
4198
2379
 
4199
2380
  context "when using the strategies via methods" do
4200
2381
 
4201
- context "when the values are a hash" do
2382
+ context "when different operators are specified" do
4202
2383
 
4203
2384
  let(:selection) do
4204
2385
  query.gt(field: 5).lt(field: 10).ne(field: 7)
@@ -4206,26 +2387,26 @@ describe Mongoid::Criteria::Queryable::Selectable do
4206
2387
 
4207
2388
  it "merges the strategies on the same field" do
4208
2389
  expect(selection.selector).to eq(
4209
- { "field" => { "$gt" => 5, "$lt" => 10, "$ne" => 7 }}
2390
+ "field" => { "$gt" => 5, "$lt" => 10, "$ne" => 7 }
4210
2391
  )
4211
2392
  end
4212
2393
  end
4213
2394
 
4214
- context "when the values are not hashes" do
2395
+ context "when the same operator is specified" do
4215
2396
 
4216
2397
  let(:selection) do
4217
2398
  query.where(field: 5).where(field: 10)
4218
2399
  end
4219
2400
 
4220
- it "overrides the previous field" do
4221
- expect(selection.selector).to eq({ "field" => 10 })
2401
+ it "combines conditions" do
2402
+ expect(selection.selector).to eq("field" => 5, '$and' => [{'field' => 10}] )
4222
2403
  end
4223
2404
  end
4224
2405
  end
4225
2406
 
4226
2407
  context "when using the strategies via #where" do
4227
2408
 
4228
- context "when the values are a hash" do
2409
+ context "when using complex keys with different operators" do
4229
2410
 
4230
2411
  let(:selection) do
4231
2412
  query.where(:field.gt => 5, :field.lt => 10, :field.ne => 7)
@@ -4233,10 +2414,57 @@ describe Mongoid::Criteria::Queryable::Selectable do
4233
2414
 
4234
2415
  it "merges the strategies on the same field" do
4235
2416
  expect(selection.selector).to eq(
4236
- { "field" => { "$gt" => 5, "$lt" => 10, "$ne" => 7 }}
2417
+ "field" => { "$gt" => 5, "$lt" => 10, "$ne" => 7 }
4237
2418
  )
4238
2419
  end
4239
2420
  end
4240
2421
  end
4241
2422
  end
2423
+
2424
+ describe "Mongoid.overwrite_chained_operators" do
2425
+ [ :eq, :elem_match, :gt, :gte, :lt, :lte, :mod, :ne, :near, :near_sphere ].each do |meth|
2426
+
2427
+ context "when chaining the #{meth} method when using the same field" do
2428
+ let(:op) do
2429
+ {
2430
+ eq: "$eq",
2431
+ elem_match: "$elemMatch",
2432
+ gt: "$gt",
2433
+ gte: "$gte",
2434
+ lt: "$lt",
2435
+ lte: "$lte",
2436
+ mod: "$mod",
2437
+ ne: "$ne",
2438
+ near: "$near",
2439
+ near_sphere: "$nearSphere"
2440
+ }[meth]
2441
+ end
2442
+
2443
+ let(:criteria) do
2444
+ Band.send(meth, {views: 1}).send(meth, {views:2})
2445
+ end
2446
+
2447
+ context "when overwrite_chained_operators is true" do
2448
+ config_override :overwrite_chained_operators, true
2449
+
2450
+ it "overrides the previous operators" do
2451
+ expect(criteria.selector).to eq({
2452
+ "views" => { op => 2 },
2453
+ })
2454
+ end
2455
+ end
2456
+
2457
+ context "when overwrite_chained_operators is false" do
2458
+ config_override :overwrite_chained_operators, false
2459
+
2460
+ it "overrides the previous operators" do
2461
+ expect(criteria.selector).to eq({
2462
+ "views" => { op => 1 },
2463
+ "$and" => [{ "views" => { op => 2 } }]
2464
+ })
2465
+ end
2466
+ end
2467
+ end
2468
+ end
2469
+ end
4242
2470
  end