mongoid 7.0.12 → 7.3.3

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 (1039) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/CHANGELOG.md +13 -13
  4. data/README.md +32 -19
  5. data/Rakefile +49 -0
  6. data/lib/config/locales/en.yml +113 -55
  7. data/lib/mongoid/association/accessors.rb +143 -53
  8. data/lib/mongoid/association/bindable.rb +7 -5
  9. data/lib/mongoid/association/builders.rb +4 -3
  10. data/lib/mongoid/association/constrainable.rb +5 -3
  11. data/lib/mongoid/association/depending.rb +10 -12
  12. data/lib/mongoid/association/eager_loadable.rb +2 -0
  13. data/lib/mongoid/association/embedded/batchable.rb +5 -3
  14. data/lib/mongoid/association/embedded/cyclic.rb +8 -6
  15. data/lib/mongoid/association/embedded/embedded_in/binding.rb +4 -1
  16. data/lib/mongoid/association/embedded/embedded_in/buildable.rb +8 -2
  17. data/lib/mongoid/association/embedded/embedded_in/proxy.rb +15 -12
  18. data/lib/mongoid/association/embedded/embedded_in.rb +7 -4
  19. data/lib/mongoid/association/embedded/embeds_many/binding.rb +5 -2
  20. data/lib/mongoid/association/embedded/embeds_many/buildable.rb +9 -3
  21. data/lib/mongoid/association/embedded/embeds_many/proxy.rb +60 -50
  22. data/lib/mongoid/association/embedded/embeds_many.rb +7 -4
  23. data/lib/mongoid/association/embedded/embeds_one/binding.rb +5 -2
  24. data/lib/mongoid/association/embedded/embeds_one/buildable.rb +10 -4
  25. data/lib/mongoid/association/embedded/embeds_one/proxy.rb +17 -14
  26. data/lib/mongoid/association/embedded/embeds_one.rb +7 -4
  27. data/lib/mongoid/association/embedded.rb +3 -0
  28. data/lib/mongoid/association/macros.rb +38 -36
  29. data/lib/mongoid/association/many.rb +16 -13
  30. data/lib/mongoid/association/marshalable.rb +3 -1
  31. data/lib/mongoid/association/nested/many.rb +18 -16
  32. data/lib/mongoid/association/nested/nested_buildable.rb +6 -3
  33. data/lib/mongoid/association/nested/one.rb +15 -11
  34. data/lib/mongoid/association/nested.rb +4 -1
  35. data/lib/mongoid/association/one.rb +3 -1
  36. data/lib/mongoid/association/options.rb +9 -6
  37. data/lib/mongoid/association/proxy.rb +37 -15
  38. data/lib/mongoid/association/referenced/auto_save.rb +6 -3
  39. data/lib/mongoid/association/referenced/belongs_to/binding.rb +4 -2
  40. data/lib/mongoid/association/referenced/belongs_to/buildable.rb +7 -4
  41. data/lib/mongoid/association/referenced/belongs_to/eager.rb +40 -2
  42. data/lib/mongoid/association/referenced/belongs_to/proxy.rb +16 -14
  43. data/lib/mongoid/association/referenced/belongs_to.rb +6 -3
  44. data/lib/mongoid/association/referenced/counter_cache.rb +2 -0
  45. data/lib/mongoid/association/referenced/eager.rb +37 -15
  46. data/lib/mongoid/association/referenced/has_and_belongs_to_many/binding.rb +12 -6
  47. data/lib/mongoid/association/referenced/has_and_belongs_to_many/buildable.rb +5 -2
  48. data/lib/mongoid/association/referenced/has_and_belongs_to_many/eager.rb +2 -0
  49. data/lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb +26 -19
  50. data/lib/mongoid/association/referenced/has_and_belongs_to_many.rb +13 -6
  51. data/lib/mongoid/association/referenced/has_many/binding.rb +3 -1
  52. data/lib/mongoid/association/referenced/has_many/buildable.rb +5 -2
  53. data/lib/mongoid/association/referenced/has_many/eager.rb +2 -0
  54. data/lib/mongoid/association/referenced/has_many/enumerable.rb +493 -457
  55. data/lib/mongoid/association/referenced/has_many/proxy.rb +57 -47
  56. data/lib/mongoid/association/referenced/has_many.rb +7 -4
  57. data/lib/mongoid/association/referenced/has_one/binding.rb +4 -2
  58. data/lib/mongoid/association/referenced/has_one/buildable.rb +17 -2
  59. data/lib/mongoid/association/referenced/has_one/eager.rb +2 -0
  60. data/lib/mongoid/association/referenced/has_one/nested_builder.rb +13 -11
  61. data/lib/mongoid/association/referenced/has_one/proxy.rb +23 -16
  62. data/lib/mongoid/association/referenced/has_one.rb +5 -2
  63. data/lib/mongoid/association/referenced/syncable.rb +7 -5
  64. data/lib/mongoid/association/referenced.rb +3 -0
  65. data/lib/mongoid/association/reflections.rb +7 -5
  66. data/lib/mongoid/association/relatable.rb +19 -14
  67. data/lib/mongoid/association.rb +9 -6
  68. data/lib/mongoid/atomic/modifiers.rb +25 -2
  69. data/lib/mongoid/atomic/paths/embedded/many.rb +4 -2
  70. data/lib/mongoid/atomic/paths/embedded/one.rb +4 -2
  71. data/lib/mongoid/atomic/paths/embedded.rb +2 -0
  72. data/lib/mongoid/atomic/paths/root.rb +4 -2
  73. data/lib/mongoid/atomic/paths.rb +2 -0
  74. data/lib/mongoid/atomic.rb +28 -2
  75. data/lib/mongoid/attributes/dynamic.rb +3 -1
  76. data/lib/mongoid/attributes/nested.rb +7 -5
  77. data/lib/mongoid/attributes/processing.rb +8 -6
  78. data/lib/mongoid/attributes/projector.rb +120 -0
  79. data/lib/mongoid/attributes/readonly.rb +3 -1
  80. data/lib/mongoid/attributes.rb +46 -27
  81. data/lib/mongoid/cacheable.rb +5 -3
  82. data/lib/mongoid/changeable.rb +3 -1
  83. data/lib/mongoid/clients/factory.rb +42 -10
  84. data/lib/mongoid/clients/options.rb +10 -8
  85. data/lib/mongoid/clients/sessions.rb +3 -0
  86. data/lib/mongoid/clients/storage_options.rb +7 -5
  87. data/lib/mongoid/clients/validators/storage.rb +2 -0
  88. data/lib/mongoid/clients/validators.rb +2 -0
  89. data/lib/mongoid/clients.rb +3 -1
  90. data/lib/mongoid/composable.rb +5 -2
  91. data/lib/mongoid/config/environment.rb +11 -1
  92. data/lib/mongoid/config/options.rb +20 -12
  93. data/lib/mongoid/config/validators/client.rb +2 -0
  94. data/lib/mongoid/config/validators/option.rb +2 -0
  95. data/lib/mongoid/config/validators.rb +2 -0
  96. data/lib/mongoid/config.rb +75 -12
  97. data/lib/mongoid/contextual/aggregable/memory.rb +3 -1
  98. data/lib/mongoid/contextual/aggregable/mongo.rb +13 -9
  99. data/lib/mongoid/contextual/atomic.rb +31 -8
  100. data/lib/mongoid/contextual/command.rb +2 -0
  101. data/lib/mongoid/contextual/geo_near.rb +5 -3
  102. data/lib/mongoid/contextual/map_reduce.rb +5 -2
  103. data/lib/mongoid/contextual/memory.rb +4 -2
  104. data/lib/mongoid/contextual/mongo.rb +29 -5
  105. data/lib/mongoid/contextual/none.rb +5 -0
  106. data/lib/mongoid/contextual/queryable.rb +2 -0
  107. data/lib/mongoid/contextual.rb +7 -4
  108. data/lib/mongoid/copyable.rb +11 -5
  109. data/lib/mongoid/criteria/findable.rb +12 -2
  110. data/lib/mongoid/criteria/includable.rb +8 -6
  111. data/lib/mongoid/criteria/inspectable.rb +2 -0
  112. data/lib/mongoid/criteria/marshalable.rb +2 -0
  113. data/lib/mongoid/criteria/modifiable.rb +2 -0
  114. data/lib/mongoid/criteria/options.rb +2 -0
  115. data/lib/mongoid/criteria/permission.rb +2 -0
  116. data/lib/mongoid/criteria/queryable/aggregable.rb +2 -0
  117. data/lib/mongoid/criteria/queryable/expandable.rb +69 -0
  118. data/lib/mongoid/criteria/queryable/extensions/array.rb +3 -1
  119. data/lib/mongoid/criteria/queryable/extensions/big_decimal.rb +3 -1
  120. data/lib/mongoid/criteria/queryable/extensions/boolean.rb +3 -1
  121. data/lib/mongoid/criteria/queryable/extensions/date.rb +3 -1
  122. data/lib/mongoid/criteria/queryable/extensions/date_time.rb +5 -6
  123. data/lib/mongoid/criteria/queryable/extensions/hash.rb +3 -1
  124. data/lib/mongoid/criteria/queryable/extensions/nil_class.rb +3 -1
  125. data/lib/mongoid/criteria/queryable/extensions/numeric.rb +3 -1
  126. data/lib/mongoid/criteria/queryable/extensions/object.rb +3 -1
  127. data/lib/mongoid/criteria/queryable/extensions/range.rb +3 -1
  128. data/lib/mongoid/criteria/queryable/extensions/regexp.rb +6 -4
  129. data/lib/mongoid/criteria/queryable/extensions/set.rb +3 -1
  130. data/lib/mongoid/criteria/queryable/extensions/string.rb +3 -1
  131. data/lib/mongoid/criteria/queryable/extensions/symbol.rb +3 -1
  132. data/lib/mongoid/criteria/queryable/extensions/time.rb +3 -1
  133. data/lib/mongoid/criteria/queryable/extensions/time_with_zone.rb +3 -1
  134. data/lib/mongoid/criteria/queryable/extensions.rb +1 -3
  135. data/lib/mongoid/criteria/queryable/key.rb +35 -7
  136. data/lib/mongoid/criteria/queryable/macroable.rb +3 -1
  137. data/lib/mongoid/criteria/queryable/mergeable.rb +179 -11
  138. data/lib/mongoid/criteria/queryable/optional.rb +5 -3
  139. data/lib/mongoid/criteria/queryable/options.rb +2 -0
  140. data/lib/mongoid/criteria/queryable/pipeline.rb +5 -2
  141. data/lib/mongoid/criteria/queryable/selectable.rb +397 -98
  142. data/lib/mongoid/criteria/queryable/selector.rb +37 -8
  143. data/lib/mongoid/criteria/queryable/smash.rb +2 -0
  144. data/lib/mongoid/criteria/queryable/storable.rb +233 -0
  145. data/lib/mongoid/criteria/queryable.rb +7 -2
  146. data/lib/mongoid/criteria/scopable.rb +2 -0
  147. data/lib/mongoid/criteria.rb +79 -15
  148. data/lib/mongoid/document.rb +21 -20
  149. data/lib/mongoid/equality.rb +3 -2
  150. data/lib/mongoid/errors/ambiguous_relationship.rb +4 -2
  151. data/lib/mongoid/errors/callback.rb +2 -0
  152. data/lib/mongoid/errors/criteria_argument_required.rb +19 -0
  153. data/lib/mongoid/errors/delete_restriction.rb +10 -10
  154. data/lib/mongoid/errors/document_not_destroyed.rb +2 -0
  155. data/lib/mongoid/errors/document_not_found.rb +2 -0
  156. data/lib/mongoid/errors/eager_load.rb +6 -2
  157. data/lib/mongoid/errors/empty_config_file.rb +26 -0
  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_file.rb +26 -0
  161. data/lib/mongoid/errors/invalid_config_option.rb +2 -0
  162. data/lib/mongoid/errors/invalid_dependent_strategy.rb +2 -0
  163. data/lib/mongoid/errors/invalid_discriminator_key_target.rb +25 -0
  164. data/lib/mongoid/errors/invalid_elem_match_operator.rb +33 -0
  165. data/lib/mongoid/errors/invalid_estimated_count_criteria.rb +26 -0
  166. data/lib/mongoid/errors/invalid_expression_operator.rb +28 -0
  167. data/lib/mongoid/errors/invalid_field.rb +2 -0
  168. data/lib/mongoid/errors/invalid_field_operator.rb +33 -0
  169. data/lib/mongoid/errors/invalid_field_option.rb +2 -0
  170. data/lib/mongoid/errors/invalid_find.rb +2 -0
  171. data/lib/mongoid/errors/invalid_includes.rb +2 -0
  172. data/lib/mongoid/errors/invalid_index.rb +2 -0
  173. data/lib/mongoid/errors/invalid_options.rb +4 -2
  174. data/lib/mongoid/errors/invalid_path.rb +2 -0
  175. data/lib/mongoid/errors/invalid_persistence_option.rb +2 -0
  176. data/lib/mongoid/errors/invalid_query.rb +41 -0
  177. data/lib/mongoid/errors/invalid_relation.rb +4 -2
  178. data/lib/mongoid/errors/invalid_relation_option.rb +4 -2
  179. data/lib/mongoid/errors/invalid_scope.rb +2 -0
  180. data/lib/mongoid/errors/invalid_session_use.rb +2 -0
  181. data/lib/mongoid/errors/invalid_set_polymorphic_relation.rb +6 -4
  182. data/lib/mongoid/errors/invalid_storage_options.rb +2 -0
  183. data/lib/mongoid/errors/invalid_storage_parent.rb +2 -0
  184. data/lib/mongoid/errors/invalid_time.rb +2 -0
  185. data/lib/mongoid/errors/invalid_value.rb +2 -0
  186. data/lib/mongoid/errors/inverse_not_found.rb +3 -1
  187. data/lib/mongoid/errors/mixed_client_configuration.rb +2 -0
  188. data/lib/mongoid/errors/mixed_relations.rb +2 -0
  189. data/lib/mongoid/errors/mongoid_error.rb +3 -1
  190. data/lib/mongoid/errors/nested_attributes_metadata_not_found.rb +3 -1
  191. data/lib/mongoid/errors/no_client_config.rb +4 -2
  192. data/lib/mongoid/errors/no_client_database.rb +2 -0
  193. data/lib/mongoid/errors/no_client_hosts.rb +2 -0
  194. data/lib/mongoid/errors/no_clients_config.rb +2 -0
  195. data/lib/mongoid/errors/no_default_client.rb +3 -1
  196. data/lib/mongoid/errors/no_environment.rb +2 -0
  197. data/lib/mongoid/errors/no_map_reduce_output.rb +2 -0
  198. data/lib/mongoid/errors/no_metadata.rb +2 -0
  199. data/lib/mongoid/errors/no_parent.rb +2 -0
  200. data/lib/mongoid/errors/readonly_attribute.rb +2 -0
  201. data/lib/mongoid/errors/readonly_document.rb +2 -0
  202. data/lib/mongoid/errors/scope_overwrite.rb +2 -0
  203. data/lib/mongoid/errors/too_many_nested_attribute_records.rb +3 -0
  204. data/lib/mongoid/errors/unknown_attribute.rb +2 -0
  205. data/lib/mongoid/errors/unknown_model.rb +2 -0
  206. data/lib/mongoid/errors/unsaved_document.rb +2 -0
  207. data/lib/mongoid/errors/unsupported_javascript.rb +2 -0
  208. data/lib/mongoid/errors/validations.rb +2 -0
  209. data/lib/mongoid/errors.rb +12 -0
  210. data/lib/mongoid/evolvable.rb +4 -2
  211. data/lib/mongoid/extensions/array.rb +23 -6
  212. data/lib/mongoid/extensions/big_decimal.rb +2 -0
  213. data/lib/mongoid/extensions/boolean.rb +3 -2
  214. data/lib/mongoid/extensions/date.rb +13 -3
  215. data/lib/mongoid/extensions/date_time.rb +4 -3
  216. data/lib/mongoid/extensions/decimal128.rb +2 -0
  217. data/lib/mongoid/extensions/false_class.rb +3 -1
  218. data/lib/mongoid/extensions/float.rb +5 -3
  219. data/lib/mongoid/extensions/hash.rb +49 -9
  220. data/lib/mongoid/extensions/integer.rb +5 -3
  221. data/lib/mongoid/extensions/module.rb +2 -0
  222. data/lib/mongoid/extensions/nil_class.rb +2 -0
  223. data/lib/mongoid/extensions/object.rb +16 -4
  224. data/lib/mongoid/extensions/object_id.rb +2 -0
  225. data/lib/mongoid/extensions/range.rb +2 -0
  226. data/lib/mongoid/extensions/regexp.rb +2 -0
  227. data/lib/mongoid/extensions/set.rb +2 -0
  228. data/lib/mongoid/extensions/string.rb +18 -9
  229. data/lib/mongoid/extensions/symbol.rb +2 -0
  230. data/lib/mongoid/extensions/time.rb +14 -0
  231. data/lib/mongoid/extensions/time_with_zone.rb +14 -0
  232. data/lib/mongoid/extensions/true_class.rb +3 -1
  233. data/lib/mongoid/extensions.rb +3 -0
  234. data/lib/mongoid/factory.rb +52 -12
  235. data/lib/mongoid/fields/foreign_key.rb +3 -1
  236. data/lib/mongoid/fields/localized.rb +2 -0
  237. data/lib/mongoid/fields/standard.rb +6 -3
  238. data/lib/mongoid/fields/validators/macro.rb +38 -11
  239. data/lib/mongoid/fields/validators.rb +2 -0
  240. data/lib/mongoid/fields.rb +49 -6
  241. data/lib/mongoid/findable.rb +59 -18
  242. data/lib/mongoid/indexable/specification.rb +3 -1
  243. data/lib/mongoid/indexable/validators/options.rb +2 -0
  244. data/lib/mongoid/indexable.rb +5 -3
  245. data/lib/mongoid/inspectable.rb +4 -2
  246. data/lib/mongoid/interceptable.rb +10 -4
  247. data/lib/mongoid/loggable.rb +13 -7
  248. data/lib/mongoid/matchable.rb +2 -148
  249. data/lib/mongoid/matcher/all.rb +22 -0
  250. data/lib/mongoid/matcher/and.rb +21 -0
  251. data/lib/mongoid/matcher/bits.rb +41 -0
  252. data/lib/mongoid/matcher/bits_all_clear.rb +20 -0
  253. data/lib/mongoid/matcher/bits_all_set.rb +20 -0
  254. data/lib/mongoid/matcher/bits_any_clear.rb +20 -0
  255. data/lib/mongoid/matcher/bits_any_set.rb +20 -0
  256. data/lib/mongoid/matcher/elem_match.rb +36 -0
  257. data/lib/mongoid/matcher/elem_match_expression.rb +20 -0
  258. data/lib/mongoid/matcher/eq.rb +11 -0
  259. data/lib/mongoid/matcher/eq_impl.rb +32 -0
  260. data/lib/mongoid/matcher/eq_impl_with_regexp.rb +21 -0
  261. data/lib/mongoid/matcher/exists.rb +15 -0
  262. data/lib/mongoid/matcher/expression.rb +35 -0
  263. data/lib/mongoid/matcher/expression_operator.rb +19 -0
  264. data/lib/mongoid/matcher/field_expression.rb +62 -0
  265. data/lib/mongoid/matcher/field_operator.rb +54 -0
  266. data/lib/mongoid/matcher/gt.rb +17 -0
  267. data/lib/mongoid/matcher/gte.rb +17 -0
  268. data/lib/mongoid/matcher/in.rb +25 -0
  269. data/lib/mongoid/matcher/lt.rb +17 -0
  270. data/lib/mongoid/matcher/lte.rb +17 -0
  271. data/lib/mongoid/matcher/mod.rb +17 -0
  272. data/lib/mongoid/matcher/ne.rb +16 -0
  273. data/lib/mongoid/matcher/nin.rb +11 -0
  274. data/lib/mongoid/matcher/nor.rb +25 -0
  275. data/lib/mongoid/matcher/not.rb +29 -0
  276. data/lib/mongoid/matcher/or.rb +21 -0
  277. data/lib/mongoid/matcher/regex.rb +41 -0
  278. data/lib/mongoid/matcher/size.rb +26 -0
  279. data/lib/mongoid/matcher/type.rb +99 -0
  280. data/lib/mongoid/matcher.rb +110 -0
  281. data/lib/mongoid/persistable/creatable.rb +3 -1
  282. data/lib/mongoid/persistable/deletable.rb +5 -4
  283. data/lib/mongoid/persistable/destroyable.rb +11 -3
  284. data/lib/mongoid/persistable/incrementable.rb +6 -2
  285. data/lib/mongoid/persistable/logical.rb +4 -1
  286. data/lib/mongoid/persistable/poppable.rb +3 -1
  287. data/lib/mongoid/persistable/pullable.rb +3 -1
  288. data/lib/mongoid/persistable/pushable.rb +3 -1
  289. data/lib/mongoid/persistable/renamable.rb +10 -3
  290. data/lib/mongoid/persistable/savable.rb +3 -1
  291. data/lib/mongoid/persistable/settable.rb +3 -1
  292. data/lib/mongoid/persistable/unsettable.rb +8 -3
  293. data/lib/mongoid/persistable/updatable.rb +30 -3
  294. data/lib/mongoid/persistable/upsertable.rb +3 -1
  295. data/lib/mongoid/persistable.rb +133 -15
  296. data/lib/mongoid/persistence_context.rb +24 -10
  297. data/lib/mongoid/positional.rb +2 -0
  298. data/lib/mongoid/query_cache.rb +118 -100
  299. data/lib/mongoid/railtie.rb +3 -1
  300. data/lib/mongoid/railties/controller_runtime.rb +4 -1
  301. data/lib/mongoid/railties/database.rake +9 -0
  302. data/lib/mongoid/reloadable.rb +11 -4
  303. data/lib/mongoid/scopable.rb +2 -1
  304. data/lib/mongoid/selectable.rb +8 -8
  305. data/lib/mongoid/serializable.rb +24 -14
  306. data/lib/mongoid/shardable.rb +80 -10
  307. data/lib/mongoid/stateful.rb +3 -1
  308. data/lib/mongoid/stringified_symbol.rb +53 -0
  309. data/lib/mongoid/tasks/database.rake +12 -5
  310. data/lib/mongoid/tasks/database.rb +85 -0
  311. data/lib/mongoid/threaded/lifecycle.rb +2 -0
  312. data/lib/mongoid/threaded.rb +2 -0
  313. data/lib/mongoid/timestamps/created/short.rb +2 -0
  314. data/lib/mongoid/timestamps/created.rb +3 -1
  315. data/lib/mongoid/timestamps/short.rb +2 -0
  316. data/lib/mongoid/timestamps/timeless.rb +6 -2
  317. data/lib/mongoid/timestamps/updated/short.rb +2 -0
  318. data/lib/mongoid/timestamps/updated.rb +3 -1
  319. data/lib/mongoid/timestamps.rb +3 -1
  320. data/lib/mongoid/touchable.rb +53 -16
  321. data/lib/mongoid/traversable.rb +115 -6
  322. data/lib/mongoid/validatable/associated.rb +5 -3
  323. data/lib/mongoid/validatable/format.rb +2 -0
  324. data/lib/mongoid/validatable/length.rb +2 -0
  325. data/lib/mongoid/validatable/localizable.rb +2 -0
  326. data/lib/mongoid/validatable/macros.rb +2 -0
  327. data/lib/mongoid/validatable/presence.rb +7 -5
  328. data/lib/mongoid/validatable/queryable.rb +2 -0
  329. data/lib/mongoid/validatable/uniqueness.rb +5 -3
  330. data/lib/mongoid/validatable.rb +7 -5
  331. data/lib/mongoid/version.rb +2 -1
  332. data/lib/mongoid.rb +34 -2
  333. data/lib/rails/generators/mongoid/config/config_generator.rb +10 -1
  334. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +45 -30
  335. data/lib/rails/generators/mongoid/model/model_generator.rb +3 -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 +19 -4
  340. data/spec/config/mongoid.yml +1 -0
  341. data/spec/integration/app_spec.rb +246 -94
  342. data/spec/integration/associations/belongs_to_spec.rb +3 -0
  343. data/spec/integration/associations/embedded_spec.rb +207 -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/contextual/empty_spec.rb +142 -0
  356. data/spec/integration/criteria/date_field_spec.rb +1 -1
  357. data/spec/integration/criteria/default_scope_spec.rb +21 -0
  358. data/spec/integration/criteria/logical_spec.rb +94 -0
  359. data/spec/integration/discriminator_key_spec.rb +354 -0
  360. data/spec/integration/discriminator_value_spec.rb +207 -0
  361. data/spec/integration/document_spec.rb +30 -0
  362. data/spec/integration/i18n_fallbacks_spec.rb +90 -0
  363. data/spec/integration/{matchable_spec.rb → matcher_examples_spec.rb} +120 -41
  364. data/spec/integration/matcher_operator_data/all.yml +140 -0
  365. data/spec/integration/matcher_operator_data/and.yml +93 -0
  366. data/spec/integration/matcher_operator_data/bits_all_clear.yml +159 -0
  367. data/spec/integration/matcher_operator_data/bits_all_set.yml +159 -0
  368. data/spec/integration/matcher_operator_data/bits_any_clear.yml +159 -0
  369. data/spec/integration/matcher_operator_data/bits_any_set.yml +159 -0
  370. data/spec/integration/matcher_operator_data/comment.yml +22 -0
  371. data/spec/integration/matcher_operator_data/elem_match.yml +409 -0
  372. data/spec/integration/matcher_operator_data/elem_match_expr.yml +213 -0
  373. data/spec/integration/matcher_operator_data/eq.yml +191 -0
  374. data/spec/integration/matcher_operator_data/exists.yml +213 -0
  375. data/spec/integration/matcher_operator_data/generic_op.yml +17 -0
  376. data/spec/integration/matcher_operator_data/gt.yml +132 -0
  377. data/spec/integration/matcher_operator_data/gt_types.yml +63 -0
  378. data/spec/integration/matcher_operator_data/gte.yml +132 -0
  379. data/spec/integration/matcher_operator_data/gte_types.yml +15 -0
  380. data/spec/integration/matcher_operator_data/implicit.yml +331 -0
  381. data/spec/integration/matcher_operator_data/implicit_traversal.yml +112 -0
  382. data/spec/integration/matcher_operator_data/in.yml +210 -0
  383. data/spec/integration/matcher_operator_data/invalid_op.yml +59 -0
  384. data/spec/integration/matcher_operator_data/invalid_syntax.yml +39 -0
  385. data/spec/integration/matcher_operator_data/lt.yml +132 -0
  386. data/spec/integration/matcher_operator_data/lt_types.yml +15 -0
  387. data/spec/integration/matcher_operator_data/lte.yml +132 -0
  388. data/spec/integration/matcher_operator_data/lte_types.yml +15 -0
  389. data/spec/integration/matcher_operator_data/mod.yml +55 -0
  390. data/spec/integration/matcher_operator_data/multiple.yml +29 -0
  391. data/spec/integration/matcher_operator_data/ne.yml +150 -0
  392. data/spec/integration/matcher_operator_data/ne_types.yml +15 -0
  393. data/spec/integration/matcher_operator_data/nin.yml +114 -0
  394. data/spec/integration/matcher_operator_data/nor.yml +126 -0
  395. data/spec/integration/matcher_operator_data/not.yml +196 -0
  396. data/spec/integration/matcher_operator_data/or.yml +137 -0
  397. data/spec/integration/matcher_operator_data/regex.yml +174 -0
  398. data/spec/integration/matcher_operator_data/regex_options.yml +72 -0
  399. data/spec/integration/matcher_operator_data/size.yml +174 -0
  400. data/spec/integration/matcher_operator_data/type.yml +70 -0
  401. data/spec/integration/matcher_operator_data/type_array.yml +16 -0
  402. data/spec/integration/matcher_operator_data/type_binary.yml +18 -0
  403. data/spec/integration/matcher_operator_data/type_boolean.yml +39 -0
  404. data/spec/integration/matcher_operator_data/type_code.yml +26 -0
  405. data/spec/integration/matcher_operator_data/type_code_with_scope.yml +26 -0
  406. data/spec/integration/matcher_operator_data/type_date.yml +39 -0
  407. data/spec/integration/matcher_operator_data/type_db_pointer.yml +19 -0
  408. data/spec/integration/matcher_operator_data/type_decimal.yml +40 -0
  409. data/spec/integration/matcher_operator_data/type_double.yml +15 -0
  410. data/spec/integration/matcher_operator_data/type_int32.yml +33 -0
  411. data/spec/integration/matcher_operator_data/type_int64.yml +33 -0
  412. data/spec/integration/matcher_operator_data/type_max_key.yml +17 -0
  413. data/spec/integration/matcher_operator_data/type_min_key.yml +17 -0
  414. data/spec/integration/matcher_operator_data/type_null.yml +23 -0
  415. data/spec/integration/matcher_operator_data/type_object.yml +23 -0
  416. data/spec/integration/matcher_operator_data/type_object_id.yml +25 -0
  417. data/spec/integration/matcher_operator_data/type_regex.yml +44 -0
  418. data/spec/integration/matcher_operator_data/type_string.yml +15 -0
  419. data/spec/integration/matcher_operator_data/type_symbol.yml +32 -0
  420. data/spec/integration/matcher_operator_data/type_timestamp.yml +25 -0
  421. data/spec/integration/matcher_operator_data/type_undefined.yml +17 -0
  422. data/spec/integration/matcher_operator_spec.rb +100 -0
  423. data/spec/integration/matcher_spec.rb +189 -0
  424. data/spec/integration/server_query_spec.rb +142 -0
  425. data/spec/integration/shardable_spec.rb +149 -0
  426. data/spec/integration/stringified_symbol_field_spec.rb +190 -0
  427. data/spec/lite_spec_helper.rb +15 -5
  428. data/spec/mongoid/association/accessors_spec.rb +241 -63
  429. data/spec/mongoid/association/auto_save_spec.rb +3 -0
  430. data/spec/mongoid/association/builders_spec.rb +3 -0
  431. data/spec/mongoid/association/constrainable_spec.rb +3 -0
  432. data/spec/mongoid/association/counter_cache_spec.rb +3 -0
  433. data/spec/mongoid/association/depending_spec.rb +427 -333
  434. data/spec/mongoid/association/eager_spec.rb +3 -0
  435. data/spec/mongoid/association/embedded/cyclic_spec.rb +3 -0
  436. data/spec/mongoid/association/embedded/dirty_spec.rb +3 -0
  437. data/spec/mongoid/association/embedded/embedded_in/binding_spec.rb +3 -0
  438. data/spec/mongoid/association/embedded/embedded_in/buildable_spec.rb +3 -0
  439. data/spec/mongoid/association/embedded/embedded_in/proxy_spec.rb +3 -0
  440. data/spec/mongoid/association/embedded/embedded_in_spec.rb +4 -1
  441. data/spec/mongoid/association/embedded/embeds_many/binding_spec.rb +3 -0
  442. data/spec/mongoid/association/embedded/embeds_many/buildable_spec.rb +3 -0
  443. data/spec/mongoid/association/embedded/embeds_many/proxy_spec.rb +53 -4
  444. data/spec/mongoid/association/embedded/embeds_many_models.rb +1 -0
  445. data/spec/mongoid/association/embedded/embeds_many_query_spec.rb +52 -0
  446. data/spec/mongoid/association/embedded/embeds_many_spec.rb +4 -1
  447. data/spec/mongoid/association/embedded/embeds_one/binding_spec.rb +3 -0
  448. data/spec/mongoid/association/embedded/embeds_one/buildable_spec.rb +3 -0
  449. data/spec/mongoid/association/embedded/embeds_one/proxy_spec.rb +3 -0
  450. data/spec/mongoid/association/embedded/embeds_one_dnl_models.rb +3 -0
  451. data/spec/mongoid/association/embedded/embeds_one_models.rb +4 -0
  452. data/spec/mongoid/association/embedded/embeds_one_query_spec.rb +29 -0
  453. data/spec/mongoid/association/embedded/embeds_one_spec.rb +4 -1
  454. data/spec/mongoid/association/macros_spec.rb +3 -0
  455. data/spec/mongoid/association/nested/many_spec.rb +3 -0
  456. data/spec/mongoid/association/nested/one_spec.rb +19 -12
  457. data/spec/mongoid/association/options_spec.rb +3 -0
  458. data/spec/mongoid/association/polymorphic_spec.rb +3 -0
  459. data/spec/mongoid/association/referenced/belongs_to/binding_spec.rb +3 -0
  460. data/spec/mongoid/association/referenced/belongs_to/buildable_spec.rb +3 -0
  461. data/spec/mongoid/association/referenced/belongs_to/eager_spec.rb +205 -10
  462. data/spec/mongoid/association/referenced/belongs_to/proxy_spec.rb +45 -8
  463. data/spec/mongoid/association/referenced/belongs_to_query_spec.rb +58 -0
  464. data/spec/mongoid/association/referenced/belongs_to_spec.rb +3 -0
  465. data/spec/mongoid/association/referenced/has_and_belongs_to_many/binding_spec.rb +4 -1
  466. data/spec/mongoid/association/referenced/has_and_belongs_to_many/buildable_spec.rb +3 -0
  467. data/spec/mongoid/association/referenced/has_and_belongs_to_many/eager_spec.rb +16 -0
  468. data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_persistence_spec.rb +26 -5
  469. data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_spec.rb +37 -14
  470. data/spec/mongoid/association/referenced/has_and_belongs_to_many_models.rb +26 -2
  471. data/spec/mongoid/association/referenced/has_and_belongs_to_many_query_spec.rb +40 -0
  472. data/spec/mongoid/association/referenced/has_and_belongs_to_many_spec.rb +26 -2
  473. data/spec/mongoid/association/referenced/has_many/binding_spec.rb +4 -1
  474. data/spec/mongoid/association/referenced/has_many/buildable_spec.rb +3 -0
  475. data/spec/mongoid/association/referenced/has_many/eager_spec.rb +18 -3
  476. data/spec/mongoid/association/referenced/has_many/enumerable_spec.rb +248 -93
  477. data/spec/mongoid/association/referenced/has_many/proxy_query_spec.rb +1 -0
  478. data/spec/mongoid/association/referenced/has_many/proxy_spec.rb +463 -186
  479. data/spec/mongoid/association/referenced/has_many_models.rb +41 -0
  480. data/spec/mongoid/association/referenced/has_many_query_spec.rb +38 -0
  481. data/spec/mongoid/association/referenced/has_many_spec.rb +3 -0
  482. data/spec/mongoid/association/referenced/has_one/binding_spec.rb +3 -0
  483. data/spec/mongoid/association/referenced/has_one/buildable_spec.rb +3 -0
  484. data/spec/mongoid/association/referenced/has_one/eager_spec.rb +18 -3
  485. data/spec/mongoid/association/referenced/has_one/proxy_spec.rb +3 -0
  486. data/spec/mongoid/association/referenced/has_one_models.rb +32 -0
  487. data/spec/mongoid/association/referenced/has_one_query_spec.rb +38 -0
  488. data/spec/mongoid/association/referenced/has_one_spec.rb +4 -1
  489. data/spec/mongoid/association/reflections_spec.rb +3 -0
  490. data/spec/mongoid/association/syncable_spec.rb +3 -0
  491. data/spec/mongoid/association_spec.rb +3 -0
  492. data/spec/mongoid/atomic/modifiers_spec.rb +50 -0
  493. data/spec/mongoid/atomic/paths/embedded/many_spec.rb +3 -0
  494. data/spec/mongoid/atomic/paths/embedded/one_spec.rb +3 -0
  495. data/spec/mongoid/atomic/paths/root_spec.rb +3 -0
  496. data/spec/mongoid/atomic/paths_spec.rb +67 -12
  497. data/spec/mongoid/atomic_spec.rb +26 -0
  498. data/spec/mongoid/attributes/nested_spec.rb +4 -1
  499. data/spec/mongoid/attributes/projector_data/embedded.yml +105 -0
  500. data/spec/mongoid/attributes/projector_data/fields.yml +93 -0
  501. data/spec/mongoid/attributes/projector_spec.rb +41 -0
  502. data/spec/mongoid/attributes/readonly_spec.rb +3 -0
  503. data/spec/mongoid/attributes_spec.rb +336 -0
  504. data/spec/mongoid/cacheable_spec.rb +3 -0
  505. data/spec/mongoid/changeable_spec.rb +26 -0
  506. data/spec/mongoid/clients/factory_spec.rb +137 -28
  507. data/spec/mongoid/clients/options_spec.rb +42 -23
  508. data/spec/mongoid/clients/sessions_spec.rb +4 -6
  509. data/spec/mongoid/clients/transactions_spec.rb +6 -3
  510. data/spec/mongoid/clients_spec.rb +3 -0
  511. data/spec/mongoid/composable_spec.rb +3 -0
  512. data/spec/mongoid/config/environment_spec.rb +89 -8
  513. data/spec/mongoid/config/options_spec.rb +23 -3
  514. data/spec/mongoid/config_spec.rb +172 -0
  515. data/spec/mongoid/contextual/aggregable/memory_spec.rb +3 -0
  516. data/spec/mongoid/contextual/aggregable/mongo_spec.rb +3 -0
  517. data/spec/mongoid/contextual/atomic_spec.rb +181 -29
  518. data/spec/mongoid/contextual/geo_near_spec.rb +4 -1
  519. data/spec/mongoid/contextual/map_reduce_spec.rb +3 -0
  520. data/spec/mongoid/contextual/memory_spec.rb +3 -0
  521. data/spec/mongoid/contextual/mongo_spec.rb +77 -18
  522. data/spec/mongoid/contextual/none_spec.rb +3 -0
  523. data/spec/mongoid/copyable_spec.rb +200 -18
  524. data/spec/mongoid/copyable_spec_models.rb +31 -0
  525. data/spec/mongoid/criteria/findable_spec.rb +58 -0
  526. data/spec/mongoid/criteria/inspectable_spec.rb +3 -0
  527. data/spec/mongoid/criteria/marshalable_spec.rb +3 -0
  528. data/spec/mongoid/criteria/modifiable_spec.rb +8 -4
  529. data/spec/mongoid/criteria/options_spec.rb +3 -0
  530. data/spec/mongoid/criteria/queryable/aggregable_spec.rb +3 -0
  531. data/spec/mongoid/criteria/queryable/expandable_spec.rb +62 -0
  532. data/spec/mongoid/criteria/queryable/extensions/array_spec.rb +3 -0
  533. data/spec/mongoid/criteria/queryable/extensions/big_decimal_spec.rb +3 -0
  534. data/spec/mongoid/criteria/queryable/extensions/bignum_spec.rb +3 -0
  535. data/spec/mongoid/criteria/queryable/extensions/boolean_spec.rb +4 -1
  536. data/spec/mongoid/criteria/queryable/extensions/date_spec.rb +3 -0
  537. data/spec/mongoid/criteria/queryable/extensions/date_time_spec.rb +36 -17
  538. data/spec/mongoid/criteria/queryable/extensions/fixnum_spec.rb +3 -0
  539. data/spec/mongoid/criteria/queryable/extensions/float_spec.rb +3 -0
  540. data/spec/mongoid/criteria/queryable/extensions/hash_spec.rb +3 -0
  541. data/spec/mongoid/criteria/queryable/extensions/integer_spec.rb +3 -0
  542. data/spec/mongoid/criteria/queryable/extensions/nil_class_spec.rb +3 -0
  543. data/spec/mongoid/criteria/queryable/extensions/object_spec.rb +3 -0
  544. data/spec/mongoid/criteria/queryable/extensions/range_spec.rb +3 -0
  545. data/spec/mongoid/criteria/queryable/extensions/regexp_raw_spec.rb +4 -1
  546. data/spec/mongoid/criteria/queryable/extensions/regexp_spec.rb +3 -0
  547. data/spec/mongoid/criteria/queryable/extensions/set_spec.rb +3 -0
  548. data/spec/mongoid/criteria/queryable/extensions/string_spec.rb +3 -0
  549. data/spec/mongoid/criteria/queryable/extensions/symbol_spec.rb +3 -0
  550. data/spec/mongoid/criteria/queryable/extensions/time_spec.rb +24 -16
  551. data/spec/mongoid/criteria/queryable/extensions/time_with_zone_spec.rb +3 -0
  552. data/spec/mongoid/criteria/queryable/key_spec.rb +3 -0
  553. data/spec/mongoid/criteria/queryable/mergeable_spec.rb +146 -12
  554. data/spec/mongoid/criteria/queryable/optional_spec.rb +3 -0
  555. data/spec/mongoid/criteria/queryable/options_spec.rb +3 -0
  556. data/spec/mongoid/criteria/queryable/pipeline_spec.rb +3 -0
  557. data/spec/mongoid/criteria/queryable/queryable_spec.rb +3 -0
  558. data/spec/mongoid/criteria/queryable/selectable_logical_spec.rb +1593 -285
  559. data/spec/mongoid/criteria/queryable/selectable_shared_examples.rb +39 -0
  560. data/spec/mongoid/criteria/queryable/selectable_spec.rb +1048 -2773
  561. data/spec/mongoid/criteria/queryable/selectable_where_spec.rb +590 -0
  562. data/spec/mongoid/criteria/queryable/selector_spec.rb +3 -0
  563. data/spec/mongoid/criteria/queryable/smash_spec.rb +3 -0
  564. data/spec/mongoid/criteria/queryable/storable_spec.rb +190 -0
  565. data/spec/mongoid/criteria/scopable_spec.rb +3 -0
  566. data/spec/mongoid/criteria_projection_spec.rb +411 -0
  567. data/spec/mongoid/criteria_spec.rb +241 -278
  568. data/spec/mongoid/document_fields_spec.rb +26 -0
  569. data/spec/mongoid/document_query_spec.rb +90 -0
  570. data/spec/mongoid/document_spec.rb +113 -16
  571. data/spec/mongoid/equality_spec.rb +3 -1
  572. data/spec/mongoid/errors/ambiguous_relationship_spec.rb +6 -3
  573. data/spec/mongoid/errors/callback_spec.rb +3 -0
  574. data/spec/mongoid/errors/delete_restriction_spec.rb +5 -2
  575. data/spec/mongoid/errors/document_not_destroyed_spec.rb +3 -0
  576. data/spec/mongoid/errors/document_not_found_spec.rb +3 -0
  577. data/spec/mongoid/errors/eager_load_spec.rb +3 -0
  578. data/spec/mongoid/errors/invalid_collection_spec.rb +3 -0
  579. data/spec/mongoid/errors/invalid_config_file_spec.rb +32 -0
  580. data/spec/mongoid/errors/invalid_config_option_spec.rb +3 -0
  581. data/spec/mongoid/errors/invalid_field_option_spec.rb +3 -0
  582. data/spec/mongoid/errors/invalid_field_spec.rb +3 -0
  583. data/spec/mongoid/errors/invalid_find_spec.rb +3 -0
  584. data/spec/mongoid/errors/invalid_includes_spec.rb +3 -0
  585. data/spec/mongoid/errors/invalid_index_spec.rb +3 -0
  586. data/spec/mongoid/errors/invalid_options_spec.rb +5 -2
  587. data/spec/mongoid/errors/invalid_path_spec.rb +3 -0
  588. data/spec/mongoid/errors/invalid_relation_spec.rb +5 -2
  589. data/spec/mongoid/errors/invalid_scope_spec.rb +3 -0
  590. data/spec/mongoid/errors/invalid_set_polymorphic_relation_spec.rb +3 -0
  591. data/spec/mongoid/errors/invalid_storage_options_spec.rb +3 -0
  592. data/spec/mongoid/errors/invalid_time_spec.rb +3 -0
  593. data/spec/mongoid/errors/inverse_not_found_spec.rb +4 -1
  594. data/spec/mongoid/errors/mixed_client_configuration_spec.rb +3 -0
  595. data/spec/mongoid/errors/mixed_relations_spec.rb +3 -0
  596. data/spec/mongoid/errors/mongoid_error_spec.rb +23 -8
  597. data/spec/mongoid/errors/nested_attributes_metadata_not_found_spec.rb +6 -3
  598. data/spec/mongoid/errors/no_client_config_spec.rb +5 -2
  599. data/spec/mongoid/errors/no_client_database_spec.rb +6 -3
  600. data/spec/mongoid/errors/no_client_hosts_spec.rb +6 -3
  601. data/spec/mongoid/errors/no_clients_config_spec.rb +3 -0
  602. data/spec/mongoid/errors/no_environment_spec.rb +3 -0
  603. data/spec/mongoid/errors/no_map_reduce_output_spec.rb +3 -0
  604. data/spec/mongoid/errors/no_metadata_spec.rb +5 -2
  605. data/spec/mongoid/errors/no_parent_spec.rb +4 -1
  606. data/spec/mongoid/errors/readonly_attribute_spec.rb +3 -0
  607. data/spec/mongoid/errors/readonly_document_spec.rb +3 -0
  608. data/spec/mongoid/errors/scope_overwrite_spec.rb +3 -0
  609. data/spec/mongoid/errors/too_many_nested_attribute_records_spec.rb +3 -0
  610. data/spec/mongoid/errors/unknown_attribute_spec.rb +3 -0
  611. data/spec/mongoid/errors/unsaved_document_spec.rb +4 -1
  612. data/spec/mongoid/errors/unsupported_javascript_spec.rb +3 -0
  613. data/spec/mongoid/errors/validations_spec.rb +3 -0
  614. data/spec/mongoid/extensions/array_spec.rb +26 -43
  615. data/spec/mongoid/extensions/big_decimal_spec.rb +3 -0
  616. data/spec/mongoid/extensions/binary_spec.rb +3 -0
  617. data/spec/mongoid/extensions/boolean_spec.rb +3 -0
  618. data/spec/mongoid/extensions/date_class_mongoize_spec.rb +336 -0
  619. data/spec/mongoid/extensions/date_spec.rb +9 -160
  620. data/spec/mongoid/extensions/date_time_spec.rb +18 -60
  621. data/spec/mongoid/extensions/decimal128_spec.rb +3 -0
  622. data/spec/mongoid/extensions/false_class_spec.rb +4 -1
  623. data/spec/mongoid/extensions/float_spec.rb +18 -3
  624. data/spec/mongoid/extensions/hash_spec.rb +106 -0
  625. data/spec/mongoid/extensions/integer_spec.rb +15 -2
  626. data/spec/mongoid/extensions/module_spec.rb +3 -0
  627. data/spec/mongoid/extensions/nil_class_spec.rb +3 -0
  628. data/spec/mongoid/extensions/object_id_spec.rb +3 -0
  629. data/spec/mongoid/extensions/object_spec.rb +14 -24
  630. data/spec/mongoid/extensions/range_spec.rb +3 -0
  631. data/spec/mongoid/extensions/regexp_spec.rb +3 -0
  632. data/spec/mongoid/extensions/set_spec.rb +3 -0
  633. data/spec/mongoid/extensions/string_spec.rb +59 -25
  634. data/spec/mongoid/extensions/stringified_symbol_spec.rb +85 -0
  635. data/spec/mongoid/extensions/symbol_spec.rb +3 -0
  636. data/spec/mongoid/extensions/time_spec.rb +30 -0
  637. data/spec/mongoid/extensions/time_with_zone_spec.rb +34 -0
  638. data/spec/mongoid/extensions/true_class_spec.rb +4 -1
  639. data/spec/mongoid/extensions_spec.rb +3 -0
  640. data/spec/mongoid/factory_spec.rb +287 -27
  641. data/spec/mongoid/fields/foreign_key_spec.rb +3 -0
  642. data/spec/mongoid/fields/localized_spec.rb +7 -4
  643. data/spec/mongoid/fields/standard_spec.rb +3 -0
  644. data/spec/mongoid/fields_spec.rb +93 -6
  645. data/spec/mongoid/findable_spec.rb +35 -0
  646. data/spec/mongoid/indexable/specification_spec.rb +3 -0
  647. data/spec/mongoid/indexable_spec.rb +31 -2
  648. data/spec/mongoid/inspectable_spec.rb +40 -2
  649. data/spec/mongoid/interceptable_spec.rb +67 -2
  650. data/spec/mongoid/interceptable_spec_models.rb +76 -0
  651. data/spec/mongoid/loggable_spec.rb +3 -0
  652. data/spec/mongoid/matcher/extract_attribute_data/numeric_keys.yml +104 -0
  653. data/spec/mongoid/matcher/extract_attribute_data/traversal.yml +239 -0
  654. data/spec/mongoid/matcher/extract_attribute_spec.rb +37 -0
  655. data/spec/mongoid/persistable/creatable_spec.rb +111 -25
  656. data/spec/mongoid/persistable/deletable_spec.rb +264 -1
  657. data/spec/mongoid/persistable/destroyable_spec.rb +194 -3
  658. data/spec/mongoid/persistable/incrementable_spec.rb +17 -0
  659. data/spec/mongoid/persistable/logical_spec.rb +17 -0
  660. data/spec/mongoid/persistable/poppable_spec.rb +17 -0
  661. data/spec/mongoid/persistable/pullable_spec.rb +31 -0
  662. data/spec/mongoid/persistable/pushable_spec.rb +31 -0
  663. data/spec/mongoid/persistable/renamable_spec.rb +17 -0
  664. data/spec/mongoid/persistable/savable_spec.rb +175 -16
  665. data/spec/mongoid/persistable/settable_spec.rb +47 -0
  666. data/spec/mongoid/persistable/unsettable_spec.rb +17 -0
  667. data/spec/mongoid/persistable/updatable_spec.rb +5 -0
  668. data/spec/mongoid/persistable/upsertable_spec.rb +4 -1
  669. data/spec/mongoid/persistable_spec.rb +85 -8
  670. data/spec/mongoid/persistence_context_spec.rb +3 -0
  671. data/spec/mongoid/positional_spec.rb +3 -0
  672. data/spec/mongoid/query_cache_middleware_spec.rb +69 -0
  673. data/spec/mongoid/query_cache_spec.rb +466 -82
  674. data/spec/mongoid/relations/proxy_spec.rb +3 -0
  675. data/spec/mongoid/reloadable_spec.rb +93 -1
  676. data/spec/mongoid/scopable_spec.rb +3 -0
  677. data/spec/mongoid/selectable_spec.rb +3 -0
  678. data/spec/mongoid/serializable_spec.rb +152 -20
  679. data/spec/mongoid/shardable_models.rb +61 -0
  680. data/spec/mongoid/shardable_spec.rb +116 -16
  681. data/spec/mongoid/stateful_spec.rb +3 -0
  682. data/spec/mongoid/tasks/database_rake_spec.rb +3 -0
  683. data/spec/mongoid/tasks/database_spec.rb +3 -0
  684. data/spec/mongoid/threaded_spec.rb +3 -0
  685. data/spec/mongoid/timestamps/created/short_spec.rb +3 -0
  686. data/spec/mongoid/timestamps/created_spec.rb +3 -0
  687. data/spec/mongoid/timestamps/timeless_spec.rb +3 -0
  688. data/spec/mongoid/timestamps/updated/short_spec.rb +3 -0
  689. data/spec/mongoid/timestamps/updated_spec.rb +3 -0
  690. data/spec/mongoid/timestamps_spec.rb +3 -0
  691. data/spec/mongoid/touchable_spec.rb +171 -19
  692. data/spec/mongoid/touchable_spec_models.rb +54 -0
  693. data/spec/mongoid/traversable_spec.rb +1103 -0
  694. data/spec/mongoid/validatable/associated_spec.rb +3 -0
  695. data/spec/mongoid/validatable/format_spec.rb +3 -0
  696. data/spec/mongoid/validatable/length_spec.rb +3 -0
  697. data/spec/mongoid/validatable/numericality_spec.rb +3 -0
  698. data/spec/mongoid/validatable/presence_spec.rb +3 -0
  699. data/spec/mongoid/validatable/uniqueness_spec.rb +3 -0
  700. data/spec/mongoid/validatable_spec.rb +4 -1
  701. data/spec/mongoid_spec.rb +3 -0
  702. data/spec/rails/controller_extension/controller_runtime_spec.rb +4 -1
  703. data/spec/rails/mongoid_spec.rb +5 -2
  704. data/spec/shared/bin/get-mongodb-download-url +17 -0
  705. data/spec/shared/bin/s3-copy +45 -0
  706. data/spec/shared/bin/s3-upload +69 -0
  707. data/spec/shared/lib/mrss/cluster_config.rb +19 -4
  708. data/spec/shared/lib/mrss/constraints.rb +67 -12
  709. data/spec/shared/lib/mrss/docker_runner.rb +10 -1
  710. data/spec/shared/lib/mrss/event_subscriber.rb +200 -0
  711. data/spec/shared/lib/mrss/lite_constraints.rb +16 -0
  712. data/spec/shared/lib/mrss/server_version_registry.rb +84 -33
  713. data/spec/shared/lib/mrss/spec_organizer.rb +32 -2
  714. data/spec/shared/lib/mrss/utils.rb +15 -0
  715. data/spec/shared/share/Dockerfile.erb +126 -32
  716. data/spec/shared/share/haproxy-1.conf +16 -0
  717. data/spec/shared/share/haproxy-2.conf +17 -0
  718. data/spec/shared/shlib/server.sh +123 -26
  719. data/spec/shared/shlib/set_env.sh +4 -1
  720. data/spec/spec_helper.rb +31 -17
  721. data/spec/support/authorization.rb +3 -0
  722. data/spec/support/client_registry.rb +9 -0
  723. data/spec/support/constraints.rb +15 -233
  724. data/spec/support/expectations.rb +6 -1
  725. data/spec/support/helpers.rb +11 -0
  726. data/spec/support/macros.rb +1 -0
  727. data/spec/{app → support}/models/account.rb +3 -0
  728. data/spec/{app → support}/models/acolyte.rb +3 -0
  729. data/spec/{app → support}/models/actor.rb +4 -1
  730. data/spec/support/models/actress.rb +5 -0
  731. data/spec/{app → support}/models/address.rb +7 -0
  732. data/spec/{app → support}/models/address_component.rb +3 -0
  733. data/spec/{app → support}/models/address_number.rb +3 -0
  734. data/spec/{app → support}/models/agency.rb +3 -0
  735. data/spec/{app → support}/models/agent.rb +3 -0
  736. data/spec/{app → support}/models/album.rb +3 -0
  737. data/spec/{app → support}/models/alert.rb +3 -0
  738. data/spec/{app → support}/models/animal.rb +3 -0
  739. data/spec/{app → support}/models/answer.rb +3 -0
  740. data/spec/{app → support}/models/appointment.rb +3 -0
  741. data/spec/support/models/armrest.rb +10 -0
  742. data/spec/{app → support}/models/array_field.rb +1 -0
  743. data/spec/{app → support}/models/article.rb +3 -0
  744. data/spec/{app → support}/models/artist.rb +3 -0
  745. data/spec/{app → support}/models/artwork.rb +3 -0
  746. data/spec/{app → support}/models/audio.rb +3 -0
  747. data/spec/{app → support}/models/augmentation.rb +3 -0
  748. data/spec/{app → support}/models/author.rb +3 -0
  749. data/spec/{app → support}/models/baby.rb +3 -0
  750. data/spec/{app → support}/models/band.rb +3 -0
  751. data/spec/{app → support}/models/bar.rb +3 -0
  752. data/spec/{app → support}/models/basic.rb +3 -0
  753. data/spec/support/models/bed.rb +4 -0
  754. data/spec/support/models/big_palette.rb +5 -0
  755. data/spec/{app → support}/models/birthday.rb +3 -0
  756. data/spec/support/models/bolt.rb +8 -0
  757. data/spec/{app → support}/models/bomb.rb +3 -0
  758. data/spec/{app → support}/models/book.rb +3 -0
  759. data/spec/{app → support}/models/breed.rb +3 -0
  760. data/spec/support/models/browser.rb +9 -0
  761. data/spec/{app → support}/models/building.rb +3 -0
  762. data/spec/{app → support}/models/building_address.rb +3 -0
  763. data/spec/{app → support}/models/bus.rb +3 -0
  764. data/spec/{app → support}/models/business.rb +3 -0
  765. data/spec/{app → support}/models/callback_test.rb +3 -0
  766. data/spec/{app → support}/models/canvas.rb +4 -1
  767. data/spec/support/models/car.rb +4 -0
  768. data/spec/{app → support}/models/cat.rb +3 -0
  769. data/spec/{app → support}/models/category.rb +3 -0
  770. data/spec/{app → support}/models/child.rb +3 -0
  771. data/spec/{app → support}/models/child_doc.rb +3 -0
  772. data/spec/{app → support}/models/church.rb +3 -0
  773. data/spec/{app → support}/models/circle.rb +3 -0
  774. data/spec/{app → support}/models/circuit.rb +3 -0
  775. data/spec/{app → support}/models/circus.rb +3 -0
  776. data/spec/{app → support}/models/code.rb +3 -0
  777. data/spec/support/models/coding/pull_request.rb +12 -0
  778. data/spec/support/models/coding.rb +4 -0
  779. data/spec/{app → support}/models/comment.rb +3 -0
  780. data/spec/{app → support}/models/company.rb +3 -0
  781. data/spec/{app → support}/models/consumption_period.rb +3 -0
  782. data/spec/{app → support}/models/contextable_item.rb +3 -0
  783. data/spec/{app → support}/models/contractor.rb +3 -0
  784. data/spec/{app → support}/models/cookie.rb +3 -0
  785. data/spec/{app → support}/models/country_code.rb +3 -0
  786. data/spec/{app → support}/models/courier_job.rb +3 -0
  787. data/spec/support/models/crate.rb +13 -0
  788. data/spec/{app → support}/models/customer.rb +0 -0
  789. data/spec/{app → support}/models/customer_address.rb +0 -0
  790. data/spec/support/models/deed.rb +8 -0
  791. data/spec/{app → support}/models/definition.rb +3 -0
  792. data/spec/{app → support}/models/delegating_patient.rb +0 -0
  793. data/spec/{app → support}/models/description.rb +3 -0
  794. data/spec/{app → support}/models/dictionary.rb +9 -0
  795. data/spec/{app → support}/models/division.rb +3 -0
  796. data/spec/{app → support}/models/doctor.rb +3 -0
  797. data/spec/{app → support}/models/dog.rb +3 -0
  798. data/spec/{app → support}/models/dokument.rb +3 -0
  799. data/spec/{app → support}/models/draft.rb +3 -0
  800. data/spec/{app → support}/models/dragon.rb +3 -0
  801. data/spec/{app → support}/models/driver.rb +4 -1
  802. data/spec/{app → support}/models/drug.rb +3 -0
  803. data/spec/{app → support}/models/dungeon.rb +3 -0
  804. data/spec/{app → support}/models/edit.rb +3 -0
  805. data/spec/{app → support}/models/email.rb +3 -0
  806. data/spec/support/models/employer.rb +8 -0
  807. data/spec/{app → support}/models/entry.rb +3 -0
  808. data/spec/support/models/eraser.rb +4 -0
  809. data/spec/{app → support}/models/even.rb +3 -0
  810. data/spec/{app → support}/models/event.rb +3 -0
  811. data/spec/{app → support}/models/exhibition.rb +3 -0
  812. data/spec/{app → support}/models/exhibitor.rb +3 -0
  813. data/spec/{app → support}/models/explosion.rb +3 -0
  814. data/spec/{app → support}/models/eye.rb +3 -0
  815. data/spec/{app → support}/models/eye_bowl.rb +3 -0
  816. data/spec/{app → support}/models/face.rb +3 -0
  817. data/spec/{app → support}/models/favorite.rb +3 -0
  818. data/spec/{app → support}/models/filesystem.rb +3 -0
  819. data/spec/{app → support}/models/fire_hydrant.rb +3 -0
  820. data/spec/{app → support}/models/firefox.rb +3 -0
  821. data/spec/{app → support}/models/fish.rb +3 -0
  822. data/spec/{app → support}/models/folder.rb +3 -0
  823. data/spec/{app → support}/models/folder_item.rb +3 -0
  824. data/spec/{app → support}/models/fruits.rb +3 -0
  825. data/spec/{app → support}/models/game.rb +3 -0
  826. data/spec/{app → support}/models/ghost.rb +3 -0
  827. data/spec/support/models/guitar.rb +5 -0
  828. data/spec/support/models/hole.rb +13 -0
  829. data/spec/{app → support}/models/home.rb +3 -0
  830. data/spec/{app → support}/models/house.rb +3 -0
  831. data/spec/support/models/html_writer.rb +6 -0
  832. data/spec/{app → support}/models/id_key.rb +3 -0
  833. data/spec/support/models/idnodef.rb +8 -0
  834. data/spec/{app → support}/models/image.rb +3 -0
  835. data/spec/{app → support}/models/implant.rb +3 -0
  836. data/spec/support/models/instrument.rb +9 -0
  837. data/spec/{app → support}/models/item.rb +4 -1
  838. data/spec/{app → support}/models/jar.rb +3 -0
  839. data/spec/{app → support}/models/kaleidoscope.rb +3 -0
  840. data/spec/{app → support}/models/kangaroo.rb +4 -1
  841. data/spec/{app → support}/models/label.rb +3 -0
  842. data/spec/{app → support}/models/language.rb +3 -0
  843. data/spec/{app → support}/models/lat_lng.rb +3 -0
  844. data/spec/{app → support}/models/league.rb +3 -0
  845. data/spec/support/models/learner.rb +5 -0
  846. data/spec/{app → support}/models/line_item.rb +3 -0
  847. data/spec/{app → support}/models/location.rb +3 -0
  848. data/spec/{app → support}/models/login.rb +3 -0
  849. data/spec/{app → support}/models/manufacturer.rb +3 -0
  850. data/spec/{app → support}/models/meat.rb +3 -0
  851. data/spec/{app → support}/models/membership.rb +3 -0
  852. data/spec/{app → support}/models/message.rb +3 -0
  853. data/spec/{app → support}/models/minim.rb +1 -1
  854. data/spec/{app → support}/models/mixed_drink.rb +3 -0
  855. data/spec/support/models/mop.rb +25 -0
  856. data/spec/{app → support}/models/movie.rb +3 -0
  857. data/spec/support/models/my_hash.rb +5 -0
  858. data/spec/{app → support}/models/name.rb +3 -0
  859. data/spec/support/models/name_only.rb +9 -0
  860. data/spec/{app → support}/models/node.rb +3 -0
  861. data/spec/{app → support}/models/note.rb +3 -0
  862. data/spec/support/models/nut.rb +8 -0
  863. data/spec/{app → support}/models/odd.rb +3 -0
  864. data/spec/support/models/order.rb +11 -0
  865. data/spec/{app → support}/models/ordered_post.rb +3 -0
  866. data/spec/{app → support}/models/ordered_preference.rb +3 -0
  867. data/spec/{app → support}/models/oscar.rb +3 -0
  868. data/spec/support/models/other_owner_object.rb +5 -0
  869. data/spec/{app → support}/models/override.rb +3 -0
  870. data/spec/{app → support}/models/ownable.rb +3 -0
  871. data/spec/{app → support}/models/owner.rb +5 -0
  872. data/spec/support/models/pack.rb +6 -0
  873. data/spec/{app → support}/models/page.rb +3 -0
  874. data/spec/{app → support}/models/page_question.rb +3 -0
  875. data/spec/{app → support}/models/palette.rb +4 -1
  876. data/spec/{app → support}/models/parent.rb +3 -0
  877. data/spec/{app → support}/models/parent_doc.rb +3 -0
  878. data/spec/{app → support}/models/passport.rb +4 -0
  879. data/spec/{app → support}/models/patient.rb +3 -0
  880. data/spec/support/models/pdf_writer.rb +6 -0
  881. data/spec/support/models/pencil.rb +4 -0
  882. data/spec/{app → support}/models/person.rb +21 -1
  883. data/spec/{app → support}/models/pet.rb +3 -0
  884. data/spec/{app → support}/models/pet_owner.rb +3 -0
  885. data/spec/{app → support}/models/phone.rb +4 -0
  886. data/spec/support/models/piano.rb +5 -0
  887. data/spec/{app → support}/models/pizza.rb +3 -0
  888. data/spec/{app → support}/models/player.rb +3 -0
  889. data/spec/{app → support}/models/post.rb +3 -0
  890. data/spec/{app → support}/models/post_genre.rb +3 -0
  891. data/spec/{app → support}/models/powerup.rb +3 -0
  892. data/spec/{app → support}/models/preference.rb +3 -0
  893. data/spec/{app → support}/models/princess.rb +3 -0
  894. data/spec/{app → support}/models/product.rb +3 -0
  895. data/spec/support/models/profile.rb +18 -0
  896. data/spec/{app → support}/models/pronunciation.rb +3 -0
  897. data/spec/{app → support}/models/pub.rb +3 -0
  898. data/spec/support/models/publication/encyclopedia.rb +12 -0
  899. data/spec/support/models/publication/review.rb +14 -0
  900. data/spec/support/models/publication.rb +5 -0
  901. data/spec/{app → support}/models/purchase.rb +3 -0
  902. data/spec/{app → support}/models/question.rb +3 -0
  903. data/spec/{app → support}/models/quiz.rb +3 -0
  904. data/spec/{app → support}/models/rating.rb +3 -0
  905. data/spec/{app → support}/models/record.rb +3 -0
  906. data/spec/{app → support}/models/registry.rb +3 -0
  907. data/spec/{app → support}/models/role.rb +3 -0
  908. data/spec/{app → support}/models/root_category.rb +3 -0
  909. data/spec/{app → support}/models/sandwich.rb +3 -0
  910. data/spec/{app → support}/models/scheduler.rb +3 -0
  911. data/spec/support/models/scribe.rb +8 -0
  912. data/spec/support/models/sealer.rb +8 -0
  913. data/spec/support/models/seat.rb +25 -0
  914. data/spec/{app → support}/models/seo.rb +3 -0
  915. data/spec/support/models/series.rb +8 -0
  916. data/spec/{app → support}/models/server.rb +3 -0
  917. data/spec/{app → support}/models/service.rb +3 -0
  918. data/spec/{app → support}/models/shape.rb +5 -2
  919. data/spec/{app → support}/models/shelf.rb +3 -0
  920. data/spec/{app → support}/models/shipment_address.rb +3 -0
  921. data/spec/{app → support}/models/shipping_container.rb +3 -0
  922. data/spec/{app → support}/models/shipping_pack.rb +3 -0
  923. data/spec/support/models/shirt.rb +12 -0
  924. data/spec/{app → support}/models/shop.rb +3 -0
  925. data/spec/{app → support}/models/short_agent.rb +3 -0
  926. data/spec/{app → support}/models/short_quiz.rb +3 -0
  927. data/spec/{app → support}/models/simple.rb +3 -0
  928. data/spec/{app → support}/models/slave.rb +3 -0
  929. data/spec/{app → support}/models/song.rb +3 -0
  930. data/spec/{app → support}/models/sound.rb +3 -0
  931. data/spec/support/models/spacer.rb +8 -0
  932. data/spec/{app → support}/models/square.rb +3 -0
  933. data/spec/{app → support}/models/staff.rb +3 -0
  934. data/spec/{app → support}/models/store_as_dup_test1.rb +3 -0
  935. data/spec/{app → support}/models/store_as_dup_test2.rb +3 -0
  936. data/spec/{app → support}/models/store_as_dup_test3.rb +1 -0
  937. data/spec/{app → support}/models/store_as_dup_test4.rb +1 -0
  938. data/spec/support/models/strategy.rb +6 -0
  939. data/spec/support/models/sub_item.rb +6 -0
  940. data/spec/{app → support}/models/subscription.rb +3 -0
  941. data/spec/{app → support}/models/survey.rb +3 -0
  942. data/spec/{app → support}/models/symptom.rb +3 -0
  943. data/spec/support/models/system_role.rb +7 -0
  944. data/spec/{app → support}/models/tag.rb +3 -0
  945. data/spec/{app → support}/models/target.rb +3 -0
  946. data/spec/{app → support}/models/template.rb +3 -0
  947. data/spec/{app → support}/models/thing.rb +3 -0
  948. data/spec/support/models/threadlocker.rb +8 -0
  949. data/spec/support/models/title.rb +6 -0
  950. data/spec/support/models/tool.rb +11 -0
  951. data/spec/{app → support}/models/topping.rb +3 -0
  952. data/spec/support/models/toy.rb +10 -0
  953. data/spec/{app → support}/models/track.rb +3 -0
  954. data/spec/{app → support}/models/translation.rb +3 -0
  955. data/spec/{app → support}/models/tree.rb +3 -0
  956. data/spec/support/models/truck.rb +8 -0
  957. data/spec/{app → support}/models/updatable.rb +1 -0
  958. data/spec/{app → support}/models/user.rb +3 -0
  959. data/spec/{app → support}/models/user_account.rb +3 -0
  960. data/spec/{app → support}/models/validation_callback.rb +3 -0
  961. data/spec/support/models/vehicle.rb +19 -0
  962. data/spec/{app → support}/models/version.rb +3 -0
  963. data/spec/{app → support}/models/vertex.rb +4 -1
  964. data/spec/{app → support}/models/vet_visit.rb +3 -0
  965. data/spec/{app → support}/models/video.rb +3 -0
  966. data/spec/support/models/video_game.rb +4 -0
  967. data/spec/support/models/washer.rb +8 -0
  968. data/spec/{app → support}/models/weapon.rb +3 -0
  969. data/spec/{app → support}/models/wiki_page.rb +4 -0
  970. data/spec/{app → support}/models/word.rb +3 -0
  971. data/spec/{app → support}/models/word_origin.rb +3 -0
  972. data/spec/{app → support}/models/writer.rb +5 -2
  973. data/spec/support/shared/time.rb +54 -0
  974. data/spec/support/spec_config.rb +14 -3
  975. data.tar.gz.sig +0 -0
  976. metadata +1035 -732
  977. metadata.gz.sig +2 -2
  978. data/lib/mongoid/criteria/queryable/forwardable.rb +0 -65
  979. data/lib/mongoid/matchable/all.rb +0 -28
  980. data/lib/mongoid/matchable/and.rb +0 -30
  981. data/lib/mongoid/matchable/default.rb +0 -119
  982. data/lib/mongoid/matchable/elem_match.rb +0 -34
  983. data/lib/mongoid/matchable/eq.rb +0 -22
  984. data/lib/mongoid/matchable/exists.rb +0 -23
  985. data/lib/mongoid/matchable/gt.rb +0 -23
  986. data/lib/mongoid/matchable/gte.rb +0 -23
  987. data/lib/mongoid/matchable/in.rb +0 -24
  988. data/lib/mongoid/matchable/lt.rb +0 -23
  989. data/lib/mongoid/matchable/lte.rb +0 -23
  990. data/lib/mongoid/matchable/ne.rb +0 -21
  991. data/lib/mongoid/matchable/nin.rb +0 -22
  992. data/lib/mongoid/matchable/nor.rb +0 -37
  993. data/lib/mongoid/matchable/or.rb +0 -33
  994. data/lib/mongoid/matchable/regexp.rb +0 -27
  995. data/lib/mongoid/matchable/size.rb +0 -21
  996. data/spec/app/models/actress.rb +0 -2
  997. data/spec/app/models/bed.rb +0 -1
  998. data/spec/app/models/big_palette.rb +0 -2
  999. data/spec/app/models/browser.rb +0 -6
  1000. data/spec/app/models/car.rb +0 -1
  1001. data/spec/app/models/employer.rb +0 -5
  1002. data/spec/app/models/eraser.rb +0 -1
  1003. data/spec/app/models/html_writer.rb +0 -3
  1004. data/spec/app/models/learner.rb +0 -2
  1005. data/spec/app/models/my_hash.rb +0 -2
  1006. data/spec/app/models/other_owner_object.rb +0 -2
  1007. data/spec/app/models/pack.rb +0 -3
  1008. data/spec/app/models/pdf_writer.rb +0 -3
  1009. data/spec/app/models/pencil.rb +0 -1
  1010. data/spec/app/models/profile.rb +0 -5
  1011. data/spec/app/models/series.rb +0 -4
  1012. data/spec/app/models/strategy.rb +0 -3
  1013. data/spec/app/models/sub_item.rb +0 -3
  1014. data/spec/app/models/title.rb +0 -3
  1015. data/spec/app/models/tool.rb +0 -8
  1016. data/spec/app/models/truck.rb +0 -3
  1017. data/spec/app/models/vehicle.rb +0 -11
  1018. data/spec/app/models/video_game.rb +0 -1
  1019. data/spec/mongoid/criteria/queryable/forwardable_spec.rb +0 -87
  1020. data/spec/mongoid/matchable/all_spec.rb +0 -31
  1021. data/spec/mongoid/matchable/and_spec.rb +0 -187
  1022. data/spec/mongoid/matchable/default_spec.rb +0 -137
  1023. data/spec/mongoid/matchable/elem_match_spec.rb +0 -106
  1024. data/spec/mongoid/matchable/eq_spec.rb +0 -48
  1025. data/spec/mongoid/matchable/exists_spec.rb +0 -57
  1026. data/spec/mongoid/matchable/gt_spec.rb +0 -86
  1027. data/spec/mongoid/matchable/gte_spec.rb +0 -84
  1028. data/spec/mongoid/matchable/in_spec.rb +0 -49
  1029. data/spec/mongoid/matchable/lt_spec.rb +0 -85
  1030. data/spec/mongoid/matchable/lte_spec.rb +0 -85
  1031. data/spec/mongoid/matchable/ne_spec.rb +0 -46
  1032. data/spec/mongoid/matchable/nin_spec.rb +0 -48
  1033. data/spec/mongoid/matchable/nor_spec.rb +0 -209
  1034. data/spec/mongoid/matchable/or_spec.rb +0 -131
  1035. data/spec/mongoid/matchable/regexp_spec.rb +0 -59
  1036. data/spec/mongoid/matchable/size_spec.rb +0 -25
  1037. data/spec/mongoid/matchable_spec.rb +0 -853
  1038. data/spec/support/child_process_helper.rb +0 -76
  1039. data/spec/support/cluster_config.rb +0 -158
@@ -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,92 +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 ])
2271
- end
2272
-
2273
- it "adds the $nearSphere expression" do
2274
- expect(selection.selector).to eq({
2275
- "location" => { "$nearSphere" => [ 20, 21 ] },
2276
- "comments" => { "$nearSphere" => [ 20, 21 ] }
2277
- })
2278
- end
2279
-
2280
- it "returns a cloned query" do
2281
- expect(selection).to_not equal(query)
2282
- end
2283
- end
2284
- end
2285
- end
2286
-
2287
- describe "#nin" do
2288
-
2289
- context "when provided no criterion" do
2290
-
2291
- let(:selection) do
2292
- query.nin
2293
- end
2294
-
2295
- it "does not add any criterion" do
2296
- expect(selection.selector).to eq({})
2297
- end
2298
-
2299
- it "returns the query" do
2300
- expect(selection).to eq(query)
2301
- end
2302
-
2303
- it "returns a cloned query" do
2304
- expect(selection).to_not equal(query)
2305
- end
2306
- end
2307
-
2308
- context "when provided nil" do
2309
-
2310
- let(:selection) do
2311
- query.nin(nil)
2312
- end
2313
-
2314
- it "does not add any criterion" do
2315
- expect(selection.selector).to eq({})
2316
- end
2317
-
2318
- it "returns the query" do
2319
- expect(selection).to eq(query)
2320
- end
2321
-
2322
- it "returns a cloned query" do
2323
- expect(selection).to_not equal(query)
2324
- end
2325
- end
2326
-
2327
- context "when provided a single criterion" do
2328
-
2329
- context "when providing an array" do
2330
-
2331
- let(:selection) do
2332
- query.nin(field: [ 1, 2 ])
2333
- end
2334
-
2335
- it "adds the $nin selector" do
2336
- expect(selection.selector).to eq({
2337
- "field" => { "$nin" => [ 1, 2 ] }
2338
- })
2339
- end
2340
-
2341
- it "returns a cloned query" do
2342
- expect(selection).to_not equal(query)
2343
- end
2344
- end
2345
-
2346
- context "when providing a range" do
2347
-
2348
- let(:selection) do
2349
- query.nin(field: 1..3)
546
+ elem_match(users: { name: "value" }).
547
+ elem_match(comments: { text: "value" })
2350
548
  end
2351
549
 
2352
- it "adds the $nin selector with converted range" do
550
+ it "adds the $elemMatch expression" do
2353
551
  expect(selection.selector).to eq({
2354
- "field" => { "$nin" => [ 1, 2, 3 ] }
552
+ "users" => { "$elemMatch" => { name: "value" }},
553
+ "comments" => { "$elemMatch" => { text: "value" }}
2355
554
  })
2356
555
  end
2357
556
 
@@ -2360,15 +559,17 @@ describe Mongoid::Criteria::Queryable::Selectable do
2360
559
  end
2361
560
  end
2362
561
 
2363
- context "when providing a single value" do
562
+ context "when the fields are the same" do
2364
563
 
2365
564
  let(:selection) do
2366
- query.nin(field: 1)
565
+ query.
566
+ elem_match(users: { name: "value" }).
567
+ elem_match(users: { state: "new" })
2367
568
  end
2368
569
 
2369
- it "adds the $nin selector with wrapped value" do
570
+ it "overrides the $elemMatch expression" do
2370
571
  expect(selection.selector).to eq({
2371
- "field" => { "$nin" => [ 1 ] }
572
+ "users" => { "$elemMatch" => { state: "new" }}
2372
573
  })
2373
574
  end
2374
575
 
@@ -2377,48 +578,26 @@ describe Mongoid::Criteria::Queryable::Selectable do
2377
578
  end
2378
579
  end
2379
580
  end
581
+ end
2380
582
 
2381
- context "when unioning on the same field" do
2382
-
2383
- context "when the field is not aliased" do
2384
-
2385
- let(:selection) do
2386
- query.nin(first: [ 1, 2 ]).union.nin(first: [ 3, 4 ])
2387
- end
2388
-
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
2395
-
2396
- context "when the field is aliased" do
2397
-
2398
- let(:selection) do
2399
- query.nin(id: [ 1, 2 ]).union.nin(id: [ 3, 4 ])
2400
- end
2401
-
2402
- it "unions the selection on the field" do
2403
- expect(selection.selector).to eq(
2404
- { "_id" => { "$nin" => [ 1, 2, 3, 4 ]}}
2405
- )
2406
- end
2407
- end
2408
- end
2409
-
2410
- context "when provided multiple criterion" do
583
+ describe "#exists" do
2411
584
 
2412
- context "when the criterion are for different fields" do
585
+ let(:query_method) { :exists }
586
+
587
+ it_behaves_like 'requires an argument'
588
+ it_behaves_like 'requires a non-nil argument'
589
+
590
+ context "when provided a criterion" do
591
+
592
+ context "when provided a boolean" do
2413
593
 
2414
594
  let(:selection) do
2415
- query.nin(first: [ 1, 2 ], second: [ 3, 4 ])
595
+ query.exists(users: true)
2416
596
  end
2417
597
 
2418
- it "adds the $nin selectors" do
598
+ it "adds the $exists expression" do
2419
599
  expect(selection.selector).to eq({
2420
- "first" => { "$nin" => [ 1, 2 ] },
2421
- "second" => { "$nin" => [ 3, 4 ] }
600
+ "users" => { "$exists" => true }
2422
601
  })
2423
602
  end
2424
603
 
@@ -2426,20 +605,16 @@ describe Mongoid::Criteria::Queryable::Selectable do
2426
605
  expect(selection).to_not equal(query)
2427
606
  end
2428
607
  end
2429
- end
2430
-
2431
- context "when chaining the criterion" do
2432
608
 
2433
- context "when the criterion are for different fields" do
609
+ context "when provided a string" do
2434
610
 
2435
611
  let(:selection) do
2436
- query.nin(first: [ 1, 2 ]).nin(second: [ 3, 4 ])
612
+ query.exists(users: "yes")
2437
613
  end
2438
614
 
2439
- it "adds the $nin selectors" do
615
+ it "adds the $exists expression" do
2440
616
  expect(selection.selector).to eq({
2441
- "first" => { "$nin" => [ 1, 2 ] },
2442
- "second" => { "$nin" => [ 3, 4 ] }
617
+ "users" => { "$exists" => true }
2443
618
  })
2444
619
  end
2445
620
 
@@ -2447,18 +622,25 @@ describe Mongoid::Criteria::Queryable::Selectable do
2447
622
  expect(selection).to_not equal(query)
2448
623
  end
2449
624
  end
625
+ end
2450
626
 
2451
- context "when the criterion are on the same field" do
627
+ context "when providing multiple criteria" do
628
+
629
+ context "when the fields differ" do
2452
630
 
2453
- context "when the stretegy is the default (intersection)" do
631
+ context "when providing boolean values" do
2454
632
 
2455
633
  let(:selection) do
2456
- query.nin(first: [ 1, 2 ]).nin(first: [ 2, 3 ])
634
+ query.exists(
635
+ users: true,
636
+ comments: true
637
+ )
2457
638
  end
2458
639
 
2459
- it "intersects the $nin selectors" do
640
+ it "adds the $exists expression" do
2460
641
  expect(selection.selector).to eq({
2461
- "first" => { "$nin" => [ 2 ] }
642
+ "users" => { "$exists" => true },
643
+ "comments" => { "$exists" => true }
2462
644
  })
2463
645
  end
2464
646
 
@@ -2467,15 +649,19 @@ describe Mongoid::Criteria::Queryable::Selectable do
2467
649
  end
2468
650
  end
2469
651
 
2470
- context "when the stretegy is intersect" do
652
+ context "when providing string values" do
2471
653
 
2472
654
  let(:selection) do
2473
- query.nin(first: [ 1, 2 ]).intersect.nin(first: [ 2, 3 ])
655
+ query.exists(
656
+ users: "y",
657
+ comments: "true"
658
+ )
2474
659
  end
2475
660
 
2476
- it "intersects the $nin selectors" do
661
+ it "adds the $exists expression" do
2477
662
  expect(selection.selector).to eq({
2478
- "first" => { "$nin" => [ 2 ] }
663
+ "users" => { "$exists" => true },
664
+ "comments" => { "$exists" => true }
2479
665
  })
2480
666
  end
2481
667
 
@@ -2483,93 +669,174 @@ describe Mongoid::Criteria::Queryable::Selectable do
2483
669
  expect(selection).to_not equal(query)
2484
670
  end
2485
671
  end
672
+ end
673
+ end
674
+
675
+ context "when chaining multiple criteria" do
676
+
677
+ context "when the fields differ" do
678
+
679
+ let(:selection) do
680
+ query.
681
+ exists(users: true).
682
+ exists(comments: true)
683
+ end
684
+
685
+ it "adds the $exists expression" do
686
+ expect(selection.selector).to eq({
687
+ "users" => { "$exists" => true },
688
+ "comments" => { "$exists" => true }
689
+ })
690
+ end
691
+
692
+ it "returns a cloned query" do
693
+ expect(selection).to_not equal(query)
694
+ end
695
+ end
696
+ end
697
+ end
698
+
699
+ %i(geo_spatial geo_spacial).each do |meth|
700
+ describe "#geo_spacial" do
2486
701
 
2487
- context "when the stretegy is override" do
702
+ let(:query_method) { meth }
703
+
704
+ it_behaves_like 'requires an argument'
705
+ it_behaves_like 'requires a non-nil argument'
706
+
707
+ context "when provided a criterion" do
708
+
709
+ context "when the geometry is a point intersection" do
2488
710
 
2489
711
  let(:selection) do
2490
- query.nin(first: [ 1, 2 ]).override.nin(first: [ 3, 4 ])
712
+ query.public_send(query_method, :location.intersects_point => [ 1, 10 ])
2491
713
  end
2492
714
 
2493
- it "overwrites the first $nin selector" do
715
+ it "adds the $geoIntersects expression" do
2494
716
  expect(selection.selector).to eq({
2495
- "first" => { "$nin" => [ 3, 4 ] }
717
+ "location" => {
718
+ "$geoIntersects" => {
719
+ "$geometry" => {
720
+ "type" => "Point",
721
+ "coordinates" => [ 1, 10 ]
722
+ }
723
+ }
724
+ }
2496
725
  })
2497
726
  end
2498
727
 
2499
- it "returns a cloned query" do
2500
- expect(selection).to_not equal(query)
2501
- end
728
+ it_behaves_like "returns a cloned query"
2502
729
  end
2503
730
 
2504
- context "when the stretegy is union" do
731
+ context "when the geometry is a line intersection" do
2505
732
 
2506
733
  let(:selection) do
2507
- query.nin(first: [ 1, 2 ]).union.nin(first: [ 3, 4 ])
734
+ query.public_send(query_method, :location.intersects_line => [[ 1, 10 ], [ 2, 10 ]])
2508
735
  end
2509
736
 
2510
- it "unions the $nin selectors" do
737
+ it "adds the $geoIntersects expression" do
2511
738
  expect(selection.selector).to eq({
2512
- "first" => { "$nin" => [ 1, 2, 3, 4 ] }
739
+ "location" => {
740
+ "$geoIntersects" => {
741
+ "$geometry" => {
742
+ "type" => "LineString",
743
+ "coordinates" => [[ 1, 10 ], [ 2, 10 ]]
744
+ }
745
+ }
746
+ }
2513
747
  })
2514
748
  end
2515
749
 
2516
- it "returns a cloned query" do
2517
- expect(selection).to_not equal(query)
2518
- end
750
+ it_behaves_like "returns a cloned query"
2519
751
  end
2520
- end
2521
- end
2522
- end
2523
752
 
2524
- describe "#nor" do
753
+ context "when the geometry is a polygon intersection" do
2525
754
 
2526
- context "when provided no criterion" do
2527
-
2528
- let(:selection) do
2529
- query.nor
2530
- end
755
+ let(:selection) do
756
+ query.public_send(query_method,
757
+ :location.intersects_polygon => [[[ 1, 10 ], [ 2, 10 ], [ 1, 10 ]]]
758
+ )
759
+ end
2531
760
 
2532
- it "does not add any criterion" do
2533
- expect(selection.selector).to eq({})
2534
- end
761
+ it "adds the $geoIntersects expression" do
762
+ expect(selection.selector).to eq({
763
+ "location" => {
764
+ "$geoIntersects" => {
765
+ "$geometry" => {
766
+ "type" => "Polygon",
767
+ "coordinates" => [[[ 1, 10 ], [ 2, 10 ], [ 1, 10 ]]]
768
+ }
769
+ }
770
+ }
771
+ })
772
+ end
2535
773
 
2536
- it "returns the query" do
2537
- expect(selection).to eq(query)
2538
- end
774
+ it_behaves_like "returns a cloned query"
775
+ end
2539
776
 
2540
- it "returns a cloned query" do
2541
- expect(selection).to_not equal(query)
2542
- end
2543
- end
777
+ context "when the geometry is within a polygon" do
2544
778
 
2545
- context "when provided nil" do
779
+ let(:selection) do
780
+ query.public_send(query_method,
781
+ :location.within_polygon => [[[ 1, 10 ], [ 2, 10 ], [ 1, 10 ]]]
782
+ )
783
+ end
2546
784
 
2547
- let(:selection) do
2548
- query.nor(nil)
2549
- end
785
+ it "adds the $geoIntersects expression" do
786
+ expect(selection.selector).to eq({
787
+ "location" => {
788
+ "$geoWithin" => {
789
+ "$geometry" => {
790
+ "type" => "Polygon",
791
+ "coordinates" => [[[ 1, 10 ], [ 2, 10 ], [ 1, 10 ]]]
792
+ }
793
+ }
794
+ }
795
+ })
796
+ end
2550
797
 
2551
- it "does not add any criterion" do
2552
- expect(selection.selector).to eq({})
2553
- end
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
2554
804
 
2555
- it "returns the query" do
2556
- expect(selection).to eq(query)
2557
- end
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
816
+ end
2558
817
 
2559
- it "returns a cloned query" do
2560
- expect(selection).to_not equal(query)
818
+ it_behaves_like "returns a cloned query"
819
+ end
2561
820
  end
2562
821
  end
822
+ end
823
+
824
+ describe "#gt" do
825
+
826
+ let(:query_method) { :gt }
827
+
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,20 +905,23 @@ describe Mongoid::Criteria::Queryable::Selectable do
2665
905
  end
2666
906
  end
2667
907
 
2668
- describe "#or" do
908
+ describe "#gte" do
2669
909
 
2670
- context "when provided no criterion" do
910
+ let(:query_method) { :gte }
2671
911
 
2672
- let(:selection) do
2673
- query.or
2674
- end
912
+ it_behaves_like 'requires an argument'
913
+ it_behaves_like 'requires a non-nil argument'
2675
914
 
2676
- it "does not add any criterion" do
2677
- expect(selection.selector).to eq({})
915
+ context "when provided a single criterion" do
916
+
917
+ let(:selection) do
918
+ query.gte(field: 10)
2678
919
  end
2679
920
 
2680
- it "returns the query" do
2681
- expect(selection).to eq(query)
921
+ it "adds the $gte selector" do
922
+ expect(selection.selector).to eq({
923
+ "field" => { "$gte" => 10 }
924
+ })
2682
925
  end
2683
926
 
2684
927
  it "returns a cloned query" do
@@ -2686,56 +929,85 @@ describe Mongoid::Criteria::Queryable::Selectable do
2686
929
  end
2687
930
  end
2688
931
 
2689
- context "when provided nil" do
932
+ context "when provided multiple criterion" do
2690
933
 
2691
- let(:selection) do
2692
- query.or(nil)
2693
- end
934
+ context "when the criterion are for different fields" do
2694
935
 
2695
- it "does not add any criterion" do
2696
- expect(selection.selector).to eq({})
936
+ let(:selection) do
937
+ query.gte(first: 10, second: 15)
938
+ end
939
+
940
+ it "adds the $gte selectors" do
941
+ expect(selection.selector).to eq({
942
+ "first" => { "$gte" => 10 },
943
+ "second" => { "$gte" => 15 }
944
+ })
945
+ end
946
+
947
+ it "returns a cloned query" do
948
+ expect(selection).to_not equal(query)
949
+ end
2697
950
  end
951
+ end
2698
952
 
2699
- it "returns the query" do
2700
- expect(selection).to eq(query)
953
+ context "when chaining the criterion" do
954
+
955
+ context "when the criterion are for different fields" do
956
+
957
+ let(:selection) do
958
+ query.gte(first: 10).gte(second: 15)
959
+ end
960
+
961
+ it "adds the $gte selectors" do
962
+ expect(selection.selector).to eq({
963
+ "first" => { "$gte" => 10 },
964
+ "second" => { "$gte" => 15 }
965
+ })
966
+ end
967
+
968
+ it "returns a cloned query" do
969
+ expect(selection).to_not equal(query)
970
+ end
2701
971
  end
2702
972
 
2703
- it "returns a cloned query" do
2704
- expect(selection).to_not equal(query)
973
+ context "when the criterion are on the same field" do
974
+
975
+ let(:selection) do
976
+ query.gte(first: 10).gte(first: 15)
977
+ end
978
+
979
+ it "overwrites the first $gte selector" do
980
+ expect(selection.selector).to eq({
981
+ "first" => { "$gte" => 15 }
982
+ })
983
+ end
984
+
985
+ it "returns a cloned query" do
986
+ expect(selection).to_not equal(query)
987
+ end
2705
988
  end
2706
989
  end
990
+ end
2707
991
 
2708
- context "when provided a single criterion" do
2709
-
2710
- let(:selection) do
2711
- query.or(field: [ 1, 2 ])
2712
- end
992
+ describe "#in" do
2713
993
 
2714
- it "adds the $or selector" do
2715
- expect(selection.selector).to eq({
2716
- "$or" => [{ "field" => [ 1, 2 ] }]
2717
- })
2718
- end
994
+ let(:query_method) { :in }
995
+ let(:operator) { '$in' }
2719
996
 
2720
- it "returns a cloned query" do
2721
- expect(selection).to_not equal(query)
2722
- end
2723
- end
997
+ it_behaves_like 'requires an argument'
998
+ it_behaves_like 'requires a non-nil argument'
2724
999
 
2725
- context "when provided multiple criterion" do
1000
+ context "when provided a single criterion" do
2726
1001
 
2727
- context "when the criterion are for different fields" do
1002
+ context "when providing an array" do
2728
1003
 
2729
1004
  let(:selection) do
2730
- query.or({ first: [ 1, 2 ] }, { second: [ 3, 4 ] })
1005
+ query.in(field: [ 1, 2 ])
2731
1006
  end
2732
1007
 
2733
- it "adds the $or selector" do
1008
+ it "adds the $in selector" do
2734
1009
  expect(selection.selector).to eq({
2735
- "$or" => [
2736
- { "first" => [ 1, 2 ] },
2737
- { "second" => [ 3, 4 ] }
2738
- ]
1010
+ "field" => { "$in" => [ 1, 2 ] }
2739
1011
  })
2740
1012
  end
2741
1013
 
@@ -2744,18 +1016,15 @@ describe Mongoid::Criteria::Queryable::Selectable do
2744
1016
  end
2745
1017
  end
2746
1018
 
2747
- context "when a criterion has a selectable key" do
1019
+ context "when providing a single value" do
2748
1020
 
2749
1021
  let(:selection) do
2750
- query.or({ first: [ 1, 2 ] }, { :second.gt => 3 })
1022
+ query.in(field: 1)
2751
1023
  end
2752
1024
 
2753
- it "adds the $or selector" do
1025
+ it "adds the $in selector with wrapped value" do
2754
1026
  expect(selection.selector).to eq({
2755
- "$or" => [
2756
- { "first" => [ 1, 2 ] },
2757
- { "second" => { "$gt" => 3 }}
2758
- ]
1027
+ "field" => { "$in" => [ 1 ] }
2759
1028
  })
2760
1029
  end
2761
1030
 
@@ -2763,16 +1032,20 @@ describe Mongoid::Criteria::Queryable::Selectable do
2763
1032
  expect(selection).to_not equal(query)
2764
1033
  end
2765
1034
  end
1035
+ end
2766
1036
 
2767
- 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
2768
1040
 
2769
1041
  let(:selection) do
2770
- query.or({ id: 1 })
1042
+ query.in(first: [ 1, 2 ], second: 3..4)
2771
1043
  end
2772
1044
 
2773
- it "adds the $or selector and aliases the field" do
1045
+ it "adds the $in selectors" do
2774
1046
  expect(selection.selector).to eq({
2775
- "$or" => [ { "_id" => 1 } ]
1047
+ "first" => { "$in" => [ 1, 2 ] },
1048
+ "second" => { "$in" => [ 3, 4 ] }
2776
1049
  })
2777
1050
  end
2778
1051
 
@@ -2780,19 +1053,20 @@ describe Mongoid::Criteria::Queryable::Selectable do
2780
1053
  expect(selection).to_not equal(query)
2781
1054
  end
2782
1055
  end
1056
+ end
2783
1057
 
2784
- 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
2785
1061
 
2786
1062
  let(:selection) do
2787
- query.or([{ first: [ 1, 2 ] }, { :second.gt => 3 }])
1063
+ query.in(first: [ 1, 2 ]).in(second: [ 3, 4 ])
2788
1064
  end
2789
1065
 
2790
- it "adds the $or selector" do
1066
+ it "adds the $in selectors" do
2791
1067
  expect(selection.selector).to eq({
2792
- "$or" => [
2793
- { "first" => [ 1, 2 ] },
2794
- { "second" => { "$gt" => 3 }}
2795
- ]
1068
+ "first" => { "$in" => [ 1, 2 ] },
1069
+ "second" => { "$in" => [ 3, 4 ] }
2796
1070
  })
2797
1071
  end
2798
1072
 
@@ -2803,16 +1077,47 @@ describe Mongoid::Criteria::Queryable::Selectable do
2803
1077
 
2804
1078
  context "when the criterion are on the same field" do
2805
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
+
2806
1113
  let(:selection) do
2807
- query.or({ first: [ 1, 2 ] }, { first: [ 3, 4 ] })
1114
+ query.lt(first: 10, second: 15)
2808
1115
  end
2809
1116
 
2810
- it "appends both $or expressions" do
1117
+ it "adds the $lt selectors" do
2811
1118
  expect(selection.selector).to eq({
2812
- "$or" => [
2813
- { "first" => [ 1, 2 ] },
2814
- { "first" => [ 3, 4 ] }
2815
- ]
1119
+ "first" => { "$lt" => 10 },
1120
+ "second" => { "$lt" => 15 }
2816
1121
  })
2817
1122
  end
2818
1123
 
@@ -2827,15 +1132,13 @@ describe Mongoid::Criteria::Queryable::Selectable do
2827
1132
  context "when the criterion are for different fields" do
2828
1133
 
2829
1134
  let(:selection) do
2830
- query.or(first: [ 1, 2 ]).or(second: [ 3, 4 ])
1135
+ query.lt(first: 10).lt(second: 15)
2831
1136
  end
2832
1137
 
2833
- it "adds the $or selectors" do
1138
+ it "adds the $lt selectors" do
2834
1139
  expect(selection.selector).to eq({
2835
- "$or" => [
2836
- { "first" => [ 1, 2 ] },
2837
- { "second" => [ 3, 4 ] }
2838
- ]
1140
+ "first" => { "$lt" => 10 },
1141
+ "second" => { "$lt" => 15 }
2839
1142
  })
2840
1143
  end
2841
1144
 
@@ -2847,15 +1150,12 @@ describe Mongoid::Criteria::Queryable::Selectable do
2847
1150
  context "when the criterion are on the same field" do
2848
1151
 
2849
1152
  let(:selection) do
2850
- query.or(first: [ 1, 2 ]).or(first: [ 3, 4 ])
1153
+ query.lt(first: 10).lt(first: 15)
2851
1154
  end
2852
1155
 
2853
- it "appends both $or expressions" do
1156
+ it "overwrites the first $lt selector" do
2854
1157
  expect(selection.selector).to eq({
2855
- "$or" => [
2856
- { "first" => [ 1, 2 ] },
2857
- { "first" => [ 3, 4 ] }
2858
- ]
1158
+ "first" => { "$lt" => 15 }
2859
1159
  })
2860
1160
  end
2861
1161
 
@@ -2866,20 +1166,23 @@ describe Mongoid::Criteria::Queryable::Selectable do
2866
1166
  end
2867
1167
  end
2868
1168
 
2869
- describe "#with_size" do
1169
+ describe "#lte" do
2870
1170
 
2871
- context "when provided no criterion" do
1171
+ let(:query_method) { :lte }
2872
1172
 
2873
- let(:selection) do
2874
- query.with_size
2875
- end
1173
+ it_behaves_like 'requires an argument'
1174
+ it_behaves_like 'requires a non-nil argument'
2876
1175
 
2877
- it "does not add any criterion" do
2878
- expect(selection.selector).to eq({})
1176
+ context "when provided a single criterion" do
1177
+
1178
+ let(:selection) do
1179
+ query.lte(field: 10)
2879
1180
  end
2880
1181
 
2881
- it "returns the query" do
2882
- expect(selection).to eq(query)
1182
+ it "adds the $lte selector" do
1183
+ expect(selection.selector).to eq({
1184
+ "field" => { "$lte" => 10 }
1185
+ })
2883
1186
  end
2884
1187
 
2885
1188
  it "returns a cloned query" do
@@ -2887,36 +1190,39 @@ describe Mongoid::Criteria::Queryable::Selectable do
2887
1190
  end
2888
1191
  end
2889
1192
 
2890
- context "when provided nil" do
1193
+ context "when provided multiple criterion" do
2891
1194
 
2892
- let(:selection) do
2893
- query.with_size(nil)
2894
- end
1195
+ context "when the criterion are for different fields" do
2895
1196
 
2896
- it "does not add any criterion" do
2897
- expect(selection.selector).to eq({})
2898
- end
1197
+ let(:selection) do
1198
+ query.lte(first: 10, second: 15)
1199
+ end
2899
1200
 
2900
- it "returns the query" do
2901
- expect(selection).to eq(query)
2902
- 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
2903
1207
 
2904
- it "returns a cloned query" do
2905
- expect(selection).to_not equal(query)
1208
+ it "returns a cloned query" do
1209
+ expect(selection).to_not equal(query)
1210
+ end
2906
1211
  end
2907
1212
  end
2908
1213
 
2909
- context "when provided a single criterion" do
1214
+ context "when chaining the criterion" do
2910
1215
 
2911
- context "when provided an integer" do
1216
+ context "when the criterion are for different fields" do
2912
1217
 
2913
1218
  let(:selection) do
2914
- query.with_size(field: 10)
1219
+ query.lte(first: 10).lte(second: 15)
2915
1220
  end
2916
1221
 
2917
- it "adds the $size selector" do
1222
+ it "adds the $lte selectors" do
2918
1223
  expect(selection.selector).to eq({
2919
- "field" => { "$size" => 10 }
1224
+ "first" => { "$lte" => 10 },
1225
+ "second" => { "$lte" => 15 }
2920
1226
  })
2921
1227
  end
2922
1228
 
@@ -2925,15 +1231,15 @@ describe Mongoid::Criteria::Queryable::Selectable do
2925
1231
  end
2926
1232
  end
2927
1233
 
2928
- context "when provided a string" do
1234
+ context "when the criterion are on the same field" do
2929
1235
 
2930
1236
  let(:selection) do
2931
- query.with_size(field: "10")
1237
+ query.lte(first: 10).lte(first: 15)
2932
1238
  end
2933
1239
 
2934
- it "adds the $size selector with an integer" do
1240
+ it "overwrites the first $lte selector" do
2935
1241
  expect(selection.selector).to eq({
2936
- "field" => { "$size" => 10 }
1242
+ "first" => { "$lte" => 15 }
2937
1243
  })
2938
1244
  end
2939
1245
 
@@ -2942,61 +1248,75 @@ describe Mongoid::Criteria::Queryable::Selectable do
2942
1248
  end
2943
1249
  end
2944
1250
  end
1251
+ end
2945
1252
 
2946
- context "when provided multiple criterion" do
1253
+ describe "#max_distance" do
2947
1254
 
2948
- context "when the criterion are for different fields" do
1255
+ let(:query_method) { :max_distance }
2949
1256
 
2950
- context "when provided integers" do
1257
+ it_behaves_like 'requires an argument'
1258
+ it_behaves_like 'requires a non-nil argument'
2951
1259
 
2952
- let(:selection) do
2953
- query.with_size(first: 10, second: 15)
2954
- end
1260
+ context "when provided a criterion" do
2955
1261
 
2956
- it "adds the $size selectors" do
2957
- expect(selection.selector).to eq({
2958
- "first" => { "$size" => 10 },
2959
- "second" => { "$size" => 15 }
2960
- })
2961
- end
1262
+ context "when a $near criterion exists on the same field" do
2962
1263
 
2963
- it "returns a cloned query" do
2964
- expect(selection).to_not equal(query)
2965
- end
1264
+ let(:selection) do
1265
+ query.near(location: [ 1, 1 ]).max_distance(location: 50)
2966
1266
  end
2967
1267
 
2968
- 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
2969
1273
 
2970
- let(:selection) do
2971
- query.with_size(first: "10", second: "15")
2972
- end
1274
+ it "returns a cloned query" do
1275
+ expect(selection).to_not equal(query)
1276
+ end
1277
+ end
1278
+ end
1279
+ end
2973
1280
 
2974
- it "adds the $size selectors" do
2975
- expect(selection.selector).to eq({
2976
- "first" => { "$size" => 10 },
2977
- "second" => { "$size" => 15 }
2978
- })
2979
- end
1281
+ describe "#mod" do
2980
1282
 
2981
- it "returns a cloned query" do
2982
- expect(selection).to_not equal(query)
2983
- end
2984
- 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)
2985
1302
  end
2986
1303
  end
2987
1304
 
2988
- context "when chaining the criterion" do
1305
+ context "when providing multiple criteria" do
2989
1306
 
2990
- context "when the criterion are for different fields" do
1307
+ context "when the fields differ" do
2991
1308
 
2992
1309
  let(:selection) do
2993
- query.with_size(first: 10).with_size(second: 15)
1310
+ query.mod(
1311
+ value: [ 10, 1 ],
1312
+ comments: [ 10, 1 ]
1313
+ )
2994
1314
  end
2995
1315
 
2996
- it "adds the $size selectors" do
1316
+ it "adds the $mod expression" do
2997
1317
  expect(selection.selector).to eq({
2998
- "first" => { "$size" => 10 },
2999
- "second" => { "$size" => 15 }
1318
+ "value" => { "$mod" => [ 10, 1 ] },
1319
+ "comments" => { "$mod" => [ 10, 1 ] }
3000
1320
  })
3001
1321
  end
3002
1322
 
@@ -3004,16 +1324,22 @@ describe Mongoid::Criteria::Queryable::Selectable do
3004
1324
  expect(selection).to_not equal(query)
3005
1325
  end
3006
1326
  end
1327
+ end
3007
1328
 
3008
- 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
3009
1332
 
3010
1333
  let(:selection) do
3011
- query.with_size(first: 10).with_size(first: 15)
1334
+ query.
1335
+ mod(value: [ 10, 1 ]).
1336
+ mod(result: [ 10, 1 ])
3012
1337
  end
3013
1338
 
3014
- it "overwrites the first $size selector" do
1339
+ it "adds the $mod expression" do
3015
1340
  expect(selection.selector).to eq({
3016
- "first" => { "$size" => 15 }
1341
+ "value" => { "$mod" => [ 10, 1 ] },
1342
+ "result" => { "$mod" => [ 10, 1 ] }
3017
1343
  })
3018
1344
  end
3019
1345
 
@@ -3024,39 +1350,23 @@ describe Mongoid::Criteria::Queryable::Selectable do
3024
1350
  end
3025
1351
  end
3026
1352
 
3027
- describe "#type" do
3028
-
3029
- context "when provided no criterion" do
3030
-
3031
- let(:selection) do
3032
- query.with_type
3033
- end
3034
-
3035
- it "does not add any criterion" do
3036
- expect(selection.selector).to eq({})
3037
- end
3038
-
3039
- it "returns the query" do
3040
- expect(selection).to eq(query)
3041
- end
1353
+ describe "#ne" do
3042
1354
 
3043
- it "returns a cloned query" do
3044
- expect(selection).to_not equal(query)
3045
- end
3046
- end
1355
+ let(:query_method) { :ne }
3047
1356
 
3048
- context "when provided nil" do
1357
+ it_behaves_like 'requires an argument'
1358
+ it_behaves_like 'requires a non-nil argument'
3049
1359
 
3050
- let(:selection) do
3051
- query.with_type(nil)
3052
- end
1360
+ context "when provided a criterion" do
3053
1361
 
3054
- it "does not add any criterion" do
3055
- expect(selection.selector).to eq({})
1362
+ let(:selection) do
1363
+ query.ne(value: 10)
3056
1364
  end
3057
1365
 
3058
- it "returns the query" do
3059
- expect(selection).to eq(query)
1366
+ it "adds the $ne expression" do
1367
+ expect(selection.selector).to eq({
1368
+ "value" => { "$ne" => 10 }
1369
+ })
3060
1370
  end
3061
1371
 
3062
1372
  it "returns a cloned query" do
@@ -3064,17 +1374,21 @@ describe Mongoid::Criteria::Queryable::Selectable do
3064
1374
  end
3065
1375
  end
3066
1376
 
3067
- context "when provided a single criterion" do
1377
+ context "when providing multiple criteria" do
3068
1378
 
3069
- context "when provided an integer" do
1379
+ context "when the fields differ" do
3070
1380
 
3071
1381
  let(:selection) do
3072
- query.with_type(field: 10)
1382
+ query.ne(
1383
+ value: 10,
1384
+ comments: 10
1385
+ )
3073
1386
  end
3074
1387
 
3075
- it "adds the $type selector" do
1388
+ it "adds the $ne expression" do
3076
1389
  expect(selection.selector).to eq({
3077
- "field" => { "$type" => 10 }
1390
+ "value" => { "$ne" => 10 },
1391
+ "comments" => { "$ne" => 10 }
3078
1392
  })
3079
1393
  end
3080
1394
 
@@ -3082,16 +1396,22 @@ describe Mongoid::Criteria::Queryable::Selectable do
3082
1396
  expect(selection).to_not equal(query)
3083
1397
  end
3084
1398
  end
1399
+ end
3085
1400
 
3086
- context "when provided a string" do
1401
+ context "when chaining multiple criteria" do
1402
+
1403
+ context "when the fields differ" do
3087
1404
 
3088
1405
  let(:selection) do
3089
- query.with_type(field: "10")
1406
+ query.
1407
+ ne(value: 10).
1408
+ ne(result: 10)
3090
1409
  end
3091
1410
 
3092
- it "adds the $type selector" do
1411
+ it "adds the $ne expression" do
3093
1412
  expect(selection.selector).to eq({
3094
- "field" => { "$type" => 10 }
1413
+ "value" => { "$ne" => 10 },
1414
+ "result" => { "$ne" => 10 }
3095
1415
  })
3096
1416
  end
3097
1417
 
@@ -3100,40 +1420,47 @@ describe Mongoid::Criteria::Queryable::Selectable do
3100
1420
  end
3101
1421
  end
3102
1422
  end
1423
+ end
3103
1424
 
3104
- context "when provided multiple criterion" do
1425
+ describe "#near" do
3105
1426
 
3106
- context "when the criterion are for different fields" do
1427
+ let(:query_method) { :near }
3107
1428
 
3108
- let(:selection) do
3109
- query.with_type(first: 10, second: 15)
3110
- end
1429
+ it_behaves_like 'requires an argument'
1430
+ it_behaves_like 'requires a non-nil argument'
3111
1431
 
3112
- it "adds the $type selectors" do
3113
- expect(selection.selector).to eq({
3114
- "first" => { "$type" => 10 },
3115
- "second" => { "$type" => 15 }
3116
- })
3117
- end
1432
+ context "when provided a criterion" do
3118
1433
 
3119
- it "returns a cloned query" do
3120
- expect(selection).to_not equal(query)
3121
- 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)
3122
1446
  end
3123
1447
  end
3124
1448
 
3125
- context "when chaining the criterion" do
1449
+ context "when providing multiple criteria" do
3126
1450
 
3127
- context "when the criterion are for different fields" do
1451
+ context "when the fields differ" do
3128
1452
 
3129
1453
  let(:selection) do
3130
- query.with_type(first: 10).with_type(second: 15)
1454
+ query.near(
1455
+ location: [ 20, 21 ],
1456
+ comments: [ 20, 21 ]
1457
+ )
3131
1458
  end
3132
1459
 
3133
- it "adds the $type selectors" do
1460
+ it "adds the $near expression" do
3134
1461
  expect(selection.selector).to eq({
3135
- "first" => { "$type" => 10 },
3136
- "second" => { "$type" => 15 }
1462
+ "location" => { "$near" => [ 20, 21 ] },
1463
+ "comments" => { "$near" => [ 20, 21 ] }
3137
1464
  })
3138
1465
  end
3139
1466
 
@@ -3141,16 +1468,22 @@ describe Mongoid::Criteria::Queryable::Selectable do
3141
1468
  expect(selection).to_not equal(query)
3142
1469
  end
3143
1470
  end
1471
+ end
3144
1472
 
3145
- 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
3146
1476
 
3147
1477
  let(:selection) do
3148
- query.with_type(first: 10).with_type(first: 15)
1478
+ query.
1479
+ near(location: [ 20, 21 ]).
1480
+ near(comments: [ 20, 21 ])
3149
1481
  end
3150
1482
 
3151
- it "overwrites the first $type selector" do
1483
+ it "adds the $near expression" do
3152
1484
  expect(selection.selector).to eq({
3153
- "first" => { "$type" => 15 }
1485
+ "location" => { "$near" => [ 20, 21 ] },
1486
+ "comments" => { "$near" => [ 20, 21 ] }
3154
1487
  })
3155
1488
  end
3156
1489
 
@@ -3161,508 +1494,450 @@ describe Mongoid::Criteria::Queryable::Selectable do
3161
1494
  end
3162
1495
  end
3163
1496
 
3164
- describe "#text_search" do
1497
+ describe "#near_sphere" do
3165
1498
 
3166
- 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
3167
1505
 
3168
1506
  let(:selection) do
3169
- query.text_search("testing")
1507
+ query.near_sphere(location: [ 20, 21 ])
3170
1508
  end
3171
1509
 
3172
- it "constructs a text search document" do
3173
- 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
+ })
3174
1514
  end
3175
1515
 
3176
- it "returns the cloned selectable" do
3177
- expect(selection).to be_a(Mongoid::Criteria::Queryable::Selectable)
1516
+ it "returns a cloned query" do
1517
+ expect(selection).to_not equal(query)
3178
1518
  end
1519
+ end
3179
1520
 
3180
- context "when providing text search options" do
1521
+ context "when providing multiple criteria" do
1522
+
1523
+ context "when the fields differ" do
3181
1524
 
3182
1525
  let(:selection) do
3183
- query.text_search("essais", { :$language => "fr" })
1526
+ query.near_sphere(
1527
+ location: [ 20, 21 ],
1528
+ comments: [ 20, 21 ]
1529
+ )
3184
1530
  end
3185
1531
 
3186
- it "constructs a text search document" do
3187
- 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
+ })
3188
1537
  end
3189
1538
 
3190
- it "add the options to the text search document" do
3191
- expect(selection.selector['$text'][:$language]).to eq("fr")
1539
+ it "returns a cloned query" do
1540
+ expect(selection).to_not equal(query)
3192
1541
  end
3193
-
3194
- it_behaves_like "a cloning selection"
3195
1542
  end
3196
1543
  end
3197
1544
 
3198
- context 'when given more than once' do
3199
- let(:selection) do
3200
- query.text_search("one").text_search('two')
3201
- end
1545
+ context "when chaining multiple criteria" do
3202
1546
 
3203
- # MongoDB server can only handle one text expression at a time,
3204
- # per https://docs.mongodb.com/manual/reference/operator/query/text/.
3205
- # Nonetheless we test that the query is built correctly when
3206
- # a user supplies more than one text condition.
3207
- it 'merges conditions' do
3208
- expect(Mongoid.logger).to receive(:warn)
3209
- expect(selection.selector).to eq('$and' => [
3210
- {'$text' => {'$search' => 'one'}}
3211
- ],
3212
- '$text' => {'$search' => 'two'},
3213
- )
3214
- end
3215
- end
3216
- end
1547
+ context "when the fields differ" do
3217
1548
 
3218
- describe "#where" do
1549
+ let(:selection) do
1550
+ query.
1551
+ near_sphere(location: [ 20, 21 ]).
1552
+ near_sphere(comments: [ 20, 21 ])
1553
+ end
3219
1554
 
3220
- 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
3221
1561
 
3222
- let(:selection) do
3223
- query.where
1562
+ it "returns a cloned query" do
1563
+ expect(selection).to_not equal(query)
1564
+ end
3224
1565
  end
1566
+ end
1567
+ end
3225
1568
 
3226
- it "does not add any criterion" do
3227
- expect(selection.selector).to eq({})
3228
- end
1569
+ describe "#nin" do
3229
1570
 
3230
- it "returns the query" do
3231
- expect(selection).to eq(query)
3232
- end
1571
+ let(:query_method) { :nin }
1572
+ let(:operator) { '$nin' }
3233
1573
 
3234
- it "returns a cloned query" do
3235
- expect(selection).to_not equal(query)
3236
- end
3237
- end
1574
+ it_behaves_like 'requires an argument'
1575
+ it_behaves_like 'requires a non-nil argument'
3238
1576
 
3239
- context "when provided nil" do
1577
+ context "when provided a single criterion" do
3240
1578
 
3241
- let(:selection) do
3242
- query.where(nil)
3243
- end
1579
+ context "when providing an array" do
3244
1580
 
3245
- it "does not add any criterion" do
3246
- expect(selection.selector).to eq({})
3247
- end
1581
+ let(:selection) do
1582
+ query.nin(field: [ 1, 2 ])
1583
+ end
3248
1584
 
3249
- it "returns the query" do
3250
- expect(selection).to eq(query)
3251
- end
1585
+ it "adds the $nin selector" do
1586
+ expect(selection.selector).to eq({
1587
+ "field" => { "$nin" => [ 1, 2 ] }
1588
+ })
1589
+ end
3252
1590
 
3253
- it "returns a cloned query" do
3254
- expect(selection).to_not equal(query)
1591
+ it "returns a cloned query" do
1592
+ expect(selection).to_not equal(query)
1593
+ end
3255
1594
  end
3256
- end
3257
1595
 
3258
- context "when provided a string" do
1596
+ context "when providing a single value" do
3259
1597
 
3260
- let(:selection) do
3261
- query.where("this.value = 10")
3262
- end
1598
+ let(:selection) do
1599
+ query.nin(field: 1)
1600
+ end
3263
1601
 
3264
- it "adds the $where criterion" do
3265
- expect(selection.selector).to eq({ "$where" => "this.value = 10" })
3266
- end
1602
+ it "adds the $nin selector with wrapped value" do
1603
+ expect(selection.selector).to eq({
1604
+ "field" => { "$nin" => [ 1 ] }
1605
+ })
1606
+ end
3267
1607
 
3268
- it "returns a cloned query" do
3269
- expect(selection).to_not equal(query)
1608
+ it "returns a cloned query" do
1609
+ expect(selection).to_not equal(query)
1610
+ end
3270
1611
  end
3271
1612
  end
3272
1613
 
3273
- context "when provided a single criterion" do
1614
+ context "when provided multiple criterion" do
3274
1615
 
3275
- context "when the value needs no evolution" do
1616
+ context "when the criterion are for different fields" do
3276
1617
 
3277
1618
  let(:selection) do
3278
- query.where(name: "Syd")
3279
- end
3280
-
3281
- it "adds the criterion to the selection" do
3282
- expect(selection.selector).to eq({ "name" => "Syd" })
1619
+ query.nin(first: [ 1, 2 ], second: [ 3, 4 ])
3283
1620
  end
3284
- end
3285
-
3286
- context "when the value must be evolved" do
3287
1621
 
3288
- before(:all) do
3289
- class Document
3290
- def id
3291
- 13
3292
- end
3293
- def self.evolve(object)
3294
- object.id
3295
- end
3296
- 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
+ })
3297
1627
  end
3298
1628
 
3299
- after(:all) do
3300
- Object.send(:remove_const, :Document)
1629
+ it "returns a cloned query" do
1630
+ expect(selection).to_not equal(query)
3301
1631
  end
1632
+ end
1633
+ end
3302
1634
 
3303
- context "when the key needs evolution" do
3304
-
3305
- let(:query) do
3306
- Mongoid::Query.new({ "user" => "user_id" })
3307
- end
3308
-
3309
- let(:document) do
3310
- Document.new
3311
- end
3312
-
3313
- let(:selection) do
3314
- query.where(user: document)
3315
- end
1635
+ context "when chaining the criterion" do
3316
1636
 
3317
- it "alters the key and value" do
3318
- expect(selection.selector).to eq({ "user_id" => document.id })
3319
- 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 ])
3320
1641
  end
3321
1642
 
3322
- 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
3323
1649
 
3324
- let(:raw_regexp) do
3325
- BSON::Regexp::Raw.new('^Em')
3326
- end
1650
+ it "returns a cloned query" do
1651
+ expect(selection).to_not equal(query)
1652
+ end
1653
+ end
3327
1654
 
3328
- let(:selection) do
3329
- Login.where(_id: raw_regexp)
3330
- end
1655
+ context "when the criterion are on the same field" do
3331
1656
 
3332
- it 'does not convert the bson raw regexp object to a String' do
3333
- expect(selection.selector).to eq({ "_id" => raw_regexp })
3334
- end
3335
- end
1657
+ it_behaves_like 'supports merge strategies'
3336
1658
  end
3337
1659
  end
1660
+ end
3338
1661
 
3339
- context "when provided complex criterion" do
1662
+ describe "#with_size" do
3340
1663
 
3341
- context "when performing an $all" do
1664
+ let(:query_method) { :with_size }
3342
1665
 
3343
- context "when performing a single query" do
1666
+ it_behaves_like 'requires an argument'
1667
+ it_behaves_like 'requires a non-nil argument'
3344
1668
 
3345
- let(:selection) do
3346
- query.where(:field.all => [ 1, 2 ])
3347
- end
1669
+ context "when provided a single criterion" do
3348
1670
 
3349
- it "adds the $all criterion" do
3350
- expect(selection.selector).to eq({ "field" => { "$all" => [ 1, 2 ] }})
3351
- end
1671
+ context "when provided an integer" do
3352
1672
 
3353
- it "returns a cloned query" do
3354
- expect(selection).to_not eq(query)
3355
- end
1673
+ let(:selection) do
1674
+ query.with_size(field: 10)
3356
1675
  end
3357
- end
3358
-
3359
- context "when performing an $elemMatch" do
3360
-
3361
- context "when the value is not complex" do
3362
-
3363
- let(:selection) do
3364
- query.where(:field.elem_match => { key: 1 })
3365
- end
3366
1676
 
3367
- it "adds the $elemMatch criterion" do
3368
- expect(selection.selector).to eq(
3369
- { "field" => { "$elemMatch" => { key: 1 } }}
3370
- )
3371
- end
1677
+ it "adds the $size selector" do
1678
+ expect(selection.selector).to eq({
1679
+ "field" => { "$size" => 10 }
1680
+ })
1681
+ end
3372
1682
 
3373
- it "returns a cloned query" do
3374
- expect(selection).to_not eq(query)
3375
- end
1683
+ it "returns a cloned query" do
1684
+ expect(selection).to_not equal(query)
3376
1685
  end
1686
+ end
3377
1687
 
3378
- context "when the value is complex" do
1688
+ context "when provided a string" do
3379
1689
 
3380
- let(:selection) do
3381
- query.where(:field.elem_match => { :key.gt => 1 })
3382
- end
1690
+ let(:selection) do
1691
+ query.with_size(field: "10")
1692
+ end
3383
1693
 
3384
- it "adds the $elemMatch criterion" do
3385
- expect(selection.selector).to eq(
3386
- { "field" => { "$elemMatch" => { "key" => { "$gt" => 1 }}}}
3387
- )
3388
- end
1694
+ it "adds the $size selector with an integer" do
1695
+ expect(selection.selector).to eq({
1696
+ "field" => { "$size" => 10 }
1697
+ })
1698
+ end
3389
1699
 
3390
- it "returns a cloned query" do
3391
- expect(selection).to_not eq(query)
3392
- end
1700
+ it "returns a cloned query" do
1701
+ expect(selection).to_not equal(query)
3393
1702
  end
3394
1703
  end
1704
+ end
3395
1705
 
3396
- context "when performing an $exists" do
1706
+ context "when provided multiple criterion" do
3397
1707
 
3398
- context "when providing boolean values" do
1708
+ context "when the criterion are for different fields" do
1709
+
1710
+ context "when provided integers" do
3399
1711
 
3400
1712
  let(:selection) do
3401
- query.where(:field.exists => true)
1713
+ query.with_size(first: 10, second: 15)
3402
1714
  end
3403
1715
 
3404
- it "adds the $exists criterion" do
3405
- expect(selection.selector).to eq(
3406
- { "field" => { "$exists" => true }}
3407
- )
1716
+ it "adds the $size selectors" do
1717
+ expect(selection.selector).to eq({
1718
+ "first" => { "$size" => 10 },
1719
+ "second" => { "$size" => 15 }
1720
+ })
3408
1721
  end
3409
1722
 
3410
1723
  it "returns a cloned query" do
3411
- expect(selection).to_not eq(query)
1724
+ expect(selection).to_not equal(query)
3412
1725
  end
3413
1726
  end
3414
1727
 
3415
- context "when providing string values" do
1728
+ context "when provided strings" do
3416
1729
 
3417
1730
  let(:selection) do
3418
- query.where(:field.exists => "t")
1731
+ query.with_size(first: "10", second: "15")
3419
1732
  end
3420
1733
 
3421
- it "adds the $exists criterion" do
3422
- expect(selection.selector).to eq(
3423
- { "field" => { "$exists" => true }}
3424
- )
1734
+ it "adds the $size selectors" do
1735
+ expect(selection.selector).to eq({
1736
+ "first" => { "$size" => 10 },
1737
+ "second" => { "$size" => 15 }
1738
+ })
3425
1739
  end
3426
1740
 
3427
1741
  it "returns a cloned query" do
3428
- expect(selection).to_not eq(query)
1742
+ expect(selection).to_not equal(query)
3429
1743
  end
3430
1744
  end
3431
1745
  end
1746
+ end
3432
1747
 
3433
- context "when performing a $gt" do
1748
+ context "when chaining the criterion" do
1749
+
1750
+ context "when the criterion are for different fields" do
3434
1751
 
3435
1752
  let(:selection) do
3436
- query.where(:field.gt => 10)
1753
+ query.with_size(first: 10).with_size(second: 15)
3437
1754
  end
3438
1755
 
3439
- it "adds the $gt criterion" do
3440
- expect(selection.selector).to eq(
3441
- { "field" => { "$gt" => 10 }}
3442
- )
1756
+ it "adds the $size selectors" do
1757
+ expect(selection.selector).to eq({
1758
+ "first" => { "$size" => 10 },
1759
+ "second" => { "$size" => 15 }
1760
+ })
3443
1761
  end
3444
1762
 
3445
1763
  it "returns a cloned query" do
3446
- expect(selection).to_not eq(query)
1764
+ expect(selection).to_not equal(query)
3447
1765
  end
3448
1766
  end
3449
1767
 
3450
- context "when performing a $gte" do
1768
+ context "when the criterion are on the same field" do
3451
1769
 
3452
1770
  let(:selection) do
3453
- query.where(:field.gte => 10)
1771
+ query.with_size(first: 10).with_size(first: 15)
3454
1772
  end
3455
1773
 
3456
- it "adds the $gte criterion" do
3457
- expect(selection.selector).to eq(
3458
- { "field" => { "$gte" => 10 }}
3459
- )
1774
+ it "overwrites the first $size selector" do
1775
+ expect(selection.selector).to eq({
1776
+ "first" => { "$size" => 15 }
1777
+ })
3460
1778
  end
3461
1779
 
3462
1780
  it "returns a cloned query" do
3463
- expect(selection).to_not eq(query)
1781
+ expect(selection).to_not equal(query)
3464
1782
  end
3465
1783
  end
1784
+ end
1785
+ end
3466
1786
 
3467
- context "when performing an $in" do
1787
+ describe "#with_type" do
3468
1788
 
3469
- let(:selection) do
3470
- query.where(:field.in => [ 1, 2 ])
3471
- end
1789
+ let(:query_method) { :with_type }
3472
1790
 
3473
- it "adds the $in criterion" do
3474
- expect(selection.selector).to eq({ "field" => { "$in" => [ 1, 2 ] }})
3475
- end
1791
+ it_behaves_like 'requires an argument'
1792
+ it_behaves_like 'requires a non-nil argument'
3476
1793
 
3477
- it "returns a cloned query" do
3478
- expect(selection).to_not eq(query)
3479
- end
3480
- end
1794
+ context "when provided a single criterion" do
3481
1795
 
3482
- context "when performing a $lt" do
1796
+ context "when provided an integer" do
3483
1797
 
3484
1798
  let(:selection) do
3485
- query.where(:field.lt => 10)
1799
+ query.with_type(field: 10)
3486
1800
  end
3487
1801
 
3488
- it "adds the $lt criterion" do
3489
- expect(selection.selector).to eq(
3490
- { "field" => { "$lt" => 10 }}
3491
- )
1802
+ it "adds the $type selector" do
1803
+ expect(selection.selector).to eq({
1804
+ "field" => { "$type" => 10 }
1805
+ })
3492
1806
  end
3493
1807
 
3494
1808
  it "returns a cloned query" do
3495
- expect(selection).to_not eq(query)
1809
+ expect(selection).to_not equal(query)
3496
1810
  end
3497
1811
  end
3498
1812
 
3499
- context "when performing a $lte" do
1813
+ context "when provided a string" do
3500
1814
 
3501
1815
  let(:selection) do
3502
- query.where(:field.lte => 10)
1816
+ query.with_type(field: "10")
3503
1817
  end
3504
1818
 
3505
- it "adds the $lte criterion" do
3506
- expect(selection.selector).to eq(
3507
- { "field" => { "$lte" => 10 }}
3508
- )
1819
+ it "adds the $type selector" do
1820
+ expect(selection.selector).to eq({
1821
+ "field" => { "$type" => 10 }
1822
+ })
3509
1823
  end
3510
1824
 
3511
1825
  it "returns a cloned query" do
3512
- expect(selection).to_not eq(query)
1826
+ expect(selection).to_not equal(query)
3513
1827
  end
3514
1828
  end
1829
+ end
1830
+
1831
+ context "when provided multiple criterion" do
3515
1832
 
3516
- context "when performing a $mod" do
1833
+ context "when the criterion are for different fields" do
3517
1834
 
3518
1835
  let(:selection) do
3519
- query.where(:field.mod => [ 10, 1 ])
1836
+ query.with_type(first: 10, second: 15)
3520
1837
  end
3521
1838
 
3522
- it "adds the $lte criterion" do
3523
- expect(selection.selector).to eq(
3524
- { "field" => { "$mod" => [ 10, 1 ]}}
3525
- )
1839
+ it "adds the $type selectors" do
1840
+ expect(selection.selector).to eq({
1841
+ "first" => { "$type" => 10 },
1842
+ "second" => { "$type" => 15 }
1843
+ })
3526
1844
  end
3527
1845
 
3528
1846
  it "returns a cloned query" do
3529
- expect(selection).to_not eq(query)
1847
+ expect(selection).to_not equal(query)
3530
1848
  end
3531
1849
  end
1850
+ end
1851
+
1852
+ context "when chaining the criterion" do
3532
1853
 
3533
- context "when performing a $ne" do
1854
+ context "when the criterion are for different fields" do
3534
1855
 
3535
1856
  let(:selection) do
3536
- query.where(:field.ne => 10)
1857
+ query.with_type(first: 10).with_type(second: 15)
3537
1858
  end
3538
1859
 
3539
- it "adds the $ne criterion" do
3540
- expect(selection.selector).to eq(
3541
- { "field" => { "$ne" => 10 }}
3542
- )
1860
+ it "adds the $type selectors" do
1861
+ expect(selection.selector).to eq({
1862
+ "first" => { "$type" => 10 },
1863
+ "second" => { "$type" => 15 }
1864
+ })
3543
1865
  end
3544
1866
 
3545
1867
  it "returns a cloned query" do
3546
- expect(selection).to_not eq(query)
1868
+ expect(selection).to_not equal(query)
3547
1869
  end
3548
1870
  end
3549
1871
 
3550
- context "when performing a $near" do
1872
+ context "when the criterion are on the same field" do
3551
1873
 
3552
1874
  let(:selection) do
3553
- query.where(:field.near => [ 1, 1 ])
1875
+ query.with_type(first: 10).with_type(first: 15)
3554
1876
  end
3555
1877
 
3556
- it "adds the $near criterion" do
3557
- expect(selection.selector).to eq(
3558
- { "field" => { "$near" => [ 1, 1 ] }}
3559
- )
1878
+ it "overwrites the first $type selector" do
1879
+ expect(selection.selector).to eq({
1880
+ "first" => { "$type" => 15 }
1881
+ })
3560
1882
  end
3561
1883
 
3562
1884
  it "returns a cloned query" do
3563
- expect(selection).to_not eq(query)
1885
+ expect(selection).to_not equal(query)
3564
1886
  end
3565
1887
  end
1888
+ end
1889
+ end
3566
1890
 
3567
- context "when performing a $nearSphere" do
3568
-
3569
- let(:selection) do
3570
- query.where(:field.near_sphere => [ 1, 1 ])
3571
- end
1891
+ describe "#text_search" do
3572
1892
 
3573
- it "adds the $nearSphere criterion" do
3574
- expect(selection.selector).to eq(
3575
- { "field" => { "$nearSphere" => [ 1, 1 ] }}
3576
- )
3577
- end
1893
+ context "when providing a search string" do
3578
1894
 
3579
- it "returns a cloned query" do
3580
- expect(selection).to_not eq(query)
3581
- end
1895
+ let(:selection) do
1896
+ query.text_search("testing")
3582
1897
  end
3583
1898
 
3584
- context "when performing a $nin" do
3585
-
3586
- let(:selection) do
3587
- query.where(:field.nin => [ 1, 2 ])
3588
- end
3589
-
3590
- it "adds the $nin criterion" do
3591
- expect(selection.selector).to eq({ "field" => { "$nin" => [ 1, 2 ] }})
3592
- end
1899
+ it "constructs a text search document" do
1900
+ expect(selection.selector).to eq({ '$text' => { '$search' => "testing" }})
1901
+ end
3593
1902
 
3594
- it "returns a cloned query" do
3595
- expect(selection).to_not eq(query)
3596
- end
1903
+ it "returns the cloned selectable" do
1904
+ expect(selection).to be_a(Mongoid::Criteria::Queryable::Selectable)
3597
1905
  end
3598
1906
 
3599
- context "when performing a $not" do
1907
+ context "when providing text search options" do
3600
1908
 
3601
1909
  let(:selection) do
3602
- query.where(:field.not => /test/)
3603
- end
3604
-
3605
- it "adds the $not criterion" do
3606
- expect(selection.selector).to eq({ "field" => { "$not" => /test/ }})
1910
+ query.text_search("essais", { :$language => "fr" })
3607
1911
  end
3608
1912
 
3609
- it "returns a cloned query" do
3610
- expect(selection).to_not eq(query)
1913
+ it "constructs a text search document" do
1914
+ expect(selection.selector['$text']['$search']).to eq("essais")
3611
1915
  end
3612
- end
3613
-
3614
- context "when performing a $size" do
3615
-
3616
- context "when providing an integer" do
3617
-
3618
- let(:selection) do
3619
- query.where(:field.with_size => 10)
3620
- end
3621
-
3622
- it "adds the $size criterion" do
3623
- expect(selection.selector).to eq(
3624
- { "field" => { "$size" => 10 }}
3625
- )
3626
- end
3627
1916
 
3628
- it "returns a cloned query" do
3629
- expect(selection).to_not eq(query)
3630
- end
1917
+ it "add the options to the text search document" do
1918
+ expect(selection.selector['$text'][:$language]).to eq("fr")
3631
1919
  end
3632
1920
 
3633
- context "when providing a string" do
3634
-
3635
- let(:selection) do
3636
- query.where(:field.with_size => "10")
3637
- end
3638
-
3639
- it "adds the $size criterion" do
3640
- expect(selection.selector).to eq(
3641
- { "field" => { "$size" => 10 }}
3642
- )
3643
- end
3644
-
3645
- it "returns a cloned query" do
3646
- expect(selection).to_not eq(query)
3647
- end
3648
- end
1921
+ it_behaves_like "returns a cloned query"
3649
1922
  end
1923
+ end
3650
1924
 
3651
- context "when performing a $type" do
3652
-
3653
- let(:selection) do
3654
- query.where(:field.with_type => 10)
3655
- end
3656
-
3657
- it "adds the $type criterion" do
3658
- expect(selection.selector).to eq(
3659
- { "field" => { "$type" => 10 }}
3660
- )
3661
- end
1925
+ context 'when given more than once' do
1926
+ let(:selection) do
1927
+ query.text_search("one").text_search('two')
1928
+ end
3662
1929
 
3663
- it "returns a cloned query" do
3664
- expect(selection).to_not eq(query)
3665
- 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
+ )
3666
1941
  end
3667
1942
  end
3668
1943
  end
@@ -3987,7 +2262,7 @@ describe Mongoid::Criteria::Queryable::Selectable do
3987
2262
 
3988
2263
  it "merges the strategies on the same field" do
3989
2264
  expect(selection.selector).to eq(
3990
- { "field" => { "$gt" => 5, "$lt" => 10, "$ne" => 7 }}
2265
+ "field" => { "$gt" => 5, "$lt" => 10, "$ne" => 7 }
3991
2266
  )
3992
2267
  end
3993
2268
  end
@@ -3998,8 +2273,8 @@ describe Mongoid::Criteria::Queryable::Selectable do
3998
2273
  query.where(field: 5).where(field: 10)
3999
2274
  end
4000
2275
 
4001
- it "overrides the previous field" do
4002
- expect(selection.selector).to eq({ "field" => 10 })
2276
+ it "combines conditions" do
2277
+ expect(selection.selector).to eq("field" => 5, '$and' => [{'field' => 10}] )
4003
2278
  end
4004
2279
  end
4005
2280
  end
@@ -4014,7 +2289,7 @@ describe Mongoid::Criteria::Queryable::Selectable do
4014
2289
 
4015
2290
  it "merges the strategies on the same field" do
4016
2291
  expect(selection.selector).to eq(
4017
- { "field" => { "$gt" => 5, "$lt" => 10, "$ne" => 7 }}
2292
+ "field" => { "$gt" => 5, "$lt" => 10, "$ne" => 7 }
4018
2293
  )
4019
2294
  end
4020
2295
  end