mongoid 5.4.1 → 6.0.0.beta

Sign up to get free protection for your applications and to get access to all the features.
Files changed (264) hide show
  1. checksums.yaml +5 -5
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/lib/config/locales/en.yml +23 -16
  5. data/lib/mongoid.rb +4 -9
  6. data/lib/mongoid/atomic.rb +1 -1
  7. data/lib/mongoid/atomic/modifiers.rb +8 -12
  8. data/lib/mongoid/attributes.rb +9 -11
  9. data/lib/mongoid/attributes/dynamic.rb +5 -6
  10. data/lib/mongoid/attributes/nested.rb +1 -1
  11. data/lib/mongoid/attributes/processing.rb +4 -0
  12. data/lib/mongoid/attributes/readonly.rb +22 -0
  13. data/lib/mongoid/cacheable.rb +36 -0
  14. data/lib/mongoid/changeable.rb +37 -1
  15. data/lib/mongoid/clients.rb +0 -63
  16. data/lib/mongoid/clients/factory.rb +0 -2
  17. data/lib/mongoid/clients/options.rb +54 -249
  18. data/lib/mongoid/clients/storage_options.rb +1 -69
  19. data/lib/mongoid/composable.rb +26 -2
  20. data/lib/mongoid/config.rb +1 -1
  21. data/lib/mongoid/config/options.rb +1 -1
  22. data/lib/mongoid/contextual/aggregable/mongo.rb +1 -0
  23. data/lib/mongoid/contextual/atomic.rb +6 -9
  24. data/lib/mongoid/contextual/geo_near.rb +2 -3
  25. data/lib/mongoid/contextual/map_reduce.rb +97 -24
  26. data/lib/mongoid/contextual/memory.rb +7 -4
  27. data/lib/mongoid/contextual/mongo.rb +63 -54
  28. data/lib/mongoid/contextual/none.rb +2 -2
  29. data/lib/mongoid/copyable.rb +19 -19
  30. data/lib/mongoid/criteria.rb +5 -4
  31. data/lib/mongoid/criteria/findable.rb +2 -3
  32. data/lib/mongoid/criteria/includable.rb +63 -16
  33. data/lib/mongoid/criteria/marshalable.rb +2 -2
  34. data/lib/mongoid/criteria/modifiable.rb +17 -1
  35. data/lib/mongoid/criteria/options.rb +25 -0
  36. data/lib/mongoid/criteria/queryable.rb +86 -0
  37. data/lib/mongoid/criteria/queryable/aggregable.rb +120 -0
  38. data/lib/mongoid/criteria/queryable/extensions.rb +28 -0
  39. data/lib/mongoid/criteria/queryable/extensions/array.rb +185 -0
  40. data/lib/mongoid/criteria/queryable/extensions/big_decimal.rb +37 -0
  41. data/lib/mongoid/criteria/queryable/extensions/boolean.rb +34 -0
  42. data/lib/mongoid/criteria/queryable/extensions/date.rb +63 -0
  43. data/lib/mongoid/criteria/queryable/extensions/date_time.rb +53 -0
  44. data/lib/mongoid/criteria/queryable/extensions/hash.rb +200 -0
  45. data/lib/mongoid/criteria/queryable/extensions/nil_class.rb +86 -0
  46. data/lib/mongoid/criteria/queryable/extensions/numeric.rb +90 -0
  47. data/lib/mongoid/criteria/queryable/extensions/object.rb +206 -0
  48. data/lib/mongoid/criteria/queryable/extensions/range.rb +70 -0
  49. data/lib/mongoid/criteria/queryable/extensions/regexp.rb +45 -0
  50. data/lib/mongoid/criteria/queryable/extensions/set.rb +34 -0
  51. data/lib/mongoid/criteria/queryable/extensions/string.rb +137 -0
  52. data/lib/mongoid/criteria/queryable/extensions/symbol.rb +79 -0
  53. data/lib/mongoid/criteria/queryable/extensions/time.rb +60 -0
  54. data/lib/mongoid/criteria/queryable/extensions/time_with_zone.rb +54 -0
  55. data/lib/mongoid/criteria/queryable/forwardable.rb +65 -0
  56. data/lib/mongoid/criteria/queryable/key.rb +103 -0
  57. data/lib/mongoid/criteria/queryable/macroable.rb +27 -0
  58. data/lib/mongoid/criteria/queryable/mergeable.rb +271 -0
  59. data/lib/mongoid/criteria/queryable/optional.rb +411 -0
  60. data/lib/mongoid/criteria/queryable/options.rb +136 -0
  61. data/lib/mongoid/criteria/queryable/pipeline.rb +111 -0
  62. data/lib/mongoid/criteria/queryable/selectable.rb +662 -0
  63. data/lib/mongoid/criteria/queryable/selector.rb +196 -0
  64. data/lib/mongoid/criteria/queryable/smash.rb +103 -0
  65. data/lib/mongoid/document.rb +9 -23
  66. data/lib/mongoid/errors.rb +2 -1
  67. data/lib/mongoid/errors/ambiguous_relationship.rb +1 -1
  68. data/lib/mongoid/errors/delete_restriction.rb +2 -2
  69. data/lib/mongoid/errors/invalid_field.rb +2 -2
  70. data/lib/mongoid/errors/invalid_persistence_option.rb +29 -0
  71. data/lib/mongoid/errors/invalid_relation.rb +66 -0
  72. data/lib/mongoid/errors/inverse_not_found.rb +1 -1
  73. data/lib/mongoid/errors/mongoid_error.rb +1 -1
  74. data/lib/mongoid/evolvable.rb +1 -1
  75. data/lib/mongoid/extensions.rb +0 -5
  76. data/lib/mongoid/extensions/big_decimal.rb +17 -8
  77. data/lib/mongoid/extensions/date.rb +4 -1
  78. data/lib/mongoid/extensions/hash.rb +2 -3
  79. data/lib/mongoid/extensions/object.rb +2 -2
  80. data/lib/mongoid/extensions/string.rb +4 -3
  81. data/lib/mongoid/extensions/time.rb +5 -2
  82. data/lib/mongoid/factory.rb +1 -0
  83. data/lib/mongoid/fields/foreign_key.rb +2 -2
  84. data/lib/mongoid/fields/localized.rb +3 -8
  85. data/lib/mongoid/fields/validators/macro.rb +18 -0
  86. data/lib/mongoid/findable.rb +3 -3
  87. data/lib/mongoid/indexable.rb +17 -16
  88. data/lib/mongoid/indexable/specification.rb +1 -1
  89. data/lib/mongoid/indexable/validators/options.rb +1 -2
  90. data/lib/mongoid/interceptable.rb +6 -17
  91. data/lib/mongoid/loggable.rb +1 -1
  92. data/lib/mongoid/matchable.rb +3 -10
  93. data/lib/mongoid/matchable/gt.rb +2 -0
  94. data/lib/mongoid/matchable/gte.rb +2 -0
  95. data/lib/mongoid/matchable/lt.rb +2 -0
  96. data/lib/mongoid/matchable/lte.rb +2 -0
  97. data/lib/mongoid/persistable.rb +6 -5
  98. data/lib/mongoid/persistable/creatable.rb +2 -0
  99. data/lib/mongoid/persistable/deletable.rb +7 -3
  100. data/lib/mongoid/persistable/settable.rb +3 -16
  101. data/lib/mongoid/persistable/updatable.rb +10 -12
  102. data/lib/mongoid/persistence_context.rb +216 -0
  103. data/lib/mongoid/query_cache.rb +5 -30
  104. data/lib/mongoid/relations/accessors.rb +6 -2
  105. data/lib/mongoid/relations/auto_save.rb +12 -4
  106. data/lib/mongoid/relations/bindings/embedded/in.rb +4 -0
  107. data/lib/mongoid/relations/bindings/embedded/many.rb +8 -1
  108. data/lib/mongoid/relations/bindings/embedded/one.rb +10 -0
  109. data/lib/mongoid/relations/bindings/referenced/many.rb +4 -0
  110. data/lib/mongoid/relations/builders.rb +2 -2
  111. data/lib/mongoid/relations/builders/embedded/one.rb +1 -1
  112. data/lib/mongoid/relations/builders/nested_attributes/many.rb +1 -1
  113. data/lib/mongoid/relations/conversions.rb +1 -1
  114. data/lib/mongoid/relations/counter_cache.rb +28 -18
  115. data/lib/mongoid/relations/eager.rb +19 -7
  116. data/lib/mongoid/relations/eager/base.rb +5 -5
  117. data/lib/mongoid/relations/embedded/batchable.rb +9 -33
  118. data/lib/mongoid/relations/embedded/in.rb +16 -2
  119. data/lib/mongoid/relations/embedded/many.rb +23 -8
  120. data/lib/mongoid/relations/embedded/one.rb +17 -2
  121. data/lib/mongoid/relations/macros.rb +9 -2
  122. data/lib/mongoid/relations/metadata.rb +3 -3
  123. data/lib/mongoid/relations/nested_builder.rb +1 -1
  124. data/lib/mongoid/relations/options.rb +2 -2
  125. data/lib/mongoid/relations/proxy.rb +2 -33
  126. data/lib/mongoid/relations/referenced/in.rb +23 -11
  127. data/lib/mongoid/relations/referenced/many.rb +24 -16
  128. data/lib/mongoid/relations/referenced/many_to_many.rb +20 -13
  129. data/lib/mongoid/relations/referenced/one.rb +17 -1
  130. data/lib/mongoid/relations/reflections.rb +3 -5
  131. data/lib/mongoid/relations/touchable.rb +1 -1
  132. data/lib/mongoid/reloadable.rb +1 -1
  133. data/lib/mongoid/scopable.rb +3 -3
  134. data/lib/mongoid/serializable.rb +2 -3
  135. data/lib/mongoid/tasks/database.rb +1 -2
  136. data/lib/mongoid/threaded.rb +4 -4
  137. data/lib/mongoid/traversable.rb +1 -1
  138. data/lib/mongoid/validatable.rb +1 -1
  139. data/lib/mongoid/validatable/macros.rb +2 -4
  140. data/lib/mongoid/validatable/uniqueness.rb +1 -2
  141. data/lib/mongoid/version.rb +1 -1
  142. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +4 -7
  143. data/spec/app/models/album.rb +5 -1
  144. data/spec/app/models/artist.rb +21 -0
  145. data/spec/app/models/band.rb +0 -1
  146. data/spec/app/models/church.rb +0 -2
  147. data/spec/app/models/ordered_post.rb +5 -0
  148. data/spec/app/models/oscar.rb +1 -2
  149. data/spec/app/models/person.rb +3 -1
  150. data/spec/app/models/post.rb +0 -1
  151. data/spec/app/models/princess.rb +2 -0
  152. data/spec/app/models/record.rb +1 -0
  153. data/spec/app/models/thing.rb +1 -1
  154. data/spec/config/mongoid.yml +1 -5
  155. data/spec/mongoid/atomic/modifiers_spec.rb +17 -17
  156. data/spec/mongoid/atomic_spec.rb +17 -17
  157. data/spec/mongoid/attributes/nested_spec.rb +14 -14
  158. data/spec/mongoid/attributes/readonly_spec.rb +87 -44
  159. data/spec/mongoid/attributes_spec.rb +63 -0
  160. data/spec/mongoid/cacheable_spec.rb +112 -0
  161. data/spec/mongoid/changeable_spec.rb +58 -0
  162. data/spec/mongoid/clients/factory_spec.rb +3 -11
  163. data/spec/mongoid/clients/options_spec.rb +378 -96
  164. data/spec/mongoid/clients_spec.rb +207 -170
  165. data/spec/mongoid/composable_spec.rb +7 -0
  166. data/spec/mongoid/config_spec.rb +41 -21
  167. data/spec/mongoid/contextual/atomic_spec.rb +77 -343
  168. data/spec/mongoid/contextual/map_reduce_spec.rb +119 -111
  169. data/spec/mongoid/contextual/memory_spec.rb +56 -316
  170. data/spec/mongoid/contextual/mongo_spec.rb +104 -378
  171. data/spec/mongoid/copyable_spec.rb +8 -15
  172. data/spec/mongoid/criteria/modifiable_spec.rb +239 -7
  173. data/spec/mongoid/criteria/options_spec.rb +29 -0
  174. data/spec/mongoid/criteria/queryable/aggregable_spec.rb +370 -0
  175. data/spec/mongoid/criteria/queryable/extensions/array_spec.rb +523 -0
  176. data/spec/mongoid/criteria/queryable/extensions/big_decimal_spec.rb +59 -0
  177. data/spec/mongoid/criteria/queryable/extensions/bignum_spec.rb +58 -0
  178. data/spec/mongoid/criteria/queryable/extensions/boolean_spec.rb +213 -0
  179. data/spec/mongoid/criteria/queryable/extensions/date_spec.rb +330 -0
  180. data/spec/mongoid/criteria/queryable/extensions/date_time_spec.rb +405 -0
  181. data/spec/mongoid/criteria/queryable/extensions/fixnum_spec.rb +58 -0
  182. data/spec/mongoid/criteria/queryable/extensions/float_spec.rb +65 -0
  183. data/spec/mongoid/criteria/queryable/extensions/hash_spec.rb +327 -0
  184. data/spec/mongoid/criteria/queryable/extensions/integer_spec.rb +65 -0
  185. data/spec/mongoid/criteria/queryable/extensions/nil_class_spec.rb +77 -0
  186. data/spec/mongoid/criteria/queryable/extensions/object_spec.rb +108 -0
  187. data/spec/mongoid/criteria/queryable/extensions/range_spec.rb +309 -0
  188. data/spec/mongoid/{extensions/origin/regexp_raw_spec.rb → criteria/queryable/extensions/regexp_spec.rb} +21 -20
  189. data/spec/mongoid/criteria/queryable/extensions/set_spec.rb +39 -0
  190. data/spec/mongoid/criteria/queryable/extensions/string_spec.rb +302 -0
  191. data/spec/mongoid/criteria/queryable/extensions/symbol_spec.rb +167 -0
  192. data/spec/mongoid/criteria/queryable/extensions/time_spec.rb +376 -0
  193. data/spec/mongoid/criteria/queryable/extensions/time_with_zone_spec.rb +347 -0
  194. data/spec/mongoid/criteria/queryable/forwardable_spec.rb +87 -0
  195. data/spec/mongoid/criteria/queryable/key_spec.rb +52 -0
  196. data/spec/mongoid/criteria/queryable/mergeable_spec.rb +49 -0
  197. data/spec/mongoid/criteria/queryable/optional_spec.rb +1786 -0
  198. data/spec/mongoid/criteria/queryable/options_spec.rb +360 -0
  199. data/spec/mongoid/criteria/queryable/pipeline_spec.rb +200 -0
  200. data/spec/mongoid/criteria/queryable/queryable_spec.rb +137 -0
  201. data/spec/mongoid/criteria/queryable/selectable_spec.rb +4159 -0
  202. data/spec/mongoid/criteria/queryable/selector_spec.rb +778 -0
  203. data/spec/mongoid/criteria/queryable/smash_spec.rb +30 -0
  204. data/spec/mongoid/criteria_spec.rb +45 -63
  205. data/spec/mongoid/document_spec.rb +21 -88
  206. data/spec/mongoid/errors/invalid_relation_spec.rb +37 -0
  207. data/spec/mongoid/errors/mongoid_error_spec.rb +6 -3
  208. data/spec/mongoid/extensions/big_decimal_spec.rb +320 -18
  209. data/spec/mongoid/extensions/date_spec.rb +2 -6
  210. data/spec/mongoid/extensions/date_time_spec.rb +2 -6
  211. data/spec/mongoid/extensions/float_spec.rb +8 -1
  212. data/spec/mongoid/extensions/integer_spec.rb +8 -1
  213. data/spec/mongoid/extensions/object_spec.rb +11 -0
  214. data/spec/mongoid/extensions/string_spec.rb +21 -0
  215. data/spec/mongoid/extensions/time_spec.rb +4 -8
  216. data/spec/mongoid/extensions/time_with_zone_spec.rb +2 -6
  217. data/spec/mongoid/fields/localized_spec.rb +0 -91
  218. data/spec/mongoid/findable_spec.rb +46 -1
  219. data/spec/mongoid/indexable_spec.rb +6 -46
  220. data/spec/mongoid/interceptable_spec.rb +49 -10
  221. data/spec/mongoid/matchable/gt_spec.rb +11 -0
  222. data/spec/mongoid/matchable/gte_spec.rb +10 -0
  223. data/spec/mongoid/matchable/lt_spec.rb +11 -0
  224. data/spec/mongoid/matchable/lte_spec.rb +11 -0
  225. data/spec/mongoid/matchable_spec.rb +1 -51
  226. data/spec/mongoid/persistable/creatable_spec.rb +2 -2
  227. data/spec/mongoid/persistable/deletable_spec.rb +1 -1
  228. data/spec/mongoid/persistable/destroyable_spec.rb +6 -2
  229. data/spec/mongoid/persistable/savable_spec.rb +30 -30
  230. data/spec/mongoid/persistable/settable_spec.rb +0 -185
  231. data/spec/mongoid/persistable/updatable_spec.rb +166 -5
  232. data/spec/mongoid/persistence_context_spec.rb +654 -0
  233. data/spec/mongoid/positional_spec.rb +10 -10
  234. data/spec/mongoid/query_cache_spec.rb +89 -65
  235. data/spec/mongoid/relations/accessors_spec.rb +1 -1
  236. data/spec/mongoid/relations/auto_save_spec.rb +39 -6
  237. data/spec/mongoid/relations/builders_spec.rb +37 -10
  238. data/spec/mongoid/relations/counter_cache_spec.rb +64 -15
  239. data/spec/mongoid/relations/cyclic_spec.rb +0 -22
  240. data/spec/mongoid/relations/embedded/many_spec.rb +9 -41
  241. data/spec/mongoid/relations/embedded/one_spec.rb +2 -1
  242. data/spec/mongoid/relations/macros_spec.rb +395 -7
  243. data/spec/mongoid/relations/proxy_spec.rb +3 -1
  244. data/spec/mongoid/relations/referenced/in_spec.rb +41 -1
  245. data/spec/mongoid/relations/referenced/many_spec.rb +6 -29
  246. data/spec/mongoid/relations/referenced/many_to_many_spec.rb +6 -29
  247. data/spec/mongoid/relations/reflections_spec.rb +9 -9
  248. data/spec/mongoid/reloadable_spec.rb +51 -0
  249. data/spec/mongoid/scopable_spec.rb +0 -12
  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 +16 -9
  253. data/spec/mongoid/validatable_spec.rb +16 -0
  254. data/spec/spec_helper.rb +10 -10
  255. metadata +536 -479
  256. metadata.gz.sig +0 -0
  257. data/lib/mongoid/clients/thread_options.rb +0 -19
  258. data/lib/mongoid/errors/in_memory_collation_not_supported.rb +0 -20
  259. data/lib/mongoid/extensions/decimal128.rb +0 -39
  260. data/lib/mongoid/extensions/origin/regexp_raw.rb +0 -43
  261. data/lib/mongoid/matchable/regexp.rb +0 -27
  262. data/spec/app/models/post_genre.rb +0 -6
  263. data/spec/mongoid/extensions/decimal128_spec.rb +0 -44
  264. data/spec/mongoid/matchable/regexp_spec.rb +0 -59
@@ -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,4159 @@
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
+ end
3473
+ end
3474
+
3475
+ context "when provided complex criterion" do
3476
+
3477
+ context "when performing an $all" do
3478
+
3479
+ context "when performing a single query" do
3480
+
3481
+ let(:selection) do
3482
+ query.where(:field.all => [ 1, 2 ])
3483
+ end
3484
+
3485
+ it "adds the $all criterion" do
3486
+ expect(selection.selector).to eq({ "field" => { "$all" => [ 1, 2 ] }})
3487
+ end
3488
+
3489
+ it "returns a cloned query" do
3490
+ expect(selection).to_not eq(query)
3491
+ end
3492
+ end
3493
+ end
3494
+
3495
+ context "when performing an $elemMatch" do
3496
+
3497
+ context "when the value is not complex" do
3498
+
3499
+ let(:selection) do
3500
+ query.where(:field.elem_match => { key: 1 })
3501
+ end
3502
+
3503
+ it "adds the $elemMatch criterion" do
3504
+ expect(selection.selector).to eq(
3505
+ { "field" => { "$elemMatch" => { key: 1 } }}
3506
+ )
3507
+ end
3508
+
3509
+ it "returns a cloned query" do
3510
+ expect(selection).to_not eq(query)
3511
+ end
3512
+ end
3513
+
3514
+ context "when the value is complex" do
3515
+
3516
+ let(:selection) do
3517
+ query.where(:field.elem_match => { :key.gt => 1 })
3518
+ end
3519
+
3520
+ it "adds the $elemMatch criterion" do
3521
+ expect(selection.selector).to eq(
3522
+ { "field" => { "$elemMatch" => { "key" => { "$gt" => 1 }}}}
3523
+ )
3524
+ end
3525
+
3526
+ it "returns a cloned query" do
3527
+ expect(selection).to_not eq(query)
3528
+ end
3529
+ end
3530
+ end
3531
+
3532
+ context "when performing an $exists" do
3533
+
3534
+ context "when providing boolean values" do
3535
+
3536
+ let(:selection) do
3537
+ query.where(:field.exists => true)
3538
+ end
3539
+
3540
+ it "adds the $exists criterion" do
3541
+ expect(selection.selector).to eq(
3542
+ { "field" => { "$exists" => true }}
3543
+ )
3544
+ end
3545
+
3546
+ it "returns a cloned query" do
3547
+ expect(selection).to_not eq(query)
3548
+ end
3549
+ end
3550
+
3551
+ context "when providing string values" do
3552
+
3553
+ let(:selection) do
3554
+ query.where(:field.exists => "t")
3555
+ end
3556
+
3557
+ it "adds the $exists criterion" do
3558
+ expect(selection.selector).to eq(
3559
+ { "field" => { "$exists" => true }}
3560
+ )
3561
+ end
3562
+
3563
+ it "returns a cloned query" do
3564
+ expect(selection).to_not eq(query)
3565
+ end
3566
+ end
3567
+ end
3568
+
3569
+ context "when performing a $gt" do
3570
+
3571
+ let(:selection) do
3572
+ query.where(:field.gt => 10)
3573
+ end
3574
+
3575
+ it "adds the $gt criterion" do
3576
+ expect(selection.selector).to eq(
3577
+ { "field" => { "$gt" => 10 }}
3578
+ )
3579
+ end
3580
+
3581
+ it "returns a cloned query" do
3582
+ expect(selection).to_not eq(query)
3583
+ end
3584
+ end
3585
+
3586
+ context "when performing a $gte" do
3587
+
3588
+ let(:selection) do
3589
+ query.where(:field.gte => 10)
3590
+ end
3591
+
3592
+ it "adds the $gte criterion" do
3593
+ expect(selection.selector).to eq(
3594
+ { "field" => { "$gte" => 10 }}
3595
+ )
3596
+ end
3597
+
3598
+ it "returns a cloned query" do
3599
+ expect(selection).to_not eq(query)
3600
+ end
3601
+ end
3602
+
3603
+ context "when performing an $in" do
3604
+
3605
+ let(:selection) do
3606
+ query.where(:field.in => [ 1, 2 ])
3607
+ end
3608
+
3609
+ it "adds the $in criterion" do
3610
+ expect(selection.selector).to eq({ "field" => { "$in" => [ 1, 2 ] }})
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 a $lt" do
3619
+
3620
+ let(:selection) do
3621
+ query.where(:field.lt => 10)
3622
+ end
3623
+
3624
+ it "adds the $lt criterion" do
3625
+ expect(selection.selector).to eq(
3626
+ { "field" => { "$lt" => 10 }}
3627
+ )
3628
+ end
3629
+
3630
+ it "returns a cloned query" do
3631
+ expect(selection).to_not eq(query)
3632
+ end
3633
+ end
3634
+
3635
+ context "when performing a $lte" do
3636
+
3637
+ let(:selection) do
3638
+ query.where(:field.lte => 10)
3639
+ end
3640
+
3641
+ it "adds the $lte criterion" do
3642
+ expect(selection.selector).to eq(
3643
+ { "field" => { "$lte" => 10 }}
3644
+ )
3645
+ end
3646
+
3647
+ it "returns a cloned query" do
3648
+ expect(selection).to_not eq(query)
3649
+ end
3650
+ end
3651
+
3652
+ context "when performing a $mod" do
3653
+
3654
+ let(:selection) do
3655
+ query.where(:field.mod => [ 10, 1 ])
3656
+ end
3657
+
3658
+ it "adds the $lte criterion" do
3659
+ expect(selection.selector).to eq(
3660
+ { "field" => { "$mod" => [ 10, 1 ]}}
3661
+ )
3662
+ end
3663
+
3664
+ it "returns a cloned query" do
3665
+ expect(selection).to_not eq(query)
3666
+ end
3667
+ end
3668
+
3669
+ context "when performing a $ne" do
3670
+
3671
+ let(:selection) do
3672
+ query.where(:field.ne => 10)
3673
+ end
3674
+
3675
+ it "adds the $ne criterion" do
3676
+ expect(selection.selector).to eq(
3677
+ { "field" => { "$ne" => 10 }}
3678
+ )
3679
+ end
3680
+
3681
+ it "returns a cloned query" do
3682
+ expect(selection).to_not eq(query)
3683
+ end
3684
+ end
3685
+
3686
+ context "when performing a $near" do
3687
+
3688
+ let(:selection) do
3689
+ query.where(:field.near => [ 1, 1 ])
3690
+ end
3691
+
3692
+ it "adds the $near criterion" do
3693
+ expect(selection.selector).to eq(
3694
+ { "field" => { "$near" => [ 1, 1 ] }}
3695
+ )
3696
+ end
3697
+
3698
+ it "returns a cloned query" do
3699
+ expect(selection).to_not eq(query)
3700
+ end
3701
+ end
3702
+
3703
+ context "when performing a $nearSphere" do
3704
+
3705
+ let(:selection) do
3706
+ query.where(:field.near_sphere => [ 1, 1 ])
3707
+ end
3708
+
3709
+ it "adds the $nearSphere criterion" do
3710
+ expect(selection.selector).to eq(
3711
+ { "field" => { "$nearSphere" => [ 1, 1 ] }}
3712
+ )
3713
+ end
3714
+
3715
+ it "returns a cloned query" do
3716
+ expect(selection).to_not eq(query)
3717
+ end
3718
+ end
3719
+
3720
+ context "when performing a $nin" do
3721
+
3722
+ let(:selection) do
3723
+ query.where(:field.nin => [ 1, 2 ])
3724
+ end
3725
+
3726
+ it "adds the $nin criterion" do
3727
+ expect(selection.selector).to eq({ "field" => { "$nin" => [ 1, 2 ] }})
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 $not" do
3736
+
3737
+ let(:selection) do
3738
+ query.where(:field.not => /test/)
3739
+ end
3740
+
3741
+ it "adds the $not criterion" do
3742
+ expect(selection.selector).to eq({ "field" => { "$not" => /test/ }})
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 $size" do
3751
+
3752
+ context "when providing an integer" do
3753
+
3754
+ let(:selection) do
3755
+ query.where(:field.with_size => 10)
3756
+ end
3757
+
3758
+ it "adds the $size criterion" do
3759
+ expect(selection.selector).to eq(
3760
+ { "field" => { "$size" => 10 }}
3761
+ )
3762
+ end
3763
+
3764
+ it "returns a cloned query" do
3765
+ expect(selection).to_not eq(query)
3766
+ end
3767
+ end
3768
+
3769
+ context "when providing a string" do
3770
+
3771
+ let(:selection) do
3772
+ query.where(:field.with_size => "10")
3773
+ end
3774
+
3775
+ it "adds the $size criterion" do
3776
+ expect(selection.selector).to eq(
3777
+ { "field" => { "$size" => 10 }}
3778
+ )
3779
+ end
3780
+
3781
+ it "returns a cloned query" do
3782
+ expect(selection).to_not eq(query)
3783
+ end
3784
+ end
3785
+ end
3786
+
3787
+ context "when performing a $type" do
3788
+
3789
+ let(:selection) do
3790
+ query.where(:field.with_type => 10)
3791
+ end
3792
+
3793
+ it "adds the $type criterion" do
3794
+ expect(selection.selector).to eq(
3795
+ { "field" => { "$type" => 10 }}
3796
+ )
3797
+ end
3798
+
3799
+ it "returns a cloned query" do
3800
+ expect(selection).to_not eq(query)
3801
+ end
3802
+ end
3803
+ end
3804
+ end
3805
+
3806
+ describe Symbol do
3807
+
3808
+ describe "#all" do
3809
+
3810
+ let(:key) do
3811
+ :field.all
3812
+ end
3813
+
3814
+ it "returns a selecton key" do
3815
+ expect(key).to be_a(Mongoid::Criteria::Queryable::Key)
3816
+ end
3817
+
3818
+ it "sets the name as the key" do
3819
+ expect(key.name).to eq(:field)
3820
+ end
3821
+
3822
+ it "sets the operator as $all" do
3823
+ expect(key.operator).to eq("$all")
3824
+ end
3825
+ end
3826
+
3827
+ describe "#elem_match" do
3828
+
3829
+ let(:key) do
3830
+ :field.elem_match
3831
+ end
3832
+
3833
+ it "returns a selecton key" do
3834
+ expect(key).to be_a(Mongoid::Criteria::Queryable::Key)
3835
+ end
3836
+
3837
+ it "sets the name as the key" do
3838
+ expect(key.name).to eq(:field)
3839
+ end
3840
+
3841
+ it "sets the operator as $elemMatch" do
3842
+ expect(key.operator).to eq("$elemMatch")
3843
+ end
3844
+ end
3845
+
3846
+ describe "#exists" do
3847
+
3848
+ let(:key) do
3849
+ :field.exists
3850
+ end
3851
+
3852
+ it "returns a selecton key" do
3853
+ expect(key).to be_a(Mongoid::Criteria::Queryable::Key)
3854
+ end
3855
+
3856
+ it "sets the name as the key" do
3857
+ expect(key.name).to eq(:field)
3858
+ end
3859
+
3860
+ it "sets the operator as $exists" do
3861
+ expect(key.operator).to eq("$exists")
3862
+ end
3863
+ end
3864
+
3865
+ describe "#gt" do
3866
+
3867
+ let(:key) do
3868
+ :field.gt
3869
+ end
3870
+
3871
+ it "returns a selecton key" do
3872
+ expect(key).to be_a(Mongoid::Criteria::Queryable::Key)
3873
+ end
3874
+
3875
+ it "sets the name as the key" do
3876
+ expect(key.name).to eq(:field)
3877
+ end
3878
+
3879
+ it "sets the operator as $gt" do
3880
+ expect(key.operator).to eq("$gt")
3881
+ end
3882
+ end
3883
+
3884
+ describe "#gte" do
3885
+
3886
+ let(:key) do
3887
+ :field.gte
3888
+ end
3889
+
3890
+ it "returns a selecton key" do
3891
+ expect(key).to be_a(Mongoid::Criteria::Queryable::Key)
3892
+ end
3893
+
3894
+ it "sets the name as the key" do
3895
+ expect(key.name).to eq(:field)
3896
+ end
3897
+
3898
+ it "sets the operator as $gte" do
3899
+ expect(key.operator).to eq("$gte")
3900
+ end
3901
+ end
3902
+
3903
+ describe "#in" do
3904
+
3905
+ let(:key) do
3906
+ :field.in
3907
+ end
3908
+
3909
+ it "returns a selecton key" do
3910
+ expect(key).to be_a(Mongoid::Criteria::Queryable::Key)
3911
+ end
3912
+
3913
+ it "sets the name as the key" do
3914
+ expect(key.name).to eq(:field)
3915
+ end
3916
+
3917
+ it "sets the operator as $in" do
3918
+ expect(key.operator).to eq("$in")
3919
+ end
3920
+ end
3921
+
3922
+ describe "#lt" do
3923
+
3924
+ let(:key) do
3925
+ :field.lt
3926
+ end
3927
+
3928
+ it "returns a selecton key" do
3929
+ expect(key).to be_a(Mongoid::Criteria::Queryable::Key)
3930
+ end
3931
+
3932
+ it "sets the name as the key" do
3933
+ expect(key.name).to eq(:field)
3934
+ end
3935
+
3936
+ it "sets the operator as $lt" do
3937
+ expect(key.operator).to eq("$lt")
3938
+ end
3939
+ end
3940
+
3941
+ describe "#lte" do
3942
+
3943
+ let(:key) do
3944
+ :field.lte
3945
+ end
3946
+
3947
+ it "returns a selecton key" do
3948
+ expect(key).to be_a(Mongoid::Criteria::Queryable::Key)
3949
+ end
3950
+
3951
+ it "sets the name as the key" do
3952
+ expect(key.name).to eq(:field)
3953
+ end
3954
+
3955
+ it "sets the operator as $lte" do
3956
+ expect(key.operator).to eq("$lte")
3957
+ end
3958
+ end
3959
+
3960
+ describe "#mod" do
3961
+
3962
+ let(:key) do
3963
+ :field.mod
3964
+ end
3965
+
3966
+ it "returns a selecton key" do
3967
+ expect(key).to be_a(Mongoid::Criteria::Queryable::Key)
3968
+ end
3969
+
3970
+ it "sets the name as the key" do
3971
+ expect(key.name).to eq(:field)
3972
+ end
3973
+
3974
+ it "sets the operator as $mod" do
3975
+ expect(key.operator).to eq("$mod")
3976
+ end
3977
+ end
3978
+
3979
+ describe "#ne" do
3980
+
3981
+ let(:key) do
3982
+ :field.ne
3983
+ end
3984
+
3985
+ it "returns a selecton key" do
3986
+ expect(key).to be_a(Mongoid::Criteria::Queryable::Key)
3987
+ end
3988
+
3989
+ it "sets the name as the key" do
3990
+ expect(key.name).to eq(:field)
3991
+ end
3992
+
3993
+ it "sets the operator as $ne" do
3994
+ expect(key.operator).to eq("$ne")
3995
+ end
3996
+ end
3997
+
3998
+ describe "#near" do
3999
+
4000
+ let(:key) do
4001
+ :field.near
4002
+ end
4003
+
4004
+ it "returns a selecton key" do
4005
+ expect(key).to be_a(Mongoid::Criteria::Queryable::Key)
4006
+ end
4007
+
4008
+ it "sets the name as the key" do
4009
+ expect(key.name).to eq(:field)
4010
+ end
4011
+
4012
+ it "sets the operator as $near" do
4013
+ expect(key.operator).to eq("$near")
4014
+ end
4015
+ end
4016
+
4017
+ describe "#near_sphere" do
4018
+
4019
+ let(:key) do
4020
+ :field.near_sphere
4021
+ end
4022
+
4023
+ it "returns a selecton key" do
4024
+ expect(key).to be_a(Mongoid::Criteria::Queryable::Key)
4025
+ end
4026
+
4027
+ it "sets the name as the key" do
4028
+ expect(key.name).to eq(:field)
4029
+ end
4030
+
4031
+ it "sets the operator as $nearSphere" do
4032
+ expect(key.operator).to eq("$nearSphere")
4033
+ end
4034
+ end
4035
+
4036
+ describe "#nin" do
4037
+
4038
+ let(:key) do
4039
+ :field.nin
4040
+ end
4041
+
4042
+ it "returns a selecton key" do
4043
+ expect(key).to be_a(Mongoid::Criteria::Queryable::Key)
4044
+ end
4045
+
4046
+ it "sets the name as the key" do
4047
+ expect(key.name).to eq(:field)
4048
+ end
4049
+
4050
+ it "sets the operator as $nin" do
4051
+ expect(key.operator).to eq("$nin")
4052
+ end
4053
+ end
4054
+
4055
+ describe "#not" do
4056
+
4057
+ let(:key) do
4058
+ :field.not
4059
+ end
4060
+
4061
+ it "returns a selection key" do
4062
+ expect(key).to be_a(Mongoid::Criteria::Queryable::Key)
4063
+ end
4064
+
4065
+ it "sets the name as the key" do
4066
+ expect(key.name).to eq(:field)
4067
+ end
4068
+
4069
+ it "sets the operator as $not" do
4070
+ expect(key.operator).to eq("$not")
4071
+ end
4072
+
4073
+ end
4074
+
4075
+ describe "#with_size" do
4076
+
4077
+ let(:key) do
4078
+ :field.with_size
4079
+ end
4080
+
4081
+ it "returns a selecton key" do
4082
+ expect(key).to be_a(Mongoid::Criteria::Queryable::Key)
4083
+ end
4084
+
4085
+ it "sets the name as the key" do
4086
+ expect(key.name).to eq(:field)
4087
+ end
4088
+
4089
+ it "sets the operator as $size" do
4090
+ expect(key.operator).to eq("$size")
4091
+ end
4092
+ end
4093
+
4094
+ describe "#with_type" do
4095
+
4096
+ let(:key) do
4097
+ :field.with_type
4098
+ end
4099
+
4100
+ it "returns a selecton key" do
4101
+ expect(key).to be_a(Mongoid::Criteria::Queryable::Key)
4102
+ end
4103
+
4104
+ it "sets the name as the key" do
4105
+ expect(key.name).to eq(:field)
4106
+ end
4107
+
4108
+ it "sets the operator as $type" do
4109
+ expect(key.operator).to eq("$type")
4110
+ end
4111
+ end
4112
+ end
4113
+
4114
+ context "when using multiple strategies on the same field" do
4115
+
4116
+ context "when using the strategies via methods" do
4117
+
4118
+ context "when the values are a hash" do
4119
+
4120
+ let(:selection) do
4121
+ query.gt(field: 5).lt(field: 10).ne(field: 7)
4122
+ end
4123
+
4124
+ it "merges the strategies on the same field" do
4125
+ expect(selection.selector).to eq(
4126
+ { "field" => { "$gt" => 5, "$lt" => 10, "$ne" => 7 }}
4127
+ )
4128
+ end
4129
+ end
4130
+
4131
+ context "when the values are not hashes" do
4132
+
4133
+ let(:selection) do
4134
+ query.where(field: 5).where(field: 10)
4135
+ end
4136
+
4137
+ it "overrides the previous field" do
4138
+ expect(selection.selector).to eq({ "field" => 10 })
4139
+ end
4140
+ end
4141
+ end
4142
+
4143
+ context "when using the strategies via #where" do
4144
+
4145
+ context "when the values are a hash" do
4146
+
4147
+ let(:selection) do
4148
+ query.where(:field.gt => 5, :field.lt => 10, :field.ne => 7)
4149
+ end
4150
+
4151
+ it "merges the strategies on the same field" do
4152
+ expect(selection.selector).to eq(
4153
+ { "field" => { "$gt" => 5, "$lt" => 10, "$ne" => 7 }}
4154
+ )
4155
+ end
4156
+ end
4157
+ end
4158
+ end
4159
+ end