mongoid 7.2.1 → 7.2.2

Sign up to get free protection for your applications and to get access to all the features.
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