mongoid 6.4.4 → 7.3.2

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