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.
Files changed (35) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/lib/mongoid/attributes.rb +8 -1
  5. data/lib/mongoid/matcher.rb +19 -43
  6. data/lib/mongoid/matcher/elem_match.rb +2 -1
  7. data/lib/mongoid/matcher/expression.rb +5 -14
  8. data/lib/mongoid/matcher/field_expression.rb +4 -5
  9. data/lib/mongoid/reloadable.rb +5 -0
  10. data/lib/mongoid/version.rb +1 -1
  11. data/lib/rails/generators/mongoid/config/config_generator.rb +8 -1
  12. data/spec/integration/app_spec.rb +136 -82
  13. data/spec/integration/document_spec.rb +21 -0
  14. data/spec/integration/matcher_operator_data/elem_match.yml +46 -0
  15. data/spec/integration/matcher_operator_data/implicit_traversal.yml +96 -0
  16. data/spec/lite_spec_helper.rb +2 -3
  17. data/spec/mongoid/attributes_spec.rb +241 -0
  18. data/spec/mongoid/contextual/atomic_spec.rb +17 -4
  19. data/spec/mongoid/matcher/extract_attribute_data/numeric_keys.yml +104 -0
  20. data/spec/mongoid/matcher/extract_attribute_data/traversal.yml +68 -88
  21. data/spec/mongoid/matcher/extract_attribute_spec.rb +3 -13
  22. data/spec/mongoid/persistable/settable_spec.rb +30 -0
  23. data/spec/shared/bin/get-mongodb-download-url +17 -0
  24. data/spec/shared/lib/mrss/cluster_config.rb +11 -1
  25. data/spec/shared/lib/mrss/constraints.rb +18 -2
  26. data/spec/shared/lib/mrss/docker_runner.rb +3 -0
  27. data/spec/shared/lib/mrss/lite_constraints.rb +16 -0
  28. data/spec/shared/lib/mrss/server_version_registry.rb +79 -33
  29. data/spec/shared/lib/mrss/spec_organizer.rb +3 -0
  30. data/spec/shared/lib/mrss/utils.rb +15 -0
  31. data/spec/shared/share/Dockerfile.erb +13 -11
  32. data/spec/shared/shlib/server.sh +29 -9
  33. data/spec/support/spec_config.rb +8 -0
  34. metadata +8 -2
  35. 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
@@ -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
- # Allow 5 minutes per test for the app tests, since they install
57
- # gems for Rails applications which can take a long time.
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