mongoid 8.0.5 → 8.0.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/lib/mongoid/association/macros.rb +6 -0
- data/lib/mongoid/attributes/processing.rb +29 -5
- data/lib/mongoid/config/options.rb +3 -0
- data/lib/mongoid/config.rb +30 -0
- data/lib/mongoid/contextual/mongo.rb +24 -1
- data/lib/mongoid/criteria/queryable/selector.rb +1 -1
- data/lib/mongoid/criteria/queryable/storable.rb +1 -1
- data/lib/mongoid/deprecable.rb +3 -2
- data/lib/mongoid/deprecation.rb +3 -3
- data/lib/mongoid/extensions/hash.rb +24 -2
- data/lib/mongoid/fields.rb +45 -18
- data/lib/mongoid/interceptable.rb +122 -13
- data/lib/mongoid/version.rb +1 -1
- data/spec/integration/callbacks_spec.rb +20 -0
- data/spec/mongoid/attributes_spec.rb +27 -0
- data/spec/mongoid/config_spec.rb +11 -2
- data/spec/mongoid/contextual/mongo_spec.rb +89 -14
- data/spec/mongoid/copyable_spec.rb +1 -1
- data/spec/mongoid/criteria/queryable/selector_spec.rb +75 -2
- data/spec/mongoid/criteria/queryable/storable_spec.rb +72 -0
- data/spec/mongoid/extensions/hash_spec.rb +3 -3
- data/spec/mongoid/fields_spec.rb +43 -0
- data/spec/mongoid/interceptable_spec.rb +362 -161
- data/spec/shared/lib/mrss/docker_runner.rb +7 -0
- data/spec/shared/lib/mrss/event_subscriber.rb +15 -5
- data/spec/shared/lib/mrss/lite_constraints.rb +10 -2
- data/spec/shared/lib/mrss/server_version_registry.rb +16 -23
- data/spec/shared/lib/mrss/utils.rb +28 -6
- data/spec/shared/share/Dockerfile.erb +36 -40
- data/spec/shared/shlib/server.sh +32 -8
- data/spec/shared/shlib/set_env.sh +4 -4
- data/spec/support/models/person.rb +1 -0
- data/spec/support/models/purse.rb +9 -0
- data.tar.gz.sig +0 -0
- metadata +10 -8
- metadata.gz.sig +0 -0
@@ -158,6 +158,16 @@ describe Mongoid::Contextual::Mongo do
|
|
158
158
|
end
|
159
159
|
end
|
160
160
|
end
|
161
|
+
|
162
|
+
context 'when for_js is present' do
|
163
|
+
let(:context) do
|
164
|
+
Band.for_js('this.name == "Depeche Mode"')
|
165
|
+
end
|
166
|
+
|
167
|
+
it 'counts the expected records' do
|
168
|
+
expect(context.count).to eq(1)
|
169
|
+
end
|
170
|
+
end
|
161
171
|
end
|
162
172
|
|
163
173
|
describe "#estimated_count" do
|
@@ -1179,33 +1189,49 @@ describe Mongoid::Contextual::Mongo do
|
|
1179
1189
|
let!(:person2) { Person.create!(ssn: BSON::Decimal128.new("1")) }
|
1180
1190
|
let(:tally) { Person.tally("ssn") }
|
1181
1191
|
|
1192
|
+
let(:tallied_classes) do
|
1193
|
+
tally.keys.map(&:class).sort do |a, b|
|
1194
|
+
a.to_s.casecmp(b.to_s)
|
1195
|
+
end
|
1196
|
+
end
|
1197
|
+
|
1182
1198
|
context "< BSON 5" do
|
1183
1199
|
max_bson_version '4.99.99'
|
1184
1200
|
|
1185
1201
|
it "stores the correct types in the database" do
|
1186
|
-
Person.find(person1.id).attributes["ssn"].
|
1187
|
-
Person.find(person2.id).attributes["ssn"].
|
1202
|
+
expect(Person.find(person1.id).attributes["ssn"]).to be_a BSON::Regexp::Raw
|
1203
|
+
expect(Person.find(person2.id).attributes["ssn"]).to be_a BSON::Decimal128
|
1204
|
+
end
|
1205
|
+
|
1206
|
+
it "tallies the correct type" do
|
1207
|
+
expect(tallied_classes).to be == [ BSON::Decimal128, BSON::Regexp::Raw ]
|
1208
|
+
end
|
1209
|
+
end
|
1210
|
+
|
1211
|
+
context '>= BSON 5' do
|
1212
|
+
min_bson_version "5.0"
|
1213
|
+
|
1214
|
+
it "stores the correct types in the database" do
|
1215
|
+
expect(Person.find(person1.id).ssn).to be_a BSON::Regexp::Raw
|
1216
|
+
expect(Person.find(person2.id).ssn).to be_a BigDecimal
|
1188
1217
|
end
|
1189
1218
|
|
1190
1219
|
it "tallies the correct type" do
|
1191
|
-
|
1192
|
-
a.to_s <=> b.to_s
|
1193
|
-
end.should == [BSON::Decimal128, BSON::Regexp::Raw]
|
1220
|
+
expect(tallied_classes).to be == [ BigDecimal, BSON::Regexp::Raw ]
|
1194
1221
|
end
|
1195
1222
|
end
|
1196
1223
|
|
1197
|
-
context
|
1224
|
+
context '>= BSON 5 with decimal128 allowed' do
|
1198
1225
|
min_bson_version "5.0"
|
1226
|
+
config_override :allow_bson5_decimal128, true
|
1199
1227
|
|
1200
1228
|
it "stores the correct types in the database" do
|
1201
|
-
Person.find(person1.id).ssn.
|
1202
|
-
Person.find(person2.id).ssn.
|
1229
|
+
expect(Person.find(person1.id).ssn).to be_a BSON::Regexp::Raw
|
1230
|
+
expect(Person.find(person2.id).ssn).to be_a BSON::Decimal128
|
1203
1231
|
end
|
1204
1232
|
|
1205
1233
|
it "tallies the correct type" do
|
1206
|
-
|
1207
|
-
a.to_s <=> b.to_s
|
1208
|
-
end.should == [BigDecimal, BSON::Regexp::Raw]
|
1234
|
+
expect(tallied_classes).to be == [ BSON::Decimal128, BSON::Regexp::Raw ]
|
1209
1235
|
end
|
1210
1236
|
end
|
1211
1237
|
end
|
@@ -3547,16 +3573,65 @@ describe Mongoid::Contextual::Mongo do
|
|
3547
3573
|
|
3548
3574
|
context "when the attributes are in the correct type" do
|
3549
3575
|
|
3576
|
+
context "when operation is $set" do
|
3577
|
+
|
3578
|
+
before do
|
3579
|
+
context.update_all("$set" => { name: "Smiths" })
|
3580
|
+
end
|
3581
|
+
|
3582
|
+
it "updates the first matching document" do
|
3583
|
+
expect(depeche_mode.reload.name).to eq("Smiths")
|
3584
|
+
end
|
3585
|
+
|
3586
|
+
it "updates the last matching document" do
|
3587
|
+
expect(new_order.reload.name).to eq("Smiths")
|
3588
|
+
end
|
3589
|
+
end
|
3590
|
+
|
3591
|
+
context "when operation is $push" do
|
3592
|
+
|
3593
|
+
before do
|
3594
|
+
depeche_mode.update_attribute(:genres, ["electronic"])
|
3595
|
+
new_order.update_attribute(:genres, ["electronic"])
|
3596
|
+
context.update_all("$push" => { genres: "pop" })
|
3597
|
+
end
|
3598
|
+
|
3599
|
+
it "updates the first matching document" do
|
3600
|
+
expect(depeche_mode.reload.genres).to eq(["electronic", "pop"])
|
3601
|
+
end
|
3602
|
+
|
3603
|
+
it "updates the last matching document" do
|
3604
|
+
expect(new_order.reload.genres).to eq(["electronic", "pop"])
|
3605
|
+
end
|
3606
|
+
end
|
3607
|
+
|
3608
|
+
context "when operation is $addToSet" do
|
3609
|
+
|
3610
|
+
before do
|
3611
|
+
context.update_all("$addToSet" => { genres: "electronic" })
|
3612
|
+
end
|
3613
|
+
|
3614
|
+
it "updates the first matching document" do
|
3615
|
+
expect(depeche_mode.reload.genres).to eq(["electronic"])
|
3616
|
+
end
|
3617
|
+
|
3618
|
+
it "updates the last matching document" do
|
3619
|
+
expect(new_order.reload.genres).to eq(["electronic"])
|
3620
|
+
end
|
3621
|
+
end
|
3622
|
+
end
|
3623
|
+
|
3624
|
+
context 'when using aliased field names' do
|
3550
3625
|
before do
|
3551
|
-
context.update_all(
|
3626
|
+
context.update_all('$set' => { years: 100 })
|
3552
3627
|
end
|
3553
3628
|
|
3554
3629
|
it "updates the first matching document" do
|
3555
|
-
expect(depeche_mode.reload.
|
3630
|
+
expect(depeche_mode.reload.years).to eq(100)
|
3556
3631
|
end
|
3557
3632
|
|
3558
3633
|
it "updates the last matching document" do
|
3559
|
-
expect(new_order.reload.
|
3634
|
+
expect(new_order.reload.years).to eq(100)
|
3560
3635
|
end
|
3561
3636
|
end
|
3562
3637
|
|
@@ -90,7 +90,7 @@ describe Mongoid::Copyable do
|
|
90
90
|
end
|
91
91
|
|
92
92
|
it 'calls constructor with explicitly declared attributes only' do
|
93
|
-
expect(Mongoid::Factory).to receive(:build).with(cls, 'name' => 'test').and_call_original
|
93
|
+
expect(Mongoid::Factory).to receive(:build).with(cls, { 'name' => 'test' }).and_call_original
|
94
94
|
cloned
|
95
95
|
end
|
96
96
|
end
|
@@ -44,7 +44,7 @@ describe Mongoid::Criteria::Queryable::Selector do
|
|
44
44
|
end
|
45
45
|
end
|
46
46
|
|
47
|
-
context "when selector contains a $nin" do
|
47
|
+
context "when selector contains a $nin string" do
|
48
48
|
|
49
49
|
let(:initial) do
|
50
50
|
{ "$nin" => ["foo"] }
|
@@ -72,7 +72,35 @@ describe Mongoid::Criteria::Queryable::Selector do
|
|
72
72
|
end
|
73
73
|
end
|
74
74
|
|
75
|
-
context "when selector contains a $
|
75
|
+
context "when selector contains a $nin symbol" do
|
76
|
+
|
77
|
+
let(:initial) do
|
78
|
+
{ :$nin => ["foo"] }
|
79
|
+
end
|
80
|
+
|
81
|
+
before do
|
82
|
+
selector["field"] = initial
|
83
|
+
end
|
84
|
+
|
85
|
+
context "when merging in a new $nin" do
|
86
|
+
|
87
|
+
let(:other) do
|
88
|
+
{ "field" => { :$nin => ["bar"] } }
|
89
|
+
end
|
90
|
+
|
91
|
+
before do
|
92
|
+
selector.merge!(other)
|
93
|
+
end
|
94
|
+
|
95
|
+
it "combines the two $nin queries into one" do
|
96
|
+
expect(selector).to eq({
|
97
|
+
"field" => { :$nin => ["foo", "bar"] }
|
98
|
+
})
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
context "when selector contains a $in string" do
|
76
104
|
|
77
105
|
let(:initial) do
|
78
106
|
{ "$in" => [1, 2] }
|
@@ -117,6 +145,51 @@ describe Mongoid::Criteria::Queryable::Selector do
|
|
117
145
|
end
|
118
146
|
end
|
119
147
|
|
148
|
+
context "when selector contains a $in symbol" do
|
149
|
+
|
150
|
+
let(:initial) do
|
151
|
+
{ :$in => [1, 2] }
|
152
|
+
end
|
153
|
+
|
154
|
+
before do
|
155
|
+
selector["field"] = initial
|
156
|
+
end
|
157
|
+
|
158
|
+
context "when merging in a new $in with an intersecting value" do
|
159
|
+
|
160
|
+
let(:other) do
|
161
|
+
{ "field" => { :$in => [1] } }
|
162
|
+
end
|
163
|
+
|
164
|
+
before do
|
165
|
+
selector.merge!(other)
|
166
|
+
end
|
167
|
+
|
168
|
+
it "intersects the $in values" do
|
169
|
+
expect(selector).to eq({
|
170
|
+
"field" => { :$in => [1] }
|
171
|
+
})
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
context "when merging in a new $in with no intersecting values" do
|
176
|
+
|
177
|
+
let(:other) do
|
178
|
+
{ "field" => { :$in => [3] } }
|
179
|
+
end
|
180
|
+
|
181
|
+
before do
|
182
|
+
selector.merge!(other)
|
183
|
+
end
|
184
|
+
|
185
|
+
it "intersects the $in values" do
|
186
|
+
expect(selector).to eq({
|
187
|
+
"field" => { :$in => [] }
|
188
|
+
})
|
189
|
+
end
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
120
193
|
context "when selector is not nested" do
|
121
194
|
|
122
195
|
before do
|
@@ -210,7 +210,79 @@ describe Mongoid::Criteria::Queryable::Storable do
|
|
210
210
|
}
|
211
211
|
end
|
212
212
|
end
|
213
|
+
|
214
|
+
context 'when value is a hash combine values with different operator keys' do
|
215
|
+
let(:base) do
|
216
|
+
query.add_field_expression('foo', {'$in' => ['bar']})
|
217
|
+
end
|
218
|
+
|
219
|
+
let(:modified) do
|
220
|
+
base.add_field_expression('foo', {'$nin' => ['zoom']})
|
221
|
+
end
|
222
|
+
|
223
|
+
it 'combines the conditions using $and' do
|
224
|
+
modified.selector.should == {
|
225
|
+
'foo' => {
|
226
|
+
'$in' => ['bar'],
|
227
|
+
'$nin' => ['zoom']
|
228
|
+
}
|
229
|
+
}
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
context 'when value is a hash with symbol operator key combine values with different operator keys' do
|
234
|
+
let(:base) do
|
235
|
+
query.add_field_expression('foo', {:$in => ['bar']})
|
236
|
+
end
|
237
|
+
|
238
|
+
let(:modified) do
|
239
|
+
base.add_field_expression('foo', {:$nin => ['zoom']})
|
240
|
+
end
|
241
|
+
|
242
|
+
it 'combines the conditions using $and' do
|
243
|
+
modified.selector.should == {
|
244
|
+
'foo' => {
|
245
|
+
:$in => ['bar'],
|
246
|
+
:$nin => ['zoom']
|
247
|
+
}
|
248
|
+
}
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
context 'when value is a hash add values with same operator keys using $and' do
|
253
|
+
let(:base) do
|
254
|
+
query.add_field_expression('foo', {'$in' => ['bar']})
|
255
|
+
end
|
256
|
+
|
257
|
+
let(:modified) do
|
258
|
+
base.add_field_expression('foo', {'$in' => ['zoom']})
|
259
|
+
end
|
260
|
+
|
261
|
+
it 'adds the new condition using $and' do
|
262
|
+
modified.selector.should == {
|
263
|
+
'foo' => {'$in' => ['bar']},
|
264
|
+
'$and' => ['foo' => {'$in' => ['zoom']}]
|
265
|
+
}
|
266
|
+
end
|
267
|
+
end
|
268
|
+
|
269
|
+
context 'when value is a hash with symbol operator key add values with same operator keys using $and' do
|
270
|
+
let(:base) do
|
271
|
+
query.add_field_expression('foo', {:$in => ['bar']})
|
272
|
+
end
|
273
|
+
|
274
|
+
let(:modified) do
|
275
|
+
base.add_field_expression('foo', {:$in => ['zoom']})
|
276
|
+
end
|
277
|
+
|
278
|
+
it 'adds the new condition using $and' do
|
279
|
+
modified.selector.should == {
|
280
|
+
'foo' => {:$in => ['bar']},
|
281
|
+
'$and' => ['foo' => {:$in => ['zoom']}]
|
282
|
+
}
|
283
|
+
end
|
213
284
|
end
|
285
|
+
end
|
214
286
|
|
215
287
|
describe '#add_operator_expression' do
|
216
288
|
let(:query_method) { :add_operator_expression }
|
@@ -178,7 +178,7 @@ describe Mongoid::Extensions::Hash do
|
|
178
178
|
|
179
179
|
it "moves the non hash values under the provided key" do
|
180
180
|
expect(consolidated).to eq({
|
181
|
-
"$set" => { name
|
181
|
+
"$set" => { 'name' => "Tool", likes: 10 }, "$inc" => { 'plays' => 1 }
|
182
182
|
})
|
183
183
|
end
|
184
184
|
end
|
@@ -195,7 +195,7 @@ describe Mongoid::Extensions::Hash do
|
|
195
195
|
|
196
196
|
it "moves the non hash values under the provided key" do
|
197
197
|
expect(consolidated).to eq({
|
198
|
-
"$set" => { likes: 10, name
|
198
|
+
"$set" => { likes: 10, 'name' => "Tool" }, "$inc" => { 'plays' => 1 }
|
199
199
|
})
|
200
200
|
end
|
201
201
|
end
|
@@ -213,7 +213,7 @@ describe Mongoid::Extensions::Hash do
|
|
213
213
|
|
214
214
|
it "moves the non hash values under the provided key" do
|
215
215
|
expect(consolidated).to eq({
|
216
|
-
"$set" => { likes: 10, name: "Tool" }, "$inc" => { plays
|
216
|
+
"$set" => { likes: 10, name: "Tool" }, "$inc" => { 'plays' => 1 }
|
217
217
|
})
|
218
218
|
end
|
219
219
|
end
|
data/spec/mongoid/fields_spec.rb
CHANGED
@@ -567,6 +567,49 @@ describe Mongoid::Fields do
|
|
567
567
|
end
|
568
568
|
end
|
569
569
|
end
|
570
|
+
|
571
|
+
context 'when the field is declared as BSON::Decimal128' do
|
572
|
+
let(:document) { Mop.create!(decimal128_field: BSON::Decimal128.new(Math::PI.to_s)).reload }
|
573
|
+
|
574
|
+
shared_context 'BSON::Decimal128 is BigDecimal' do
|
575
|
+
it 'should return a BigDecimal' do
|
576
|
+
expect(document.decimal128_field).to be_a BigDecimal
|
577
|
+
end
|
578
|
+
end
|
579
|
+
|
580
|
+
shared_context 'BSON::Decimal128 is BSON::Decimal128' do
|
581
|
+
it 'should return a BSON::Decimal128' do
|
582
|
+
expect(document.decimal128_field).to be_a BSON::Decimal128
|
583
|
+
end
|
584
|
+
end
|
585
|
+
|
586
|
+
it 'is declared as BSON::Decimal128' do
|
587
|
+
expect(Mop.fields['decimal128_field'].type).to be == BSON::Decimal128
|
588
|
+
end
|
589
|
+
|
590
|
+
context 'when BSON version <= 4' do
|
591
|
+
max_bson_version '4.99.99'
|
592
|
+
it_behaves_like 'BSON::Decimal128 is BSON::Decimal128'
|
593
|
+
end
|
594
|
+
|
595
|
+
context 'when BSON version >= 5' do
|
596
|
+
min_bson_version '5.0.0'
|
597
|
+
|
598
|
+
context 'when allow_bson5_decimal128 is false' do
|
599
|
+
config_override :allow_bson5_decimal128, false
|
600
|
+
it_behaves_like 'BSON::Decimal128 is BigDecimal'
|
601
|
+
end
|
602
|
+
|
603
|
+
context 'when allow_bson5_decimal128 is true' do
|
604
|
+
config_override :allow_bson5_decimal128, true
|
605
|
+
it_behaves_like 'BSON::Decimal128 is BSON::Decimal128'
|
606
|
+
end
|
607
|
+
|
608
|
+
context 'when allow_bson5_decimal128 is default' do
|
609
|
+
it_behaves_like 'BSON::Decimal128 is BigDecimal'
|
610
|
+
end
|
611
|
+
end
|
612
|
+
end
|
570
613
|
end
|
571
614
|
|
572
615
|
describe "#getter_before_type_cast" do
|