mongoid 7.0.13 → 8.0.8

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