mongoid 7.1.0 → 7.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/CHANGELOG.md +6 -6
- data/README.md +1 -1
- data/lib/config/locales/en.yml +4 -4
- data/lib/mongoid/association/referenced/belongs_to/eager.rb +38 -2
- data/lib/mongoid/association/referenced/eager.rb +29 -9
- data/lib/mongoid/config.rb +39 -9
- data/lib/mongoid/criteria.rb +16 -3
- data/lib/mongoid/criteria/queryable/pipeline.rb +3 -2
- data/lib/mongoid/criteria/queryable/selectable.rb +94 -7
- data/lib/mongoid/criteria/queryable/storable.rb +104 -99
- data/lib/mongoid/errors/eager_load.rb +2 -0
- data/lib/mongoid/persistable/pushable.rb +7 -1
- data/lib/mongoid/serializable.rb +9 -3
- data/lib/mongoid/version.rb +1 -1
- data/lib/rails/generators/mongoid/config/templates/mongoid.yml +32 -23
- data/spec/app/models/coding.rb +4 -0
- data/spec/app/models/coding/pull_request.rb +12 -0
- data/spec/app/models/delegating_patient.rb +16 -0
- data/spec/app/models/publication.rb +5 -0
- data/spec/app/models/publication/encyclopedia.rb +12 -0
- data/spec/app/models/publication/review.rb +14 -0
- data/spec/integration/document_spec.rb +22 -0
- data/spec/mongoid/association/referenced/belongs_to/eager_spec.rb +193 -10
- data/spec/mongoid/criteria/queryable/selectable_logical_spec.rb +504 -127
- data/spec/mongoid/criteria/queryable/selectable_spec.rb +52 -0
- data/spec/mongoid/criteria/queryable/storable_spec.rb +80 -2
- data/spec/mongoid/criteria_spec.rb +32 -0
- data/spec/mongoid/persistable/pushable_spec.rb +55 -1
- data/spec/mongoid/serializable_spec.rb +129 -18
- data/spec/spec_helper.rb +2 -0
- data/spec/support/expectations.rb +3 -1
- data/spec/support/helpers.rb +11 -0
- metadata +504 -490
- metadata.gz.sig +0 -0
@@ -16,7 +16,161 @@ describe Mongoid::Criteria::Queryable::Selectable do
|
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
|
-
|
19
|
+
# Hoisting means the operator can be elided, for example
|
20
|
+
# Foo.and(a: 1) produces simply {'a' => 1}.
|
21
|
+
shared_examples_for 'a hoisting logical operation' do
|
22
|
+
|
23
|
+
let(:query) do
|
24
|
+
Mongoid::Query.new
|
25
|
+
end
|
26
|
+
|
27
|
+
context "when provided a single criterion" do
|
28
|
+
|
29
|
+
shared_examples_for 'adds the conditions to top level' do
|
30
|
+
|
31
|
+
it "adds the conditions to top level" do
|
32
|
+
expect(selection.selector).to eq(
|
33
|
+
"field" => [ 1, 2 ]
|
34
|
+
)
|
35
|
+
end
|
36
|
+
|
37
|
+
it_behaves_like 'returns a cloned query'
|
38
|
+
end
|
39
|
+
|
40
|
+
let(:selection) do
|
41
|
+
query.send(tested_method, field: [ 1, 2 ])
|
42
|
+
end
|
43
|
+
|
44
|
+
it_behaves_like 'adds the conditions to top level'
|
45
|
+
|
46
|
+
context 'when the criterion is wrapped in an array' do
|
47
|
+
let(:selection) do
|
48
|
+
query.send(tested_method, [{field: [ 1, 2 ] }])
|
49
|
+
end
|
50
|
+
|
51
|
+
it_behaves_like 'adds the conditions to top level'
|
52
|
+
end
|
53
|
+
|
54
|
+
context 'when the criterion is wrapped in a deep array with nil elements' do
|
55
|
+
let(:selection) do
|
56
|
+
query.send(tested_method, [[[{field: [ 1, 2 ] }]], [nil]])
|
57
|
+
end
|
58
|
+
|
59
|
+
it_behaves_like 'adds the conditions to top level'
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
context 'when argument is a Criteria' do
|
64
|
+
let(:base) do
|
65
|
+
query.where(hello: 'world')
|
66
|
+
end
|
67
|
+
|
68
|
+
let(:other) do
|
69
|
+
query.where(foo: 'bar')
|
70
|
+
end
|
71
|
+
|
72
|
+
let(:result) { base.send(tested_method, other) }
|
73
|
+
|
74
|
+
it 'combines' do
|
75
|
+
expect(result.selector).to eq(
|
76
|
+
'hello' => 'world',
|
77
|
+
'foo' => 'bar',
|
78
|
+
)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
context "when provided a single criterion that is handled via Key" do
|
83
|
+
|
84
|
+
shared_examples_for 'adds the conditions to top level' do
|
85
|
+
|
86
|
+
it "adds the conditions to top level" do
|
87
|
+
expect(selection.selector).to eq({
|
88
|
+
"field" => {'$gt' => 3 },
|
89
|
+
})
|
90
|
+
end
|
91
|
+
|
92
|
+
it_behaves_like 'returns a cloned query'
|
93
|
+
end
|
94
|
+
|
95
|
+
let(:selection) do
|
96
|
+
query.send(tested_method, :field.gt => 3)
|
97
|
+
end
|
98
|
+
|
99
|
+
it_behaves_like 'adds the conditions to top level'
|
100
|
+
|
101
|
+
context 'when the criterion is wrapped in an array' do
|
102
|
+
let(:selection) do
|
103
|
+
query.send(tested_method, [{ :field.gt => 3 }])
|
104
|
+
end
|
105
|
+
|
106
|
+
it_behaves_like 'adds the conditions to top level'
|
107
|
+
end
|
108
|
+
|
109
|
+
context 'when the criterion is wrapped in a deep array with nil elements' do
|
110
|
+
let(:selection) do
|
111
|
+
query.send(tested_method, [[[{ :field.gt => 3 }]], [nil]])
|
112
|
+
end
|
113
|
+
|
114
|
+
it_behaves_like 'adds the conditions to top level'
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
context "when provided a nested criterion" do
|
119
|
+
|
120
|
+
let(:selection) do
|
121
|
+
query.send(tested_method, :test.elem_match => { :field.in => [ 1, 2 ] })
|
122
|
+
end
|
123
|
+
|
124
|
+
it "builds the correct selector" do
|
125
|
+
expect(selection.selector).to eq({
|
126
|
+
"test" => { "$elemMatch" => { "field" => { "$in" => [ 1, 2 ] }}}
|
127
|
+
})
|
128
|
+
end
|
129
|
+
|
130
|
+
it_behaves_like 'returns a cloned query'
|
131
|
+
end
|
132
|
+
|
133
|
+
context "when chaining the criteria" do
|
134
|
+
|
135
|
+
context "when the criteria are for different fields" do
|
136
|
+
|
137
|
+
let(:selection) do
|
138
|
+
query.and(first: [ 1, 2 ]).send(tested_method, second: [ 3, 4 ])
|
139
|
+
end
|
140
|
+
|
141
|
+
it "adds the conditions to top level" do
|
142
|
+
expect(selection.selector).to eq({
|
143
|
+
"first" => [ 1, 2 ],
|
144
|
+
"second" => [ 3, 4 ],
|
145
|
+
})
|
146
|
+
end
|
147
|
+
|
148
|
+
it_behaves_like 'returns a cloned query'
|
149
|
+
end
|
150
|
+
|
151
|
+
context "when the criteria are on the same field" do
|
152
|
+
|
153
|
+
let(:selection) do
|
154
|
+
query.and(first: [ 1, 2 ]).send(tested_method, first: [ 3, 4 ])
|
155
|
+
end
|
156
|
+
|
157
|
+
it "combines via $and operator" do
|
158
|
+
expect(selection.selector).to eq({
|
159
|
+
"first" => [ 1, 2 ],
|
160
|
+
"$and" => [
|
161
|
+
{ "first" => [ 3, 4 ] }
|
162
|
+
]
|
163
|
+
})
|
164
|
+
end
|
165
|
+
|
166
|
+
it_behaves_like 'returns a cloned query'
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
# Non-hoisting means the operator is always present, for example
|
172
|
+
# Foo.or(a: 1) produces {'$or' => [{'a' => 1}]}.
|
173
|
+
shared_examples_for 'a non-hoisting logical operation' do
|
20
174
|
|
21
175
|
context 'when there is a single predicate' do
|
22
176
|
let(:query) do
|
@@ -88,6 +242,11 @@ describe Mongoid::Criteria::Queryable::Selectable do
|
|
88
242
|
|
89
243
|
describe "#and" do
|
90
244
|
|
245
|
+
let(:tested_method) { :and }
|
246
|
+
let(:expected_operator) { '$and' }
|
247
|
+
|
248
|
+
it_behaves_like 'a hoisting logical operation'
|
249
|
+
|
91
250
|
context "when provided no criterion" do
|
92
251
|
|
93
252
|
let(:selection) do
|
@@ -122,93 +281,6 @@ describe Mongoid::Criteria::Queryable::Selectable do
|
|
122
281
|
it_behaves_like 'returns a cloned query'
|
123
282
|
end
|
124
283
|
|
125
|
-
context "when provided a single criterion" do
|
126
|
-
|
127
|
-
shared_examples_for 'adds the conditions to top level' do
|
128
|
-
|
129
|
-
it "adds the conditions to top level" do
|
130
|
-
expect(selection.selector).to eq({
|
131
|
-
"field" => [ 1, 2 ]
|
132
|
-
})
|
133
|
-
end
|
134
|
-
|
135
|
-
it_behaves_like 'returns a cloned query'
|
136
|
-
end
|
137
|
-
|
138
|
-
let(:selection) do
|
139
|
-
query.and(field: [ 1, 2 ])
|
140
|
-
end
|
141
|
-
|
142
|
-
it_behaves_like 'adds the conditions to top level'
|
143
|
-
|
144
|
-
context 'when the criterion is wrapped in an array' do
|
145
|
-
let(:selection) do
|
146
|
-
query.and([{field: [ 1, 2 ] }])
|
147
|
-
end
|
148
|
-
|
149
|
-
it_behaves_like 'adds the conditions to top level'
|
150
|
-
end
|
151
|
-
|
152
|
-
context 'when the criterion is wrapped in a deep array with nil elements' do
|
153
|
-
let(:selection) do
|
154
|
-
query.and([[[{field: [ 1, 2 ] }]], [nil]])
|
155
|
-
end
|
156
|
-
|
157
|
-
it_behaves_like 'adds the conditions to top level'
|
158
|
-
end
|
159
|
-
end
|
160
|
-
|
161
|
-
context "when provided a single criterion that is handled via Key" do
|
162
|
-
|
163
|
-
shared_examples_for 'adds the conditions to top level' do
|
164
|
-
|
165
|
-
it "adds the conditions to top level" do
|
166
|
-
expect(selection.selector).to eq({
|
167
|
-
"field" => {'$gt' => 3 },
|
168
|
-
})
|
169
|
-
end
|
170
|
-
|
171
|
-
it_behaves_like 'returns a cloned query'
|
172
|
-
end
|
173
|
-
|
174
|
-
let(:selection) do
|
175
|
-
query.and(:field.gt => 3)
|
176
|
-
end
|
177
|
-
|
178
|
-
it_behaves_like 'adds the conditions to top level'
|
179
|
-
|
180
|
-
context 'when the criterion is wrapped in an array' do
|
181
|
-
let(:selection) do
|
182
|
-
query.and([{ :field.gt => 3 }])
|
183
|
-
end
|
184
|
-
|
185
|
-
it_behaves_like 'adds the conditions to top level'
|
186
|
-
end
|
187
|
-
|
188
|
-
context 'when the criterion is wrapped in a deep array with nil elements' do
|
189
|
-
let(:selection) do
|
190
|
-
query.and([[[{ :field.gt => 3 }]], [nil]])
|
191
|
-
end
|
192
|
-
|
193
|
-
it_behaves_like 'adds the conditions to top level'
|
194
|
-
end
|
195
|
-
end
|
196
|
-
|
197
|
-
context "when provided a nested criterion" do
|
198
|
-
|
199
|
-
let(:selection) do
|
200
|
-
query.and(:test.elem_match => { :field.in => [ 1, 2 ] })
|
201
|
-
end
|
202
|
-
|
203
|
-
it "builds the correct selector" do
|
204
|
-
expect(selection.selector).to eq({
|
205
|
-
"test" => { "$elemMatch" => { "field" => { "$in" => [ 1, 2 ] }}}
|
206
|
-
})
|
207
|
-
end
|
208
|
-
|
209
|
-
it_behaves_like 'returns a cloned query'
|
210
|
-
end
|
211
|
-
|
212
284
|
context "when provided multiple criteria" do
|
213
285
|
|
214
286
|
context "when the criteria is already included" do
|
@@ -264,43 +336,6 @@ describe Mongoid::Criteria::Queryable::Selectable do
|
|
264
336
|
end
|
265
337
|
end
|
266
338
|
|
267
|
-
context "when chaining the criteria" do
|
268
|
-
|
269
|
-
context "when the criteria are for different fields" do
|
270
|
-
|
271
|
-
let(:selection) do
|
272
|
-
query.and(first: [ 1, 2 ]).and(second: [ 3, 4 ])
|
273
|
-
end
|
274
|
-
|
275
|
-
it "adds the conditions to top level" do
|
276
|
-
expect(selection.selector).to eq({
|
277
|
-
"first" => [ 1, 2 ],
|
278
|
-
"second" => [ 3, 4 ],
|
279
|
-
})
|
280
|
-
end
|
281
|
-
|
282
|
-
it_behaves_like 'returns a cloned query'
|
283
|
-
end
|
284
|
-
|
285
|
-
context "when the criteria are on the same field" do
|
286
|
-
|
287
|
-
let(:selection) do
|
288
|
-
query.and(first: [ 1, 2 ]).and(first: [ 3, 4 ])
|
289
|
-
end
|
290
|
-
|
291
|
-
it "combines via $and operator" do
|
292
|
-
expect(selection.selector).to eq({
|
293
|
-
"first" => [ 1, 2 ],
|
294
|
-
"$and" => [
|
295
|
-
{ "first" => [ 3, 4 ] }
|
296
|
-
]
|
297
|
-
})
|
298
|
-
end
|
299
|
-
|
300
|
-
it_behaves_like 'returns a cloned query'
|
301
|
-
end
|
302
|
-
end
|
303
|
-
|
304
339
|
context 'when argument is a Criteria' do
|
305
340
|
let(:query) do
|
306
341
|
Mongoid::Query.new.where(hello: 'world')
|
@@ -424,6 +459,54 @@ describe Mongoid::Criteria::Queryable::Selectable do
|
|
424
459
|
it_behaves_like 'adds most recent criterion as $and'
|
425
460
|
end
|
426
461
|
end
|
462
|
+
|
463
|
+
context 'when conditions already exist in criteria' do
|
464
|
+
let(:base_selection) do
|
465
|
+
query.where(foo: 'bar')
|
466
|
+
end
|
467
|
+
|
468
|
+
context 'when hash conditions are given' do
|
469
|
+
let(:selection) do
|
470
|
+
base_selection.and(hello: 'world')
|
471
|
+
end
|
472
|
+
|
473
|
+
it 'adds new conditions to top level' do
|
474
|
+
selection.selector.should == {
|
475
|
+
'foo' => 'bar',
|
476
|
+
'hello' => 'world',
|
477
|
+
}
|
478
|
+
end
|
479
|
+
end
|
480
|
+
|
481
|
+
context 'when criteria conditions are given' do
|
482
|
+
let(:selection) do
|
483
|
+
base_selection.and(query.where(hello: 'world'))
|
484
|
+
end
|
485
|
+
|
486
|
+
it 'adds new conditions to top level' do
|
487
|
+
selection.selector.should == {
|
488
|
+
'foo' => 'bar',
|
489
|
+
'hello' => 'world',
|
490
|
+
}
|
491
|
+
end
|
492
|
+
end
|
493
|
+
|
494
|
+
context 'when complex criteria conditions are given' do
|
495
|
+
let(:selection) do
|
496
|
+
base_selection.and(query.or([one: 'one'], [two: 'two']))
|
497
|
+
end
|
498
|
+
|
499
|
+
it 'adds new conditions to top level' do
|
500
|
+
selection.selector.should == {
|
501
|
+
'foo' => 'bar',
|
502
|
+
'$or' => [
|
503
|
+
{'one' => 'one'},
|
504
|
+
{'two' => 'two'},
|
505
|
+
],
|
506
|
+
}
|
507
|
+
end
|
508
|
+
end
|
509
|
+
end
|
427
510
|
end
|
428
511
|
|
429
512
|
describe "#or" do
|
@@ -431,7 +514,7 @@ describe Mongoid::Criteria::Queryable::Selectable do
|
|
431
514
|
let(:tested_method) { :or }
|
432
515
|
let(:expected_operator) { '$or' }
|
433
516
|
|
434
|
-
it_behaves_like 'a non-
|
517
|
+
it_behaves_like 'a non-hoisting logical operation'
|
435
518
|
|
436
519
|
context "when provided no arguments" do
|
437
520
|
|
@@ -679,7 +762,7 @@ describe Mongoid::Criteria::Queryable::Selectable do
|
|
679
762
|
let(:tested_method) { :nor }
|
680
763
|
let(:expected_operator) { '$nor' }
|
681
764
|
|
682
|
-
it_behaves_like 'a non-
|
765
|
+
it_behaves_like 'a non-hoisting logical operation'
|
683
766
|
|
684
767
|
context "when provided no criterion" do
|
685
768
|
|
@@ -809,6 +892,300 @@ describe Mongoid::Criteria::Queryable::Selectable do
|
|
809
892
|
end
|
810
893
|
end
|
811
894
|
|
895
|
+
describe "#any_of" do
|
896
|
+
|
897
|
+
let(:tested_method) { :any_of }
|
898
|
+
let(:expected_operator) { '$or' }
|
899
|
+
|
900
|
+
it_behaves_like 'a hoisting logical operation'
|
901
|
+
|
902
|
+
# When multiple arguments are given to any_of, it behaves differently
|
903
|
+
# from and.
|
904
|
+
context 'when argument is a mix of Criteria and hashes' do
|
905
|
+
let(:query) do
|
906
|
+
Mongoid::Query.new.where(hello: 'world')
|
907
|
+
end
|
908
|
+
|
909
|
+
let(:other1) do
|
910
|
+
Mongoid::Query.new.where(foo: 'bar')
|
911
|
+
end
|
912
|
+
|
913
|
+
let(:other2) do
|
914
|
+
{bar: 42}
|
915
|
+
end
|
916
|
+
|
917
|
+
let(:other3) do
|
918
|
+
Mongoid::Query.new.where(a: 2)
|
919
|
+
end
|
920
|
+
|
921
|
+
let(:result) { query.send(tested_method, other1, other2, other3) }
|
922
|
+
|
923
|
+
it 'combines' do
|
924
|
+
expect(result.selector).to eq(
|
925
|
+
'hello' => 'world',
|
926
|
+
expected_operator => [
|
927
|
+
{'foo' => 'bar'},
|
928
|
+
{'bar' => 42},
|
929
|
+
{'a' => 2},
|
930
|
+
],
|
931
|
+
)
|
932
|
+
end
|
933
|
+
end
|
934
|
+
|
935
|
+
context "when provided no arguments" do
|
936
|
+
|
937
|
+
let(:selection) do
|
938
|
+
query.any_of
|
939
|
+
end
|
940
|
+
|
941
|
+
it_behaves_like 'returns a cloned query'
|
942
|
+
|
943
|
+
it "does not add any criteria" do
|
944
|
+
expect(selection.selector).to eq({})
|
945
|
+
end
|
946
|
+
|
947
|
+
it "returns the query" do
|
948
|
+
expect(selection).to eq(query)
|
949
|
+
end
|
950
|
+
end
|
951
|
+
|
952
|
+
context "when provided nil" do
|
953
|
+
|
954
|
+
let(:selection) do
|
955
|
+
query.any_of(nil)
|
956
|
+
end
|
957
|
+
|
958
|
+
it_behaves_like 'returns a cloned query'
|
959
|
+
|
960
|
+
it "does not add any criteria" do
|
961
|
+
expect(selection.selector).to eq({})
|
962
|
+
end
|
963
|
+
|
964
|
+
it "returns the query" do
|
965
|
+
expect(selection).to eq(query)
|
966
|
+
end
|
967
|
+
end
|
968
|
+
|
969
|
+
context "when provided a single criterion" do
|
970
|
+
|
971
|
+
let(:selection) do
|
972
|
+
query.any_of(field: [ 1, 2 ])
|
973
|
+
end
|
974
|
+
|
975
|
+
it_behaves_like 'returns a cloned query'
|
976
|
+
|
977
|
+
it "adds the $or selector" do
|
978
|
+
expect(selection.selector).to eq(
|
979
|
+
"field" => [ 1, 2 ],
|
980
|
+
)
|
981
|
+
end
|
982
|
+
|
983
|
+
context 'when the criterion is wrapped in array' do
|
984
|
+
|
985
|
+
let(:selection) do
|
986
|
+
query.any_of([{ field: [ 1, 2 ] }])
|
987
|
+
end
|
988
|
+
|
989
|
+
it_behaves_like 'returns a cloned query'
|
990
|
+
|
991
|
+
it "adds the condition" do
|
992
|
+
expect(selection.selector).to eq(
|
993
|
+
"field" => [ 1, 2 ],
|
994
|
+
)
|
995
|
+
end
|
996
|
+
|
997
|
+
context 'when the array has nil as one of the elements' do
|
998
|
+
|
999
|
+
let(:selection) do
|
1000
|
+
query.any_of([{ field: [ 1, 2 ] }, nil])
|
1001
|
+
end
|
1002
|
+
|
1003
|
+
it_behaves_like 'returns a cloned query'
|
1004
|
+
|
1005
|
+
it "adds the $or selector ignoring the nil element" do
|
1006
|
+
expect(selection.selector).to eq(
|
1007
|
+
"field" => [ 1, 2 ],
|
1008
|
+
)
|
1009
|
+
end
|
1010
|
+
end
|
1011
|
+
end
|
1012
|
+
|
1013
|
+
context 'when query already has a condition on another field' do
|
1014
|
+
|
1015
|
+
context 'when there is one argument' do
|
1016
|
+
|
1017
|
+
let(:selection) do
|
1018
|
+
query.where(foo: 'bar').any_of(field: [ 1, 2 ])
|
1019
|
+
end
|
1020
|
+
|
1021
|
+
it 'adds the new condition' do
|
1022
|
+
expect(selection.selector).to eq(
|
1023
|
+
'foo' => 'bar',
|
1024
|
+
'field' => [1, 2],
|
1025
|
+
)
|
1026
|
+
end
|
1027
|
+
end
|
1028
|
+
|
1029
|
+
context 'when there are multiple arguments' do
|
1030
|
+
|
1031
|
+
let(:selection) do
|
1032
|
+
query.where(foo: 'bar').any_of({field: [ 1, 2 ]}, {hello: 'world'})
|
1033
|
+
end
|
1034
|
+
|
1035
|
+
it 'adds the new condition' do
|
1036
|
+
expect(selection.selector).to eq(
|
1037
|
+
'foo' => 'bar',
|
1038
|
+
'$or' => [
|
1039
|
+
{'field' => [1, 2]},
|
1040
|
+
{'hello' => 'world'},
|
1041
|
+
],
|
1042
|
+
)
|
1043
|
+
end
|
1044
|
+
end
|
1045
|
+
end
|
1046
|
+
|
1047
|
+
context 'when query already has an $or condition and another condition' do
|
1048
|
+
|
1049
|
+
let(:selection) do
|
1050
|
+
query.or(field: [ 1, 2 ]).where(foo: 'bar').any_of(test: 1)
|
1051
|
+
end
|
1052
|
+
|
1053
|
+
it 'adds the new condition' do
|
1054
|
+
expect(selection.selector).to eq(
|
1055
|
+
'$or' => [{'field' => [1, 2]}],
|
1056
|
+
'foo' => 'bar',
|
1057
|
+
'test' => 1,
|
1058
|
+
)
|
1059
|
+
end
|
1060
|
+
end
|
1061
|
+
end
|
1062
|
+
|
1063
|
+
context "when provided multiple criteria" do
|
1064
|
+
|
1065
|
+
context "when the criteria are for different fields" do
|
1066
|
+
|
1067
|
+
let(:selection) do
|
1068
|
+
query.any_of({ first: [ 1, 2 ] }, { second: [ 3, 4 ] })
|
1069
|
+
end
|
1070
|
+
|
1071
|
+
it_behaves_like 'returns a cloned query'
|
1072
|
+
|
1073
|
+
it "adds the $or selector" do
|
1074
|
+
expect(selection.selector).to eq({
|
1075
|
+
"$or" => [
|
1076
|
+
{ "first" => [ 1, 2 ] },
|
1077
|
+
{ "second" => [ 3, 4 ] }
|
1078
|
+
]
|
1079
|
+
})
|
1080
|
+
end
|
1081
|
+
end
|
1082
|
+
|
1083
|
+
context "when the criteria uses a Key instance" do
|
1084
|
+
|
1085
|
+
let(:selection) do
|
1086
|
+
query.any_of({ first: [ 1, 2 ] }, { :second.gt => 3 })
|
1087
|
+
end
|
1088
|
+
|
1089
|
+
it "adds the $or selector" do
|
1090
|
+
expect(selection.selector).to eq({
|
1091
|
+
"$or" => [
|
1092
|
+
{ "first" => [ 1, 2 ] },
|
1093
|
+
{ "second" => { "$gt" => 3 }}
|
1094
|
+
]
|
1095
|
+
})
|
1096
|
+
end
|
1097
|
+
|
1098
|
+
it_behaves_like 'returns a cloned query'
|
1099
|
+
end
|
1100
|
+
|
1101
|
+
context "when a criterion has an aliased field" do
|
1102
|
+
|
1103
|
+
let(:selection) do
|
1104
|
+
query.any_of({ id: 1 })
|
1105
|
+
end
|
1106
|
+
|
1107
|
+
it "adds the $or selector and aliases the field" do
|
1108
|
+
expect(selection.selector).to eq(
|
1109
|
+
"_id" => 1,
|
1110
|
+
)
|
1111
|
+
end
|
1112
|
+
|
1113
|
+
it_behaves_like 'returns a cloned query'
|
1114
|
+
end
|
1115
|
+
|
1116
|
+
context "when a criterion is wrapped in an array" do
|
1117
|
+
|
1118
|
+
let(:selection) do
|
1119
|
+
query.any_of([{ first: [ 1, 2 ] }, { :second.gt => 3 }])
|
1120
|
+
end
|
1121
|
+
|
1122
|
+
it_behaves_like 'returns a cloned query'
|
1123
|
+
|
1124
|
+
it "adds the $or selector" do
|
1125
|
+
expect(selection.selector).to eq({
|
1126
|
+
"$or" => [
|
1127
|
+
{ "first" => [ 1, 2 ] },
|
1128
|
+
{ "second" => { "$gt" => 3 }}
|
1129
|
+
]
|
1130
|
+
})
|
1131
|
+
end
|
1132
|
+
end
|
1133
|
+
|
1134
|
+
context "when the criteria are on the same field" do
|
1135
|
+
|
1136
|
+
let(:selection) do
|
1137
|
+
query.any_of({ first: [ 1, 2 ] }, { first: [ 3, 4 ] })
|
1138
|
+
end
|
1139
|
+
|
1140
|
+
it_behaves_like 'returns a cloned query'
|
1141
|
+
|
1142
|
+
it "appends both $or expressions" do
|
1143
|
+
expect(selection.selector).to eq({
|
1144
|
+
"$or" => [
|
1145
|
+
{ "first" => [ 1, 2 ] },
|
1146
|
+
{ "first" => [ 3, 4 ] }
|
1147
|
+
]
|
1148
|
+
})
|
1149
|
+
end
|
1150
|
+
end
|
1151
|
+
end
|
1152
|
+
|
1153
|
+
context "when chaining the criteria" do
|
1154
|
+
|
1155
|
+
context "when the criteria are for different fields" do
|
1156
|
+
|
1157
|
+
let(:selection) do
|
1158
|
+
query.any_of(first: [ 1, 2 ]).any_of(second: [ 3, 4 ])
|
1159
|
+
end
|
1160
|
+
|
1161
|
+
it_behaves_like 'returns a cloned query'
|
1162
|
+
|
1163
|
+
it "adds the conditions separately" do
|
1164
|
+
expect(selection.selector).to eq(
|
1165
|
+
"first" => [ 1, 2 ],
|
1166
|
+
"second" => [ 3, 4 ],
|
1167
|
+
)
|
1168
|
+
end
|
1169
|
+
end
|
1170
|
+
|
1171
|
+
context "when the criteria are on the same field" do
|
1172
|
+
|
1173
|
+
let(:selection) do
|
1174
|
+
query.any_of(first: [ 1, 2 ]).any_of(first: [ 3, 4 ])
|
1175
|
+
end
|
1176
|
+
|
1177
|
+
it_behaves_like 'returns a cloned query'
|
1178
|
+
|
1179
|
+
it "adds the conditions separately" do
|
1180
|
+
expect(selection.selector).to eq(
|
1181
|
+
"first" => [ 1, 2 ],
|
1182
|
+
'$and' => [{"first" => [ 3, 4 ]}],
|
1183
|
+
)
|
1184
|
+
end
|
1185
|
+
end
|
1186
|
+
end
|
1187
|
+
end
|
1188
|
+
|
812
1189
|
describe "#not" do
|
813
1190
|
|
814
1191
|
context "when provided no criterion" do
|