mongoid 7.0.0 → 7.4.0

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