mongoid 5.4.1 → 6.1.1

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 (260) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +3 -3
  3. data/lib/config/locales/en.yml +19 -0
  4. data/lib/mongoid.rb +4 -4
  5. data/lib/mongoid/atomic.rb +2 -2
  6. data/lib/mongoid/atomic/modifiers.rb +8 -12
  7. data/lib/mongoid/attributes.rb +22 -21
  8. data/lib/mongoid/attributes/readonly.rb +22 -0
  9. data/lib/mongoid/cacheable.rb +36 -0
  10. data/lib/mongoid/changeable.rb +36 -0
  11. data/lib/mongoid/clients.rb +8 -63
  12. data/lib/mongoid/clients/options.rb +55 -250
  13. data/lib/mongoid/clients/storage_options.rb +1 -69
  14. data/lib/mongoid/composable.rb +29 -3
  15. data/lib/mongoid/config.rb +1 -0
  16. data/lib/mongoid/contextual/atomic.rb +5 -8
  17. data/lib/mongoid/contextual/map_reduce.rb +0 -4
  18. data/lib/mongoid/contextual/memory.rb +2 -2
  19. data/lib/mongoid/contextual/mongo.rb +40 -22
  20. data/lib/mongoid/contextual/none.rb +12 -0
  21. data/lib/mongoid/copyable.rb +13 -6
  22. data/lib/mongoid/criteria.rb +5 -2
  23. data/lib/mongoid/criteria/marshalable.rb +2 -2
  24. data/lib/mongoid/criteria/modifiable.rb +17 -1
  25. data/lib/mongoid/criteria/options.rb +25 -0
  26. data/lib/mongoid/criteria/queryable.rb +87 -0
  27. data/lib/mongoid/criteria/queryable/aggregable.rb +120 -0
  28. data/lib/mongoid/criteria/queryable/extensions.rb +28 -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/forwardable.rb +65 -0
  46. data/lib/mongoid/criteria/queryable/key.rb +103 -0
  47. data/lib/mongoid/criteria/queryable/macroable.rb +27 -0
  48. data/lib/mongoid/criteria/queryable/mergeable.rb +271 -0
  49. data/lib/mongoid/criteria/queryable/optional.rb +429 -0
  50. data/lib/mongoid/criteria/queryable/options.rb +153 -0
  51. data/lib/mongoid/criteria/queryable/pipeline.rb +111 -0
  52. data/lib/mongoid/criteria/queryable/selectable.rb +662 -0
  53. data/lib/mongoid/criteria/queryable/selector.rb +212 -0
  54. data/lib/mongoid/criteria/queryable/smash.rb +104 -0
  55. data/lib/mongoid/document.rb +30 -37
  56. data/lib/mongoid/errors.rb +2 -0
  57. data/lib/mongoid/errors/ambiguous_relationship.rb +1 -1
  58. data/lib/mongoid/errors/in_memory_collation_not_supported.rb +1 -1
  59. data/lib/mongoid/errors/invalid_field.rb +2 -2
  60. data/lib/mongoid/errors/invalid_persistence_option.rb +29 -0
  61. data/lib/mongoid/errors/invalid_relation.rb +66 -0
  62. data/lib/mongoid/evolvable.rb +1 -1
  63. data/lib/mongoid/extensions.rb +0 -4
  64. data/lib/mongoid/extensions/big_decimal.rb +17 -8
  65. data/lib/mongoid/extensions/date.rb +4 -1
  66. data/lib/mongoid/extensions/decimal128.rb +3 -3
  67. data/lib/mongoid/extensions/hash.rb +1 -0
  68. data/lib/mongoid/extensions/string.rb +4 -3
  69. data/lib/mongoid/extensions/time.rb +4 -1
  70. data/lib/mongoid/fields/validators/macro.rb +18 -0
  71. data/lib/mongoid/findable.rb +2 -2
  72. data/lib/mongoid/indexable.rb +15 -13
  73. data/lib/mongoid/interceptable.rb +5 -22
  74. data/lib/mongoid/matchable.rb +13 -7
  75. data/lib/mongoid/matchable/all.rb +2 -2
  76. data/lib/mongoid/matchable/and.rb +3 -3
  77. data/lib/mongoid/matchable/default.rb +2 -2
  78. data/lib/mongoid/matchable/elem_match.rb +28 -0
  79. data/lib/mongoid/matchable/exists.rb +2 -2
  80. data/lib/mongoid/matchable/gt.rb +4 -2
  81. data/lib/mongoid/matchable/gte.rb +4 -2
  82. data/lib/mongoid/matchable/in.rb +2 -2
  83. data/lib/mongoid/matchable/lt.rb +4 -2
  84. data/lib/mongoid/matchable/lte.rb +4 -2
  85. data/lib/mongoid/matchable/ne.rb +2 -2
  86. data/lib/mongoid/matchable/nin.rb +2 -2
  87. data/lib/mongoid/matchable/or.rb +3 -3
  88. data/lib/mongoid/matchable/regexp.rb +3 -3
  89. data/lib/mongoid/matchable/size.rb +2 -2
  90. data/lib/mongoid/persistable.rb +3 -5
  91. data/lib/mongoid/persistable/creatable.rb +2 -2
  92. data/lib/mongoid/persistable/deletable.rb +1 -1
  93. data/lib/mongoid/persistable/settable.rb +1 -1
  94. data/lib/mongoid/persistable/updatable.rb +5 -12
  95. data/lib/mongoid/persistable/upsertable.rb +1 -1
  96. data/lib/mongoid/persistence_context.rb +215 -0
  97. data/lib/mongoid/query_cache.rb +3 -6
  98. data/lib/mongoid/relations/accessors.rb +3 -0
  99. data/lib/mongoid/relations/auto_save.rb +12 -4
  100. data/lib/mongoid/relations/bindings/referenced/many_to_many.rb +4 -4
  101. data/lib/mongoid/relations/counter_cache.rb +15 -5
  102. data/lib/mongoid/relations/eager.rb +6 -11
  103. data/lib/mongoid/relations/eager/base.rb +3 -3
  104. data/lib/mongoid/relations/eager/has_and_belongs_to_many.rb +2 -2
  105. data/lib/mongoid/relations/eager/has_many.rb +1 -1
  106. data/lib/mongoid/relations/embedded/batchable.rb +12 -36
  107. data/lib/mongoid/relations/embedded/in.rb +13 -1
  108. data/lib/mongoid/relations/embedded/many.rb +28 -10
  109. data/lib/mongoid/relations/embedded/one.rb +14 -1
  110. data/lib/mongoid/relations/macros.rb +9 -1
  111. data/lib/mongoid/relations/metadata.rb +3 -3
  112. data/lib/mongoid/relations/options.rb +2 -2
  113. data/lib/mongoid/relations/proxy.rb +1 -31
  114. data/lib/mongoid/relations/referenced/in.rb +19 -10
  115. data/lib/mongoid/relations/referenced/many.rb +23 -17
  116. data/lib/mongoid/relations/referenced/many_to_many.rb +20 -13
  117. data/lib/mongoid/relations/referenced/one.rb +15 -1
  118. data/lib/mongoid/relations/synchronization.rb +11 -11
  119. data/lib/mongoid/relations/touchable.rb +6 -3
  120. data/lib/mongoid/reloadable.rb +1 -1
  121. data/lib/mongoid/serializable.rb +1 -1
  122. data/lib/mongoid/traversable.rb +1 -1
  123. data/lib/mongoid/validatable/uniqueness.rb +1 -2
  124. data/lib/mongoid/version.rb +1 -1
  125. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +14 -3
  126. data/spec/app/models/album.rb +5 -1
  127. data/spec/app/models/artist.rb +21 -0
  128. data/spec/app/models/book.rb +2 -1
  129. data/spec/app/models/dokument.rb +1 -0
  130. data/spec/app/models/ordered_post.rb +5 -0
  131. data/spec/app/models/oscar.rb +1 -2
  132. data/spec/app/models/page.rb +1 -1
  133. data/spec/app/models/person.rb +3 -3
  134. data/spec/app/models/princess.rb +2 -0
  135. data/spec/app/models/record.rb +1 -0
  136. data/spec/app/models/subscription.rb +1 -0
  137. data/spec/app/models/thing.rb +1 -1
  138. data/spec/config/mongoid.yml +15 -0
  139. data/spec/mongoid/atomic/modifiers_spec.rb +17 -17
  140. data/spec/mongoid/atomic_spec.rb +17 -17
  141. data/spec/mongoid/attributes/nested_spec.rb +14 -14
  142. data/spec/mongoid/attributes/readonly_spec.rb +87 -44
  143. data/spec/mongoid/attributes_spec.rb +90 -5
  144. data/spec/mongoid/cacheable_spec.rb +112 -0
  145. data/spec/mongoid/changeable_spec.rb +58 -0
  146. data/spec/mongoid/clients/factory_spec.rb +31 -3
  147. data/spec/mongoid/clients/options_spec.rb +382 -96
  148. data/spec/mongoid/clients_spec.rb +243 -101
  149. data/spec/mongoid/composable_spec.rb +7 -0
  150. data/spec/mongoid/config_spec.rb +67 -11
  151. data/spec/mongoid/contextual/atomic_spec.rb +3 -3
  152. data/spec/mongoid/contextual/mongo_spec.rb +165 -20
  153. data/spec/mongoid/contextual/none_spec.rb +15 -0
  154. data/spec/mongoid/copyable_spec.rb +13 -4
  155. data/spec/mongoid/criteria/modifiable_spec.rb +239 -7
  156. data/spec/mongoid/criteria/options_spec.rb +29 -0
  157. data/spec/mongoid/criteria/queryable/aggregable_spec.rb +370 -0
  158. data/spec/mongoid/criteria/queryable/extensions/array_spec.rb +523 -0
  159. data/spec/mongoid/criteria/queryable/extensions/big_decimal_spec.rb +59 -0
  160. data/spec/mongoid/criteria/queryable/extensions/bignum_spec.rb +58 -0
  161. data/spec/mongoid/criteria/queryable/extensions/boolean_spec.rb +213 -0
  162. data/spec/mongoid/criteria/queryable/extensions/date_spec.rb +330 -0
  163. data/spec/mongoid/criteria/queryable/extensions/date_time_spec.rb +405 -0
  164. data/spec/mongoid/criteria/queryable/extensions/fixnum_spec.rb +58 -0
  165. data/spec/mongoid/criteria/queryable/extensions/float_spec.rb +65 -0
  166. data/spec/mongoid/criteria/queryable/extensions/hash_spec.rb +327 -0
  167. data/spec/mongoid/criteria/queryable/extensions/integer_spec.rb +65 -0
  168. data/spec/mongoid/criteria/queryable/extensions/nil_class_spec.rb +77 -0
  169. data/spec/mongoid/criteria/queryable/extensions/object_spec.rb +108 -0
  170. data/spec/mongoid/criteria/queryable/extensions/range_spec.rb +309 -0
  171. data/spec/mongoid/{extensions/origin → criteria/queryable/extensions}/regexp_raw_spec.rb +2 -2
  172. data/spec/mongoid/criteria/queryable/extensions/regexp_spec.rb +90 -0
  173. data/spec/mongoid/criteria/queryable/extensions/set_spec.rb +39 -0
  174. data/spec/mongoid/criteria/queryable/extensions/string_spec.rb +302 -0
  175. data/spec/mongoid/criteria/queryable/extensions/symbol_spec.rb +167 -0
  176. data/spec/mongoid/criteria/queryable/extensions/time_spec.rb +376 -0
  177. data/spec/mongoid/criteria/queryable/extensions/time_with_zone_spec.rb +347 -0
  178. data/spec/mongoid/criteria/queryable/forwardable_spec.rb +87 -0
  179. data/spec/mongoid/criteria/queryable/key_spec.rb +52 -0
  180. data/spec/mongoid/criteria/queryable/mergeable_spec.rb +49 -0
  181. data/spec/mongoid/criteria/queryable/optional_spec.rb +1799 -0
  182. data/spec/mongoid/criteria/queryable/options_spec.rb +360 -0
  183. data/spec/mongoid/criteria/queryable/pipeline_spec.rb +200 -0
  184. data/spec/mongoid/criteria/queryable/queryable_spec.rb +137 -0
  185. data/spec/mongoid/criteria/queryable/selectable_spec.rb +4174 -0
  186. data/spec/mongoid/criteria/queryable/selector_spec.rb +844 -0
  187. data/spec/mongoid/criteria/queryable/smash_spec.rb +30 -0
  188. data/spec/mongoid/criteria_spec.rb +152 -21
  189. data/spec/mongoid/document_spec.rb +37 -88
  190. data/spec/mongoid/errors/invalid_relation_spec.rb +37 -0
  191. data/spec/mongoid/errors/mongoid_error_spec.rb +6 -3
  192. data/spec/mongoid/extensions/big_decimal_spec.rb +320 -18
  193. data/spec/mongoid/extensions/boolean_spec.rb +14 -0
  194. data/spec/mongoid/extensions/date_spec.rb +2 -6
  195. data/spec/mongoid/extensions/date_time_spec.rb +2 -6
  196. data/spec/mongoid/extensions/decimal128_spec.rb +1 -1
  197. data/spec/mongoid/extensions/float_spec.rb +8 -1
  198. data/spec/mongoid/extensions/hash_spec.rb +15 -0
  199. data/spec/mongoid/extensions/integer_spec.rb +8 -1
  200. data/spec/mongoid/extensions/object_spec.rb +11 -0
  201. data/spec/mongoid/extensions/string_spec.rb +21 -0
  202. data/spec/mongoid/extensions/time_spec.rb +2 -6
  203. data/spec/mongoid/extensions/time_with_zone_spec.rb +2 -6
  204. data/spec/mongoid/findable_spec.rb +46 -1
  205. data/spec/mongoid/indexable_spec.rb +15 -3
  206. data/spec/mongoid/interceptable_spec.rb +68 -10
  207. data/spec/mongoid/matchable/all_spec.rb +4 -4
  208. data/spec/mongoid/matchable/and_spec.rb +10 -10
  209. data/spec/mongoid/matchable/default_spec.rb +12 -12
  210. data/spec/mongoid/matchable/elem_match_spec.rb +86 -0
  211. data/spec/mongoid/matchable/exists_spec.rb +5 -5
  212. data/spec/mongoid/matchable/gt_spec.rb +18 -7
  213. data/spec/mongoid/matchable/gte_spec.rb +17 -7
  214. data/spec/mongoid/matchable/in_spec.rb +5 -5
  215. data/spec/mongoid/matchable/lt_spec.rb +18 -7
  216. data/spec/mongoid/matchable/lte_spec.rb +18 -7
  217. data/spec/mongoid/matchable/ne_spec.rb +5 -5
  218. data/spec/mongoid/matchable/nin_spec.rb +5 -5
  219. data/spec/mongoid/matchable/or_spec.rb +7 -7
  220. data/spec/mongoid/matchable/regexp_spec.rb +5 -5
  221. data/spec/mongoid/matchable/size_spec.rb +3 -3
  222. data/spec/mongoid/matchable_spec.rb +173 -53
  223. data/spec/mongoid/persistable/creatable_spec.rb +7 -2
  224. data/spec/mongoid/persistable/deletable_spec.rb +16 -1
  225. data/spec/mongoid/persistable/destroyable_spec.rb +6 -2
  226. data/spec/mongoid/persistable/savable_spec.rb +35 -30
  227. data/spec/mongoid/persistable/settable_spec.rb +45 -29
  228. data/spec/mongoid/persistable/updatable_spec.rb +184 -5
  229. data/spec/mongoid/persistence_context_spec.rb +680 -0
  230. data/spec/mongoid/positional_spec.rb +10 -10
  231. data/spec/mongoid/query_cache_spec.rb +89 -0
  232. data/spec/mongoid/relations/accessors_spec.rb +1 -1
  233. data/spec/mongoid/relations/auto_save_spec.rb +39 -6
  234. data/spec/mongoid/relations/bindings/referenced/many_to_many_spec.rb +4 -4
  235. data/spec/mongoid/relations/builders_spec.rb +37 -10
  236. data/spec/mongoid/relations/counter_cache_spec.rb +64 -3
  237. data/spec/mongoid/relations/eager/has_and_belongs_to_many_spec.rb +16 -0
  238. data/spec/mongoid/relations/eager_spec.rb +40 -0
  239. data/spec/mongoid/relations/embedded/many_spec.rb +63 -47
  240. data/spec/mongoid/relations/embedded/one_spec.rb +2 -1
  241. data/spec/mongoid/relations/macros_spec.rb +395 -7
  242. data/spec/mongoid/relations/metadata_spec.rb +15 -1
  243. data/spec/mongoid/relations/proxy_spec.rb +27 -1
  244. data/spec/mongoid/relations/referenced/in_spec.rb +41 -1
  245. data/spec/mongoid/relations/referenced/many_spec.rb +13 -25
  246. data/spec/mongoid/relations/referenced/many_to_many_spec.rb +14 -26
  247. data/spec/mongoid/relations/synchronization_spec.rb +48 -2
  248. data/spec/mongoid/relations/touchable_spec.rb +40 -0
  249. data/spec/mongoid/reloadable_spec.rb +51 -0
  250. data/spec/mongoid/serializable_spec.rb +0 -50
  251. data/spec/mongoid/validatable/presence_spec.rb +1 -1
  252. data/spec/mongoid/validatable/uniqueness_spec.rb +18 -9
  253. data/spec/mongoid/validatable_spec.rb +16 -0
  254. data/spec/spec_helper.rb +20 -11
  255. metadata +524 -469
  256. checksums.yaml.gz.sig +0 -0
  257. data.tar.gz.sig +0 -0
  258. data/lib/mongoid/clients/thread_options.rb +0 -19
  259. data/lib/mongoid/extensions/origin/regexp_raw.rb +0 -43
  260. metadata.gz.sig +0 -0
@@ -0,0 +1,137 @@
1
+ require "spec_helper"
2
+
3
+ describe Mongoid::Query do
4
+
5
+ describe "#==" do
6
+
7
+ let(:query) do
8
+ described_class.new
9
+ end
10
+
11
+ context "when the objects have the same selector" do
12
+
13
+ let(:other) do
14
+ described_class.new
15
+ end
16
+
17
+ context "when the options are the same" do
18
+
19
+ it "returns true" do
20
+ expect(query).to eq(other)
21
+ end
22
+ end
23
+
24
+ context "when the options are different" do
25
+
26
+ before do
27
+ other.options[:skip] = 20
28
+ end
29
+
30
+ it "returns false" do
31
+ expect(query).to_not eq(other)
32
+ end
33
+ end
34
+ end
35
+
36
+ context "when the objects have different selectors" do
37
+
38
+ let(:other) do
39
+ described_class.new do |query|
40
+ query.selector["field"] = "value"
41
+ end
42
+ end
43
+
44
+ it "returns false" do
45
+ expect(query).to_not eq(other)
46
+ end
47
+ end
48
+
49
+ context "when the objects are different types" do
50
+
51
+ let(:other) do
52
+ "Query"
53
+ end
54
+
55
+ it "returns false" do
56
+ expect(query).to_not eq(other)
57
+ end
58
+ end
59
+ end
60
+
61
+ describe "#initialize" do
62
+
63
+ context "when passed no arguments" do
64
+
65
+ let(:query) do
66
+ described_class.new
67
+ end
68
+
69
+ it "intializes the selector" do
70
+ expect(query.selector).to eq({})
71
+ end
72
+
73
+ it "initializes the options" do
74
+ expect(query.options).to eq({})
75
+ end
76
+ end
77
+
78
+ context "when passed a block" do
79
+
80
+ let(:query) do
81
+ described_class.new do |query|
82
+ query.selector["field"] = "value"
83
+ end
84
+ end
85
+
86
+ it "yields to the block" do
87
+ expect(query.selector).to eq({ "field" => "value" })
88
+ end
89
+ end
90
+ end
91
+
92
+ describe "#initialize_copy" do
93
+
94
+ let(:sort) do
95
+ { "name" => 1 }
96
+ end
97
+
98
+ let(:query) do
99
+ described_class.new do |query|
100
+ query.selector["field"] = "value"
101
+ query.options["sort"] = { "field" => sort }
102
+ end
103
+ end
104
+
105
+ let!(:cloned) do
106
+ query.clone
107
+ end
108
+
109
+ it "returns a query" do
110
+ expect(cloned).to be_a(Mongoid::Query)
111
+ end
112
+
113
+ it "returns a new instance" do
114
+ expect(cloned).to_not equal(query)
115
+ end
116
+
117
+ it "retains the selector values" do
118
+ expect(cloned.selector).to eq({ "field" => "value" })
119
+ end
120
+
121
+ it "retains the option values" do
122
+ expect(cloned.options).to eq({ "sort" => { "field" => sort }})
123
+ end
124
+
125
+ it "deep copies the selector" do
126
+ expect(cloned.selector).to_not equal(query.selector)
127
+ end
128
+
129
+ it "deep copies the options" do
130
+ expect(cloned.options).to_not equal(query.options)
131
+ end
132
+
133
+ it "deep copies n levels deep" do
134
+ expect(cloned.options["sort"]["field"]).to_not equal(sort)
135
+ end
136
+ end
137
+ end
@@ -0,0 +1,4174 @@
1
+ require "spec_helper"
2
+
3
+ describe Mongoid::Criteria::Queryable::Selectable do
4
+
5
+ let(:query) do
6
+ Mongoid::Query.new("id" => "_id")
7
+ end
8
+
9
+ shared_examples_for "a cloning selection" do
10
+
11
+ it "returns a cloned query" do
12
+ expect(selection).to_not equal(query)
13
+ end
14
+ end
15
+
16
+ describe "#all" do
17
+
18
+ context "when provided no criterion" do
19
+
20
+ let(:selection) do
21
+ query.all
22
+ end
23
+
24
+ it "does not add any criterion" do
25
+ expect(selection.selector).to eq({})
26
+ end
27
+
28
+ it "returns the query" do
29
+ expect(selection).to eq(query)
30
+ end
31
+
32
+ it "returns a cloned query" do
33
+ expect(selection).to_not equal(query)
34
+ end
35
+ end
36
+
37
+ context "when provided nil" do
38
+
39
+ let(:selection) do
40
+ query.all(nil)
41
+ end
42
+
43
+ it "does not add any criterion" do
44
+ expect(selection.selector).to eq({})
45
+ end
46
+
47
+ it "returns the query" do
48
+ expect(selection).to eq(query)
49
+ end
50
+
51
+ it "returns a cloned query" do
52
+ expect(selection).to_not equal(query)
53
+ end
54
+ end
55
+
56
+ context "when provided a single criterion" do
57
+
58
+ context "when no serializers are provided" do
59
+
60
+ context "when providing an array" do
61
+
62
+ let(:selection) do
63
+ query.all(field: [ 1, 2 ])
64
+ end
65
+
66
+ it "adds the $all selector" do
67
+ expect(selection.selector).to eq({
68
+ "field" => { "$all" => [ 1, 2 ] }
69
+ })
70
+ end
71
+
72
+ it "returns a cloned query" do
73
+ expect(selection).to_not equal(query)
74
+ end
75
+ end
76
+
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
+ context "when providing a single value" do
95
+
96
+ let(:selection) do
97
+ query.all(field: 1)
98
+ end
99
+
100
+ it "adds the $all selector with wrapped value" do
101
+ expect(selection.selector).to eq({
102
+ "field" => { "$all" => [ 1 ] }
103
+ })
104
+ end
105
+
106
+ it "returns a cloned query" do
107
+ expect(selection).to_not equal(query)
108
+ end
109
+ end
110
+ end
111
+
112
+ context "when serializers are provided" do
113
+
114
+ before(:all) do
115
+ class Field
116
+ def evolve(object)
117
+ Integer.evolve(object)
118
+ end
119
+ def localized?
120
+ false
121
+ end
122
+ end
123
+ end
124
+
125
+ after(:all) do
126
+ Object.send(:remove_const, :Field)
127
+ end
128
+
129
+ let!(:query) do
130
+ Mongoid::Query.new({}, { "field" => Field.new })
131
+ end
132
+
133
+ context "when providing an array" do
134
+
135
+ let(:selection) do
136
+ query.all(field: [ "1", "2" ])
137
+ end
138
+
139
+ it "adds the $all selector" do
140
+ expect(selection.selector).to eq({
141
+ "field" => { "$all" => [ 1, 2 ] }
142
+ })
143
+ end
144
+
145
+ it "returns a cloned query" do
146
+ expect(selection).to_not equal(query)
147
+ end
148
+ end
149
+
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
+ context "when providing a single value" do
168
+
169
+ let(:selection) do
170
+ query.all(field: "1")
171
+ end
172
+
173
+ it "adds the $all selector with wrapped value" do
174
+ expect(selection.selector).to eq({
175
+ "field" => { "$all" => [ 1 ] }
176
+ })
177
+ end
178
+
179
+ it "returns a cloned query" do
180
+ expect(selection).to_not equal(query)
181
+ end
182
+ end
183
+ end
184
+ end
185
+
186
+ context "when provided multiple criterion" do
187
+
188
+ context "when the criterion are for different fields" do
189
+
190
+ let(:selection) do
191
+ query.all(first: [ 1, 2 ], second: [ 3, 4 ])
192
+ end
193
+
194
+ it "adds the $all selectors" do
195
+ expect(selection.selector).to eq({
196
+ "first" => { "$all" => [ 1, 2 ] },
197
+ "second" => { "$all" => [ 3, 4 ] }
198
+ })
199
+ end
200
+
201
+ it "returns a cloned query" do
202
+ expect(selection).to_not equal(query)
203
+ end
204
+ end
205
+ end
206
+
207
+ context "when chaining the criterion" do
208
+
209
+ context "when the criterion are for different fields" do
210
+
211
+ let(:selection) do
212
+ query.all(first: [ 1, 2 ]).all(second: [ 3, 4 ])
213
+ end
214
+
215
+ it "adds the $all selectors" do
216
+ expect(selection.selector).to eq({
217
+ "first" => { "$all" => [ 1, 2 ] },
218
+ "second" => { "$all" => [ 3, 4 ] }
219
+ })
220
+ end
221
+
222
+ it "returns a cloned query" do
223
+ expect(selection).to_not equal(query)
224
+ end
225
+ end
226
+
227
+ context "when the criterion are on the same field" do
228
+
229
+ context "when no serializers are provided" do
230
+
231
+ context "when the strategy is the default (union)" do
232
+
233
+ let(:selection) do
234
+ query.all(first: [ 1, 2 ]).all(first: [ 3, 4 ])
235
+ end
236
+
237
+ it "overwrites the first $all selector" do
238
+ expect(selection.selector).to eq({
239
+ "first" => { "$all" => [ 1, 2, 3, 4 ] }
240
+ })
241
+ end
242
+
243
+ it "returns a cloned query" do
244
+ expect(selection).to_not equal(query)
245
+ end
246
+ end
247
+
248
+ context "when the strategy is intersect" do
249
+
250
+ let(:selection) do
251
+ query.all(first: [ 1, 2 ]).intersect.all(first: [ 2, 3 ])
252
+ end
253
+
254
+ it "intersects the $all selectors" do
255
+ expect(selection.selector).to eq({
256
+ "first" => { "$all" => [ 2 ] }
257
+ })
258
+ end
259
+
260
+ it "returns a cloned query" do
261
+ expect(selection).to_not equal(query)
262
+ end
263
+ end
264
+
265
+ context "when the strategy is override" do
266
+
267
+ let(:selection) do
268
+ query.all(first: [ 1, 2 ]).override.all(first: [ 3, 4 ])
269
+ end
270
+
271
+ it "overwrites the first $all selector" do
272
+ expect(selection.selector).to eq({
273
+ "first" => { "$all" => [ 3, 4 ] }
274
+ })
275
+ end
276
+
277
+ it "returns a cloned query" do
278
+ expect(selection).to_not equal(query)
279
+ end
280
+ end
281
+
282
+ context "when the strategy is union" do
283
+
284
+ let(:selection) do
285
+ query.all(first: [ 1, 2 ]).union.all(first: [ 3, 4 ])
286
+ end
287
+
288
+ it "unions the $all selectors" do
289
+ expect(selection.selector).to eq({
290
+ "first" => { "$all" => [ 1, 2, 3, 4 ] }
291
+ })
292
+ end
293
+
294
+ it "returns a cloned query" do
295
+ expect(selection).to_not equal(query)
296
+ end
297
+ end
298
+ end
299
+
300
+ context "when serializers are provided" do
301
+
302
+ before(:all) do
303
+ class Field
304
+ def evolve(object)
305
+ Integer.evolve(object)
306
+ end
307
+ def localized?
308
+ false
309
+ end
310
+ end
311
+ end
312
+
313
+ after(:all) do
314
+ Object.send(:remove_const, :Field)
315
+ end
316
+
317
+ let!(:query) do
318
+ Mongoid::Query.new({}, { "field" => Field.new })
319
+ end
320
+
321
+ context "when the strategy is the default (union)" do
322
+
323
+ let(:selection) do
324
+ query.all(field: [ "1", "2" ]).all(field: [ "3", "4" ])
325
+ end
326
+
327
+ it "overwrites the field $all selector" do
328
+ expect(selection.selector).to eq({
329
+ "field" => { "$all" => [ 1, 2, 3, 4 ] }
330
+ })
331
+ end
332
+
333
+ it "returns a cloned query" do
334
+ expect(selection).to_not equal(query)
335
+ end
336
+ end
337
+
338
+ context "when the strategy is intersect" do
339
+
340
+ let(:selection) do
341
+ query.all(field: [ "1", "2" ]).intersect.all(field: [ "2", "3" ])
342
+ end
343
+
344
+ it "intersects the $all selectors" do
345
+ expect(selection.selector).to eq({
346
+ "field" => { "$all" => [ 2 ] }
347
+ })
348
+ end
349
+
350
+ it "returns a cloned query" do
351
+ expect(selection).to_not equal(query)
352
+ end
353
+ end
354
+
355
+ context "when the strategy is override" do
356
+
357
+ let(:selection) do
358
+ query.all(field: [ "1", "2" ]).override.all(field: [ "3", "4" ])
359
+ end
360
+
361
+ it "overwrites the field $all selector" do
362
+ expect(selection.selector).to eq({
363
+ "field" => { "$all" => [ 3, 4 ] }
364
+ })
365
+ end
366
+
367
+ it "returns a cloned query" do
368
+ expect(selection).to_not equal(query)
369
+ end
370
+ end
371
+
372
+ context "when the strategy is union" do
373
+
374
+ let(:selection) do
375
+ query.all(field: [ "1", "2" ]).union.all(field: [ "3", "4" ])
376
+ end
377
+
378
+ it "unions the $all selectors" do
379
+ expect(selection.selector).to eq({
380
+ "field" => { "$all" => [ 1, 2, 3, 4 ] }
381
+ })
382
+ end
383
+
384
+ it "returns a cloned query" do
385
+ expect(selection).to_not equal(query)
386
+ end
387
+ end
388
+ end
389
+ end
390
+ end
391
+ end
392
+
393
+ describe "#and" do
394
+
395
+ context "when provided no criterion" do
396
+
397
+ let(:selection) do
398
+ query.and
399
+ end
400
+
401
+ it "does not add any criterion" do
402
+ expect(selection.selector).to eq({})
403
+ end
404
+
405
+ it "returns the query" do
406
+ expect(selection).to eq(query)
407
+ end
408
+
409
+ it "returns a cloned query" do
410
+ expect(selection).to_not equal(query)
411
+ end
412
+ end
413
+
414
+ context "when provided nil" do
415
+
416
+ let(:selection) do
417
+ query.and(nil)
418
+ end
419
+
420
+ it "does not add any criterion" do
421
+ expect(selection.selector).to eq({})
422
+ end
423
+
424
+ it "returns the query" do
425
+ expect(selection).to eq(query)
426
+ end
427
+
428
+ it "returns a cloned query" do
429
+ expect(selection).to_not equal(query)
430
+ end
431
+ end
432
+
433
+ context "when provided a single criterion" do
434
+
435
+ let(:selection) do
436
+ query.and(field: [ 1, 2 ])
437
+ end
438
+
439
+ it "adds the $and selector" do
440
+ expect(selection.selector).to eq({
441
+ "$and" => [{ "field" => [ 1, 2 ] }]
442
+ })
443
+ end
444
+
445
+ it "returns a cloned query" do
446
+ expect(selection).to_not equal(query)
447
+ end
448
+ end
449
+
450
+ context "when provided a nested criterion" do
451
+
452
+ let(:selection) do
453
+ query.and(:test.elem_match => { :field.in => [ 1, 2 ] })
454
+ end
455
+
456
+ it "adds the $and selector" do
457
+ expect(selection.selector).to eq({
458
+ "$and" => [{ "test" => { "$elemMatch" => { "field" => { "$in" => [ 1, 2 ] }}}}]
459
+ })
460
+ end
461
+
462
+ it "returns a cloned query" do
463
+ expect(selection).to_not equal(query)
464
+ end
465
+ end
466
+
467
+ context "when provided multiple criterion" do
468
+
469
+ context "when the criterion is already included" do
470
+
471
+ let(:selection) do
472
+ query.and({ first: [ 1, 2 ] }).and({ first: [ 1, 2 ] })
473
+ end
474
+
475
+ it "does not duplicate the $and selector" do
476
+ expect(selection.selector).to eq({
477
+ "$and" => [
478
+ { "first" => [ 1, 2 ] }
479
+ ]
480
+ })
481
+ end
482
+
483
+ it "returns a cloned query" do
484
+ expect(selection).to_not equal(query)
485
+ end
486
+ end
487
+
488
+ context "when the criterion are for different fields" do
489
+
490
+ let(:selection) do
491
+ query.and({ first: [ 1, 2 ] }, { second: [ 3, 4 ] })
492
+ end
493
+
494
+ it "adds the $and selector" do
495
+ expect(selection.selector).to eq({
496
+ "$and" => [
497
+ { "first" => [ 1, 2 ] },
498
+ { "second" => [ 3, 4 ] }
499
+ ]
500
+ })
501
+ end
502
+
503
+ it "returns a cloned query" do
504
+ expect(selection).to_not equal(query)
505
+ end
506
+ end
507
+
508
+ context "when the criterion are on the same field" do
509
+
510
+ let(:selection) do
511
+ query.and({ first: [ 1, 2 ] }, { first: [ 3, 4 ] })
512
+ end
513
+
514
+ it "appends both $and expressions" do
515
+ expect(selection.selector).to eq({
516
+ "$and" => [
517
+ { "first" => [ 1, 2 ] },
518
+ { "first" => [ 3, 4 ] }
519
+ ]
520
+ })
521
+ end
522
+
523
+ it "returns a cloned query" do
524
+ expect(selection).to_not equal(query)
525
+ end
526
+ end
527
+ end
528
+
529
+ context "when chaining the criterion" do
530
+
531
+ context "when the criterion are for different fields" do
532
+
533
+ let(:selection) do
534
+ query.and(first: [ 1, 2 ]).and(second: [ 3, 4 ])
535
+ end
536
+
537
+ it "adds the $and selectors" do
538
+ expect(selection.selector).to eq({
539
+ "$and" => [
540
+ { "first" => [ 1, 2 ] },
541
+ { "second" => [ 3, 4 ] }
542
+ ]
543
+ })
544
+ end
545
+
546
+ it "returns a cloned query" do
547
+ expect(selection).to_not equal(query)
548
+ end
549
+ end
550
+
551
+ context "when the criterion are on the same field" do
552
+
553
+ let(:selection) do
554
+ query.and(first: [ 1, 2 ]).and(first: [ 3, 4 ])
555
+ end
556
+
557
+ it "appends both $and expressions" do
558
+ expect(selection.selector).to eq({
559
+ "$and" => [
560
+ { "first" => [ 1, 2 ] },
561
+ { "first" => [ 3, 4 ] }
562
+ ]
563
+ })
564
+ end
565
+
566
+ it "returns a cloned query" do
567
+ expect(selection).to_not equal(query)
568
+ end
569
+ end
570
+ end
571
+ end
572
+
573
+ describe "#between" do
574
+
575
+ context "when provided no criterion" do
576
+
577
+ let(:selection) do
578
+ query.between
579
+ end
580
+
581
+ it "does not add any criterion" do
582
+ expect(selection.selector).to eq({})
583
+ end
584
+
585
+ it "returns the query" do
586
+ expect(selection).to eq(query)
587
+ end
588
+
589
+ it "returns a cloned query" do
590
+ expect(selection).to_not equal(query)
591
+ end
592
+ end
593
+
594
+ context "when provided nil" do
595
+
596
+ let(:selection) do
597
+ query.between(nil)
598
+ end
599
+
600
+ it "does not add any criterion" do
601
+ expect(selection.selector).to eq({})
602
+ end
603
+
604
+ it "returns the query" do
605
+ expect(selection).to eq(query)
606
+ end
607
+
608
+ it "returns a cloned query" do
609
+ expect(selection).to_not equal(query)
610
+ end
611
+ end
612
+
613
+ context "when provided a single range" do
614
+
615
+ let(:selection) do
616
+ query.between(field: 1..10)
617
+ end
618
+
619
+ it "adds the $gte and $lte selectors" do
620
+ expect(selection.selector).to eq({
621
+ "field" => { "$gte" => 1, "$lte" => 10 }
622
+ })
623
+ end
624
+
625
+ it "returns a cloned query" do
626
+ expect(selection).to_not equal(query)
627
+ end
628
+ end
629
+
630
+ context "when provided multiple ranges" do
631
+
632
+ context "when the ranges are on different fields" do
633
+
634
+ let(:selection) do
635
+ query.between(field: 1..10, key: 5..7)
636
+ end
637
+
638
+ it "adds the $gte and $lte selectors" do
639
+ expect(selection.selector).to eq({
640
+ "field" => { "$gte" => 1, "$lte" => 10 },
641
+ "key" => { "$gte" => 5, "$lte" => 7 }
642
+ })
643
+ end
644
+
645
+ it "returns a cloned query" do
646
+ expect(selection).to_not equal(query)
647
+ end
648
+ end
649
+ end
650
+ end
651
+
652
+ describe "#elem_match" do
653
+
654
+ context "when provided no criterion" do
655
+
656
+ let(:selection) do
657
+ query.elem_match
658
+ end
659
+
660
+ it "does not add any criterion" do
661
+ expect(selection.selector).to eq({})
662
+ end
663
+
664
+ it "returns the query" do
665
+ expect(selection).to eq(query)
666
+ end
667
+
668
+ it "returns a cloned query" do
669
+ expect(selection).to_not equal(query)
670
+ end
671
+ end
672
+
673
+ context "when provided nil" do
674
+
675
+ let(:selection) do
676
+ query.elem_match(nil)
677
+ end
678
+
679
+ it "does not add any criterion" do
680
+ expect(selection.selector).to eq({})
681
+ end
682
+
683
+ it "returns the query" do
684
+ expect(selection).to eq(query)
685
+ end
686
+
687
+ it "returns a cloned query" do
688
+ expect(selection).to_not equal(query)
689
+ end
690
+ end
691
+
692
+ context "when provided a criterion" do
693
+
694
+ context "when there are no nested complex keys" do
695
+
696
+ let(:selection) do
697
+ query.elem_match(users: { name: "value" })
698
+ end
699
+
700
+ it "adds the $elemMatch expression" do
701
+ expect(selection.selector).to eq({
702
+ "users" => { "$elemMatch" => { name: "value" }}
703
+ })
704
+ end
705
+
706
+ it "returns a cloned query" do
707
+ expect(selection).to_not equal(query)
708
+ end
709
+ end
710
+
711
+ context "when there are nested complex keys" do
712
+
713
+ let(:time) do
714
+ Time.now
715
+ end
716
+
717
+ let(:selection) do
718
+ query.elem_match(users: { :time.gt => time })
719
+ end
720
+
721
+ it "adds the $elemMatch expression" do
722
+ expect(selection.selector).to eq({
723
+ "users" => { "$elemMatch" => { "time" => { "$gt" => time }}}
724
+ })
725
+ end
726
+
727
+ it "returns a cloned query" do
728
+ expect(selection).to_not equal(query)
729
+ end
730
+ end
731
+ end
732
+
733
+ context "when providing multiple criteria" do
734
+
735
+ context "when the fields differ" do
736
+
737
+ let(:selection) do
738
+ query.elem_match(
739
+ users: { name: "value" },
740
+ comments: { text: "value" }
741
+ )
742
+ end
743
+
744
+ it "adds the $elemMatch expression" do
745
+ expect(selection.selector).to eq({
746
+ "users" => { "$elemMatch" => { name: "value" }},
747
+ "comments" => { "$elemMatch" => { text: "value" }}
748
+ })
749
+ end
750
+
751
+ it "returns a cloned query" do
752
+ expect(selection).to_not equal(query)
753
+ end
754
+ end
755
+ end
756
+
757
+ context "when chaining multiple criteria" do
758
+
759
+ context "when the fields differ" do
760
+
761
+ let(:selection) do
762
+ query.
763
+ elem_match(users: { name: "value" }).
764
+ elem_match(comments: { text: "value" })
765
+ end
766
+
767
+ it "adds the $elemMatch expression" do
768
+ expect(selection.selector).to eq({
769
+ "users" => { "$elemMatch" => { name: "value" }},
770
+ "comments" => { "$elemMatch" => { text: "value" }}
771
+ })
772
+ end
773
+
774
+ it "returns a cloned query" do
775
+ expect(selection).to_not equal(query)
776
+ end
777
+ end
778
+
779
+ context "when the fields are the same" do
780
+
781
+ let(:selection) do
782
+ query.
783
+ elem_match(users: { name: "value" }).
784
+ elem_match(users: { state: "new" })
785
+ end
786
+
787
+ it "overrides the $elemMatch expression" do
788
+ expect(selection.selector).to eq({
789
+ "users" => { "$elemMatch" => { state: "new" }}
790
+ })
791
+ end
792
+
793
+ it "returns a cloned query" do
794
+ expect(selection).to_not equal(query)
795
+ end
796
+ end
797
+ end
798
+ end
799
+
800
+ describe "#exists" do
801
+
802
+ context "when provided no criterion" do
803
+
804
+ let(:selection) do
805
+ query.exists
806
+ end
807
+
808
+ it "does not add any criterion" do
809
+ expect(selection.selector).to eq({})
810
+ end
811
+
812
+ it "returns the query" do
813
+ expect(selection).to eq(query)
814
+ end
815
+
816
+ it "returns a cloned query" do
817
+ expect(selection).to_not equal(query)
818
+ end
819
+ end
820
+
821
+ context "when provided nil" do
822
+
823
+ let(:selection) do
824
+ query.exists(nil)
825
+ end
826
+
827
+ it "does not add any criterion" do
828
+ expect(selection.selector).to eq({})
829
+ end
830
+
831
+ it "returns the query" do
832
+ expect(selection).to eq(query)
833
+ end
834
+
835
+ it "returns a cloned query" do
836
+ expect(selection).to_not equal(query)
837
+ end
838
+ end
839
+
840
+ context "when provided a criterion" do
841
+
842
+ context "when provided a boolean" do
843
+
844
+ let(:selection) do
845
+ query.exists(users: true)
846
+ end
847
+
848
+ it "adds the $exists expression" do
849
+ expect(selection.selector).to eq({
850
+ "users" => { "$exists" => true }
851
+ })
852
+ end
853
+
854
+ it "returns a cloned query" do
855
+ expect(selection).to_not equal(query)
856
+ end
857
+ end
858
+
859
+ context "when provided a string" do
860
+
861
+ let(:selection) do
862
+ query.exists(users: "yes")
863
+ end
864
+
865
+ it "adds the $exists expression" do
866
+ expect(selection.selector).to eq({
867
+ "users" => { "$exists" => true }
868
+ })
869
+ end
870
+
871
+ it "returns a cloned query" do
872
+ expect(selection).to_not equal(query)
873
+ end
874
+ end
875
+ end
876
+
877
+ context "when providing multiple criteria" do
878
+
879
+ context "when the fields differ" do
880
+
881
+ context "when providing boolean values" do
882
+
883
+ let(:selection) do
884
+ query.exists(
885
+ users: true,
886
+ comments: true
887
+ )
888
+ end
889
+
890
+ it "adds the $exists expression" do
891
+ expect(selection.selector).to eq({
892
+ "users" => { "$exists" => true },
893
+ "comments" => { "$exists" => true }
894
+ })
895
+ end
896
+
897
+ it "returns a cloned query" do
898
+ expect(selection).to_not equal(query)
899
+ end
900
+ end
901
+
902
+ context "when providing string values" do
903
+
904
+ let(:selection) do
905
+ query.exists(
906
+ users: "y",
907
+ comments: "true"
908
+ )
909
+ end
910
+
911
+ it "adds the $exists expression" do
912
+ expect(selection.selector).to eq({
913
+ "users" => { "$exists" => true },
914
+ "comments" => { "$exists" => true }
915
+ })
916
+ end
917
+
918
+ it "returns a cloned query" do
919
+ expect(selection).to_not equal(query)
920
+ end
921
+ end
922
+ end
923
+ end
924
+
925
+ context "when chaining multiple criteria" do
926
+
927
+ context "when the fields differ" do
928
+
929
+ let(:selection) do
930
+ query.
931
+ exists(users: true).
932
+ exists(comments: true)
933
+ end
934
+
935
+ it "adds the $exists expression" do
936
+ expect(selection.selector).to eq({
937
+ "users" => { "$exists" => true },
938
+ "comments" => { "$exists" => true }
939
+ })
940
+ end
941
+
942
+ it "returns a cloned query" do
943
+ expect(selection).to_not equal(query)
944
+ end
945
+ end
946
+ end
947
+ end
948
+
949
+ describe "#geo_spacial" do
950
+
951
+ context "when provided no criterion" do
952
+
953
+ let(:selection) do
954
+ query.geo_spacial
955
+ end
956
+
957
+ it "does not add any criterion" do
958
+ expect(selection.selector).to be_empty
959
+ end
960
+
961
+ it "returns the query" do
962
+ expect(selection).to eq(query)
963
+ end
964
+
965
+ it_behaves_like "a cloning selection"
966
+ end
967
+
968
+ context "when provided nil" do
969
+
970
+ let(:selection) do
971
+ query.geo_spacial(nil)
972
+ end
973
+
974
+ it "does not add any criterion" do
975
+ expect(selection.selector).to be_empty
976
+ end
977
+
978
+ it "returns the query" do
979
+ expect(selection).to eq(query)
980
+ end
981
+
982
+ it_behaves_like "a cloning selection"
983
+ end
984
+
985
+ context "when provided a criterion" do
986
+
987
+ context "when the geometry is a point intersection" do
988
+
989
+ let(:selection) do
990
+ query.geo_spacial(:location.intersects_point => [ 1, 10 ])
991
+ end
992
+
993
+ it "adds the $geoIntersects expression" do
994
+ expect(selection.selector).to eq({
995
+ "location" => {
996
+ "$geoIntersects" => {
997
+ "$geometry" => {
998
+ "type" => "Point",
999
+ "coordinates" => [ 1, 10 ]
1000
+ }
1001
+ }
1002
+ }
1003
+ })
1004
+ end
1005
+
1006
+ it_behaves_like "a cloning selection"
1007
+ end
1008
+
1009
+ context "when the geometry is a line intersection" do
1010
+
1011
+ let(:selection) do
1012
+ query.geo_spacial(:location.intersects_line => [[ 1, 10 ], [ 2, 10 ]])
1013
+ end
1014
+
1015
+ it "adds the $geoIntersects expression" do
1016
+ expect(selection.selector).to eq({
1017
+ "location" => {
1018
+ "$geoIntersects" => {
1019
+ "$geometry" => {
1020
+ "type" => "LineString",
1021
+ "coordinates" => [[ 1, 10 ], [ 2, 10 ]]
1022
+ }
1023
+ }
1024
+ }
1025
+ })
1026
+ end
1027
+
1028
+ it_behaves_like "a cloning selection"
1029
+ end
1030
+
1031
+ context "when the geometry is a polygon intersection" do
1032
+
1033
+ let(:selection) do
1034
+ query.geo_spacial(
1035
+ :location.intersects_polygon => [[[ 1, 10 ], [ 2, 10 ], [ 1, 10 ]]]
1036
+ )
1037
+ end
1038
+
1039
+ it "adds the $geoIntersects expression" do
1040
+ expect(selection.selector).to eq({
1041
+ "location" => {
1042
+ "$geoIntersects" => {
1043
+ "$geometry" => {
1044
+ "type" => "Polygon",
1045
+ "coordinates" => [[[ 1, 10 ], [ 2, 10 ], [ 1, 10 ]]]
1046
+ }
1047
+ }
1048
+ }
1049
+ })
1050
+ end
1051
+
1052
+ it_behaves_like "a cloning selection"
1053
+ end
1054
+
1055
+ context "when the geometry is within a polygon" do
1056
+
1057
+ let(:selection) do
1058
+ query.geo_spacial(
1059
+ :location.within_polygon => [[[ 1, 10 ], [ 2, 10 ], [ 1, 10 ]]]
1060
+ )
1061
+ end
1062
+
1063
+ it "adds the $geoIntersects expression" do
1064
+ expect(selection.selector).to eq({
1065
+ "location" => {
1066
+ "$geoWithin" => {
1067
+ "$geometry" => {
1068
+ "type" => "Polygon",
1069
+ "coordinates" => [[[ 1, 10 ], [ 2, 10 ], [ 1, 10 ]]]
1070
+ }
1071
+ }
1072
+ }
1073
+ })
1074
+ end
1075
+
1076
+ it_behaves_like "a cloning selection"
1077
+ end
1078
+ end
1079
+ end
1080
+
1081
+ describe "#gt" do
1082
+
1083
+ context "when provided no criterion" do
1084
+
1085
+ let(:selection) do
1086
+ query.gt
1087
+ end
1088
+
1089
+ it "does not add any criterion" do
1090
+ expect(selection.selector).to eq({})
1091
+ end
1092
+
1093
+ it "returns the query" do
1094
+ expect(selection).to eq(query)
1095
+ end
1096
+
1097
+ it "returns a cloned query" do
1098
+ expect(selection).to_not equal(query)
1099
+ end
1100
+ end
1101
+
1102
+ context "when provided nil" do
1103
+
1104
+ let(:selection) do
1105
+ query.gt(nil)
1106
+ end
1107
+
1108
+ it "does not add any criterion" do
1109
+ expect(selection.selector).to eq({})
1110
+ end
1111
+
1112
+ it "returns the query" do
1113
+ expect(selection).to eq(query)
1114
+ end
1115
+
1116
+ it "returns a cloned query" do
1117
+ expect(selection).to_not equal(query)
1118
+ end
1119
+ end
1120
+
1121
+ context "when provided a single criterion" do
1122
+
1123
+ let(:selection) do
1124
+ query.gt(field: 10)
1125
+ end
1126
+
1127
+ it "adds the $gt selector" do
1128
+ expect(selection.selector).to eq({
1129
+ "field" => { "$gt" => 10 }
1130
+ })
1131
+ end
1132
+
1133
+ it "returns a cloned query" do
1134
+ expect(selection).to_not equal(query)
1135
+ end
1136
+ end
1137
+
1138
+ context "when provided multiple criterion" do
1139
+
1140
+ context "when the criterion are for different fields" do
1141
+
1142
+ let(:selection) do
1143
+ query.gt(first: 10, second: 15)
1144
+ end
1145
+
1146
+ it "adds the $gt selectors" do
1147
+ expect(selection.selector).to eq({
1148
+ "first" => { "$gt" => 10 },
1149
+ "second" => { "$gt" => 15 }
1150
+ })
1151
+ end
1152
+
1153
+ it "returns a cloned query" do
1154
+ expect(selection).to_not equal(query)
1155
+ end
1156
+ end
1157
+ end
1158
+
1159
+ context "when chaining the criterion" do
1160
+
1161
+ context "when the criterion are for different fields" do
1162
+
1163
+ let(:selection) do
1164
+ query.gt(first: 10).gt(second: 15)
1165
+ end
1166
+
1167
+ it "adds the $gt selectors" do
1168
+ expect(selection.selector).to eq({
1169
+ "first" => { "$gt" => 10 },
1170
+ "second" => { "$gt" => 15 }
1171
+ })
1172
+ end
1173
+
1174
+ it "returns a cloned query" do
1175
+ expect(selection).to_not equal(query)
1176
+ end
1177
+ end
1178
+
1179
+ context "when the criterion are on the same field" do
1180
+
1181
+ let(:selection) do
1182
+ query.gt(first: 10).gt(first: 15)
1183
+ end
1184
+
1185
+ it "overwrites the first $gt selector" do
1186
+ expect(selection.selector).to eq({
1187
+ "first" => { "$gt" => 15 }
1188
+ })
1189
+ end
1190
+
1191
+ it "returns a cloned query" do
1192
+ expect(selection).to_not equal(query)
1193
+ end
1194
+ end
1195
+ end
1196
+ end
1197
+
1198
+ describe "#gte" do
1199
+
1200
+ context "when provided no criterion" do
1201
+
1202
+ let(:selection) do
1203
+ query.gte
1204
+ end
1205
+
1206
+ it "does not add any criterion" do
1207
+ expect(selection.selector).to eq({})
1208
+ end
1209
+
1210
+ it "returns the query" do
1211
+ expect(selection).to eq(query)
1212
+ end
1213
+
1214
+ it "returns a cloned query" do
1215
+ expect(selection).to_not equal(query)
1216
+ end
1217
+ end
1218
+
1219
+ context "when provided nil" do
1220
+
1221
+ let(:selection) do
1222
+ query.gte(nil)
1223
+ end
1224
+
1225
+ it "does not add any criterion" do
1226
+ expect(selection.selector).to eq({})
1227
+ end
1228
+
1229
+ it "returns the query" do
1230
+ expect(selection).to eq(query)
1231
+ end
1232
+
1233
+ it "returns a cloned query" do
1234
+ expect(selection).to_not equal(query)
1235
+ end
1236
+ end
1237
+
1238
+ context "when provided a single criterion" do
1239
+
1240
+ let(:selection) do
1241
+ query.gte(field: 10)
1242
+ end
1243
+
1244
+ it "adds the $gte selector" do
1245
+ expect(selection.selector).to eq({
1246
+ "field" => { "$gte" => 10 }
1247
+ })
1248
+ end
1249
+
1250
+ it "returns a cloned query" do
1251
+ expect(selection).to_not equal(query)
1252
+ end
1253
+ end
1254
+
1255
+ context "when provided multiple criterion" do
1256
+
1257
+ context "when the criterion are for different fields" do
1258
+
1259
+ let(:selection) do
1260
+ query.gte(first: 10, second: 15)
1261
+ end
1262
+
1263
+ it "adds the $gte selectors" do
1264
+ expect(selection.selector).to eq({
1265
+ "first" => { "$gte" => 10 },
1266
+ "second" => { "$gte" => 15 }
1267
+ })
1268
+ end
1269
+
1270
+ it "returns a cloned query" do
1271
+ expect(selection).to_not equal(query)
1272
+ end
1273
+ end
1274
+ end
1275
+
1276
+ context "when chaining the criterion" do
1277
+
1278
+ context "when the criterion are for different fields" do
1279
+
1280
+ let(:selection) do
1281
+ query.gte(first: 10).gte(second: 15)
1282
+ end
1283
+
1284
+ it "adds the $gte selectors" do
1285
+ expect(selection.selector).to eq({
1286
+ "first" => { "$gte" => 10 },
1287
+ "second" => { "$gte" => 15 }
1288
+ })
1289
+ end
1290
+
1291
+ it "returns a cloned query" do
1292
+ expect(selection).to_not equal(query)
1293
+ end
1294
+ end
1295
+
1296
+ context "when the criterion are on the same field" do
1297
+
1298
+ let(:selection) do
1299
+ query.gte(first: 10).gte(first: 15)
1300
+ end
1301
+
1302
+ it "overwrites the first $gte selector" do
1303
+ expect(selection.selector).to eq({
1304
+ "first" => { "$gte" => 15 }
1305
+ })
1306
+ end
1307
+
1308
+ it "returns a cloned query" do
1309
+ expect(selection).to_not equal(query)
1310
+ end
1311
+ end
1312
+ end
1313
+ end
1314
+
1315
+ describe "#in" do
1316
+
1317
+ context "when provided no criterion" do
1318
+
1319
+ let(:selection) do
1320
+ query.in
1321
+ end
1322
+
1323
+ it "does not add any criterion" do
1324
+ expect(selection.selector).to eq({})
1325
+ end
1326
+
1327
+ it "returns the query" do
1328
+ expect(selection).to eq(query)
1329
+ end
1330
+
1331
+ it "returns a cloned query" do
1332
+ expect(selection).to_not equal(query)
1333
+ end
1334
+ end
1335
+
1336
+ context "when provided nil" do
1337
+
1338
+ let(:selection) do
1339
+ query.in(nil)
1340
+ end
1341
+
1342
+ it "does not add any criterion" do
1343
+ expect(selection.selector).to eq({})
1344
+ end
1345
+
1346
+ it "returns the query" do
1347
+ expect(selection).to eq(query)
1348
+ end
1349
+
1350
+ it "returns a cloned query" do
1351
+ expect(selection).to_not equal(query)
1352
+ end
1353
+ end
1354
+
1355
+ context "when provided a single criterion" do
1356
+
1357
+ context "when providing an array" do
1358
+
1359
+ let(:selection) do
1360
+ query.in(field: [ 1, 2 ])
1361
+ end
1362
+
1363
+ it "adds the $in selector" do
1364
+ expect(selection.selector).to eq({
1365
+ "field" => { "$in" => [ 1, 2 ] }
1366
+ })
1367
+ end
1368
+
1369
+ it "returns a cloned query" do
1370
+ expect(selection).to_not equal(query)
1371
+ end
1372
+ end
1373
+
1374
+ context "when providing a range" do
1375
+
1376
+ let(:selection) do
1377
+ query.in(field: 1..3)
1378
+ end
1379
+
1380
+ it "adds the $in selector with converted range" do
1381
+ expect(selection.selector).to eq({
1382
+ "field" => { "$in" => [ 1, 2, 3 ] }
1383
+ })
1384
+ end
1385
+
1386
+ it "returns a cloned query" do
1387
+ expect(selection).to_not equal(query)
1388
+ end
1389
+ end
1390
+
1391
+ context "when providing a single value" do
1392
+
1393
+ let(:selection) do
1394
+ query.in(field: 1)
1395
+ end
1396
+
1397
+ it "adds the $in selector with wrapped value" do
1398
+ expect(selection.selector).to eq({
1399
+ "field" => { "$in" => [ 1 ] }
1400
+ })
1401
+ end
1402
+
1403
+ it "returns a cloned query" do
1404
+ expect(selection).to_not equal(query)
1405
+ end
1406
+ end
1407
+ end
1408
+
1409
+ context "when provided multiple criterion" do
1410
+
1411
+ context "when the criterion are for different fields" do
1412
+
1413
+ let(:selection) do
1414
+ query.in(first: [ 1, 2 ], second: 3..4)
1415
+ end
1416
+
1417
+ it "adds the $in selectors" do
1418
+ expect(selection.selector).to eq({
1419
+ "first" => { "$in" => [ 1, 2 ] },
1420
+ "second" => { "$in" => [ 3, 4 ] }
1421
+ })
1422
+ end
1423
+
1424
+ it "returns a cloned query" do
1425
+ expect(selection).to_not equal(query)
1426
+ end
1427
+ end
1428
+ end
1429
+
1430
+ context "when chaining the criterion" do
1431
+
1432
+ context "when the criterion are for different fields" do
1433
+
1434
+ let(:selection) do
1435
+ query.in(first: [ 1, 2 ]).in(second: [ 3, 4 ])
1436
+ end
1437
+
1438
+ it "adds the $in selectors" do
1439
+ expect(selection.selector).to eq({
1440
+ "first" => { "$in" => [ 1, 2 ] },
1441
+ "second" => { "$in" => [ 3, 4 ] }
1442
+ })
1443
+ end
1444
+
1445
+ it "returns a cloned query" do
1446
+ expect(selection).to_not equal(query)
1447
+ end
1448
+ end
1449
+
1450
+ context "when the criterion are on the same field" do
1451
+
1452
+ context "when the stretegy is the default (intersection)" do
1453
+
1454
+ let(:selection) do
1455
+ query.in(first: [ 1, 2 ].freeze).in(first: [ 2, 3 ])
1456
+ end
1457
+
1458
+ it "intersects the $in selectors" do
1459
+ expect(selection.selector).to eq({
1460
+ "first" => { "$in" => [ 2 ] }
1461
+ })
1462
+ end
1463
+
1464
+ it "returns a cloned query" do
1465
+ expect(selection).to_not equal(query)
1466
+ end
1467
+ end
1468
+
1469
+ context "when the stretegy is intersect" do
1470
+
1471
+ let(:selection) do
1472
+ query.in(first: [ 1, 2 ]).intersect.in(first: [ 2, 3 ])
1473
+ end
1474
+
1475
+ it "intersects the $in selectors" do
1476
+ expect(selection.selector).to eq({
1477
+ "first" => { "$in" => [ 2 ] }
1478
+ })
1479
+ end
1480
+
1481
+ it "returns a cloned query" do
1482
+ expect(selection).to_not equal(query)
1483
+ end
1484
+ end
1485
+
1486
+ context "when the stretegy is override" do
1487
+
1488
+ let(:selection) do
1489
+ query.in(first: [ 1, 2 ]).override.in(first: [ 3, 4 ])
1490
+ end
1491
+
1492
+ it "overwrites the first $in selector" do
1493
+ expect(selection.selector).to eq({
1494
+ "first" => { "$in" => [ 3, 4 ] }
1495
+ })
1496
+ end
1497
+
1498
+ it "returns a cloned query" do
1499
+ expect(selection).to_not equal(query)
1500
+ end
1501
+ end
1502
+
1503
+ context "when the stretegy is union" do
1504
+
1505
+ let(:selection) do
1506
+ query.in(first: [ 1, 2 ]).union.in(first: [ 3, 4 ])
1507
+ end
1508
+
1509
+ it "unions the $in selectors" do
1510
+ expect(selection.selector).to eq({
1511
+ "first" => { "$in" => [ 1, 2, 3, 4 ] }
1512
+ })
1513
+ end
1514
+
1515
+ it "returns a cloned query" do
1516
+ expect(selection).to_not equal(query)
1517
+ end
1518
+ end
1519
+ end
1520
+ end
1521
+ end
1522
+
1523
+ describe "#lt" do
1524
+
1525
+ context "when provided no criterion" do
1526
+
1527
+ let(:selection) do
1528
+ query.lt
1529
+ end
1530
+
1531
+ it "does not add any criterion" do
1532
+ expect(selection.selector).to eq({})
1533
+ end
1534
+
1535
+ it "returns the query" do
1536
+ expect(selection).to eq(query)
1537
+ end
1538
+
1539
+ it "returns a cloned query" do
1540
+ expect(selection).to_not equal(query)
1541
+ end
1542
+ end
1543
+
1544
+ context "when provided nil" do
1545
+
1546
+ let(:selection) do
1547
+ query.lt(nil)
1548
+ end
1549
+
1550
+ it "does not add any criterion" do
1551
+ expect(selection.selector).to eq({})
1552
+ end
1553
+
1554
+ it "returns the query" do
1555
+ expect(selection).to eq(query)
1556
+ end
1557
+
1558
+ it "returns a cloned query" do
1559
+ expect(selection).to_not equal(query)
1560
+ end
1561
+ end
1562
+
1563
+ context "when provided a single criterion" do
1564
+
1565
+ let(:selection) do
1566
+ query.lt(field: 10)
1567
+ end
1568
+
1569
+ it "adds the $lt selector" do
1570
+ expect(selection.selector).to eq({
1571
+ "field" => { "$lt" => 10 }
1572
+ })
1573
+ end
1574
+
1575
+ it "returns a cloned query" do
1576
+ expect(selection).to_not equal(query)
1577
+ end
1578
+ end
1579
+
1580
+ context "when provided multiple criterion" do
1581
+
1582
+ context "when the criterion are for different fields" do
1583
+
1584
+ let(:selection) do
1585
+ query.lt(first: 10, second: 15)
1586
+ end
1587
+
1588
+ it "adds the $lt selectors" do
1589
+ expect(selection.selector).to eq({
1590
+ "first" => { "$lt" => 10 },
1591
+ "second" => { "$lt" => 15 }
1592
+ })
1593
+ end
1594
+
1595
+ it "returns a cloned query" do
1596
+ expect(selection).to_not equal(query)
1597
+ end
1598
+ end
1599
+ end
1600
+
1601
+ context "when chaining the criterion" do
1602
+
1603
+ context "when the criterion are for different fields" do
1604
+
1605
+ let(:selection) do
1606
+ query.lt(first: 10).lt(second: 15)
1607
+ end
1608
+
1609
+ it "adds the $lt selectors" do
1610
+ expect(selection.selector).to eq({
1611
+ "first" => { "$lt" => 10 },
1612
+ "second" => { "$lt" => 15 }
1613
+ })
1614
+ end
1615
+
1616
+ it "returns a cloned query" do
1617
+ expect(selection).to_not equal(query)
1618
+ end
1619
+ end
1620
+
1621
+ context "when the criterion are on the same field" do
1622
+
1623
+ let(:selection) do
1624
+ query.lt(first: 10).lt(first: 15)
1625
+ end
1626
+
1627
+ it "overwrites the first $lt selector" do
1628
+ expect(selection.selector).to eq({
1629
+ "first" => { "$lt" => 15 }
1630
+ })
1631
+ end
1632
+
1633
+ it "returns a cloned query" do
1634
+ expect(selection).to_not equal(query)
1635
+ end
1636
+ end
1637
+ end
1638
+ end
1639
+
1640
+ describe "#lte" do
1641
+
1642
+ context "when provided no criterion" do
1643
+
1644
+ let(:selection) do
1645
+ query.lte
1646
+ end
1647
+
1648
+ it "does not add any criterion" do
1649
+ expect(selection.selector).to eq({})
1650
+ end
1651
+
1652
+ it "returns the query" do
1653
+ expect(selection).to eq(query)
1654
+ end
1655
+
1656
+ it "returns a cloned query" do
1657
+ expect(selection).to_not equal(query)
1658
+ end
1659
+ end
1660
+
1661
+ context "when provided nil" do
1662
+
1663
+ let(:selection) do
1664
+ query.lte(nil)
1665
+ end
1666
+
1667
+ it "does not add any criterion" do
1668
+ expect(selection.selector).to eq({})
1669
+ end
1670
+
1671
+ it "returns the query" do
1672
+ expect(selection).to eq(query)
1673
+ end
1674
+
1675
+ it "returns a cloned query" do
1676
+ expect(selection).to_not equal(query)
1677
+ end
1678
+ end
1679
+
1680
+ context "when provided a single criterion" do
1681
+
1682
+ let(:selection) do
1683
+ query.lte(field: 10)
1684
+ end
1685
+
1686
+ it "adds the $lte selector" do
1687
+ expect(selection.selector).to eq({
1688
+ "field" => { "$lte" => 10 }
1689
+ })
1690
+ end
1691
+
1692
+ it "returns a cloned query" do
1693
+ expect(selection).to_not equal(query)
1694
+ end
1695
+ end
1696
+
1697
+ context "when provided multiple criterion" do
1698
+
1699
+ context "when the criterion are for different fields" do
1700
+
1701
+ let(:selection) do
1702
+ query.lte(first: 10, second: 15)
1703
+ end
1704
+
1705
+ it "adds the $lte selectors" do
1706
+ expect(selection.selector).to eq({
1707
+ "first" => { "$lte" => 10 },
1708
+ "second" => { "$lte" => 15 }
1709
+ })
1710
+ end
1711
+
1712
+ it "returns a cloned query" do
1713
+ expect(selection).to_not equal(query)
1714
+ end
1715
+ end
1716
+ end
1717
+
1718
+ context "when chaining the criterion" do
1719
+
1720
+ context "when the criterion are for different fields" do
1721
+
1722
+ let(:selection) do
1723
+ query.lte(first: 10).lte(second: 15)
1724
+ end
1725
+
1726
+ it "adds the $lte selectors" do
1727
+ expect(selection.selector).to eq({
1728
+ "first" => { "$lte" => 10 },
1729
+ "second" => { "$lte" => 15 }
1730
+ })
1731
+ end
1732
+
1733
+ it "returns a cloned query" do
1734
+ expect(selection).to_not equal(query)
1735
+ end
1736
+ end
1737
+
1738
+ context "when the criterion are on the same field" do
1739
+
1740
+ let(:selection) do
1741
+ query.lte(first: 10).lte(first: 15)
1742
+ end
1743
+
1744
+ it "overwrites the first $lte selector" do
1745
+ expect(selection.selector).to eq({
1746
+ "first" => { "$lte" => 15 }
1747
+ })
1748
+ end
1749
+
1750
+ it "returns a cloned query" do
1751
+ expect(selection).to_not equal(query)
1752
+ end
1753
+ end
1754
+ end
1755
+ end
1756
+
1757
+ describe "#max_distance" do
1758
+
1759
+ context "when provided no criterion" do
1760
+
1761
+ let(:selection) do
1762
+ query.max_distance
1763
+ end
1764
+
1765
+ it "does not add any criterion" do
1766
+ expect(selection.selector).to eq({})
1767
+ end
1768
+
1769
+ it "returns the query" do
1770
+ expect(selection).to eq(query)
1771
+ end
1772
+
1773
+ it "returns a cloned query" do
1774
+ expect(selection).to_not equal(query)
1775
+ end
1776
+ end
1777
+
1778
+ context "when provided nil" do
1779
+
1780
+ let(:selection) do
1781
+ query.max_distance(nil)
1782
+ end
1783
+
1784
+ it "does not add any criterion" do
1785
+ expect(selection.selector).to eq({})
1786
+ end
1787
+
1788
+ it "returns the query" do
1789
+ expect(selection).to eq(query)
1790
+ end
1791
+
1792
+ it "returns a cloned query" do
1793
+ expect(selection).to_not equal(query)
1794
+ end
1795
+ end
1796
+
1797
+ context "when provided a criterion" do
1798
+
1799
+ context "when a $near criterion exists on the same field" do
1800
+
1801
+ let(:selection) do
1802
+ query.near(location: [ 1, 1 ]).max_distance(location: 50)
1803
+ end
1804
+
1805
+ it "adds the $maxDistance expression" do
1806
+ expect(selection.selector).to eq({
1807
+ "location" => { "$near" => [ 1, 1 ], "$maxDistance" => 50 }
1808
+ })
1809
+ end
1810
+
1811
+ it "returns a cloned query" do
1812
+ expect(selection).to_not equal(query)
1813
+ end
1814
+ end
1815
+ end
1816
+ end
1817
+
1818
+ describe "#mod" do
1819
+
1820
+ context "when provided no criterion" do
1821
+
1822
+ let(:selection) do
1823
+ query.mod
1824
+ end
1825
+
1826
+ it "does not add any criterion" do
1827
+ expect(selection.selector).to eq({})
1828
+ end
1829
+
1830
+ it "returns the query" do
1831
+ expect(selection).to eq(query)
1832
+ end
1833
+
1834
+ it "returns a cloned query" do
1835
+ expect(selection).to_not equal(query)
1836
+ end
1837
+ end
1838
+
1839
+ context "when provided nil" do
1840
+
1841
+ let(:selection) do
1842
+ query.mod(nil)
1843
+ end
1844
+
1845
+ it "does not add any criterion" do
1846
+ expect(selection.selector).to eq({})
1847
+ end
1848
+
1849
+ it "returns the query" do
1850
+ expect(selection).to eq(query)
1851
+ end
1852
+
1853
+ it "returns a cloned query" do
1854
+ expect(selection).to_not equal(query)
1855
+ end
1856
+ end
1857
+
1858
+ context "when provided a criterion" do
1859
+
1860
+ let(:selection) do
1861
+ query.mod(value: [ 10, 1 ])
1862
+ end
1863
+
1864
+ it "adds the $mod expression" do
1865
+ expect(selection.selector).to eq({
1866
+ "value" => { "$mod" => [ 10, 1 ] }
1867
+ })
1868
+ end
1869
+
1870
+ it "returns a cloned query" do
1871
+ expect(selection).to_not equal(query)
1872
+ end
1873
+ end
1874
+
1875
+ context "when providing multiple criteria" do
1876
+
1877
+ context "when the fields differ" do
1878
+
1879
+ let(:selection) do
1880
+ query.mod(
1881
+ value: [ 10, 1 ],
1882
+ comments: [ 10, 1 ]
1883
+ )
1884
+ end
1885
+
1886
+ it "adds the $mod expression" do
1887
+ expect(selection.selector).to eq({
1888
+ "value" => { "$mod" => [ 10, 1 ] },
1889
+ "comments" => { "$mod" => [ 10, 1 ] }
1890
+ })
1891
+ end
1892
+
1893
+ it "returns a cloned query" do
1894
+ expect(selection).to_not equal(query)
1895
+ end
1896
+ end
1897
+ end
1898
+
1899
+ context "when chaining multiple criteria" do
1900
+
1901
+ context "when the fields differ" do
1902
+
1903
+ let(:selection) do
1904
+ query.
1905
+ mod(value: [ 10, 1 ]).
1906
+ mod(result: [ 10, 1 ])
1907
+ end
1908
+
1909
+ it "adds the $mod expression" do
1910
+ expect(selection.selector).to eq({
1911
+ "value" => { "$mod" => [ 10, 1 ] },
1912
+ "result" => { "$mod" => [ 10, 1 ] }
1913
+ })
1914
+ end
1915
+
1916
+ it "returns a cloned query" do
1917
+ expect(selection).to_not equal(query)
1918
+ end
1919
+ end
1920
+ end
1921
+ end
1922
+
1923
+ describe "#ne" do
1924
+
1925
+ context "when provided no criterion" do
1926
+
1927
+ let(:selection) do
1928
+ query.ne
1929
+ end
1930
+
1931
+ it "does not add any criterion" do
1932
+ expect(selection.selector).to eq({})
1933
+ end
1934
+
1935
+ it "returns the query" do
1936
+ expect(selection).to eq(query)
1937
+ end
1938
+
1939
+ it "returns a cloned query" do
1940
+ expect(selection).to_not equal(query)
1941
+ end
1942
+ end
1943
+
1944
+ context "when provided nil" do
1945
+
1946
+ let(:selection) do
1947
+ query.ne(nil)
1948
+ end
1949
+
1950
+ it "does not add any criterion" do
1951
+ expect(selection.selector).to eq({})
1952
+ end
1953
+
1954
+ it "returns the query" do
1955
+ expect(selection).to eq(query)
1956
+ end
1957
+
1958
+ it "returns a cloned query" do
1959
+ expect(selection).to_not equal(query)
1960
+ end
1961
+ end
1962
+
1963
+ context "when provided a criterion" do
1964
+
1965
+ let(:selection) do
1966
+ query.ne(value: 10)
1967
+ end
1968
+
1969
+ it "adds the $ne expression" do
1970
+ expect(selection.selector).to eq({
1971
+ "value" => { "$ne" => 10 }
1972
+ })
1973
+ end
1974
+
1975
+ it "returns a cloned query" do
1976
+ expect(selection).to_not equal(query)
1977
+ end
1978
+ end
1979
+
1980
+ context "when providing multiple criteria" do
1981
+
1982
+ context "when the fields differ" do
1983
+
1984
+ let(:selection) do
1985
+ query.ne(
1986
+ value: 10,
1987
+ comments: 10
1988
+ )
1989
+ end
1990
+
1991
+ it "adds the $ne expression" do
1992
+ expect(selection.selector).to eq({
1993
+ "value" => { "$ne" => 10 },
1994
+ "comments" => { "$ne" => 10 }
1995
+ })
1996
+ end
1997
+
1998
+ it "returns a cloned query" do
1999
+ expect(selection).to_not equal(query)
2000
+ end
2001
+ end
2002
+ end
2003
+
2004
+ context "when chaining multiple criteria" do
2005
+
2006
+ context "when the fields differ" do
2007
+
2008
+ let(:selection) do
2009
+ query.
2010
+ ne(value: 10).
2011
+ ne(result: 10)
2012
+ end
2013
+
2014
+ it "adds the $ne expression" do
2015
+ expect(selection.selector).to eq({
2016
+ "value" => { "$ne" => 10 },
2017
+ "result" => { "$ne" => 10 }
2018
+ })
2019
+ end
2020
+
2021
+ it "returns a cloned query" do
2022
+ expect(selection).to_not equal(query)
2023
+ end
2024
+ end
2025
+ end
2026
+ end
2027
+
2028
+ describe "#near" do
2029
+
2030
+ context "when provided no criterion" do
2031
+
2032
+ let(:selection) do
2033
+ query.near
2034
+ end
2035
+
2036
+ it "does not add any criterion" do
2037
+ expect(selection.selector).to eq({})
2038
+ end
2039
+
2040
+ it "returns the query" do
2041
+ expect(selection).to eq(query)
2042
+ end
2043
+
2044
+ it "returns a cloned query" do
2045
+ expect(selection).to_not equal(query)
2046
+ end
2047
+ end
2048
+
2049
+ context "when provided nil" do
2050
+
2051
+ let(:selection) do
2052
+ query.near(nil)
2053
+ end
2054
+
2055
+ it "does not add any criterion" do
2056
+ expect(selection.selector).to eq({})
2057
+ end
2058
+
2059
+ it "returns the query" do
2060
+ expect(selection).to eq(query)
2061
+ end
2062
+
2063
+ it "returns a cloned query" do
2064
+ expect(selection).to_not equal(query)
2065
+ end
2066
+ end
2067
+
2068
+ context "when provided a criterion" do
2069
+
2070
+ let(:selection) do
2071
+ query.near(location: [ 20, 21 ])
2072
+ end
2073
+
2074
+ it "adds the $near expression" do
2075
+ expect(selection.selector).to eq({
2076
+ "location" => { "$near" => [ 20, 21 ] }
2077
+ })
2078
+ end
2079
+
2080
+ it "returns a cloned query" do
2081
+ expect(selection).to_not equal(query)
2082
+ end
2083
+ end
2084
+
2085
+ context "when providing multiple criteria" do
2086
+
2087
+ context "when the fields differ" do
2088
+
2089
+ let(:selection) do
2090
+ query.near(
2091
+ location: [ 20, 21 ],
2092
+ comments: [ 20, 21 ]
2093
+ )
2094
+ end
2095
+
2096
+ it "adds the $near expression" do
2097
+ expect(selection.selector).to eq({
2098
+ "location" => { "$near" => [ 20, 21 ] },
2099
+ "comments" => { "$near" => [ 20, 21 ] }
2100
+ })
2101
+ end
2102
+
2103
+ it "returns a cloned query" do
2104
+ expect(selection).to_not equal(query)
2105
+ end
2106
+ end
2107
+ end
2108
+
2109
+ context "when chaining multiple criteria" do
2110
+
2111
+ context "when the fields differ" do
2112
+
2113
+ let(:selection) do
2114
+ query.
2115
+ near(location: [ 20, 21 ]).
2116
+ near(comments: [ 20, 21 ])
2117
+ end
2118
+
2119
+ it "adds the $near expression" do
2120
+ expect(selection.selector).to eq({
2121
+ "location" => { "$near" => [ 20, 21 ] },
2122
+ "comments" => { "$near" => [ 20, 21 ] }
2123
+ })
2124
+ end
2125
+
2126
+ it "returns a cloned query" do
2127
+ expect(selection).to_not equal(query)
2128
+ end
2129
+ end
2130
+ end
2131
+ end
2132
+
2133
+ describe "#near_sphere" do
2134
+
2135
+ context "when provided no criterion" do
2136
+
2137
+ let(:selection) do
2138
+ query.near_sphere
2139
+ end
2140
+
2141
+ it "does not add any criterion" do
2142
+ expect(selection.selector).to eq({})
2143
+ end
2144
+
2145
+ it "returns the query" do
2146
+ expect(selection).to eq(query)
2147
+ end
2148
+
2149
+ it "returns a cloned query" do
2150
+ expect(selection).to_not equal(query)
2151
+ end
2152
+ end
2153
+
2154
+ context "when provided nil" do
2155
+
2156
+ let(:selection) do
2157
+ query.near_sphere(nil)
2158
+ end
2159
+
2160
+ it "does not add any criterion" do
2161
+ expect(selection.selector).to eq({})
2162
+ end
2163
+
2164
+ it "returns the query" do
2165
+ expect(selection).to eq(query)
2166
+ end
2167
+
2168
+ it "returns a cloned query" do
2169
+ expect(selection).to_not equal(query)
2170
+ end
2171
+ end
2172
+
2173
+ context "when provided a criterion" do
2174
+
2175
+ let(:selection) do
2176
+ query.near_sphere(location: [ 20, 21 ])
2177
+ end
2178
+
2179
+ it "adds the $nearSphere expression" do
2180
+ expect(selection.selector).to eq({
2181
+ "location" => { "$nearSphere" => [ 20, 21 ] }
2182
+ })
2183
+ end
2184
+
2185
+ it "returns a cloned query" do
2186
+ expect(selection).to_not equal(query)
2187
+ end
2188
+ end
2189
+
2190
+ context "when providing multiple criteria" do
2191
+
2192
+ context "when the fields differ" do
2193
+
2194
+ let(:selection) do
2195
+ query.near_sphere(
2196
+ location: [ 20, 21 ],
2197
+ comments: [ 20, 21 ]
2198
+ )
2199
+ end
2200
+
2201
+ it "adds the $nearSphere expression" do
2202
+ expect(selection.selector).to eq({
2203
+ "location" => { "$nearSphere" => [ 20, 21 ] },
2204
+ "comments" => { "$nearSphere" => [ 20, 21 ] }
2205
+ })
2206
+ end
2207
+
2208
+ it "returns a cloned query" do
2209
+ expect(selection).to_not equal(query)
2210
+ end
2211
+ end
2212
+ end
2213
+
2214
+ context "when chaining multiple criteria" do
2215
+
2216
+ context "when the fields differ" do
2217
+
2218
+ let(:selection) do
2219
+ query.
2220
+ near_sphere(location: [ 20, 21 ]).
2221
+ near_sphere(comments: [ 20, 21 ])
2222
+ end
2223
+
2224
+ it "adds the $nearSphere expression" do
2225
+ expect(selection.selector).to eq({
2226
+ "location" => { "$nearSphere" => [ 20, 21 ] },
2227
+ "comments" => { "$nearSphere" => [ 20, 21 ] }
2228
+ })
2229
+ end
2230
+
2231
+ it "returns a cloned query" do
2232
+ expect(selection).to_not equal(query)
2233
+ end
2234
+ end
2235
+ end
2236
+ end
2237
+
2238
+ describe "#nin" do
2239
+
2240
+ context "when provided no criterion" do
2241
+
2242
+ let(:selection) do
2243
+ query.nin
2244
+ end
2245
+
2246
+ it "does not add any criterion" do
2247
+ expect(selection.selector).to eq({})
2248
+ end
2249
+
2250
+ it "returns the query" do
2251
+ expect(selection).to eq(query)
2252
+ end
2253
+
2254
+ it "returns a cloned query" do
2255
+ expect(selection).to_not equal(query)
2256
+ end
2257
+ end
2258
+
2259
+ context "when provided nil" do
2260
+
2261
+ let(:selection) do
2262
+ query.nin(nil)
2263
+ end
2264
+
2265
+ it "does not add any criterion" do
2266
+ expect(selection.selector).to eq({})
2267
+ end
2268
+
2269
+ it "returns the query" do
2270
+ expect(selection).to eq(query)
2271
+ end
2272
+
2273
+ it "returns a cloned query" do
2274
+ expect(selection).to_not equal(query)
2275
+ end
2276
+ end
2277
+
2278
+ context "when provided a single criterion" do
2279
+
2280
+ context "when providing an array" do
2281
+
2282
+ let(:selection) do
2283
+ query.nin(field: [ 1, 2 ])
2284
+ end
2285
+
2286
+ it "adds the $nin selector" do
2287
+ expect(selection.selector).to eq({
2288
+ "field" => { "$nin" => [ 1, 2 ] }
2289
+ })
2290
+ end
2291
+
2292
+ it "returns a cloned query" do
2293
+ expect(selection).to_not equal(query)
2294
+ end
2295
+ end
2296
+
2297
+ context "when providing a range" do
2298
+
2299
+ let(:selection) do
2300
+ query.nin(field: 1..3)
2301
+ end
2302
+
2303
+ it "adds the $nin selector with converted range" do
2304
+ expect(selection.selector).to eq({
2305
+ "field" => { "$nin" => [ 1, 2, 3 ] }
2306
+ })
2307
+ end
2308
+
2309
+ it "returns a cloned query" do
2310
+ expect(selection).to_not equal(query)
2311
+ end
2312
+ end
2313
+
2314
+ context "when providing a single value" do
2315
+
2316
+ let(:selection) do
2317
+ query.nin(field: 1)
2318
+ end
2319
+
2320
+ it "adds the $nin selector with wrapped value" do
2321
+ expect(selection.selector).to eq({
2322
+ "field" => { "$nin" => [ 1 ] }
2323
+ })
2324
+ end
2325
+
2326
+ it "returns a cloned query" do
2327
+ expect(selection).to_not equal(query)
2328
+ end
2329
+ end
2330
+ end
2331
+
2332
+ context "when unioning on the same field" do
2333
+
2334
+ context "when the field is not aliased" do
2335
+
2336
+ let(:selection) do
2337
+ query.nin(first: [ 1, 2 ]).union.nin(first: [ 3, 4 ])
2338
+ end
2339
+
2340
+ it "unions the selection on the field" do
2341
+ expect(selection.selector).to eq(
2342
+ { "first" => { "$nin" => [ 1, 2, 3, 4 ]}}
2343
+ )
2344
+ end
2345
+ end
2346
+
2347
+ context "when the field is aliased" do
2348
+
2349
+ let(:selection) do
2350
+ query.nin(id: [ 1, 2 ]).union.nin(id: [ 3, 4 ])
2351
+ end
2352
+
2353
+ it "unions the selection on the field" do
2354
+ expect(selection.selector).to eq(
2355
+ { "_id" => { "$nin" => [ 1, 2, 3, 4 ]}}
2356
+ )
2357
+ end
2358
+ end
2359
+ end
2360
+
2361
+ context "when provided multiple criterion" do
2362
+
2363
+ context "when the criterion are for different fields" do
2364
+
2365
+ let(:selection) do
2366
+ query.nin(first: [ 1, 2 ], second: [ 3, 4 ])
2367
+ end
2368
+
2369
+ it "adds the $nin selectors" do
2370
+ expect(selection.selector).to eq({
2371
+ "first" => { "$nin" => [ 1, 2 ] },
2372
+ "second" => { "$nin" => [ 3, 4 ] }
2373
+ })
2374
+ end
2375
+
2376
+ it "returns a cloned query" do
2377
+ expect(selection).to_not equal(query)
2378
+ end
2379
+ end
2380
+ end
2381
+
2382
+ context "when chaninning the criterion" do
2383
+
2384
+ context "when the criterion are for different fields" do
2385
+
2386
+ let(:selection) do
2387
+ query.nin(first: [ 1, 2 ]).nin(second: [ 3, 4 ])
2388
+ end
2389
+
2390
+ it "adds the $nin selectors" do
2391
+ expect(selection.selector).to eq({
2392
+ "first" => { "$nin" => [ 1, 2 ] },
2393
+ "second" => { "$nin" => [ 3, 4 ] }
2394
+ })
2395
+ end
2396
+
2397
+ it "returns a cloned query" do
2398
+ expect(selection).to_not equal(query)
2399
+ end
2400
+ end
2401
+
2402
+ context "when the criterion are on the same field" do
2403
+
2404
+ context "when the stretegy is the default (intersection)" do
2405
+
2406
+ let(:selection) do
2407
+ query.nin(first: [ 1, 2 ]).nin(first: [ 2, 3 ])
2408
+ end
2409
+
2410
+ it "intersects the $nin selectors" do
2411
+ expect(selection.selector).to eq({
2412
+ "first" => { "$nin" => [ 2 ] }
2413
+ })
2414
+ end
2415
+
2416
+ it "returns a cloned query" do
2417
+ expect(selection).to_not equal(query)
2418
+ end
2419
+ end
2420
+
2421
+ context "when the stretegy is intersect" do
2422
+
2423
+ let(:selection) do
2424
+ query.nin(first: [ 1, 2 ]).intersect.nin(first: [ 2, 3 ])
2425
+ end
2426
+
2427
+ it "intersects the $nin selectors" do
2428
+ expect(selection.selector).to eq({
2429
+ "first" => { "$nin" => [ 2 ] }
2430
+ })
2431
+ end
2432
+
2433
+ it "returns a cloned query" do
2434
+ expect(selection).to_not equal(query)
2435
+ end
2436
+ end
2437
+
2438
+ context "when the stretegy is override" do
2439
+
2440
+ let(:selection) do
2441
+ query.nin(first: [ 1, 2 ]).override.nin(first: [ 3, 4 ])
2442
+ end
2443
+
2444
+ it "overwrites the first $nin selector" do
2445
+ expect(selection.selector).to eq({
2446
+ "first" => { "$nin" => [ 3, 4 ] }
2447
+ })
2448
+ end
2449
+
2450
+ it "returns a cloned query" do
2451
+ expect(selection).to_not equal(query)
2452
+ end
2453
+ end
2454
+
2455
+ context "when the stretegy is union" do
2456
+
2457
+ let(:selection) do
2458
+ query.nin(first: [ 1, 2 ]).union.nin(first: [ 3, 4 ])
2459
+ end
2460
+
2461
+ it "unions the $nin selectors" do
2462
+ expect(selection.selector).to eq({
2463
+ "first" => { "$nin" => [ 1, 2, 3, 4 ] }
2464
+ })
2465
+ end
2466
+
2467
+ it "returns a cloned query" do
2468
+ expect(selection).to_not equal(query)
2469
+ end
2470
+ end
2471
+ end
2472
+ end
2473
+ end
2474
+
2475
+ describe "#nor" do
2476
+
2477
+ context "when provided no criterion" do
2478
+
2479
+ let(:selection) do
2480
+ query.nor
2481
+ end
2482
+
2483
+ it "does not add any criterion" do
2484
+ expect(selection.selector).to eq({})
2485
+ end
2486
+
2487
+ it "returns the query" do
2488
+ expect(selection).to eq(query)
2489
+ end
2490
+
2491
+ it "returns a cloned query" do
2492
+ expect(selection).to_not equal(query)
2493
+ end
2494
+ end
2495
+
2496
+ context "when provided nil" do
2497
+
2498
+ let(:selection) do
2499
+ query.nor(nil)
2500
+ end
2501
+
2502
+ it "does not add any criterion" do
2503
+ expect(selection.selector).to eq({})
2504
+ end
2505
+
2506
+ it "returns the query" do
2507
+ expect(selection).to eq(query)
2508
+ end
2509
+
2510
+ it "returns a cloned query" do
2511
+ expect(selection).to_not equal(query)
2512
+ end
2513
+ end
2514
+
2515
+ context "when provided a single criterion" do
2516
+
2517
+ let(:selection) do
2518
+ query.nor(field: [ 1, 2 ])
2519
+ end
2520
+
2521
+ it "adds the $nor selector" do
2522
+ expect(selection.selector).to eq({
2523
+ "$nor" => [{"field" => [ 1, 2 ] }]
2524
+ })
2525
+ end
2526
+
2527
+ it "returns a cloned query" do
2528
+ expect(selection).to_not equal(query)
2529
+ end
2530
+ end
2531
+
2532
+ context "when provided multiple criterion" do
2533
+
2534
+ context "when the criterion are fnor different fields" do
2535
+
2536
+ let(:selection) do
2537
+ query.nor({ first: [ 1, 2 ] }, { second: [ 3, 4 ] })
2538
+ end
2539
+
2540
+ it "adds the $nor selector" do
2541
+ expect(selection.selector).to eq({
2542
+ "$nor" => [
2543
+ { "first" => [ 1, 2 ] },
2544
+ { "second" => [ 3, 4 ] }
2545
+ ]
2546
+ })
2547
+ end
2548
+
2549
+ it "returns a cloned query" do
2550
+ expect(selection).to_not equal(query)
2551
+ end
2552
+ end
2553
+
2554
+ context "when the criterion are on the same field" do
2555
+
2556
+ let(:selection) do
2557
+ query.nor({ first: [ 1, 2 ] }, { first: [ 3, 4 ] })
2558
+ end
2559
+
2560
+ it "appends both $nor expressions" do
2561
+ expect(selection.selector).to eq({
2562
+ "$nor" => [
2563
+ { "first" => [ 1, 2 ] },
2564
+ { "first" => [ 3, 4 ] }
2565
+ ]
2566
+ })
2567
+ end
2568
+
2569
+ it "returns a cloned query" do
2570
+ expect(selection).to_not equal(query)
2571
+ end
2572
+ end
2573
+ end
2574
+
2575
+ context "when chaining the criterion" do
2576
+
2577
+ context "when the criterion are fnor different fields" do
2578
+
2579
+ let(:selection) do
2580
+ query.nor(first: [ 1, 2 ]).nor(second: [ 3, 4 ])
2581
+ end
2582
+
2583
+ it "adds the $nor selectors" do
2584
+ expect(selection.selector).to eq({
2585
+ "$nor" => [
2586
+ { "first" => [ 1, 2 ] },
2587
+ { "second" => [ 3, 4 ] }
2588
+ ]
2589
+ })
2590
+ end
2591
+
2592
+ it "returns a cloned query" do
2593
+ expect(selection).to_not equal(query)
2594
+ end
2595
+ end
2596
+
2597
+ context "when the criterion are on the same field" do
2598
+
2599
+ let(:selection) do
2600
+ query.nor(first: [ 1, 2 ]).nor(first: [ 3, 4 ])
2601
+ end
2602
+
2603
+ it "appends both $nor expressions" do
2604
+ expect(selection.selector).to eq({
2605
+ "$nor" => [
2606
+ { "first" => [ 1, 2 ] },
2607
+ { "first" => [ 3, 4 ] }
2608
+ ]
2609
+ })
2610
+ end
2611
+
2612
+ it "returns a cloned query" do
2613
+ expect(selection).to_not equal(query)
2614
+ end
2615
+ end
2616
+ end
2617
+ end
2618
+
2619
+ describe "#not" do
2620
+
2621
+ context "when provided no criterion" do
2622
+
2623
+ let(:selection) do
2624
+ query.not
2625
+ end
2626
+
2627
+ it "does not add any criterion" do
2628
+ expect(selection.selector).to eq({})
2629
+ end
2630
+
2631
+ it "returns the query" do
2632
+ expect(selection).to eq(query)
2633
+ end
2634
+
2635
+ it "returns a non cloned query" do
2636
+ expect(selection).to equal(query)
2637
+ end
2638
+
2639
+ context "when the following criteria is a query method" do
2640
+
2641
+ let(:selection) do
2642
+ query.not.all(field: [ 1, 2 ])
2643
+ end
2644
+
2645
+ it "negates the all selection" do
2646
+ expect(selection.selector).to eq(
2647
+ { "field" => { "$not" => { "$all" => [ 1, 2 ] }}}
2648
+ )
2649
+ end
2650
+
2651
+ it "returns a cloned query" do
2652
+ expect(selection).to_not equal(query)
2653
+ end
2654
+
2655
+ it "removes the negation on the clone" do
2656
+ expect(selection).to_not be_negating
2657
+ end
2658
+ end
2659
+
2660
+ context "when the following criteria is a gt method" do
2661
+
2662
+ let(:selection) do
2663
+ query.not.gt(age: 50)
2664
+ end
2665
+
2666
+ it "negates the gt selection" do
2667
+ expect(selection.selector).to eq(
2668
+ { "age" => { "$not" => { "$gt" => 50 }}}
2669
+ )
2670
+ end
2671
+
2672
+ it "returns a coned query" do
2673
+ expect(selection).to_not eq(query)
2674
+ end
2675
+
2676
+ it "removes the negation on the clone" do
2677
+ expect(selection).to_not be_negating
2678
+ end
2679
+ end
2680
+
2681
+ context "when the following criteria is a where" do
2682
+
2683
+ let(:selection) do
2684
+ query.not.where(field: 1, :other.in => [ 1, 2 ])
2685
+ end
2686
+
2687
+ it "negates the selection with an operator" do
2688
+ expect(selection.selector).to eq(
2689
+ { "field" => { "$ne" => 1 }, "other" => { "$not" => { "$in" => [ 1, 2 ] }}}
2690
+ )
2691
+ end
2692
+
2693
+ it "returns a cloned query" do
2694
+ expect(selection).to_not equal(query)
2695
+ end
2696
+
2697
+ it "removes the negation on the clone" do
2698
+ expect(selection).to_not be_negating
2699
+ end
2700
+ end
2701
+
2702
+ context "when the following criteria is a where with a regexp" do
2703
+
2704
+ let(:selection) do
2705
+ query.not.where(field: 1, other: /test/)
2706
+ end
2707
+
2708
+ it "negates the selection with an operator" do
2709
+ expect(selection.selector).to eq(
2710
+ { "field" => { "$ne" => 1 }, "other" => { "$not" => /test/ } }
2711
+ )
2712
+ end
2713
+
2714
+ it "returns a cloned query" do
2715
+ expect(selection).to_not equal(query)
2716
+ end
2717
+
2718
+ it "removes the negation on the clone" do
2719
+ expect(selection).to_not be_negating
2720
+ end
2721
+
2722
+ end
2723
+ end
2724
+
2725
+ context "when provided nil" do
2726
+
2727
+ let(:selection) do
2728
+ query.not(nil)
2729
+ end
2730
+
2731
+ it "does not add any criterion" do
2732
+ expect(selection.selector).to eq({})
2733
+ end
2734
+
2735
+ it "returns the query" do
2736
+ expect(selection).to eq(query)
2737
+ end
2738
+
2739
+ it "returns a cloned query" do
2740
+ expect(selection).to_not equal(query)
2741
+ end
2742
+ end
2743
+
2744
+ context "when provided a single criterion" do
2745
+
2746
+ let(:selection) do
2747
+ query.not(field: /test/)
2748
+ end
2749
+
2750
+ it "adds the $not selector" do
2751
+ expect(selection.selector).to eq({
2752
+ "field" => { "$not" => /test/ }
2753
+ })
2754
+ end
2755
+
2756
+ it "returns a cloned query" do
2757
+ expect(selection).to_not equal(query)
2758
+ end
2759
+ end
2760
+
2761
+ context "when provided multiple criterion" do
2762
+
2763
+ context "when the criterion are for different fields" do
2764
+
2765
+ let(:selection) do
2766
+ query.not(first: /1/, second: /2/)
2767
+ end
2768
+
2769
+ it "adds the $not selectors" do
2770
+ expect(selection.selector).to eq({
2771
+ "first" => { "$not" => /1/ },
2772
+ "second" => { "$not" => /2/ }
2773
+ })
2774
+ end
2775
+
2776
+ it "returns a cloned query" do
2777
+ expect(selection).to_not equal(query)
2778
+ end
2779
+ end
2780
+ end
2781
+
2782
+ context "when chaining the criterion" do
2783
+
2784
+ context "when the criterion are for different fields" do
2785
+
2786
+ let(:selection) do
2787
+ query.not(first: /1/).not(second: /2/)
2788
+ end
2789
+
2790
+ it "adds the $not selectors" do
2791
+ expect(selection.selector).to eq({
2792
+ "first" => { "$not" => /1/ },
2793
+ "second" => { "$not" => /2/ }
2794
+ })
2795
+ end
2796
+
2797
+ it "returns a cloned query" do
2798
+ expect(selection).to_not equal(query)
2799
+ end
2800
+ end
2801
+
2802
+ context "when the criterion are on the same field" do
2803
+
2804
+ let(:selection) do
2805
+ query.not(first: /1/).not(first: /2/)
2806
+ end
2807
+
2808
+ it "overwrites the first $not selector" do
2809
+ expect(selection.selector).to eq({
2810
+ "first" => { "$not" => /2/ }
2811
+ })
2812
+ end
2813
+
2814
+ it "returns a cloned query" do
2815
+ expect(selection).to_not equal(query)
2816
+ end
2817
+ end
2818
+
2819
+ context "when the criterion are a double negative" do
2820
+
2821
+ let(:selection) do
2822
+ query.not.where(:first.not => /1/)
2823
+ end
2824
+
2825
+ it "does not double the $not selector" do
2826
+ expect(selection.selector).to eq({
2827
+ "first" => { "$not" => /1/ }
2828
+ })
2829
+ end
2830
+
2831
+ it "returns a cloned query" do
2832
+ expect(selection).to_not equal(query)
2833
+ end
2834
+ end
2835
+ end
2836
+ end
2837
+
2838
+ describe "#or" do
2839
+
2840
+ context "when provided no criterion" do
2841
+
2842
+ let(:selection) do
2843
+ query.or
2844
+ end
2845
+
2846
+ it "does not add any criterion" do
2847
+ expect(selection.selector).to eq({})
2848
+ end
2849
+
2850
+ it "returns the query" do
2851
+ expect(selection).to eq(query)
2852
+ end
2853
+
2854
+ it "returns a cloned query" do
2855
+ expect(selection).to_not equal(query)
2856
+ end
2857
+ end
2858
+
2859
+ context "when provided nil" do
2860
+
2861
+ let(:selection) do
2862
+ query.or(nil)
2863
+ end
2864
+
2865
+ it "does not add any criterion" do
2866
+ expect(selection.selector).to eq({})
2867
+ end
2868
+
2869
+ it "returns the query" do
2870
+ expect(selection).to eq(query)
2871
+ end
2872
+
2873
+ it "returns a cloned query" do
2874
+ expect(selection).to_not equal(query)
2875
+ end
2876
+ end
2877
+
2878
+ context "when provided a single criterion" do
2879
+
2880
+ let(:selection) do
2881
+ query.or(field: [ 1, 2 ])
2882
+ end
2883
+
2884
+ it "adds the $or selector" do
2885
+ expect(selection.selector).to eq({
2886
+ "$or" => [{ "field" => [ 1, 2 ] }]
2887
+ })
2888
+ end
2889
+
2890
+ it "returns a cloned query" do
2891
+ expect(selection).to_not equal(query)
2892
+ end
2893
+ end
2894
+
2895
+ context "when provided multiple criterion" do
2896
+
2897
+ context "when the criterion are for different fields" do
2898
+
2899
+ let(:selection) do
2900
+ query.or({ first: [ 1, 2 ] }, { second: [ 3, 4 ] })
2901
+ end
2902
+
2903
+ it "adds the $or selector" do
2904
+ expect(selection.selector).to eq({
2905
+ "$or" => [
2906
+ { "first" => [ 1, 2 ] },
2907
+ { "second" => [ 3, 4 ] }
2908
+ ]
2909
+ })
2910
+ end
2911
+
2912
+ it "returns a cloned query" do
2913
+ expect(selection).to_not equal(query)
2914
+ end
2915
+ end
2916
+
2917
+ context "when a criterion has a selectable key" do
2918
+
2919
+ let(:selection) do
2920
+ query.or({ first: [ 1, 2 ] }, { :second.gt => 3 })
2921
+ end
2922
+
2923
+ it "adds the $or selector" do
2924
+ expect(selection.selector).to eq({
2925
+ "$or" => [
2926
+ { "first" => [ 1, 2 ] },
2927
+ { "second" => { "$gt" => 3 }}
2928
+ ]
2929
+ })
2930
+ end
2931
+
2932
+ it "returns a cloned query" do
2933
+ expect(selection).to_not equal(query)
2934
+ end
2935
+ end
2936
+
2937
+ context "when the criterion has an aliased field" do
2938
+
2939
+ let(:selection) do
2940
+ query.or({ id: 1 })
2941
+ end
2942
+
2943
+ it "adds the $or selector and aliases the field" do
2944
+ expect(selection.selector).to eq({
2945
+ "$or" => [ { "_id" => 1 } ]
2946
+ })
2947
+ end
2948
+
2949
+ it "returns a cloned query" do
2950
+ expect(selection).to_not equal(query)
2951
+ end
2952
+ end
2953
+
2954
+ context "when a criterion is wrapped in an array" do
2955
+
2956
+ let(:selection) do
2957
+ query.or([{ first: [ 1, 2 ] }, { :second.gt => 3 }])
2958
+ end
2959
+
2960
+ it "adds the $or selector" do
2961
+ expect(selection.selector).to eq({
2962
+ "$or" => [
2963
+ { "first" => [ 1, 2 ] },
2964
+ { "second" => { "$gt" => 3 }}
2965
+ ]
2966
+ })
2967
+ end
2968
+
2969
+ it "returns a cloned query" do
2970
+ expect(selection).to_not equal(query)
2971
+ end
2972
+ end
2973
+
2974
+ context "when the criterion are on the same field" do
2975
+
2976
+ let(:selection) do
2977
+ query.or({ first: [ 1, 2 ] }, { first: [ 3, 4 ] })
2978
+ end
2979
+
2980
+ it "appends both $or expressions" do
2981
+ expect(selection.selector).to eq({
2982
+ "$or" => [
2983
+ { "first" => [ 1, 2 ] },
2984
+ { "first" => [ 3, 4 ] }
2985
+ ]
2986
+ })
2987
+ end
2988
+
2989
+ it "returns a cloned query" do
2990
+ expect(selection).to_not equal(query)
2991
+ end
2992
+ end
2993
+ end
2994
+
2995
+ context "when chaining the criterion" do
2996
+
2997
+ context "when the criterion are for different fields" do
2998
+
2999
+ let(:selection) do
3000
+ query.or(first: [ 1, 2 ]).or(second: [ 3, 4 ])
3001
+ end
3002
+
3003
+ it "adds the $or selectors" do
3004
+ expect(selection.selector).to eq({
3005
+ "$or" => [
3006
+ { "first" => [ 1, 2 ] },
3007
+ { "second" => [ 3, 4 ] }
3008
+ ]
3009
+ })
3010
+ end
3011
+
3012
+ it "returns a cloned query" do
3013
+ expect(selection).to_not equal(query)
3014
+ end
3015
+ end
3016
+
3017
+ context "when the criterion are on the same field" do
3018
+
3019
+ let(:selection) do
3020
+ query.or(first: [ 1, 2 ]).or(first: [ 3, 4 ])
3021
+ end
3022
+
3023
+ it "appends both $or expressions" do
3024
+ expect(selection.selector).to eq({
3025
+ "$or" => [
3026
+ { "first" => [ 1, 2 ] },
3027
+ { "first" => [ 3, 4 ] }
3028
+ ]
3029
+ })
3030
+ end
3031
+
3032
+ it "returns a cloned query" do
3033
+ expect(selection).to_not equal(query)
3034
+ end
3035
+ end
3036
+ end
3037
+ end
3038
+
3039
+ describe "#with_size" do
3040
+
3041
+ context "when provided no criterion" do
3042
+
3043
+ let(:selection) do
3044
+ query.with_size
3045
+ end
3046
+
3047
+ it "does not add any criterion" do
3048
+ expect(selection.selector).to eq({})
3049
+ end
3050
+
3051
+ it "returns the query" do
3052
+ expect(selection).to eq(query)
3053
+ end
3054
+
3055
+ it "returns a cloned query" do
3056
+ expect(selection).to_not equal(query)
3057
+ end
3058
+ end
3059
+
3060
+ context "when provided nil" do
3061
+
3062
+ let(:selection) do
3063
+ query.with_size(nil)
3064
+ end
3065
+
3066
+ it "does not add any criterion" do
3067
+ expect(selection.selector).to eq({})
3068
+ end
3069
+
3070
+ it "returns the query" do
3071
+ expect(selection).to eq(query)
3072
+ end
3073
+
3074
+ it "returns a cloned query" do
3075
+ expect(selection).to_not equal(query)
3076
+ end
3077
+ end
3078
+
3079
+ context "when provided a single criterion" do
3080
+
3081
+ context "when provided an integer" do
3082
+
3083
+ let(:selection) do
3084
+ query.with_size(field: 10)
3085
+ end
3086
+
3087
+ it "adds the $size selector" do
3088
+ expect(selection.selector).to eq({
3089
+ "field" => { "$size" => 10 }
3090
+ })
3091
+ end
3092
+
3093
+ it "returns a cloned query" do
3094
+ expect(selection).to_not equal(query)
3095
+ end
3096
+ end
3097
+
3098
+ context "when provided a string" do
3099
+
3100
+ let(:selection) do
3101
+ query.with_size(field: "10")
3102
+ end
3103
+
3104
+ it "adds the $size selector with an integer" do
3105
+ expect(selection.selector).to eq({
3106
+ "field" => { "$size" => 10 }
3107
+ })
3108
+ end
3109
+
3110
+ it "returns a cloned query" do
3111
+ expect(selection).to_not equal(query)
3112
+ end
3113
+ end
3114
+ end
3115
+
3116
+ context "when provided multiple criterion" do
3117
+
3118
+ context "when the criterion are for different fields" do
3119
+
3120
+ context "when provided integers" do
3121
+
3122
+ let(:selection) do
3123
+ query.with_size(first: 10, second: 15)
3124
+ end
3125
+
3126
+ it "adds the $size selectors" do
3127
+ expect(selection.selector).to eq({
3128
+ "first" => { "$size" => 10 },
3129
+ "second" => { "$size" => 15 }
3130
+ })
3131
+ end
3132
+
3133
+ it "returns a cloned query" do
3134
+ expect(selection).to_not equal(query)
3135
+ end
3136
+ end
3137
+
3138
+ context "when provided strings" do
3139
+
3140
+ let(:selection) do
3141
+ query.with_size(first: "10", second: "15")
3142
+ end
3143
+
3144
+ it "adds the $size selectors" do
3145
+ expect(selection.selector).to eq({
3146
+ "first" => { "$size" => 10 },
3147
+ "second" => { "$size" => 15 }
3148
+ })
3149
+ end
3150
+
3151
+ it "returns a cloned query" do
3152
+ expect(selection).to_not equal(query)
3153
+ end
3154
+ end
3155
+ end
3156
+ end
3157
+
3158
+ context "when chaining the criterion" do
3159
+
3160
+ context "when the criterion are for different fields" do
3161
+
3162
+ let(:selection) do
3163
+ query.with_size(first: 10).with_size(second: 15)
3164
+ end
3165
+
3166
+ it "adds the $size selectors" do
3167
+ expect(selection.selector).to eq({
3168
+ "first" => { "$size" => 10 },
3169
+ "second" => { "$size" => 15 }
3170
+ })
3171
+ end
3172
+
3173
+ it "returns a cloned query" do
3174
+ expect(selection).to_not equal(query)
3175
+ end
3176
+ end
3177
+
3178
+ context "when the criterion are on the same field" do
3179
+
3180
+ let(:selection) do
3181
+ query.with_size(first: 10).with_size(first: 15)
3182
+ end
3183
+
3184
+ it "overwrites the first $size selector" do
3185
+ expect(selection.selector).to eq({
3186
+ "first" => { "$size" => 15 }
3187
+ })
3188
+ end
3189
+
3190
+ it "returns a cloned query" do
3191
+ expect(selection).to_not equal(query)
3192
+ end
3193
+ end
3194
+ end
3195
+ end
3196
+
3197
+ describe "#type" do
3198
+
3199
+ context "when provided no criterion" do
3200
+
3201
+ let(:selection) do
3202
+ query.with_type
3203
+ end
3204
+
3205
+ it "does not add any criterion" do
3206
+ expect(selection.selector).to eq({})
3207
+ end
3208
+
3209
+ it "returns the query" do
3210
+ expect(selection).to eq(query)
3211
+ end
3212
+
3213
+ it "returns a cloned query" do
3214
+ expect(selection).to_not equal(query)
3215
+ end
3216
+ end
3217
+
3218
+ context "when provided nil" do
3219
+
3220
+ let(:selection) do
3221
+ query.with_type(nil)
3222
+ end
3223
+
3224
+ it "does not add any criterion" do
3225
+ expect(selection.selector).to eq({})
3226
+ end
3227
+
3228
+ it "returns the query" do
3229
+ expect(selection).to eq(query)
3230
+ end
3231
+
3232
+ it "returns a cloned query" do
3233
+ expect(selection).to_not equal(query)
3234
+ end
3235
+ end
3236
+
3237
+ context "when provided a single criterion" do
3238
+
3239
+ context "when provided an integer" do
3240
+
3241
+ let(:selection) do
3242
+ query.with_type(field: 10)
3243
+ end
3244
+
3245
+ it "adds the $type selector" do
3246
+ expect(selection.selector).to eq({
3247
+ "field" => { "$type" => 10 }
3248
+ })
3249
+ end
3250
+
3251
+ it "returns a cloned query" do
3252
+ expect(selection).to_not equal(query)
3253
+ end
3254
+ end
3255
+
3256
+ context "when provided a string" do
3257
+
3258
+ let(:selection) do
3259
+ query.with_type(field: "10")
3260
+ end
3261
+
3262
+ it "adds the $type selector" do
3263
+ expect(selection.selector).to eq({
3264
+ "field" => { "$type" => 10 }
3265
+ })
3266
+ end
3267
+
3268
+ it "returns a cloned query" do
3269
+ expect(selection).to_not equal(query)
3270
+ end
3271
+ end
3272
+ end
3273
+
3274
+ context "when provided multiple criterion" do
3275
+
3276
+ context "when the criterion are for different fields" do
3277
+
3278
+ let(:selection) do
3279
+ query.with_type(first: 10, second: 15)
3280
+ end
3281
+
3282
+ it "adds the $type selectors" do
3283
+ expect(selection.selector).to eq({
3284
+ "first" => { "$type" => 10 },
3285
+ "second" => { "$type" => 15 }
3286
+ })
3287
+ end
3288
+
3289
+ it "returns a cloned query" do
3290
+ expect(selection).to_not equal(query)
3291
+ end
3292
+ end
3293
+ end
3294
+
3295
+ context "when chaining the criterion" do
3296
+
3297
+ context "when the criterion are for different fields" do
3298
+
3299
+ let(:selection) do
3300
+ query.with_type(first: 10).with_type(second: 15)
3301
+ end
3302
+
3303
+ it "adds the $type selectors" do
3304
+ expect(selection.selector).to eq({
3305
+ "first" => { "$type" => 10 },
3306
+ "second" => { "$type" => 15 }
3307
+ })
3308
+ end
3309
+
3310
+ it "returns a cloned query" do
3311
+ expect(selection).to_not equal(query)
3312
+ end
3313
+ end
3314
+
3315
+ context "when the criterion are on the same field" do
3316
+
3317
+ let(:selection) do
3318
+ query.with_type(first: 10).with_type(first: 15)
3319
+ end
3320
+
3321
+ it "overwrites the first $type selector" do
3322
+ expect(selection.selector).to eq({
3323
+ "first" => { "$type" => 15 }
3324
+ })
3325
+ end
3326
+
3327
+ it "returns a cloned query" do
3328
+ expect(selection).to_not equal(query)
3329
+ end
3330
+ end
3331
+ end
3332
+ end
3333
+
3334
+ describe "#text_search" do
3335
+
3336
+ context "when providing a search string" do
3337
+
3338
+ let(:selection) do
3339
+ query.text_search("testing")
3340
+ end
3341
+
3342
+ it "constructs a text search document" do
3343
+ expect(selection.selector).to eq({ :$text => { :$search => "testing" }})
3344
+ end
3345
+
3346
+ it "returns the cloned selectable" do
3347
+ expect(selection).to be_a(Mongoid::Criteria::Queryable::Selectable)
3348
+ end
3349
+
3350
+ context "when providing text search options" do
3351
+
3352
+ let(:selection) do
3353
+ query.text_search("essais", { :$language => "fr" })
3354
+ end
3355
+
3356
+ it "constructs a text search document" do
3357
+ expect(selection.selector[:$text][:$search]).to eq("essais")
3358
+ end
3359
+
3360
+ it "add the options to the text search document" do
3361
+ expect(selection.selector[:$text][:$language]).to eq("fr")
3362
+ end
3363
+
3364
+ it_behaves_like "a cloning selection"
3365
+ end
3366
+ end
3367
+ end
3368
+
3369
+ describe "#where" do
3370
+
3371
+ context "when provided no criterion" do
3372
+
3373
+ let(:selection) do
3374
+ query.where
3375
+ end
3376
+
3377
+ it "does not add any criterion" do
3378
+ expect(selection.selector).to eq({})
3379
+ end
3380
+
3381
+ it "returns the query" do
3382
+ expect(selection).to eq(query)
3383
+ end
3384
+
3385
+ it "returns a cloned query" do
3386
+ expect(selection).to_not equal(query)
3387
+ end
3388
+ end
3389
+
3390
+ context "when provided nil" do
3391
+
3392
+ let(:selection) do
3393
+ query.where(nil)
3394
+ end
3395
+
3396
+ it "does not add any criterion" do
3397
+ expect(selection.selector).to eq({})
3398
+ end
3399
+
3400
+ it "returns the query" do
3401
+ expect(selection).to eq(query)
3402
+ end
3403
+
3404
+ it "returns a cloned query" do
3405
+ expect(selection).to_not equal(query)
3406
+ end
3407
+ end
3408
+
3409
+ context "when provided a string" do
3410
+
3411
+ let(:selection) do
3412
+ query.where("this.value = 10")
3413
+ end
3414
+
3415
+ it "adds the $where criterion" do
3416
+ expect(selection.selector).to eq({ "$where" => "this.value = 10" })
3417
+ end
3418
+
3419
+ it "returns a cloned query" do
3420
+ expect(selection).to_not equal(query)
3421
+ end
3422
+ end
3423
+
3424
+ context "when provided a single criterion" do
3425
+
3426
+ context "when the value needs no evolution" do
3427
+
3428
+ let(:selection) do
3429
+ query.where(name: "Syd")
3430
+ end
3431
+
3432
+ it "adds the criterion to the selection" do
3433
+ expect(selection.selector).to eq({ "name" => "Syd" })
3434
+ end
3435
+ end
3436
+
3437
+ context "when the value must be evolved" do
3438
+
3439
+ before(:all) do
3440
+ class Document
3441
+ def id
3442
+ 13
3443
+ end
3444
+ def self.evolve(object)
3445
+ object.id
3446
+ end
3447
+ end
3448
+ end
3449
+
3450
+ after(:all) do
3451
+ Object.send(:remove_const, :Document)
3452
+ end
3453
+
3454
+ context "when the key needs evolution" do
3455
+
3456
+ let(:query) do
3457
+ Mongoid::Query.new({ "user" => "user_id" })
3458
+ end
3459
+
3460
+ let(:document) do
3461
+ Document.new
3462
+ end
3463
+
3464
+ let(:selection) do
3465
+ query.where(user: document)
3466
+ end
3467
+
3468
+ it "alters the key and value" do
3469
+ expect(selection.selector).to eq({ "user_id" => document.id })
3470
+ end
3471
+ end
3472
+
3473
+ context 'when the field is a String and the value is a BSON::Regexp::Raw' do
3474
+
3475
+ let(:raw_regexp) do
3476
+ BSON::Regexp::Raw.new('^Em')
3477
+ end
3478
+
3479
+ let(:selection) do
3480
+ Login.where(_id: raw_regexp)
3481
+ end
3482
+
3483
+ it 'does not convert the bson raw regexp object to a String' do
3484
+ expect(selection.selector).to eq({ "_id" => raw_regexp })
3485
+ end
3486
+ end
3487
+ end
3488
+ end
3489
+
3490
+ context "when provided complex criterion" do
3491
+
3492
+ context "when performing an $all" do
3493
+
3494
+ context "when performing a single query" do
3495
+
3496
+ let(:selection) do
3497
+ query.where(:field.all => [ 1, 2 ])
3498
+ end
3499
+
3500
+ it "adds the $all criterion" do
3501
+ expect(selection.selector).to eq({ "field" => { "$all" => [ 1, 2 ] }})
3502
+ end
3503
+
3504
+ it "returns a cloned query" do
3505
+ expect(selection).to_not eq(query)
3506
+ end
3507
+ end
3508
+ end
3509
+
3510
+ context "when performing an $elemMatch" do
3511
+
3512
+ context "when the value is not complex" do
3513
+
3514
+ let(:selection) do
3515
+ query.where(:field.elem_match => { key: 1 })
3516
+ end
3517
+
3518
+ it "adds the $elemMatch criterion" do
3519
+ expect(selection.selector).to eq(
3520
+ { "field" => { "$elemMatch" => { key: 1 } }}
3521
+ )
3522
+ end
3523
+
3524
+ it "returns a cloned query" do
3525
+ expect(selection).to_not eq(query)
3526
+ end
3527
+ end
3528
+
3529
+ context "when the value is complex" do
3530
+
3531
+ let(:selection) do
3532
+ query.where(:field.elem_match => { :key.gt => 1 })
3533
+ end
3534
+
3535
+ it "adds the $elemMatch criterion" do
3536
+ expect(selection.selector).to eq(
3537
+ { "field" => { "$elemMatch" => { "key" => { "$gt" => 1 }}}}
3538
+ )
3539
+ end
3540
+
3541
+ it "returns a cloned query" do
3542
+ expect(selection).to_not eq(query)
3543
+ end
3544
+ end
3545
+ end
3546
+
3547
+ context "when performing an $exists" do
3548
+
3549
+ context "when providing boolean values" do
3550
+
3551
+ let(:selection) do
3552
+ query.where(:field.exists => true)
3553
+ end
3554
+
3555
+ it "adds the $exists criterion" do
3556
+ expect(selection.selector).to eq(
3557
+ { "field" => { "$exists" => true }}
3558
+ )
3559
+ end
3560
+
3561
+ it "returns a cloned query" do
3562
+ expect(selection).to_not eq(query)
3563
+ end
3564
+ end
3565
+
3566
+ context "when providing string values" do
3567
+
3568
+ let(:selection) do
3569
+ query.where(:field.exists => "t")
3570
+ end
3571
+
3572
+ it "adds the $exists criterion" do
3573
+ expect(selection.selector).to eq(
3574
+ { "field" => { "$exists" => true }}
3575
+ )
3576
+ end
3577
+
3578
+ it "returns a cloned query" do
3579
+ expect(selection).to_not eq(query)
3580
+ end
3581
+ end
3582
+ end
3583
+
3584
+ context "when performing a $gt" do
3585
+
3586
+ let(:selection) do
3587
+ query.where(:field.gt => 10)
3588
+ end
3589
+
3590
+ it "adds the $gt criterion" do
3591
+ expect(selection.selector).to eq(
3592
+ { "field" => { "$gt" => 10 }}
3593
+ )
3594
+ end
3595
+
3596
+ it "returns a cloned query" do
3597
+ expect(selection).to_not eq(query)
3598
+ end
3599
+ end
3600
+
3601
+ context "when performing a $gte" do
3602
+
3603
+ let(:selection) do
3604
+ query.where(:field.gte => 10)
3605
+ end
3606
+
3607
+ it "adds the $gte criterion" do
3608
+ expect(selection.selector).to eq(
3609
+ { "field" => { "$gte" => 10 }}
3610
+ )
3611
+ end
3612
+
3613
+ it "returns a cloned query" do
3614
+ expect(selection).to_not eq(query)
3615
+ end
3616
+ end
3617
+
3618
+ context "when performing an $in" do
3619
+
3620
+ let(:selection) do
3621
+ query.where(:field.in => [ 1, 2 ])
3622
+ end
3623
+
3624
+ it "adds the $in criterion" do
3625
+ expect(selection.selector).to eq({ "field" => { "$in" => [ 1, 2 ] }})
3626
+ end
3627
+
3628
+ it "returns a cloned query" do
3629
+ expect(selection).to_not eq(query)
3630
+ end
3631
+ end
3632
+
3633
+ context "when performing a $lt" do
3634
+
3635
+ let(:selection) do
3636
+ query.where(:field.lt => 10)
3637
+ end
3638
+
3639
+ it "adds the $lt criterion" do
3640
+ expect(selection.selector).to eq(
3641
+ { "field" => { "$lt" => 10 }}
3642
+ )
3643
+ end
3644
+
3645
+ it "returns a cloned query" do
3646
+ expect(selection).to_not eq(query)
3647
+ end
3648
+ end
3649
+
3650
+ context "when performing a $lte" do
3651
+
3652
+ let(:selection) do
3653
+ query.where(:field.lte => 10)
3654
+ end
3655
+
3656
+ it "adds the $lte criterion" do
3657
+ expect(selection.selector).to eq(
3658
+ { "field" => { "$lte" => 10 }}
3659
+ )
3660
+ end
3661
+
3662
+ it "returns a cloned query" do
3663
+ expect(selection).to_not eq(query)
3664
+ end
3665
+ end
3666
+
3667
+ context "when performing a $mod" do
3668
+
3669
+ let(:selection) do
3670
+ query.where(:field.mod => [ 10, 1 ])
3671
+ end
3672
+
3673
+ it "adds the $lte criterion" do
3674
+ expect(selection.selector).to eq(
3675
+ { "field" => { "$mod" => [ 10, 1 ]}}
3676
+ )
3677
+ end
3678
+
3679
+ it "returns a cloned query" do
3680
+ expect(selection).to_not eq(query)
3681
+ end
3682
+ end
3683
+
3684
+ context "when performing a $ne" do
3685
+
3686
+ let(:selection) do
3687
+ query.where(:field.ne => 10)
3688
+ end
3689
+
3690
+ it "adds the $ne criterion" do
3691
+ expect(selection.selector).to eq(
3692
+ { "field" => { "$ne" => 10 }}
3693
+ )
3694
+ end
3695
+
3696
+ it "returns a cloned query" do
3697
+ expect(selection).to_not eq(query)
3698
+ end
3699
+ end
3700
+
3701
+ context "when performing a $near" do
3702
+
3703
+ let(:selection) do
3704
+ query.where(:field.near => [ 1, 1 ])
3705
+ end
3706
+
3707
+ it "adds the $near criterion" do
3708
+ expect(selection.selector).to eq(
3709
+ { "field" => { "$near" => [ 1, 1 ] }}
3710
+ )
3711
+ end
3712
+
3713
+ it "returns a cloned query" do
3714
+ expect(selection).to_not eq(query)
3715
+ end
3716
+ end
3717
+
3718
+ context "when performing a $nearSphere" do
3719
+
3720
+ let(:selection) do
3721
+ query.where(:field.near_sphere => [ 1, 1 ])
3722
+ end
3723
+
3724
+ it "adds the $nearSphere criterion" do
3725
+ expect(selection.selector).to eq(
3726
+ { "field" => { "$nearSphere" => [ 1, 1 ] }}
3727
+ )
3728
+ end
3729
+
3730
+ it "returns a cloned query" do
3731
+ expect(selection).to_not eq(query)
3732
+ end
3733
+ end
3734
+
3735
+ context "when performing a $nin" do
3736
+
3737
+ let(:selection) do
3738
+ query.where(:field.nin => [ 1, 2 ])
3739
+ end
3740
+
3741
+ it "adds the $nin criterion" do
3742
+ expect(selection.selector).to eq({ "field" => { "$nin" => [ 1, 2 ] }})
3743
+ end
3744
+
3745
+ it "returns a cloned query" do
3746
+ expect(selection).to_not eq(query)
3747
+ end
3748
+ end
3749
+
3750
+ context "when performing a $not" do
3751
+
3752
+ let(:selection) do
3753
+ query.where(:field.not => /test/)
3754
+ end
3755
+
3756
+ it "adds the $not criterion" do
3757
+ expect(selection.selector).to eq({ "field" => { "$not" => /test/ }})
3758
+ end
3759
+
3760
+ it "returns a cloned query" do
3761
+ expect(selection).to_not eq(query)
3762
+ end
3763
+ end
3764
+
3765
+ context "when performing a $size" do
3766
+
3767
+ context "when providing an integer" do
3768
+
3769
+ let(:selection) do
3770
+ query.where(:field.with_size => 10)
3771
+ end
3772
+
3773
+ it "adds the $size criterion" do
3774
+ expect(selection.selector).to eq(
3775
+ { "field" => { "$size" => 10 }}
3776
+ )
3777
+ end
3778
+
3779
+ it "returns a cloned query" do
3780
+ expect(selection).to_not eq(query)
3781
+ end
3782
+ end
3783
+
3784
+ context "when providing a string" do
3785
+
3786
+ let(:selection) do
3787
+ query.where(:field.with_size => "10")
3788
+ end
3789
+
3790
+ it "adds the $size criterion" do
3791
+ expect(selection.selector).to eq(
3792
+ { "field" => { "$size" => 10 }}
3793
+ )
3794
+ end
3795
+
3796
+ it "returns a cloned query" do
3797
+ expect(selection).to_not eq(query)
3798
+ end
3799
+ end
3800
+ end
3801
+
3802
+ context "when performing a $type" do
3803
+
3804
+ let(:selection) do
3805
+ query.where(:field.with_type => 10)
3806
+ end
3807
+
3808
+ it "adds the $type criterion" do
3809
+ expect(selection.selector).to eq(
3810
+ { "field" => { "$type" => 10 }}
3811
+ )
3812
+ end
3813
+
3814
+ it "returns a cloned query" do
3815
+ expect(selection).to_not eq(query)
3816
+ end
3817
+ end
3818
+ end
3819
+ end
3820
+
3821
+ describe Symbol do
3822
+
3823
+ describe "#all" do
3824
+
3825
+ let(:key) do
3826
+ :field.all
3827
+ end
3828
+
3829
+ it "returns a selecton key" do
3830
+ expect(key).to be_a(Mongoid::Criteria::Queryable::Key)
3831
+ end
3832
+
3833
+ it "sets the name as the key" do
3834
+ expect(key.name).to eq(:field)
3835
+ end
3836
+
3837
+ it "sets the operator as $all" do
3838
+ expect(key.operator).to eq("$all")
3839
+ end
3840
+ end
3841
+
3842
+ describe "#elem_match" do
3843
+
3844
+ let(:key) do
3845
+ :field.elem_match
3846
+ end
3847
+
3848
+ it "returns a selecton key" do
3849
+ expect(key).to be_a(Mongoid::Criteria::Queryable::Key)
3850
+ end
3851
+
3852
+ it "sets the name as the key" do
3853
+ expect(key.name).to eq(:field)
3854
+ end
3855
+
3856
+ it "sets the operator as $elemMatch" do
3857
+ expect(key.operator).to eq("$elemMatch")
3858
+ end
3859
+ end
3860
+
3861
+ describe "#exists" do
3862
+
3863
+ let(:key) do
3864
+ :field.exists
3865
+ end
3866
+
3867
+ it "returns a selecton key" do
3868
+ expect(key).to be_a(Mongoid::Criteria::Queryable::Key)
3869
+ end
3870
+
3871
+ it "sets the name as the key" do
3872
+ expect(key.name).to eq(:field)
3873
+ end
3874
+
3875
+ it "sets the operator as $exists" do
3876
+ expect(key.operator).to eq("$exists")
3877
+ end
3878
+ end
3879
+
3880
+ describe "#gt" do
3881
+
3882
+ let(:key) do
3883
+ :field.gt
3884
+ end
3885
+
3886
+ it "returns a selecton key" do
3887
+ expect(key).to be_a(Mongoid::Criteria::Queryable::Key)
3888
+ end
3889
+
3890
+ it "sets the name as the key" do
3891
+ expect(key.name).to eq(:field)
3892
+ end
3893
+
3894
+ it "sets the operator as $gt" do
3895
+ expect(key.operator).to eq("$gt")
3896
+ end
3897
+ end
3898
+
3899
+ describe "#gte" do
3900
+
3901
+ let(:key) do
3902
+ :field.gte
3903
+ end
3904
+
3905
+ it "returns a selecton key" do
3906
+ expect(key).to be_a(Mongoid::Criteria::Queryable::Key)
3907
+ end
3908
+
3909
+ it "sets the name as the key" do
3910
+ expect(key.name).to eq(:field)
3911
+ end
3912
+
3913
+ it "sets the operator as $gte" do
3914
+ expect(key.operator).to eq("$gte")
3915
+ end
3916
+ end
3917
+
3918
+ describe "#in" do
3919
+
3920
+ let(:key) do
3921
+ :field.in
3922
+ end
3923
+
3924
+ it "returns a selecton key" do
3925
+ expect(key).to be_a(Mongoid::Criteria::Queryable::Key)
3926
+ end
3927
+
3928
+ it "sets the name as the key" do
3929
+ expect(key.name).to eq(:field)
3930
+ end
3931
+
3932
+ it "sets the operator as $in" do
3933
+ expect(key.operator).to eq("$in")
3934
+ end
3935
+ end
3936
+
3937
+ describe "#lt" do
3938
+
3939
+ let(:key) do
3940
+ :field.lt
3941
+ end
3942
+
3943
+ it "returns a selecton key" do
3944
+ expect(key).to be_a(Mongoid::Criteria::Queryable::Key)
3945
+ end
3946
+
3947
+ it "sets the name as the key" do
3948
+ expect(key.name).to eq(:field)
3949
+ end
3950
+
3951
+ it "sets the operator as $lt" do
3952
+ expect(key.operator).to eq("$lt")
3953
+ end
3954
+ end
3955
+
3956
+ describe "#lte" do
3957
+
3958
+ let(:key) do
3959
+ :field.lte
3960
+ end
3961
+
3962
+ it "returns a selecton key" do
3963
+ expect(key).to be_a(Mongoid::Criteria::Queryable::Key)
3964
+ end
3965
+
3966
+ it "sets the name as the key" do
3967
+ expect(key.name).to eq(:field)
3968
+ end
3969
+
3970
+ it "sets the operator as $lte" do
3971
+ expect(key.operator).to eq("$lte")
3972
+ end
3973
+ end
3974
+
3975
+ describe "#mod" do
3976
+
3977
+ let(:key) do
3978
+ :field.mod
3979
+ end
3980
+
3981
+ it "returns a selecton key" do
3982
+ expect(key).to be_a(Mongoid::Criteria::Queryable::Key)
3983
+ end
3984
+
3985
+ it "sets the name as the key" do
3986
+ expect(key.name).to eq(:field)
3987
+ end
3988
+
3989
+ it "sets the operator as $mod" do
3990
+ expect(key.operator).to eq("$mod")
3991
+ end
3992
+ end
3993
+
3994
+ describe "#ne" do
3995
+
3996
+ let(:key) do
3997
+ :field.ne
3998
+ end
3999
+
4000
+ it "returns a selecton key" do
4001
+ expect(key).to be_a(Mongoid::Criteria::Queryable::Key)
4002
+ end
4003
+
4004
+ it "sets the name as the key" do
4005
+ expect(key.name).to eq(:field)
4006
+ end
4007
+
4008
+ it "sets the operator as $ne" do
4009
+ expect(key.operator).to eq("$ne")
4010
+ end
4011
+ end
4012
+
4013
+ describe "#near" do
4014
+
4015
+ let(:key) do
4016
+ :field.near
4017
+ end
4018
+
4019
+ it "returns a selecton key" do
4020
+ expect(key).to be_a(Mongoid::Criteria::Queryable::Key)
4021
+ end
4022
+
4023
+ it "sets the name as the key" do
4024
+ expect(key.name).to eq(:field)
4025
+ end
4026
+
4027
+ it "sets the operator as $near" do
4028
+ expect(key.operator).to eq("$near")
4029
+ end
4030
+ end
4031
+
4032
+ describe "#near_sphere" do
4033
+
4034
+ let(:key) do
4035
+ :field.near_sphere
4036
+ end
4037
+
4038
+ it "returns a selecton key" do
4039
+ expect(key).to be_a(Mongoid::Criteria::Queryable::Key)
4040
+ end
4041
+
4042
+ it "sets the name as the key" do
4043
+ expect(key.name).to eq(:field)
4044
+ end
4045
+
4046
+ it "sets the operator as $nearSphere" do
4047
+ expect(key.operator).to eq("$nearSphere")
4048
+ end
4049
+ end
4050
+
4051
+ describe "#nin" do
4052
+
4053
+ let(:key) do
4054
+ :field.nin
4055
+ end
4056
+
4057
+ it "returns a selecton key" do
4058
+ expect(key).to be_a(Mongoid::Criteria::Queryable::Key)
4059
+ end
4060
+
4061
+ it "sets the name as the key" do
4062
+ expect(key.name).to eq(:field)
4063
+ end
4064
+
4065
+ it "sets the operator as $nin" do
4066
+ expect(key.operator).to eq("$nin")
4067
+ end
4068
+ end
4069
+
4070
+ describe "#not" do
4071
+
4072
+ let(:key) do
4073
+ :field.not
4074
+ end
4075
+
4076
+ it "returns a selection key" do
4077
+ expect(key).to be_a(Mongoid::Criteria::Queryable::Key)
4078
+ end
4079
+
4080
+ it "sets the name as the key" do
4081
+ expect(key.name).to eq(:field)
4082
+ end
4083
+
4084
+ it "sets the operator as $not" do
4085
+ expect(key.operator).to eq("$not")
4086
+ end
4087
+
4088
+ end
4089
+
4090
+ describe "#with_size" do
4091
+
4092
+ let(:key) do
4093
+ :field.with_size
4094
+ end
4095
+
4096
+ it "returns a selecton key" do
4097
+ expect(key).to be_a(Mongoid::Criteria::Queryable::Key)
4098
+ end
4099
+
4100
+ it "sets the name as the key" do
4101
+ expect(key.name).to eq(:field)
4102
+ end
4103
+
4104
+ it "sets the operator as $size" do
4105
+ expect(key.operator).to eq("$size")
4106
+ end
4107
+ end
4108
+
4109
+ describe "#with_type" do
4110
+
4111
+ let(:key) do
4112
+ :field.with_type
4113
+ end
4114
+
4115
+ it "returns a selecton key" do
4116
+ expect(key).to be_a(Mongoid::Criteria::Queryable::Key)
4117
+ end
4118
+
4119
+ it "sets the name as the key" do
4120
+ expect(key.name).to eq(:field)
4121
+ end
4122
+
4123
+ it "sets the operator as $type" do
4124
+ expect(key.operator).to eq("$type")
4125
+ end
4126
+ end
4127
+ end
4128
+
4129
+ context "when using multiple strategies on the same field" do
4130
+
4131
+ context "when using the strategies via methods" do
4132
+
4133
+ context "when the values are a hash" do
4134
+
4135
+ let(:selection) do
4136
+ query.gt(field: 5).lt(field: 10).ne(field: 7)
4137
+ end
4138
+
4139
+ it "merges the strategies on the same field" do
4140
+ expect(selection.selector).to eq(
4141
+ { "field" => { "$gt" => 5, "$lt" => 10, "$ne" => 7 }}
4142
+ )
4143
+ end
4144
+ end
4145
+
4146
+ context "when the values are not hashes" do
4147
+
4148
+ let(:selection) do
4149
+ query.where(field: 5).where(field: 10)
4150
+ end
4151
+
4152
+ it "overrides the previous field" do
4153
+ expect(selection.selector).to eq({ "field" => 10 })
4154
+ end
4155
+ end
4156
+ end
4157
+
4158
+ context "when using the strategies via #where" do
4159
+
4160
+ context "when the values are a hash" do
4161
+
4162
+ let(:selection) do
4163
+ query.where(:field.gt => 5, :field.lt => 10, :field.ne => 7)
4164
+ end
4165
+
4166
+ it "merges the strategies on the same field" do
4167
+ expect(selection.selector).to eq(
4168
+ { "field" => { "$gt" => 5, "$lt" => 10, "$ne" => 7 }}
4169
+ )
4170
+ end
4171
+ end
4172
+ end
4173
+ end
4174
+ end