mongoid 7.2.1 → 7.2.2
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/lib/mongoid/attributes.rb +8 -1
- data/lib/mongoid/matcher.rb +19 -43
- data/lib/mongoid/matcher/elem_match.rb +2 -1
- data/lib/mongoid/matcher/expression.rb +5 -14
- data/lib/mongoid/matcher/field_expression.rb +4 -5
- data/lib/mongoid/reloadable.rb +5 -0
- data/lib/mongoid/version.rb +1 -1
- data/lib/rails/generators/mongoid/config/config_generator.rb +8 -1
- data/spec/integration/app_spec.rb +136 -82
- data/spec/integration/document_spec.rb +21 -0
- data/spec/integration/matcher_operator_data/elem_match.yml +46 -0
- data/spec/integration/matcher_operator_data/implicit_traversal.yml +96 -0
- data/spec/lite_spec_helper.rb +2 -3
- data/spec/mongoid/attributes_spec.rb +241 -0
- data/spec/mongoid/contextual/atomic_spec.rb +17 -4
- data/spec/mongoid/matcher/extract_attribute_data/numeric_keys.yml +104 -0
- data/spec/mongoid/matcher/extract_attribute_data/traversal.yml +68 -88
- data/spec/mongoid/matcher/extract_attribute_spec.rb +3 -13
- data/spec/mongoid/persistable/settable_spec.rb +30 -0
- data/spec/shared/bin/get-mongodb-download-url +17 -0
- data/spec/shared/lib/mrss/cluster_config.rb +11 -1
- data/spec/shared/lib/mrss/constraints.rb +18 -2
- data/spec/shared/lib/mrss/docker_runner.rb +3 -0
- data/spec/shared/lib/mrss/lite_constraints.rb +16 -0
- data/spec/shared/lib/mrss/server_version_registry.rb +79 -33
- data/spec/shared/lib/mrss/spec_organizer.rb +3 -0
- data/spec/shared/lib/mrss/utils.rb +15 -0
- data/spec/shared/share/Dockerfile.erb +13 -11
- data/spec/shared/shlib/server.sh +29 -9
- data/spec/support/spec_config.rb +8 -0
- metadata +8 -2
- metadata.gz.sig +0 -0
@@ -19,4 +19,25 @@ describe Mongoid::Document do
|
|
19
19
|
DelegatingPatient.default_client.should be Mongoid.default_client
|
20
20
|
end
|
21
21
|
end
|
22
|
+
|
23
|
+
describe '#reload' do
|
24
|
+
context 'when changing shard key value' do
|
25
|
+
require_topology :sharded
|
26
|
+
|
27
|
+
let(:profile) do
|
28
|
+
# Profile shard_key :name
|
29
|
+
Profile.create!(name: "Alice")
|
30
|
+
end
|
31
|
+
|
32
|
+
it "successfully reloads the document after saving an update to the sharded field" do
|
33
|
+
expect(profile.name).to eq("Alice")
|
34
|
+
profile.name = "Bob"
|
35
|
+
profile.save!
|
36
|
+
|
37
|
+
profile.reload
|
38
|
+
|
39
|
+
expect(profile.name).to eq("Bob")
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
22
43
|
end
|
@@ -361,3 +361,49 @@
|
|
361
361
|
# https://jira.mongodb.org/browse/MONGOID-4908
|
362
362
|
matches: false
|
363
363
|
error: [matcher, driver]
|
364
|
+
|
365
|
+
- name: $elemMatch given as symbol
|
366
|
+
document:
|
367
|
+
tags:
|
368
|
+
- intelligent
|
369
|
+
query:
|
370
|
+
tags:
|
371
|
+
:$elemMatch:
|
372
|
+
$eq: intelligent
|
373
|
+
matches: true
|
374
|
+
|
375
|
+
- name: $elemMatch given as symbol - document does not contain the matched field
|
376
|
+
document:
|
377
|
+
query:
|
378
|
+
tags:
|
379
|
+
:$elemMatch:
|
380
|
+
$eq: intelligent
|
381
|
+
matches: false
|
382
|
+
|
383
|
+
- name: $elemMatch argument operator given as symbol - matches
|
384
|
+
document:
|
385
|
+
tags:
|
386
|
+
- intelligent
|
387
|
+
query:
|
388
|
+
tags:
|
389
|
+
$elemMatch:
|
390
|
+
:$eq: intelligent
|
391
|
+
matches: true
|
392
|
+
|
393
|
+
- name: $elemMatch argument operator given as symbol - does not match
|
394
|
+
document:
|
395
|
+
tags:
|
396
|
+
- intelligent
|
397
|
+
query:
|
398
|
+
tags:
|
399
|
+
$elemMatch:
|
400
|
+
:$eq: intelli
|
401
|
+
matches: false
|
402
|
+
|
403
|
+
- name: $elemMatch argument operator given as symbol - document does not contain the matched field
|
404
|
+
document:
|
405
|
+
query:
|
406
|
+
tags:
|
407
|
+
$elemMatch:
|
408
|
+
:$eq: intelli
|
409
|
+
matches: false
|
@@ -14,3 +14,99 @@
|
|
14
14
|
query:
|
15
15
|
foo.bar: 2
|
16
16
|
matches: true
|
17
|
+
|
18
|
+
- name: numeric key - matches
|
19
|
+
document: &numeric-key
|
20
|
+
foo:
|
21
|
+
'42':
|
22
|
+
bar: 1
|
23
|
+
query:
|
24
|
+
foo.42.bar: 1
|
25
|
+
matches: true
|
26
|
+
|
27
|
+
- name: numeric key - does not match
|
28
|
+
document: *numeric-key
|
29
|
+
query:
|
30
|
+
foo.142.bar: 1
|
31
|
+
matches: false
|
32
|
+
|
33
|
+
- name: array under numeric key - matches
|
34
|
+
document: &numeric-key-array
|
35
|
+
foo:
|
36
|
+
'42':
|
37
|
+
-
|
38
|
+
bar: 1
|
39
|
+
query:
|
40
|
+
foo.42.bar: 1
|
41
|
+
matches: true
|
42
|
+
|
43
|
+
- name: array under numeric key - does not match
|
44
|
+
document: *numeric-key-array
|
45
|
+
query:
|
46
|
+
foo.142.bar: 1
|
47
|
+
matches: false
|
48
|
+
|
49
|
+
- name: numeric key under array - matches
|
50
|
+
document: &array-numeric-key
|
51
|
+
foo:
|
52
|
+
-
|
53
|
+
'42':
|
54
|
+
bar: 1
|
55
|
+
query:
|
56
|
+
foo.42.bar: 1
|
57
|
+
matches: true
|
58
|
+
|
59
|
+
- name: numeric key under array - does not match
|
60
|
+
document: *array-numeric-key
|
61
|
+
query:
|
62
|
+
foo.142.bar: 1
|
63
|
+
matches: false
|
64
|
+
|
65
|
+
- name: numeric key eligible as both array index and hash key - matches array index
|
66
|
+
document: &numeric-key-mixed
|
67
|
+
foo:
|
68
|
+
-
|
69
|
+
'1':
|
70
|
+
bar: 1
|
71
|
+
-
|
72
|
+
'1':
|
73
|
+
bar: 2
|
74
|
+
query:
|
75
|
+
foo.1:
|
76
|
+
'1':
|
77
|
+
bar: 2
|
78
|
+
matches: true
|
79
|
+
|
80
|
+
- name: numeric key eligible as both array index and hash key - does not match array index
|
81
|
+
document: *numeric-key-mixed
|
82
|
+
query:
|
83
|
+
foo.1:
|
84
|
+
# The second array item has bar: 2, bar: 1 is not matched
|
85
|
+
'1':
|
86
|
+
bar: 1
|
87
|
+
matches: false
|
88
|
+
|
89
|
+
- name: numeric key eligible as both array index and hash key - matches hash key
|
90
|
+
document: *numeric-key-mixed
|
91
|
+
query:
|
92
|
+
foo.1:
|
93
|
+
# Both bar: 1 and bar: 2 are ok, 1 in query matches the key under each
|
94
|
+
# array element
|
95
|
+
bar: 2
|
96
|
+
matches: true
|
97
|
+
|
98
|
+
- name: numeric key eligible as both array index and hash key - matches hash key again
|
99
|
+
document: *numeric-key-mixed
|
100
|
+
query:
|
101
|
+
foo.1:
|
102
|
+
# Both bar: 1 and bar: 2 are ok, 1 in query matches the key under each
|
103
|
+
# array element
|
104
|
+
bar: 1
|
105
|
+
matches: true
|
106
|
+
|
107
|
+
- name: numeric key eligible as both array index and hash key - does not match hash key
|
108
|
+
document: *numeric-key-mixed
|
109
|
+
query:
|
110
|
+
foo.0:
|
111
|
+
bar: 2
|
112
|
+
matches: false
|
data/spec/lite_spec_helper.rb
CHANGED
@@ -53,9 +53,8 @@ RSpec.configure do |config|
|
|
53
53
|
|
54
54
|
if SpecConfig.instance.ci? && !%w(1 true yes).include?(ENV['INTERACTIVE']&.downcase)
|
55
55
|
timeout = if SpecConfig.instance.app_tests?
|
56
|
-
#
|
57
|
-
|
58
|
-
300
|
56
|
+
# App tests under JRuby take a REALLY long time (over 5 minutes per test).
|
57
|
+
500
|
59
58
|
else
|
60
59
|
# Allow a max of 30 seconds per test.
|
61
60
|
# Tests should take under 10 seconds ideally but it seems
|
@@ -245,6 +245,97 @@ describe Mongoid::Attributes do
|
|
245
245
|
end
|
246
246
|
end
|
247
247
|
|
248
|
+
context "when the field was not explicitly defined" do
|
249
|
+
|
250
|
+
context "when excluding with only and the field was not excluded" do
|
251
|
+
|
252
|
+
let(:from_db) do
|
253
|
+
Person.only(:_id).first
|
254
|
+
end
|
255
|
+
|
256
|
+
it "raises an error" do
|
257
|
+
expect {
|
258
|
+
from_db[:undefined_field]
|
259
|
+
}.to raise_error(ActiveModel::MissingAttributeError)
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
263
|
+
context "when excluding with without and the field was excluded" do
|
264
|
+
|
265
|
+
let(:from_db) do
|
266
|
+
Person.without(:title).first
|
267
|
+
end
|
268
|
+
|
269
|
+
it "raises an error" do
|
270
|
+
expect {
|
271
|
+
from_db[:title]
|
272
|
+
}.to raise_error(ActiveModel::MissingAttributeError)
|
273
|
+
end
|
274
|
+
end
|
275
|
+
|
276
|
+
context "when excluding with without and the field was not excluded" do
|
277
|
+
|
278
|
+
let(:from_db) do
|
279
|
+
Person.without(:title).first
|
280
|
+
end
|
281
|
+
|
282
|
+
it "returns nil" do
|
283
|
+
from_db[:undefined_field].should be nil
|
284
|
+
end
|
285
|
+
end
|
286
|
+
end
|
287
|
+
|
288
|
+
context 'when projecting with #only' do
|
289
|
+
let!(:person) do
|
290
|
+
Person.create(title: 'sir', name: { first_name: 'Jose', language: { name: 'es' } })
|
291
|
+
end
|
292
|
+
|
293
|
+
context 'when projecting an embedded association' do
|
294
|
+
let(:from_db) do
|
295
|
+
Person.only(:name).first
|
296
|
+
end
|
297
|
+
|
298
|
+
context 'when retrieving a field of the association using the dot notation' do
|
299
|
+
|
300
|
+
it 'retrieves the field' do
|
301
|
+
pending 'MONGOID-5032, fixed in 7.3'
|
302
|
+
|
303
|
+
expect(from_db['name.first_name']).to eq 'Jose'
|
304
|
+
end
|
305
|
+
end
|
306
|
+
|
307
|
+
context 'when retrieving a field of a nested association using the dot notation' do
|
308
|
+
it 'retrieves the field' do
|
309
|
+
pending 'MONGOID-5032, fixed in 7.3'
|
310
|
+
|
311
|
+
expect(from_db['name.language.name']).to eq 'es'
|
312
|
+
end
|
313
|
+
end
|
314
|
+
end
|
315
|
+
|
316
|
+
context 'when projecting a sub-association of an embedded association' do
|
317
|
+
let(:from_db) do
|
318
|
+
Person.only('name.language').first
|
319
|
+
end
|
320
|
+
|
321
|
+
context 'when retrieving a field under the projected sub-association' do
|
322
|
+
it 'retrieves the field' do
|
323
|
+
pending 'MONGOID-5032, fixed in 7.3'
|
324
|
+
|
325
|
+
expect(from_db['name.language.name']).to eq 'es'
|
326
|
+
end
|
327
|
+
end
|
328
|
+
|
329
|
+
context 'when retrieving a non-projected field' do
|
330
|
+
it 'raises MissingAttributeError' do
|
331
|
+
expect do
|
332
|
+
from_db['name.first_name']
|
333
|
+
end.to raise_error(ActiveModel::MissingAttributeError)
|
334
|
+
end
|
335
|
+
end
|
336
|
+
end
|
337
|
+
end
|
338
|
+
|
248
339
|
context "when the attribute does not exist" do
|
249
340
|
|
250
341
|
before do
|
@@ -329,6 +420,67 @@ describe Mongoid::Attributes do
|
|
329
420
|
expect(terms).to eq(true)
|
330
421
|
end
|
331
422
|
end
|
423
|
+
|
424
|
+
context 'when the field is not explicitly defined' do
|
425
|
+
let(:bar) { Bar.new }
|
426
|
+
|
427
|
+
before do
|
428
|
+
bar['missing_field'] = 42
|
429
|
+
end
|
430
|
+
|
431
|
+
it 'writes the value into attributes' do
|
432
|
+
bar.attributes.should == {'_id' => bar.id, 'missing_field' => 42}
|
433
|
+
end
|
434
|
+
|
435
|
+
it 'makes the attribute accessible via []' do
|
436
|
+
bar['missing_field'].should == 42
|
437
|
+
end
|
438
|
+
|
439
|
+
context 'when writing fields on a document with projection' do
|
440
|
+
|
441
|
+
let!(:person) do
|
442
|
+
Person.create(title: "sir")
|
443
|
+
end
|
444
|
+
|
445
|
+
context "when excluding with only and the field was not excluded" do
|
446
|
+
|
447
|
+
let(:from_db) do
|
448
|
+
Person.only(:_id).first
|
449
|
+
end
|
450
|
+
|
451
|
+
it "raises an error" do
|
452
|
+
expect {
|
453
|
+
from_db[:undefined_field] = 'x'
|
454
|
+
}.to raise_error(ActiveModel::MissingAttributeError)
|
455
|
+
end
|
456
|
+
end
|
457
|
+
|
458
|
+
context "when excluding with without and the field was excluded" do
|
459
|
+
|
460
|
+
let(:from_db) do
|
461
|
+
Person.without(:title).first
|
462
|
+
end
|
463
|
+
|
464
|
+
it "raises an error" do
|
465
|
+
expect {
|
466
|
+
from_db[:title] = 'x'
|
467
|
+
}.to raise_error(ActiveModel::MissingAttributeError)
|
468
|
+
end
|
469
|
+
end
|
470
|
+
|
471
|
+
context "when excluding with without and the field was not excluded" do
|
472
|
+
|
473
|
+
let(:from_db) do
|
474
|
+
Person.without(:title).first
|
475
|
+
end
|
476
|
+
|
477
|
+
it "writes the value" do
|
478
|
+
from_db[:undefined_field] = 'x'
|
479
|
+
from_db[:undefined_field].should == 'x'
|
480
|
+
end
|
481
|
+
end
|
482
|
+
end
|
483
|
+
end
|
332
484
|
end
|
333
485
|
|
334
486
|
describe "#_id" do
|
@@ -893,6 +1045,50 @@ describe Mongoid::Attributes do
|
|
893
1045
|
expect(person.age_before_type_cast).to eq("old")
|
894
1046
|
end
|
895
1047
|
end
|
1048
|
+
|
1049
|
+
context 'when reading fields on a document with projection' do
|
1050
|
+
|
1051
|
+
let!(:person) do
|
1052
|
+
Person.create(title: "sir")
|
1053
|
+
end
|
1054
|
+
|
1055
|
+
context "when excluding with only and the field was not excluded" do
|
1056
|
+
|
1057
|
+
let(:from_db) do
|
1058
|
+
Person.only(:_id).first
|
1059
|
+
end
|
1060
|
+
|
1061
|
+
it "raises an error" do
|
1062
|
+
expect {
|
1063
|
+
from_db.read_attribute(:undefined_field)
|
1064
|
+
}.to raise_error(ActiveModel::MissingAttributeError)
|
1065
|
+
end
|
1066
|
+
end
|
1067
|
+
|
1068
|
+
context "when excluding with without and the field was excluded" do
|
1069
|
+
|
1070
|
+
let(:from_db) do
|
1071
|
+
Person.without(:title).first
|
1072
|
+
end
|
1073
|
+
|
1074
|
+
it "raises an error" do
|
1075
|
+
expect {
|
1076
|
+
from_db.read_attribute(:title)
|
1077
|
+
}.to raise_error(ActiveModel::MissingAttributeError)
|
1078
|
+
end
|
1079
|
+
end
|
1080
|
+
|
1081
|
+
context "when excluding with without and the field was not excluded" do
|
1082
|
+
|
1083
|
+
let(:from_db) do
|
1084
|
+
Person.without(:title).first
|
1085
|
+
end
|
1086
|
+
|
1087
|
+
it "returns nil" do
|
1088
|
+
from_db.read_attribute(:undefined_field).should be nil
|
1089
|
+
end
|
1090
|
+
end
|
1091
|
+
end
|
896
1092
|
end
|
897
1093
|
|
898
1094
|
describe "#attribute_present?" do
|
@@ -1398,6 +1594,51 @@ describe Mongoid::Attributes do
|
|
1398
1594
|
expect(dictionary.description).to eq('foo')
|
1399
1595
|
end
|
1400
1596
|
end
|
1597
|
+
|
1598
|
+
context 'when writing fields on a document with projection' do
|
1599
|
+
|
1600
|
+
let!(:person) do
|
1601
|
+
Person.create(title: "sir")
|
1602
|
+
end
|
1603
|
+
|
1604
|
+
context "when excluding with only and the field was not excluded" do
|
1605
|
+
|
1606
|
+
let(:from_db) do
|
1607
|
+
Person.only(:_id).first
|
1608
|
+
end
|
1609
|
+
|
1610
|
+
it "raises an error" do
|
1611
|
+
expect {
|
1612
|
+
from_db.write_attribute(:undefined_field, 'x')
|
1613
|
+
}.to raise_error(ActiveModel::MissingAttributeError)
|
1614
|
+
end
|
1615
|
+
end
|
1616
|
+
|
1617
|
+
context "when excluding with without and the field was excluded" do
|
1618
|
+
|
1619
|
+
let(:from_db) do
|
1620
|
+
Person.without(:title).first
|
1621
|
+
end
|
1622
|
+
|
1623
|
+
it "raises an error" do
|
1624
|
+
expect {
|
1625
|
+
from_db.write_attribute(:title, 'x')
|
1626
|
+
}.to raise_error(ActiveModel::MissingAttributeError)
|
1627
|
+
end
|
1628
|
+
end
|
1629
|
+
|
1630
|
+
context "when excluding with without and the field was not excluded" do
|
1631
|
+
|
1632
|
+
let(:from_db) do
|
1633
|
+
Person.without(:title).first
|
1634
|
+
end
|
1635
|
+
|
1636
|
+
it "writes the value" do
|
1637
|
+
from_db.write_attribute(:undefined_field, 'x')
|
1638
|
+
from_db.read_attribute(:undefined_field).should == 'x'
|
1639
|
+
end
|
1640
|
+
end
|
1641
|
+
end
|
1401
1642
|
end
|
1402
1643
|
|
1403
1644
|
describe "#typed_value_for" do
|