mongoid 8.0.5 → 8.0.7
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/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
|