mongoid 5.4.1 → 6.0.0.beta

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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