mongoid 5.4.0 → 6.4.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (301) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/README.md +3 -3
  4. data/Rakefile +26 -0
  5. data/lib/config/locales/en.yml +40 -0
  6. data/lib/mongoid/atomic/modifiers.rb +2 -2
  7. data/lib/mongoid/atomic.rb +5 -5
  8. data/lib/mongoid/attributes/readonly.rb +22 -0
  9. data/lib/mongoid/attributes.rb +22 -21
  10. data/lib/mongoid/cacheable.rb +36 -0
  11. data/lib/mongoid/changeable.rb +36 -0
  12. data/lib/mongoid/clients/options.rb +55 -250
  13. data/lib/mongoid/clients/sessions.rb +113 -0
  14. data/lib/mongoid/clients/storage_options.rb +2 -69
  15. data/lib/mongoid/clients.rb +10 -63
  16. data/lib/mongoid/composable.rb +29 -2
  17. data/lib/mongoid/config.rb +1 -0
  18. data/lib/mongoid/contextual/aggregable/mongo.rb +1 -1
  19. data/lib/mongoid/contextual/atomic.rb +4 -4
  20. data/lib/mongoid/contextual/map_reduce.rb +7 -3
  21. data/lib/mongoid/contextual/memory.rb +9 -4
  22. data/lib/mongoid/contextual/mongo.rb +65 -30
  23. data/lib/mongoid/contextual/none.rb +12 -0
  24. data/lib/mongoid/copyable.rb +13 -6
  25. data/lib/mongoid/criteria/marshalable.rb +2 -2
  26. data/lib/mongoid/criteria/modifiable.rb +29 -3
  27. data/lib/mongoid/criteria/options.rb +25 -0
  28. data/lib/mongoid/criteria/queryable/aggregable.rb +120 -0
  29. data/lib/mongoid/criteria/queryable/extensions/array.rb +185 -0
  30. data/lib/mongoid/criteria/queryable/extensions/big_decimal.rb +37 -0
  31. data/lib/mongoid/criteria/queryable/extensions/boolean.rb +34 -0
  32. data/lib/mongoid/criteria/queryable/extensions/date.rb +63 -0
  33. data/lib/mongoid/criteria/queryable/extensions/date_time.rb +53 -0
  34. data/lib/mongoid/criteria/queryable/extensions/hash.rb +200 -0
  35. data/lib/mongoid/criteria/queryable/extensions/nil_class.rb +86 -0
  36. data/lib/mongoid/criteria/queryable/extensions/numeric.rb +90 -0
  37. data/lib/mongoid/criteria/queryable/extensions/object.rb +206 -0
  38. data/lib/mongoid/criteria/queryable/extensions/range.rb +70 -0
  39. data/lib/mongoid/criteria/queryable/extensions/regexp.rb +79 -0
  40. data/lib/mongoid/criteria/queryable/extensions/set.rb +34 -0
  41. data/lib/mongoid/criteria/queryable/extensions/string.rb +137 -0
  42. data/lib/mongoid/criteria/queryable/extensions/symbol.rb +79 -0
  43. data/lib/mongoid/criteria/queryable/extensions/time.rb +60 -0
  44. data/lib/mongoid/criteria/queryable/extensions/time_with_zone.rb +54 -0
  45. data/lib/mongoid/criteria/queryable/extensions.rb +28 -0
  46. data/lib/mongoid/criteria/queryable/forwardable.rb +65 -0
  47. data/lib/mongoid/criteria/queryable/key.rb +103 -0
  48. data/lib/mongoid/criteria/queryable/macroable.rb +27 -0
  49. data/lib/mongoid/criteria/queryable/mergeable.rb +273 -0
  50. data/lib/mongoid/criteria/queryable/optional.rb +429 -0
  51. data/lib/mongoid/criteria/queryable/options.rb +153 -0
  52. data/lib/mongoid/criteria/queryable/pipeline.rb +111 -0
  53. data/lib/mongoid/criteria/queryable/selectable.rb +689 -0
  54. data/lib/mongoid/criteria/queryable/selector.rb +212 -0
  55. data/lib/mongoid/criteria/queryable/smash.rb +104 -0
  56. data/lib/mongoid/criteria/queryable.rb +87 -0
  57. data/lib/mongoid/criteria.rb +6 -2
  58. data/lib/mongoid/document.rb +34 -41
  59. data/lib/mongoid/errors/ambiguous_relationship.rb +1 -1
  60. data/lib/mongoid/errors/in_memory_collation_not_supported.rb +1 -1
  61. data/lib/mongoid/errors/invalid_field.rb +2 -2
  62. data/lib/mongoid/errors/invalid_persistence_option.rb +29 -0
  63. data/lib/mongoid/errors/invalid_relation.rb +66 -0
  64. data/lib/mongoid/errors/invalid_session_use.rb +24 -0
  65. data/lib/mongoid/errors.rb +3 -0
  66. data/lib/mongoid/evolvable.rb +1 -1
  67. data/lib/mongoid/extensions/big_decimal.rb +17 -8
  68. data/lib/mongoid/extensions/date.rb +4 -1
  69. data/lib/mongoid/extensions/decimal128.rb +3 -3
  70. data/lib/mongoid/extensions/hash.rb +1 -0
  71. data/lib/mongoid/extensions/regexp.rb +1 -0
  72. data/lib/mongoid/extensions/string.rb +6 -3
  73. data/lib/mongoid/extensions/time.rb +4 -1
  74. data/lib/mongoid/extensions.rb +0 -4
  75. data/lib/mongoid/factory.rb +2 -1
  76. data/lib/mongoid/fields/validators/macro.rb +18 -0
  77. data/lib/mongoid/findable.rb +2 -2
  78. data/lib/mongoid/indexable.rb +16 -14
  79. data/lib/mongoid/interceptable.rb +9 -22
  80. data/lib/mongoid/matchable/all.rb +2 -2
  81. data/lib/mongoid/matchable/and.rb +3 -3
  82. data/lib/mongoid/matchable/default.rb +2 -2
  83. data/lib/mongoid/matchable/elem_match.rb +28 -0
  84. data/lib/mongoid/matchable/exists.rb +2 -2
  85. data/lib/mongoid/matchable/gt.rb +4 -2
  86. data/lib/mongoid/matchable/gte.rb +4 -2
  87. data/lib/mongoid/matchable/in.rb +2 -2
  88. data/lib/mongoid/matchable/lt.rb +4 -2
  89. data/lib/mongoid/matchable/lte.rb +4 -2
  90. data/lib/mongoid/matchable/ne.rb +2 -2
  91. data/lib/mongoid/matchable/nin.rb +2 -2
  92. data/lib/mongoid/matchable/nor.rb +37 -0
  93. data/lib/mongoid/matchable/or.rb +3 -3
  94. data/lib/mongoid/matchable/regexp.rb +3 -3
  95. data/lib/mongoid/matchable/size.rb +2 -2
  96. data/lib/mongoid/matchable.rb +16 -7
  97. data/lib/mongoid/persistable/creatable.rb +5 -3
  98. data/lib/mongoid/persistable/deletable.rb +5 -3
  99. data/lib/mongoid/persistable/destroyable.rb +1 -5
  100. data/lib/mongoid/persistable/settable.rb +5 -5
  101. data/lib/mongoid/persistable/updatable.rb +7 -14
  102. data/lib/mongoid/persistable/upsertable.rb +2 -1
  103. data/lib/mongoid/persistable.rb +4 -6
  104. data/lib/mongoid/persistence_context.rb +220 -0
  105. data/lib/mongoid/query_cache.rb +67 -23
  106. data/lib/mongoid/railtie.rb +17 -1
  107. data/lib/mongoid/railties/controller_runtime.rb +86 -0
  108. data/lib/mongoid/relations/accessors.rb +3 -0
  109. data/lib/mongoid/relations/auto_save.rb +12 -4
  110. data/lib/mongoid/relations/bindings/referenced/many_to_many.rb +4 -4
  111. data/lib/mongoid/relations/counter_cache.rb +15 -5
  112. data/lib/mongoid/relations/eager/base.rb +3 -3
  113. data/lib/mongoid/relations/eager/has_and_belongs_to_many.rb +2 -2
  114. data/lib/mongoid/relations/eager/has_many.rb +1 -1
  115. data/lib/mongoid/relations/eager.rb +6 -11
  116. data/lib/mongoid/relations/embedded/batchable.rb +20 -18
  117. data/lib/mongoid/relations/embedded/in.rb +13 -1
  118. data/lib/mongoid/relations/embedded/many.rb +51 -10
  119. data/lib/mongoid/relations/embedded/one.rb +14 -1
  120. data/lib/mongoid/relations/macros.rb +9 -1
  121. data/lib/mongoid/relations/many.rb +4 -0
  122. data/lib/mongoid/relations/metadata.rb +3 -3
  123. data/lib/mongoid/relations/options.rb +2 -2
  124. data/lib/mongoid/relations/proxy.rb +1 -31
  125. data/lib/mongoid/relations/referenced/in.rb +19 -10
  126. data/lib/mongoid/relations/referenced/many.rb +30 -26
  127. data/lib/mongoid/relations/referenced/many_to_many.rb +20 -13
  128. data/lib/mongoid/relations/referenced/one.rb +15 -1
  129. data/lib/mongoid/relations/synchronization.rb +12 -12
  130. data/lib/mongoid/relations/targets/enumerable.rb +24 -4
  131. data/lib/mongoid/relations/touchable.rb +7 -4
  132. data/lib/mongoid/reloadable.rb +2 -2
  133. data/lib/mongoid/scopable.rb +3 -3
  134. data/lib/mongoid/serializable.rb +1 -1
  135. data/lib/mongoid/stateful.rb +1 -0
  136. data/lib/mongoid/tasks/database.rb +3 -2
  137. data/lib/mongoid/threaded.rb +74 -0
  138. data/lib/mongoid/traversable.rb +1 -1
  139. data/lib/mongoid/validatable/uniqueness.rb +1 -2
  140. data/lib/mongoid/version.rb +1 -1
  141. data/lib/mongoid.rb +6 -6
  142. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +18 -3
  143. data/spec/app/models/agent.rb +2 -0
  144. data/spec/app/models/album.rb +5 -1
  145. data/spec/app/models/array_field.rb +7 -0
  146. data/spec/app/models/artist.rb +21 -0
  147. data/spec/app/models/band.rb +3 -0
  148. data/spec/app/models/book.rb +2 -1
  149. data/spec/app/models/delegating_patient.rb +16 -0
  150. data/spec/app/models/dokument.rb +1 -0
  151. data/spec/app/models/ordered_post.rb +5 -0
  152. data/spec/app/models/oscar.rb +1 -2
  153. data/spec/app/models/page.rb +1 -1
  154. data/spec/app/models/person.rb +3 -3
  155. data/spec/app/models/princess.rb +2 -0
  156. data/spec/app/models/record.rb +1 -0
  157. data/spec/app/models/subscription.rb +1 -0
  158. data/spec/app/models/thing.rb +1 -1
  159. data/spec/config/mongoid.yml +15 -0
  160. data/spec/integration/document_spec.rb +22 -0
  161. data/spec/mongoid/atomic/modifiers_spec.rb +3 -3
  162. data/spec/mongoid/atomic_spec.rb +5 -5
  163. data/spec/mongoid/attributes/nested_spec.rb +18 -14
  164. data/spec/mongoid/attributes/readonly_spec.rb +87 -44
  165. data/spec/mongoid/attributes_spec.rb +90 -5
  166. data/spec/mongoid/cacheable_spec.rb +112 -0
  167. data/spec/mongoid/changeable_spec.rb +58 -0
  168. data/spec/mongoid/clients/factory_spec.rb +80 -28
  169. data/spec/mongoid/clients/options_spec.rb +396 -95
  170. data/spec/mongoid/clients/sessions_spec.rb +334 -0
  171. data/spec/mongoid/clients_spec.rb +243 -101
  172. data/spec/mongoid/composable_spec.rb +7 -0
  173. data/spec/mongoid/config_spec.rb +67 -11
  174. data/spec/mongoid/contextual/atomic_spec.rb +3 -3
  175. data/spec/mongoid/contextual/geo_near_spec.rb +1 -0
  176. data/spec/mongoid/contextual/mongo_spec.rb +275 -22
  177. data/spec/mongoid/contextual/none_spec.rb +15 -0
  178. data/spec/mongoid/copyable_spec.rb +13 -4
  179. data/spec/mongoid/criteria/modifiable_spec.rb +297 -16
  180. data/spec/mongoid/criteria/options_spec.rb +29 -0
  181. data/spec/mongoid/criteria/queryable/aggregable_spec.rb +370 -0
  182. data/spec/mongoid/criteria/queryable/extensions/array_spec.rb +523 -0
  183. data/spec/mongoid/criteria/queryable/extensions/big_decimal_spec.rb +59 -0
  184. data/spec/mongoid/criteria/queryable/extensions/bignum_spec.rb +58 -0
  185. data/spec/mongoid/criteria/queryable/extensions/boolean_spec.rb +213 -0
  186. data/spec/mongoid/criteria/queryable/extensions/date_spec.rb +330 -0
  187. data/spec/mongoid/criteria/queryable/extensions/date_time_spec.rb +405 -0
  188. data/spec/mongoid/criteria/queryable/extensions/fixnum_spec.rb +58 -0
  189. data/spec/mongoid/criteria/queryable/extensions/float_spec.rb +65 -0
  190. data/spec/mongoid/criteria/queryable/extensions/hash_spec.rb +327 -0
  191. data/spec/mongoid/criteria/queryable/extensions/integer_spec.rb +65 -0
  192. data/spec/mongoid/criteria/queryable/extensions/nil_class_spec.rb +77 -0
  193. data/spec/mongoid/criteria/queryable/extensions/object_spec.rb +108 -0
  194. data/spec/mongoid/criteria/queryable/extensions/range_spec.rb +309 -0
  195. data/spec/mongoid/{extensions/origin → criteria/queryable/extensions}/regexp_raw_spec.rb +2 -2
  196. data/spec/mongoid/criteria/queryable/extensions/regexp_spec.rb +90 -0
  197. data/spec/mongoid/criteria/queryable/extensions/set_spec.rb +39 -0
  198. data/spec/mongoid/criteria/queryable/extensions/string_spec.rb +302 -0
  199. data/spec/mongoid/criteria/queryable/extensions/symbol_spec.rb +167 -0
  200. data/spec/mongoid/criteria/queryable/extensions/time_spec.rb +376 -0
  201. data/spec/mongoid/criteria/queryable/extensions/time_with_zone_spec.rb +347 -0
  202. data/spec/mongoid/criteria/queryable/forwardable_spec.rb +87 -0
  203. data/spec/mongoid/criteria/queryable/key_spec.rb +52 -0
  204. data/spec/mongoid/criteria/queryable/mergeable_spec.rb +49 -0
  205. data/spec/mongoid/criteria/queryable/optional_spec.rb +1799 -0
  206. data/spec/mongoid/criteria/queryable/options_spec.rb +360 -0
  207. data/spec/mongoid/criteria/queryable/pipeline_spec.rb +200 -0
  208. data/spec/mongoid/criteria/queryable/queryable_spec.rb +137 -0
  209. data/spec/mongoid/criteria/queryable/selectable_spec.rb +4242 -0
  210. data/spec/mongoid/criteria/queryable/selector_spec.rb +844 -0
  211. data/spec/mongoid/criteria/queryable/smash_spec.rb +30 -0
  212. data/spec/mongoid/criteria/scopable_spec.rb +81 -0
  213. data/spec/mongoid/criteria_spec.rb +156 -22
  214. data/spec/mongoid/document_spec.rb +100 -90
  215. data/spec/mongoid/errors/invalid_relation_spec.rb +37 -0
  216. data/spec/mongoid/errors/mongoid_error_spec.rb +6 -3
  217. data/spec/mongoid/extensions/big_decimal_spec.rb +321 -19
  218. data/spec/mongoid/extensions/boolean_spec.rb +14 -0
  219. data/spec/mongoid/extensions/date_spec.rb +2 -6
  220. data/spec/mongoid/extensions/date_time_spec.rb +2 -6
  221. data/spec/mongoid/extensions/decimal128_spec.rb +1 -1
  222. data/spec/mongoid/extensions/float_spec.rb +8 -1
  223. data/spec/mongoid/extensions/hash_spec.rb +15 -0
  224. data/spec/mongoid/extensions/integer_spec.rb +8 -1
  225. data/spec/mongoid/extensions/object_spec.rb +11 -0
  226. data/spec/mongoid/extensions/regexp_spec.rb +23 -0
  227. data/spec/mongoid/extensions/string_spec.rb +53 -4
  228. data/spec/mongoid/extensions/time_spec.rb +2 -6
  229. data/spec/mongoid/extensions/time_with_zone_spec.rb +2 -6
  230. data/spec/mongoid/factory_spec.rb +11 -0
  231. data/spec/mongoid/fields_spec.rb +1 -1
  232. data/spec/mongoid/findable_spec.rb +47 -2
  233. data/spec/mongoid/indexable_spec.rb +15 -3
  234. data/spec/mongoid/interceptable_spec.rb +85 -19
  235. data/spec/mongoid/matchable/all_spec.rb +4 -4
  236. data/spec/mongoid/matchable/and_spec.rb +10 -10
  237. data/spec/mongoid/matchable/default_spec.rb +12 -12
  238. data/spec/mongoid/matchable/elem_match_spec.rb +86 -0
  239. data/spec/mongoid/matchable/exists_spec.rb +5 -5
  240. data/spec/mongoid/matchable/gt_spec.rb +18 -7
  241. data/spec/mongoid/matchable/gte_spec.rb +17 -7
  242. data/spec/mongoid/matchable/in_spec.rb +5 -5
  243. data/spec/mongoid/matchable/lt_spec.rb +18 -7
  244. data/spec/mongoid/matchable/lte_spec.rb +18 -7
  245. data/spec/mongoid/matchable/ne_spec.rb +5 -5
  246. data/spec/mongoid/matchable/nin_spec.rb +5 -5
  247. data/spec/mongoid/matchable/nor_spec.rb +209 -0
  248. data/spec/mongoid/matchable/or_spec.rb +7 -7
  249. data/spec/mongoid/matchable/regexp_spec.rb +5 -5
  250. data/spec/mongoid/matchable/size_spec.rb +3 -3
  251. data/spec/mongoid/matchable_spec.rb +199 -54
  252. data/spec/mongoid/persistable/creatable_spec.rb +7 -2
  253. data/spec/mongoid/persistable/deletable_spec.rb +35 -1
  254. data/spec/mongoid/persistable/destroyable_spec.rb +25 -2
  255. data/spec/mongoid/persistable/incrementable_spec.rb +6 -6
  256. data/spec/mongoid/persistable/savable_spec.rb +34 -29
  257. data/spec/mongoid/persistable/settable_spec.rb +77 -27
  258. data/spec/mongoid/persistable/updatable_spec.rb +182 -3
  259. data/spec/mongoid/persistable_spec.rb +16 -16
  260. data/spec/mongoid/persistence_context_spec.rb +694 -0
  261. data/spec/mongoid/positional_spec.rb +1 -1
  262. data/spec/mongoid/query_cache_spec.rb +170 -12
  263. data/spec/mongoid/relations/accessors_spec.rb +1 -1
  264. data/spec/mongoid/relations/auto_save_spec.rb +39 -6
  265. data/spec/mongoid/relations/bindings/referenced/many_to_many_spec.rb +4 -4
  266. data/spec/mongoid/relations/builders_spec.rb +37 -10
  267. data/spec/mongoid/relations/counter_cache_spec.rb +64 -3
  268. data/spec/mongoid/relations/eager/has_and_belongs_to_many_spec.rb +16 -0
  269. data/spec/mongoid/relations/eager_spec.rb +40 -0
  270. data/spec/mongoid/relations/embedded/many_spec.rb +305 -59
  271. data/spec/mongoid/relations/embedded/one_spec.rb +2 -1
  272. data/spec/mongoid/relations/macros_spec.rb +415 -7
  273. data/spec/mongoid/relations/metadata_spec.rb +15 -1
  274. data/spec/mongoid/relations/proxy_spec.rb +27 -1
  275. data/spec/mongoid/relations/referenced/in_spec.rb +41 -1
  276. data/spec/mongoid/relations/referenced/many_spec.rb +35 -25
  277. data/spec/mongoid/relations/referenced/many_to_many_spec.rb +14 -26
  278. data/spec/mongoid/relations/synchronization_spec.rb +48 -2
  279. data/spec/mongoid/relations/targets/enumerable_spec.rb +108 -0
  280. data/spec/mongoid/relations/touchable_spec.rb +40 -0
  281. data/spec/mongoid/reloadable_spec.rb +51 -0
  282. data/spec/mongoid/scopable_spec.rb +13 -0
  283. data/spec/mongoid/serializable_spec.rb +0 -50
  284. data/spec/mongoid/threaded_spec.rb +68 -0
  285. data/spec/mongoid/validatable/presence_spec.rb +1 -1
  286. data/spec/mongoid/validatable/uniqueness_spec.rb +18 -9
  287. data/spec/mongoid/validatable_spec.rb +16 -0
  288. data/spec/rails/controller_extension/controller_runtime_spec.rb +110 -0
  289. data/spec/spec_helper.rb +101 -8
  290. data/spec/support/cluster_config.rb +158 -0
  291. data/spec/support/constraints.rb +101 -0
  292. data/spec/support/macros.rb +20 -0
  293. data/spec/support/session_registry.rb +50 -0
  294. data/spec/support/spec_config.rb +42 -0
  295. data.tar.gz.sig +0 -0
  296. metadata +163 -61
  297. metadata.gz.sig +0 -0
  298. data/lib/mongoid/clients/thread_options.rb +0 -19
  299. data/lib/mongoid/extensions/origin/regexp_raw.rb +0 -43
  300. data/lib/mongoid/railties/document.rb +0 -12
  301. data/spec/mongoid/railties/document_spec.rb +0 -24
@@ -0,0 +1,1799 @@
1
+ require "spec_helper"
2
+
3
+ describe Mongoid::Criteria::Queryable::Optional do
4
+
5
+ let(:query) do
6
+ Mongoid::Query.new
7
+ end
8
+
9
+ shared_examples_for "a cloning option" do
10
+
11
+ it "returns a cloned query" do
12
+ expect(selection).to_not equal(query)
13
+ end
14
+ end
15
+
16
+ [ :asc, :ascending ].each do |method|
17
+
18
+ describe "##{method}" do
19
+
20
+ context "when using the official mongodb driver syntax" do
21
+
22
+ context "when the query is aggregating" do
23
+
24
+ let(:selection) do
25
+ query.project(name: 1).send(method, :field_one, :field_two)
26
+ end
27
+
28
+ it "adds the sorting criteria" do
29
+ expect(selection.options).to eq(
30
+ { sort: { "field_one" => 1, "field_two" => 1 }}
31
+ )
32
+ end
33
+
34
+ it "adds the sort to the aggregation" do
35
+ expect(selection.pipeline).to include(
36
+ { "$sort" => { "field_one" => 1, "field_two" => 1 }}
37
+ )
38
+ end
39
+
40
+ it "does not add multiple entries to the pipeline" do
41
+ expect(selection.pipeline).to_not include(
42
+ { "$sort" => { "field_one" => 1 }}
43
+ )
44
+ end
45
+
46
+ it_behaves_like "a cloning option"
47
+ end
48
+
49
+ context "when provided symbols" do
50
+
51
+ let(:selection) do
52
+ query.send(method, :field_one, :field_two)
53
+ end
54
+
55
+ it "adds the sorting criteria" do
56
+ expect(selection.options).to eq(
57
+ { sort: { "field_one" => 1, "field_two" => 1 }}
58
+ )
59
+ end
60
+
61
+ it_behaves_like "a cloning option"
62
+ end
63
+
64
+ context "when provided an array of symbols" do
65
+
66
+ let(:selection) do
67
+ query.send(method, [ :field_one, :field_two ])
68
+ end
69
+
70
+ it "adds the sorting criteria" do
71
+ expect(selection.options).to eq(
72
+ { sort: { "field_one" => 1, "field_two" => 1 }}
73
+ )
74
+ end
75
+
76
+ it_behaves_like "a cloning option"
77
+ end
78
+
79
+ context "when provided strings" do
80
+
81
+ let(:selection) do
82
+ query.send(method, "field_one", "field_two")
83
+ end
84
+
85
+ it "adds the sorting criteria" do
86
+ expect(selection.options).to eq(
87
+ { sort: { "field_one" => 1, "field_two" => 1 }}
88
+ )
89
+ end
90
+
91
+ it_behaves_like "a cloning option"
92
+ end
93
+
94
+ context "when provided an array of strings" do
95
+
96
+ let(:selection) do
97
+ query.send(method, [ "field_one", "field_two" ])
98
+ end
99
+
100
+ it "adds the sorting criteria" do
101
+ expect(selection.options).to eq(
102
+ { sort: { "field_one" => 1, "field_two" => 1 }}
103
+ )
104
+ end
105
+
106
+ it_behaves_like "a cloning option"
107
+ end
108
+
109
+ context "when provided no options" do
110
+
111
+ let(:selection) do
112
+ query.send(method)
113
+ end
114
+
115
+ it "does not add any sorting criteria" do
116
+ expect(selection.options).to be_empty
117
+ end
118
+
119
+ it "returns the query" do
120
+ expect(selection).to eq(query)
121
+ end
122
+
123
+ it_behaves_like "a cloning option"
124
+ end
125
+
126
+ context "when provided nil" do
127
+
128
+ let(:selection) do
129
+ query.send(method, nil)
130
+ end
131
+
132
+ it "does not add any sorting criteria" do
133
+ expect(selection.options).to be_empty
134
+ end
135
+
136
+ it "returns the query" do
137
+ expect(selection).to eq(query)
138
+ end
139
+
140
+ it_behaves_like "a cloning option"
141
+ end
142
+ end
143
+
144
+ context "when using the mongo-1.x driver syntax" do
145
+
146
+ let(:query) do
147
+ Mongoid::Query.new({}, {}, :mongo1x)
148
+ end
149
+
150
+ context "when provided symbols" do
151
+
152
+ let(:selection) do
153
+ query.send(method, :field_one, :field_two)
154
+ end
155
+
156
+ it "adds the sorting criteria" do
157
+ expect(selection.options).to eq(
158
+ { sort: [[ :field_one, 1 ], [ :field_two, 1 ]]}
159
+ )
160
+ end
161
+
162
+ it_behaves_like "a cloning option"
163
+ end
164
+
165
+ context "when provided an array of symbols" do
166
+
167
+ let(:selection) do
168
+ query.send(method, [ :field_one, :field_two ])
169
+ end
170
+
171
+ it "adds the sorting criteria" do
172
+ expect(selection.options).to eq(
173
+ { sort: [[ :field_one, 1 ], [ :field_two, 1 ]]}
174
+ )
175
+ end
176
+
177
+ it_behaves_like "a cloning option"
178
+ end
179
+
180
+ context "when provided strings" do
181
+
182
+ let(:selection) do
183
+ query.send(method, "field_one", "field_two")
184
+ end
185
+
186
+ it "adds the sorting criteria" do
187
+ expect(selection.options).to eq(
188
+ { sort: [[ "field_one", 1 ], [ "field_two", 1 ]]}
189
+ )
190
+ end
191
+
192
+ it_behaves_like "a cloning option"
193
+ end
194
+
195
+ context "when provided an array of strings" do
196
+
197
+ let(:selection) do
198
+ query.send(method, [ "field_one", "field_two" ])
199
+ end
200
+
201
+ it "adds the sorting criteria" do
202
+ expect(selection.options).to eq(
203
+ { sort: [[ "field_one", 1 ], [ "field_two", 1 ]]}
204
+ )
205
+ end
206
+
207
+ it_behaves_like "a cloning option"
208
+ end
209
+
210
+ context "when provided no options" do
211
+
212
+ let(:selection) do
213
+ query.send(method)
214
+ end
215
+
216
+ it "does not add any sorting criteria" do
217
+ expect(selection.options).to be_empty
218
+ end
219
+
220
+ it "returns the query" do
221
+ expect(selection).to eq(query)
222
+ end
223
+
224
+ it_behaves_like "a cloning option"
225
+ end
226
+
227
+ context "when provided nil" do
228
+
229
+ let(:selection) do
230
+ query.send(method, nil)
231
+ end
232
+
233
+ it "does not add any sorting criteria" do
234
+ expect(selection.options).to be_empty
235
+ end
236
+
237
+ it "returns the query" do
238
+ expect(selection).to eq(query)
239
+ end
240
+
241
+ it_behaves_like "a cloning option"
242
+ end
243
+ end
244
+ end
245
+ end
246
+
247
+ describe "#batch_size" do
248
+
249
+ context "when provided no options" do
250
+
251
+ let(:selection) do
252
+ query.batch_size
253
+ end
254
+
255
+ it "does not add any options" do
256
+ expect(selection.options).to eq({})
257
+ end
258
+
259
+ it_behaves_like "a cloning option"
260
+ end
261
+
262
+ context "when provided nil" do
263
+
264
+ let(:selection) do
265
+ query.batch_size(nil)
266
+ end
267
+
268
+ it "does not add any options" do
269
+ expect(selection.options).to eq({})
270
+ end
271
+
272
+ it_behaves_like "a cloning option"
273
+ end
274
+
275
+ context "when provided arguments" do
276
+
277
+ let(:selection) do
278
+ query.batch_size(500)
279
+ end
280
+
281
+ it "adds the field options" do
282
+ expect(selection.options).to eq({ batch_size: 500 })
283
+ end
284
+
285
+ it_behaves_like "a cloning option"
286
+ end
287
+ end
288
+
289
+ [ :desc, :descending ].each do |method|
290
+
291
+ describe "##{method}" do
292
+
293
+ context "when using the official mongodb driver syntax" do
294
+
295
+ context "when the query is aggregating" do
296
+
297
+ let(:selection) do
298
+ query.project(name: 1).send(method, :field_one, :field_two)
299
+ end
300
+
301
+ it "adds the sorting criteria" do
302
+ expect(selection.options).to eq(
303
+ { sort: { "field_one" => -1, "field_two" => -1 }}
304
+ )
305
+ end
306
+
307
+ it "adds the sort to the aggregation" do
308
+ expect(selection.pipeline).to include(
309
+ { "$sort" => { "field_one" => -1, "field_two" => -1 }}
310
+ )
311
+ end
312
+
313
+ it "does not add multiple entries to the pipeline" do
314
+ expect(selection.pipeline).to_not include(
315
+ { "$sort" => { "field_one" => -1 }}
316
+ )
317
+ end
318
+
319
+ it_behaves_like "a cloning option"
320
+ end
321
+
322
+ context "when provided symbols" do
323
+
324
+ let(:selection) do
325
+ query.send(method, :field_one, :field_two)
326
+ end
327
+
328
+ it "adds the sorting criteria" do
329
+ expect(selection.options).to eq(
330
+ { sort: { "field_one" => -1, "field_two" => -1 }}
331
+ )
332
+ end
333
+
334
+ it_behaves_like "a cloning option"
335
+ end
336
+
337
+ context "when provided an array of symbols" do
338
+
339
+ let(:selection) do
340
+ query.send(method, [ :field_one, :field_two ])
341
+ end
342
+
343
+ it "adds the sorting criteria" do
344
+ expect(selection.options).to eq(
345
+ { sort: { "field_one" => -1, "field_two" => -1 }}
346
+ )
347
+ end
348
+
349
+ it_behaves_like "a cloning option"
350
+ end
351
+
352
+ context "when provided strings" do
353
+
354
+ let(:selection) do
355
+ query.send(method, "field_one", "field_two")
356
+ end
357
+
358
+ it "adds the sorting criteria" do
359
+ expect(selection.options).to eq(
360
+ { sort: { "field_one" => -1, "field_two" => -1 }}
361
+ )
362
+ end
363
+
364
+ it_behaves_like "a cloning option"
365
+ end
366
+
367
+ context "when provided an array of strings" do
368
+
369
+ let(:selection) do
370
+ query.send(method, [ "field_one", "field_two" ])
371
+ end
372
+
373
+ it "adds the sorting criteria" do
374
+ expect(selection.options).to eq(
375
+ { sort: { "field_one" => -1, "field_two" => -1 }}
376
+ )
377
+ end
378
+
379
+ it_behaves_like "a cloning option"
380
+ end
381
+
382
+ context "when provided no options" do
383
+
384
+ let(:selection) do
385
+ query.send(method)
386
+ end
387
+
388
+ it "does not add any sorting criteria" do
389
+ expect(selection.options).to be_empty
390
+ end
391
+
392
+ it "returns the query" do
393
+ expect(selection).to eq(query)
394
+ end
395
+
396
+ it_behaves_like "a cloning option"
397
+ end
398
+
399
+ context "when provided nil" do
400
+
401
+ let(:selection) do
402
+ query.send(method, nil)
403
+ end
404
+
405
+ it "does not add any sorting criteria" do
406
+ expect(selection.options).to be_empty
407
+ end
408
+
409
+ it "returns the query" do
410
+ expect(selection).to eq(query)
411
+ end
412
+
413
+ it_behaves_like "a cloning option"
414
+ end
415
+ end
416
+
417
+ context "when using the mongo-1.x driver syntax" do
418
+
419
+ let(:query) do
420
+ Mongoid::Query.new({}, {}, :mongo1x)
421
+ end
422
+
423
+ context "when provided symbols" do
424
+
425
+ let(:selection) do
426
+ query.send(method, :field_one, :field_two)
427
+ end
428
+
429
+ it "adds the sorting criteria" do
430
+ expect(selection.options).to eq(
431
+ { sort: [[ :field_one, -1 ], [ :field_two, -1 ]]}
432
+ )
433
+ end
434
+
435
+ it_behaves_like "a cloning option"
436
+ end
437
+
438
+ context "when provided an array of symbols" do
439
+
440
+ let(:selection) do
441
+ query.send(method, [ :field_one, :field_two ])
442
+ end
443
+
444
+ it "adds the sorting criteria" do
445
+ expect(selection.options).to eq(
446
+ { sort: [[ :field_one, -1 ], [ :field_two, -1 ]]}
447
+ )
448
+ end
449
+
450
+ it_behaves_like "a cloning option"
451
+ end
452
+
453
+ context "when provided strings" do
454
+
455
+ let(:selection) do
456
+ query.send(method, "field_one", "field_two")
457
+ end
458
+
459
+ it "adds the sorting criteria" do
460
+ expect(selection.options).to eq(
461
+ { sort: [[ "field_one", -1 ], [ "field_two", -1 ]]}
462
+ )
463
+ end
464
+
465
+ it_behaves_like "a cloning option"
466
+ end
467
+
468
+ context "when provided an array of strings" do
469
+
470
+ let(:selection) do
471
+ query.send(method, [ "field_one", "field_two" ])
472
+ end
473
+
474
+ it "adds the sorting criteria" do
475
+ expect(selection.options).to eq(
476
+ { sort: [[ "field_one", -1 ], [ "field_two", -1 ]]}
477
+ )
478
+ end
479
+
480
+ it_behaves_like "a cloning option"
481
+ end
482
+
483
+ context "when provided no options" do
484
+
485
+ let(:selection) do
486
+ query.send(method)
487
+ end
488
+
489
+ it "does not add any sorting criteria" do
490
+ expect(selection.options).to be_empty
491
+ end
492
+
493
+ it "returns the query" do
494
+ expect(selection).to eq(query)
495
+ end
496
+
497
+ it_behaves_like "a cloning option"
498
+ end
499
+
500
+ context "when provided nil" do
501
+
502
+ let(:selection) do
503
+ query.send(method, nil)
504
+ end
505
+
506
+ it "does not add any sorting criteria" do
507
+ expect(selection.options).to be_empty
508
+ end
509
+
510
+ it "returns the query" do
511
+ expect(selection).to eq(query)
512
+ end
513
+
514
+ it_behaves_like "a cloning option"
515
+ end
516
+ end
517
+ end
518
+ end
519
+
520
+ describe "#hint" do
521
+
522
+ context "when provided no options" do
523
+
524
+ let(:selection) do
525
+ query.hint
526
+ end
527
+
528
+ it "does not add any options" do
529
+ expect(selection.options).to eq({})
530
+ end
531
+
532
+ it "returns the query" do
533
+ expect(selection).to eq(query)
534
+ end
535
+
536
+ it_behaves_like "a cloning option"
537
+ end
538
+
539
+ context "when provided nil" do
540
+
541
+ let(:selection) do
542
+ query.hint(nil)
543
+ end
544
+
545
+ it "does not add any options" do
546
+ expect(selection.options).to eq({})
547
+ end
548
+
549
+ it "returns the query" do
550
+ expect(selection).to eq(query)
551
+ end
552
+
553
+ it_behaves_like "a cloning option"
554
+ end
555
+
556
+ context "when provided arguments" do
557
+
558
+ context "when the argument is a hash" do
559
+
560
+ let(:selection) do
561
+ query.hint("$natural" => 1)
562
+ end
563
+
564
+ it "adds the field options" do
565
+ expect(selection.options).to eq({ hint: { "$natural" => 1 }})
566
+ end
567
+
568
+ it_behaves_like "a cloning option"
569
+ end
570
+ end
571
+ end
572
+
573
+ describe "#limit" do
574
+
575
+ context "when provided no options" do
576
+
577
+ let(:selection) do
578
+ query.limit
579
+ end
580
+
581
+ it "does not add any options" do
582
+ expect(selection.options).to eq({})
583
+ end
584
+
585
+ it "returns the query" do
586
+ expect(selection).to eq(query)
587
+ end
588
+
589
+ it_behaves_like "a cloning option"
590
+ end
591
+
592
+ context "when provided nil" do
593
+
594
+ let(:selection) do
595
+ query.limit(nil)
596
+ end
597
+
598
+ it "does not add any options" do
599
+ expect(selection.options).to eq({})
600
+ end
601
+
602
+ it "returns the query" do
603
+ expect(selection).to eq(query)
604
+ end
605
+
606
+ it_behaves_like "a cloning option"
607
+ end
608
+
609
+ context "when the query is aggregating" do
610
+
611
+ let(:selection) do
612
+ query.project(name: 1).limit(10)
613
+ end
614
+
615
+ it "adds the field options" do
616
+ expect(selection.options).to eq({ limit: 10 })
617
+ end
618
+
619
+ it "adds the limit to the aggregation" do
620
+ expect(selection.pipeline).to include({ "$limit" => 10 })
621
+ end
622
+
623
+ it_behaves_like "a cloning option"
624
+ end
625
+
626
+ context "when provided arguments" do
627
+
628
+ context "when the argument is an integer" do
629
+
630
+ let(:selection) do
631
+ query.limit(10)
632
+ end
633
+
634
+ it "adds the field options" do
635
+ expect(selection.options).to eq({ limit: 10 })
636
+ end
637
+
638
+ it_behaves_like "a cloning option"
639
+ end
640
+
641
+ context "when the argument is a float" do
642
+
643
+ let(:selection) do
644
+ query.limit(10.25)
645
+ end
646
+
647
+ it "adds the field options as an integer" do
648
+ expect(selection.options).to eq({ limit: 10 })
649
+ end
650
+
651
+ it_behaves_like "a cloning option"
652
+ end
653
+
654
+ context "when the argument is a string" do
655
+
656
+ let(:selection) do
657
+ query.limit("10")
658
+ end
659
+
660
+ it "adds the field options as an integer" do
661
+ expect(selection.options).to eq({ limit: 10 })
662
+ end
663
+
664
+ it_behaves_like "a cloning option"
665
+ end
666
+ end
667
+ end
668
+
669
+ describe "#max_scan" do
670
+
671
+ context "when provided no options" do
672
+
673
+ let(:selection) do
674
+ query.max_scan
675
+ end
676
+
677
+ it "does not add any options" do
678
+ expect(selection.options).to eq({})
679
+ end
680
+
681
+ it "returns the query" do
682
+ expect(selection).to eq(query)
683
+ end
684
+
685
+ it_behaves_like "a cloning option"
686
+ end
687
+
688
+ context "when provided nil" do
689
+
690
+ let(:selection) do
691
+ query.max_scan(nil)
692
+ end
693
+
694
+ it "does not add any options" do
695
+ expect(selection.options).to eq({})
696
+ end
697
+
698
+ it "returns the query" do
699
+ expect(selection).to eq(query)
700
+ end
701
+
702
+ it_behaves_like "a cloning option"
703
+ end
704
+
705
+ context "when provided arguments" do
706
+
707
+ let(:selection) do
708
+ query.max_scan(500)
709
+ end
710
+
711
+ it "adds the field options" do
712
+ expect(selection.options).to eq({ max_scan: 500 })
713
+ end
714
+
715
+ it_behaves_like "a cloning option"
716
+ end
717
+ end
718
+
719
+ describe "#max_time_ms" do
720
+
721
+ context "when provided no options" do
722
+
723
+ let(:selection) do
724
+ query.max_time_ms
725
+ end
726
+
727
+ it "does not add any options" do
728
+ expect(selection.options).to eq({})
729
+ end
730
+
731
+ it "returns the query" do
732
+ expect(selection).to eq(query)
733
+ end
734
+
735
+ it_behaves_like "a cloning option"
736
+ end
737
+
738
+ context "when provided nil" do
739
+
740
+ let(:selection) do
741
+ query.max_time_ms(nil)
742
+ end
743
+
744
+ it "does not add any options" do
745
+ expect(selection.options).to eq({})
746
+ end
747
+
748
+ it "returns the query" do
749
+ expect(selection).to eq(query)
750
+ end
751
+
752
+ it_behaves_like "a cloning option"
753
+ end
754
+
755
+ context "when provided arguments" do
756
+
757
+ let(:selection) do
758
+ query.max_time_ms(500)
759
+ end
760
+
761
+ it "adds the field options" do
762
+ expect(selection.options).to eq({ max_time_ms: 500 })
763
+ end
764
+
765
+ it_behaves_like "a cloning option"
766
+ end
767
+ end
768
+
769
+ describe "#no_timeout" do
770
+
771
+ let(:selection) do
772
+ query.no_timeout
773
+ end
774
+
775
+ it "adds the timeout option" do
776
+ expect(selection.options).to eq({ timeout: false })
777
+ end
778
+
779
+ it_behaves_like "a cloning option"
780
+ end
781
+
782
+ describe "#only" do
783
+
784
+ context "when provided no options" do
785
+
786
+ let(:selection) do
787
+ query.only
788
+ end
789
+
790
+ it "does not add any options" do
791
+ expect(selection.options).to eq({})
792
+ end
793
+
794
+ it "returns the query" do
795
+ expect(selection).to eq(query)
796
+ end
797
+
798
+ it_behaves_like "a cloning option"
799
+ end
800
+
801
+ context "when provided nil" do
802
+
803
+ let(:selection) do
804
+ query.only(nil)
805
+ end
806
+
807
+ it "does not add any options" do
808
+ expect(selection.options).to eq({})
809
+ end
810
+
811
+ it "returns the query" do
812
+ expect(selection).to eq(query)
813
+ end
814
+
815
+ it_behaves_like "a cloning option"
816
+ end
817
+
818
+ context "when provided fields" do
819
+
820
+ context "as several arguments" do
821
+
822
+ let(:selection) do
823
+ query.only(:first, :second)
824
+ end
825
+
826
+ it "adds the field options" do
827
+ expect(selection.options).to eq(
828
+ { fields: { "first" => 1, "second" => 1 }}
829
+ )
830
+ end
831
+
832
+ it_behaves_like "a cloning option"
833
+ end
834
+
835
+ context "as one argument - array" do
836
+
837
+ let(:selection) do
838
+ query.only([:first, :second])
839
+ end
840
+
841
+ it "adds the field options" do
842
+ expect(selection.options).to eq(
843
+ { fields: { "first" => 1, "second" => 1 }}
844
+ )
845
+ end
846
+
847
+ it_behaves_like "a cloning option"
848
+ end
849
+ end
850
+
851
+ context "when #without was called first" do
852
+
853
+ let(:selection) do
854
+ query.without(:id).only(:first)
855
+ end
856
+
857
+ it "adds both fields to option" do
858
+ expect(selection.options).to eq(
859
+ { fields: { "id" => 0, "first" => 1 } }
860
+ )
861
+ end
862
+ end
863
+ end
864
+
865
+ [ :order, :order_by ].each do |method|
866
+
867
+ describe "##{method}" do
868
+
869
+ context "when using the official mongodb driver syntax" do
870
+
871
+ context "when provided a hash" do
872
+
873
+ context "when the query is aggregating" do
874
+
875
+ let(:selection) do
876
+ query.project(name: 1).send("#{method}", field_one: 1, field_two: -1)
877
+ end
878
+
879
+ it "adds the sorting criteria" do
880
+ expect(selection.options).to eq(
881
+ { sort: { "field_one" => 1, "field_two" => -1 }}
882
+ )
883
+ end
884
+
885
+ it "adds the sort to the aggregation" do
886
+ expect(selection.pipeline).to include(
887
+ { "$sort" => { "field_one" => 1, "field_two" => -1 }}
888
+ )
889
+ end
890
+
891
+ it "does not add multiple entries to the pipeline" do
892
+ expect(selection.pipeline).to_not include(
893
+ { "$sort" => { "field_one" => 1 }}
894
+ )
895
+ end
896
+
897
+ it_behaves_like "a cloning option"
898
+ end
899
+
900
+ context "when the hash has integer values" do
901
+
902
+ let(:selection) do
903
+ query.send("#{method}", field_one: 1, field_two: -1)
904
+ end
905
+
906
+ it "adds the sorting criteria" do
907
+ expect(selection.options).to eq(
908
+ { sort: { "field_one" => 1, "field_two" => -1 }}
909
+ )
910
+ end
911
+
912
+ it_behaves_like "a cloning option"
913
+ end
914
+
915
+ context "when the hash has symbol values" do
916
+
917
+ let(:selection) do
918
+ query.send("#{method}", field_one: :asc, field_two: :desc)
919
+ end
920
+
921
+ it "adds the sorting criteria" do
922
+ expect(selection.options).to eq(
923
+ { sort: { "field_one" => 1, "field_two" => -1 }}
924
+ )
925
+ end
926
+
927
+ it_behaves_like "a cloning option"
928
+ end
929
+
930
+ context "when the hash has string values" do
931
+
932
+ let(:selection) do
933
+ query.send("#{method}", field_one: "asc", field_two: "desc")
934
+ end
935
+
936
+ it "adds the sorting criteria" do
937
+ expect(selection.options).to eq(
938
+ { sort: { "field_one" => 1, "field_two" => -1 }}
939
+ )
940
+ end
941
+
942
+ it_behaves_like "a cloning option"
943
+ end
944
+ end
945
+
946
+ context "when provided an array" do
947
+
948
+ context "when the array is multi-dimensional" do
949
+
950
+ context "when the arrays have integer values" do
951
+
952
+ let(:selection) do
953
+ query.send("#{method}", [[ :field_one, 1 ],[ :field_two, -1 ]])
954
+ end
955
+
956
+ it "adds the sorting criteria" do
957
+ expect(selection.options).to eq(
958
+ { sort: { "field_one" => 1, "field_two" => -1 }}
959
+ )
960
+ end
961
+
962
+ it_behaves_like "a cloning option"
963
+ end
964
+
965
+ context "when the arrays have symbol values" do
966
+
967
+ let(:selection) do
968
+ query.send("#{method}", [[ :field_one, :asc ],[ :field_two, :desc ]])
969
+ end
970
+
971
+ it "adds the sorting criteria" do
972
+ expect(selection.options).to eq(
973
+ { sort: { "field_one" => 1, "field_two" => -1 }}
974
+ )
975
+ end
976
+
977
+ it_behaves_like "a cloning option"
978
+ end
979
+
980
+ context "when the arrays have string values" do
981
+
982
+ let(:selection) do
983
+ query.send("#{method}", [[ :field_one, "asc" ],[ :field_two, "desc" ]])
984
+ end
985
+
986
+ it "adds the sorting criteria" do
987
+ expect(selection.options).to eq(
988
+ { sort: { "field_one" => 1, "field_two" => -1 }}
989
+ )
990
+ end
991
+
992
+ it_behaves_like "a cloning option"
993
+ end
994
+ end
995
+
996
+ context "when the array is selectable keys" do
997
+
998
+ let(:selection) do
999
+ query.send("#{method}", [ :field_one.asc, :field_two.desc ])
1000
+ end
1001
+
1002
+ it "adds the sorting criteria" do
1003
+ expect(selection.options).to eq(
1004
+ { sort: { "field_one" => 1, "field_two" => -1 }}
1005
+ )
1006
+ end
1007
+
1008
+ it_behaves_like "a cloning option"
1009
+ end
1010
+ end
1011
+
1012
+ context "when provided values" do
1013
+
1014
+ context "when the values are arrays" do
1015
+
1016
+ context "when the values have integer directions" do
1017
+
1018
+ let(:selection) do
1019
+ query.send("#{method}", [ :field_one, 1 ],[ :field_two, -1 ])
1020
+ end
1021
+
1022
+ it "adds the sorting criteria" do
1023
+ expect(selection.options).to eq(
1024
+ { sort: { "field_one" => 1, "field_two" => -1 }}
1025
+ )
1026
+ end
1027
+
1028
+ it_behaves_like "a cloning option"
1029
+ end
1030
+
1031
+ context "when the values have symbol directions" do
1032
+
1033
+ let(:selection) do
1034
+ query.send("#{method}", [ :field_one, :asc ],[ :field_two, :desc ])
1035
+ end
1036
+
1037
+ it "adds the sorting criteria" do
1038
+ expect(selection.options).to eq(
1039
+ { sort: { "field_one" => 1, "field_two" => -1 }}
1040
+ )
1041
+ end
1042
+
1043
+ it_behaves_like "a cloning option"
1044
+ end
1045
+
1046
+ context "when the values have string directions" do
1047
+
1048
+ let(:selection) do
1049
+ query.send("#{method}", [ :field_one, "asc" ],[ :field_two, "desc" ])
1050
+ end
1051
+
1052
+ it "adds the sorting criteria" do
1053
+ expect(selection.options).to eq(
1054
+ { sort: { "field_one" => 1, "field_two" => -1 }}
1055
+ )
1056
+ end
1057
+
1058
+ it_behaves_like "a cloning option"
1059
+ end
1060
+ end
1061
+
1062
+ context "when the values are selectable keys" do
1063
+
1064
+ let(:selection) do
1065
+ query.send("#{method}", :field_one.asc, :field_two.desc)
1066
+ end
1067
+
1068
+ it "adds the sorting criteria" do
1069
+ expect(selection.options).to eq(
1070
+ { sort: { "field_one" => 1, "field_two" => -1 }}
1071
+ )
1072
+ end
1073
+
1074
+ it_behaves_like "a cloning option"
1075
+ end
1076
+ end
1077
+
1078
+ context "when provided a string" do
1079
+
1080
+ context "when the direction is lowercase" do
1081
+
1082
+ context "when abbreviated" do
1083
+
1084
+ let(:selection) do
1085
+ query.send("#{method}", "field_one asc, field_two desc")
1086
+ end
1087
+
1088
+ it "adds the sorting criteria" do
1089
+ expect(selection.options).to eq(
1090
+ { sort: { "field_one" => 1, "field_two" => -1 }}
1091
+ )
1092
+ end
1093
+
1094
+ it_behaves_like "a cloning option"
1095
+ end
1096
+
1097
+ context "when spelled out" do
1098
+
1099
+ let(:selection) do
1100
+ query.send("#{method}", "field_one ascending, field_two descending")
1101
+ end
1102
+
1103
+ it "adds the sorting criteria" do
1104
+ expect(selection.options).to eq(
1105
+ { sort: { "field_one" => 1, "field_two" => -1 }}
1106
+ )
1107
+ end
1108
+
1109
+ it_behaves_like "a cloning option"
1110
+ end
1111
+ end
1112
+
1113
+ context "when the direction is uppercase" do
1114
+
1115
+ context "when abbreviated" do
1116
+
1117
+ let(:selection) do
1118
+ query.send("#{method}", "field_one ASC, field_two DESC")
1119
+ end
1120
+
1121
+ it "adds the sorting criteria" do
1122
+ expect(selection.options).to eq(
1123
+ { sort: { "field_one" => 1, "field_two" => -1 }}
1124
+ )
1125
+ end
1126
+
1127
+ it_behaves_like "a cloning option"
1128
+ end
1129
+
1130
+ context "when spelled out" do
1131
+
1132
+ let(:selection) do
1133
+ query.send("#{method}", "field_one ASCENDING, field_two DESCENDING")
1134
+ end
1135
+
1136
+ it "adds the sorting criteria" do
1137
+ expect(selection.options).to eq(
1138
+ { sort: { "field_one" => 1, "field_two" => -1 }}
1139
+ )
1140
+ end
1141
+
1142
+ it_behaves_like "a cloning option"
1143
+ end
1144
+ end
1145
+ end
1146
+
1147
+ context "when provided no options" do
1148
+
1149
+ let(:selection) do
1150
+ query.order_by
1151
+ end
1152
+
1153
+ it "returns the query" do
1154
+ expect(selection).to eq(query)
1155
+ end
1156
+
1157
+ it_behaves_like "a cloning option"
1158
+ end
1159
+
1160
+ context "when provided nil" do
1161
+
1162
+ let(:selection) do
1163
+ query.send("#{method}", nil)
1164
+ end
1165
+
1166
+ it "returns the query" do
1167
+ expect(selection).to eq(query)
1168
+ end
1169
+
1170
+ it_behaves_like "a cloning option"
1171
+ end
1172
+ end
1173
+
1174
+ context "when using the mongo-1.x driver syntax" do
1175
+
1176
+ let(:query) do
1177
+ Mongoid::Query.new({}, {}, :mongo1x)
1178
+ end
1179
+
1180
+ context "when provided a hash" do
1181
+
1182
+ context "when the hash has integer values" do
1183
+
1184
+ let(:selection) do
1185
+ query.send("#{method}", field_one: 1, field_two: -1)
1186
+ end
1187
+
1188
+ it "adds the sorting criteria" do
1189
+ expect(selection.options).to eq(
1190
+ { sort: [[ :field_one, 1 ], [ :field_two, -1 ]]}
1191
+ )
1192
+ end
1193
+
1194
+ it_behaves_like "a cloning option"
1195
+ end
1196
+
1197
+ context "when the hash has symbol values" do
1198
+
1199
+ let(:selection) do
1200
+ query.send("#{method}", field_one: :asc, field_two: :desc)
1201
+ end
1202
+
1203
+ it "adds the sorting criteria" do
1204
+ expect(selection.options).to eq(
1205
+ { sort: [[ :field_one, 1 ], [ :field_two, -1 ]]}
1206
+ )
1207
+ end
1208
+
1209
+ it_behaves_like "a cloning option"
1210
+ end
1211
+
1212
+ context "when the hash has string values" do
1213
+
1214
+ let(:selection) do
1215
+ query.send("#{method}", field_one: "asc", field_two: "desc")
1216
+ end
1217
+
1218
+ it "adds the sorting criteria" do
1219
+ expect(selection.options).to eq(
1220
+ { sort: [[ :field_one, 1 ], [ :field_two, -1 ]]}
1221
+ )
1222
+ end
1223
+
1224
+ it_behaves_like "a cloning option"
1225
+ end
1226
+ end
1227
+
1228
+ context "when provided an array" do
1229
+
1230
+ context "when the array is multi-dimensional" do
1231
+
1232
+ context "when the arrays have integer values" do
1233
+
1234
+ let(:selection) do
1235
+ query.send("#{method}", [[ :field_one, 1 ],[ :field_two, -1 ]])
1236
+ end
1237
+
1238
+ it "adds the sorting criteria" do
1239
+ expect(selection.options).to eq(
1240
+ { sort: [[ :field_one, 1 ], [ :field_two, -1 ]]}
1241
+ )
1242
+ end
1243
+
1244
+ it_behaves_like "a cloning option"
1245
+ end
1246
+
1247
+ context "when the arrays have symbol values" do
1248
+
1249
+ let(:selection) do
1250
+ query.send("#{method}", [[ :field_one, :asc ],[ :field_two, :desc ]])
1251
+ end
1252
+
1253
+ it "adds the sorting criteria" do
1254
+ expect(selection.options).to eq(
1255
+ { sort: [[ :field_one, 1 ], [ :field_two, -1 ]]}
1256
+ )
1257
+ end
1258
+
1259
+ it_behaves_like "a cloning option"
1260
+ end
1261
+
1262
+ context "when the arrays have string values" do
1263
+
1264
+ let(:selection) do
1265
+ query.send("#{method}", [[ :field_one, "asc" ],[ :field_two, "desc" ]])
1266
+ end
1267
+
1268
+ it "adds the sorting criteria" do
1269
+ expect(selection.options).to eq(
1270
+ { sort: [[ :field_one, 1 ], [ :field_two, -1 ]]}
1271
+ )
1272
+ end
1273
+
1274
+ it_behaves_like "a cloning option"
1275
+ end
1276
+ end
1277
+
1278
+ context "when the array is selectable keys" do
1279
+
1280
+ let(:selection) do
1281
+ query.send("#{method}", [ :field_one.asc, :field_two.desc ])
1282
+ end
1283
+
1284
+ it "adds the sorting criteria" do
1285
+ expect(selection.options).to eq(
1286
+ { sort: [[ :field_one, 1 ], [ :field_two, -1 ]]}
1287
+ )
1288
+ end
1289
+
1290
+ it_behaves_like "a cloning option"
1291
+ end
1292
+ end
1293
+
1294
+ context "when provided values" do
1295
+
1296
+ context "when the values are arrays" do
1297
+
1298
+ context "when the values have integer directions" do
1299
+
1300
+ let(:selection) do
1301
+ query.send("#{method}", [ :field_one, 1 ],[ :field_two, -1 ])
1302
+ end
1303
+
1304
+ it "adds the sorting criteria" do
1305
+ expect(selection.options).to eq(
1306
+ { sort: [[ :field_one, 1 ], [ :field_two, -1 ]]}
1307
+ )
1308
+ end
1309
+
1310
+ it_behaves_like "a cloning option"
1311
+ end
1312
+
1313
+ context "when the values have symbol directions" do
1314
+
1315
+ let(:selection) do
1316
+ query.send("#{method}", [ :field_one, :asc ],[ :field_two, :desc ])
1317
+ end
1318
+
1319
+ it "adds the sorting criteria" do
1320
+ expect(selection.options).to eq(
1321
+ { sort: [[ :field_one, 1 ], [ :field_two, -1 ]]}
1322
+ )
1323
+ end
1324
+
1325
+ it_behaves_like "a cloning option"
1326
+ end
1327
+
1328
+ context "when the values have string directions" do
1329
+
1330
+ let(:selection) do
1331
+ query.send("#{method}", [ :field_one, "asc" ],[ :field_two, "desc" ])
1332
+ end
1333
+
1334
+ it "adds the sorting criteria" do
1335
+ expect(selection.options).to eq(
1336
+ { sort: [[ :field_one, 1 ], [ :field_two, -1 ]]}
1337
+ )
1338
+ end
1339
+
1340
+ it_behaves_like "a cloning option"
1341
+ end
1342
+ end
1343
+
1344
+ context "when the values are selectable keys" do
1345
+
1346
+ let(:selection) do
1347
+ query.send("#{method}", :field_one.asc, :field_two.desc)
1348
+ end
1349
+
1350
+ it "adds the sorting criteria" do
1351
+ expect(selection.options).to eq(
1352
+ { sort: [[ :field_one, 1 ], [ :field_two, -1 ]]}
1353
+ )
1354
+ end
1355
+
1356
+ it_behaves_like "a cloning option"
1357
+ end
1358
+ end
1359
+
1360
+ context "when provided a string" do
1361
+
1362
+ context "when the direction is lowercase" do
1363
+
1364
+ context "when abbreviated" do
1365
+
1366
+ let(:selection) do
1367
+ query.send("#{method}", "field_one asc, field_two desc")
1368
+ end
1369
+
1370
+ it "adds the sorting criteria" do
1371
+ expect(selection.options).to eq(
1372
+ { sort: [[ :field_one, 1 ], [ :field_two, -1 ]]}
1373
+ )
1374
+ end
1375
+
1376
+ it_behaves_like "a cloning option"
1377
+ end
1378
+
1379
+ context "when spelled out" do
1380
+
1381
+ let(:selection) do
1382
+ query.send("#{method}", "field_one ascending, field_two descending")
1383
+ end
1384
+
1385
+ it "adds the sorting criteria" do
1386
+ expect(selection.options).to eq(
1387
+ { sort: [[ :field_one, 1 ], [ :field_two, -1 ]]}
1388
+ )
1389
+ end
1390
+
1391
+ it_behaves_like "a cloning option"
1392
+ end
1393
+ end
1394
+
1395
+ context "when the direction is uppercase" do
1396
+
1397
+ context "when abbreviated" do
1398
+
1399
+ let(:selection) do
1400
+ query.send("#{method}", "field_one ASC, field_two DESC")
1401
+ end
1402
+
1403
+ it "adds the sorting criteria" do
1404
+ expect(selection.options).to eq(
1405
+ { sort: [[ :field_one, 1 ], [ :field_two, -1 ]]}
1406
+ )
1407
+ end
1408
+
1409
+ it_behaves_like "a cloning option"
1410
+ end
1411
+
1412
+ context "when spelled out" do
1413
+
1414
+ let(:selection) do
1415
+ query.send("#{method}", "field_one ASCENDING, field_two DESCENDING")
1416
+ end
1417
+
1418
+ it "adds the sorting criteria" do
1419
+ expect(selection.options).to eq(
1420
+ { sort: [[ :field_one, 1 ], [ :field_two, -1 ]]}
1421
+ )
1422
+ end
1423
+
1424
+ it_behaves_like "a cloning option"
1425
+ end
1426
+ end
1427
+ end
1428
+
1429
+ context "when provided no options" do
1430
+
1431
+ let(:selection) do
1432
+ query.order_by
1433
+ end
1434
+
1435
+ it "returns the query" do
1436
+ expect(selection).to eq(query)
1437
+ end
1438
+
1439
+ it_behaves_like "a cloning option"
1440
+ end
1441
+
1442
+ context "when provided nil" do
1443
+
1444
+ let(:selection) do
1445
+ query.send("#{method}", nil)
1446
+ end
1447
+
1448
+ it "returns the query" do
1449
+ expect(selection).to eq(query)
1450
+ end
1451
+
1452
+ it_behaves_like "a cloning option"
1453
+ end
1454
+ end
1455
+ end
1456
+ end
1457
+
1458
+ describe "#reoder" do
1459
+
1460
+ let(:selection) do
1461
+ query.order_by(field_one: 1, field_two: -1)
1462
+ end
1463
+
1464
+ let!(:reordered) do
1465
+ selection.reorder(field_three: 1)
1466
+ end
1467
+
1468
+ it "replaces all order options with the new options" do
1469
+ expect(reordered.options).to eq(sort: { "field_three" => 1 })
1470
+ end
1471
+
1472
+ it 'does not alter the original criteria object' do
1473
+ expect(selection.options[:sort]).to eq({ 'field_one' => 1, 'field_two' => -1 })
1474
+ end
1475
+ end
1476
+
1477
+ [ :skip, :offset ].each do |method|
1478
+
1479
+ describe "\##{method}" do
1480
+
1481
+ context "when provided no options" do
1482
+
1483
+ let(:selection) do
1484
+ query.send(method)
1485
+ end
1486
+
1487
+ it "does not add any options" do
1488
+ expect(selection.options).to eq({})
1489
+ end
1490
+
1491
+ it "returns the query" do
1492
+ expect(selection).to eq(query)
1493
+ end
1494
+
1495
+ it_behaves_like "a cloning option"
1496
+ end
1497
+
1498
+ context "when provided nil" do
1499
+
1500
+ let(:selection) do
1501
+ query.send(method, nil)
1502
+ end
1503
+
1504
+ it "does not add any options" do
1505
+ expect(selection.options).to eq({})
1506
+ end
1507
+
1508
+ it "returns the query" do
1509
+ expect(selection).to eq(query)
1510
+ end
1511
+
1512
+ it_behaves_like "a cloning option"
1513
+ end
1514
+
1515
+ context "when the query is aggregating" do
1516
+
1517
+ let(:selection) do
1518
+ query.project(name: 1).skip(10)
1519
+ end
1520
+
1521
+ it "adds the field options" do
1522
+ expect(selection.options).to eq({ skip: 10 })
1523
+ end
1524
+
1525
+ it "adds the skip to the aggregation" do
1526
+ expect(selection.pipeline).to include({ "$skip" => 10 })
1527
+ end
1528
+
1529
+ it_behaves_like "a cloning option"
1530
+ end
1531
+
1532
+ context "when provided arguments" do
1533
+
1534
+ context "when provided an integer" do
1535
+
1536
+ let(:selection) do
1537
+ query.send(method, 10)
1538
+ end
1539
+
1540
+ it "adds the field options" do
1541
+ expect(selection.options).to eq({ skip: 10 })
1542
+ end
1543
+
1544
+ it_behaves_like "a cloning option"
1545
+ end
1546
+
1547
+ context "when provided a float" do
1548
+
1549
+ let(:selection) do
1550
+ query.send(method, 10.25)
1551
+ end
1552
+
1553
+ it "adds the field options converted to an integer" do
1554
+ expect(selection.options).to eq({ skip: 10 })
1555
+ end
1556
+
1557
+ it_behaves_like "a cloning option"
1558
+ end
1559
+
1560
+ context "when provided a non number" do
1561
+
1562
+ let(:selection) do
1563
+ query.send(method, "10")
1564
+ end
1565
+
1566
+ it "adds the field options converted to an integer" do
1567
+ expect(selection.options).to eq({ skip: 10 })
1568
+ end
1569
+
1570
+ it_behaves_like "a cloning option"
1571
+ end
1572
+ end
1573
+ end
1574
+ end
1575
+
1576
+ describe "#slice" do
1577
+
1578
+ context "when provided no options" do
1579
+
1580
+ let(:selection) do
1581
+ query.slice
1582
+ end
1583
+
1584
+ it "does not add any options" do
1585
+ expect(selection.options).to eq({})
1586
+ end
1587
+
1588
+ it "returns the query" do
1589
+ expect(selection).to eq(query)
1590
+ end
1591
+
1592
+ it_behaves_like "a cloning option"
1593
+ end
1594
+
1595
+ context "when provided nil" do
1596
+
1597
+ let(:selection) do
1598
+ query.slice(nil)
1599
+ end
1600
+
1601
+ it "does not add any options" do
1602
+ expect(selection.options).to eq({})
1603
+ end
1604
+
1605
+ it "returns the query" do
1606
+ expect(selection).to eq(query)
1607
+ end
1608
+
1609
+ it_behaves_like "a cloning option"
1610
+ end
1611
+
1612
+ context "when provided a single argument" do
1613
+
1614
+ let(:selection) do
1615
+ query.slice(:first => 5)
1616
+ end
1617
+
1618
+ it "adds the field options" do
1619
+ expect(selection.options).to eq(
1620
+ { fields: { "first" => { "$slice" => 5 }}}
1621
+ )
1622
+ end
1623
+
1624
+ it_behaves_like "a cloning option"
1625
+ end
1626
+
1627
+ context "when provided a multiple arguments" do
1628
+
1629
+ let(:selection) do
1630
+ query.slice(:first => 5, :second => [ 0, 3 ])
1631
+ end
1632
+
1633
+ it "adds the field options" do
1634
+ expect(selection.options).to eq({ fields:
1635
+ { "first" => { "$slice" => 5 }, "second" => { "$slice" => [ 0, 3 ] }}
1636
+ })
1637
+ end
1638
+
1639
+ it_behaves_like "a cloning option"
1640
+ end
1641
+
1642
+ context "when existing field arguments exist" do
1643
+
1644
+ let(:limited) do
1645
+ query.only(:name)
1646
+ end
1647
+
1648
+ let(:selection) do
1649
+ limited.slice(:first => 5, :second => [ 0, 3 ])
1650
+ end
1651
+
1652
+ it "adds the field options" do
1653
+ expect(selection.options).to eq({
1654
+ fields: {
1655
+ "name" => 1,
1656
+ "first" => { "$slice" => 5 },
1657
+ "second" => { "$slice" => [ 0, 3 ] }
1658
+ }
1659
+ })
1660
+ end
1661
+
1662
+ it_behaves_like "a cloning option"
1663
+ end
1664
+ end
1665
+
1666
+ describe "#snapshot" do
1667
+
1668
+ let(:selection) do
1669
+ query.snapshot
1670
+ end
1671
+
1672
+ it "adds the snapshot option" do
1673
+ expect(selection.options).to eq({ snapshot: true })
1674
+ end
1675
+
1676
+ it_behaves_like "a cloning option"
1677
+ end
1678
+
1679
+ describe "#comment" do
1680
+
1681
+ let(:selection) do
1682
+ query.comment('slow query')
1683
+ end
1684
+
1685
+ it "adds the comment option" do
1686
+ expect(selection.options).to eq({ comment: 'slow query' })
1687
+ end
1688
+
1689
+ it_behaves_like "a cloning option"
1690
+ end
1691
+
1692
+ describe "#cursor_type" do
1693
+
1694
+ let(:selection) do
1695
+ query.cursor_type(:tailable)
1696
+ end
1697
+
1698
+ it "adds the cursor type option" do
1699
+ expect(selection.options).to eq({ cursor_type: :tailable })
1700
+ end
1701
+
1702
+ it_behaves_like "a cloning option"
1703
+ end
1704
+
1705
+ describe "#collation" do
1706
+
1707
+ let(:selection) do
1708
+ query.collation(locale: 'fr', strength: 2)
1709
+ end
1710
+
1711
+ it "adds the collation option" do
1712
+ expect(selection.options).to eq(collation: {'locale' => 'fr', 'strength' => 2})
1713
+ end
1714
+
1715
+ it_behaves_like "a cloning option"
1716
+ end
1717
+
1718
+ describe "#without" do
1719
+
1720
+ context "when provided no options" do
1721
+
1722
+ let(:selection) do
1723
+ query.without
1724
+ end
1725
+
1726
+ it "does not add any options" do
1727
+ expect(selection.options).to eq({})
1728
+ end
1729
+
1730
+ it "returns the query" do
1731
+ expect(selection).to eq(query)
1732
+ end
1733
+
1734
+ it_behaves_like "a cloning option"
1735
+ end
1736
+
1737
+ context "when provided nil" do
1738
+
1739
+ let(:selection) do
1740
+ query.without(nil)
1741
+ end
1742
+
1743
+ it "does not add any options" do
1744
+ expect(selection.options).to eq({})
1745
+ end
1746
+
1747
+ it "returns the query" do
1748
+ expect(selection).to eq(query)
1749
+ end
1750
+
1751
+ it_behaves_like "a cloning option"
1752
+ end
1753
+
1754
+ context "when provided fields" do
1755
+
1756
+ context "as sevaral arguments" do
1757
+
1758
+ let(:selection) do
1759
+ query.without(:first, :second)
1760
+ end
1761
+
1762
+ it "adds the field options" do
1763
+ expect(selection.options).to eq(
1764
+ { fields: { "first" => 0, "second" => 0 }}
1765
+ )
1766
+ end
1767
+
1768
+ it_behaves_like "a cloning option"
1769
+ end
1770
+
1771
+ context "as one argument - array" do
1772
+
1773
+ let(:selection) do
1774
+ query.without([:first, :second])
1775
+ end
1776
+
1777
+ it "adds the field options" do
1778
+ expect(selection.options).to eq(
1779
+ { fields: { "first" => 0, "second" => 0 }}
1780
+ )
1781
+ end
1782
+
1783
+ it_behaves_like "a cloning option"
1784
+ end
1785
+ end
1786
+
1787
+ context "when #only was called before" do
1788
+ let(:selection) do
1789
+ query.only(:first).without(:id)
1790
+ end
1791
+
1792
+ it "adds both fields to options" do
1793
+ expect(selection.options).to eq(
1794
+ { fields: { "first" => 1, "id" => 0 } }
1795
+ )
1796
+ end
1797
+ end
1798
+ end
1799
+ end