mongoid 7.0.10 → 7.4.0

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