mongoid 7.0.12 → 7.0.13
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/Rakefile +31 -0
- data/lib/mongoid/association/embedded/embeds_many/proxy.rb +9 -9
- data/lib/mongoid/association/proxy.rb +14 -1
- data/lib/mongoid/attributes.rb +8 -1
- data/lib/mongoid/version.rb +1 -1
- data/lib/rails/generators/mongoid/config/config_generator.rb +8 -1
- data/spec/integration/app_spec.rb +243 -94
- data/spec/integration/associations/embedded_spec.rb +114 -0
- data/spec/lite_spec_helper.rb +5 -1
- data/spec/mongoid/attributes_spec.rb +241 -0
- data/spec/mongoid/contextual/atomic_spec.rb +17 -4
- data/spec/mongoid/factory_spec.rb +2 -2
- data/spec/mongoid/persistable/savable_spec.rb +4 -4
- 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 +26 -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 +14 -1
- data/spec/shared/lib/mrss/utils.rb +15 -0
- data/spec/shared/share/Dockerfile.erb +15 -13
- data/spec/shared/shlib/server.sh +29 -9
- data/spec/spec_helper.rb +2 -0
- data/spec/support/constraints.rb +0 -226
- data/spec/support/spec_config.rb +8 -0
- metadata +6 -4
- metadata.gz.sig +1 -2
- data/spec/support/child_process_helper.rb +0 -76
@@ -59,4 +59,118 @@ describe 'embedded associations' do
|
|
59
59
|
end
|
60
60
|
end
|
61
61
|
end
|
62
|
+
|
63
|
+
context 'without default order' do
|
64
|
+
let(:congress) do
|
65
|
+
EmmCongress.create!
|
66
|
+
end
|
67
|
+
|
68
|
+
let(:legislator) do
|
69
|
+
EmmLegislator.create!(congress: congress, a: 1)
|
70
|
+
end
|
71
|
+
|
72
|
+
shared_examples_for 'an embedded association' do
|
73
|
+
it 'adds child documents to parent association object' do
|
74
|
+
legislator
|
75
|
+
congress.legislators._target.should == [legislator]
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'adds child documents to parent association object criteria' do
|
79
|
+
legislator
|
80
|
+
congress.legislators.criteria.documents.should == [legislator]
|
81
|
+
end
|
82
|
+
|
83
|
+
it 'populates documents on parent association object' do
|
84
|
+
congress.legislators.documents.should == [legislator]
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'returns created child when referencing embedded association' do
|
88
|
+
congress.legislators.should == [legislator]
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'returns created child when referencing Criteria created from embedded association' do
|
92
|
+
congress.legislators.all.should be_a(Mongoid::Criteria)
|
93
|
+
congress.legislators.all.to_a.should == [legislator]
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
context 'when association was not previously referenced' do
|
98
|
+
before do
|
99
|
+
legislator
|
100
|
+
end
|
101
|
+
|
102
|
+
it_behaves_like 'an embedded association'
|
103
|
+
end
|
104
|
+
|
105
|
+
context 'when association was previously referenced' do
|
106
|
+
before do
|
107
|
+
# This query must be before the product is created
|
108
|
+
congress.legislators.where(a: 1).first
|
109
|
+
|
110
|
+
legislator
|
111
|
+
end
|
112
|
+
|
113
|
+
it_behaves_like 'an embedded association'
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
context 'with default order' do
|
118
|
+
let(:manufactory) do
|
119
|
+
EmmManufactory.create!
|
120
|
+
end
|
121
|
+
|
122
|
+
let(:product) do
|
123
|
+
EmmProduct.create!(manufactory: manufactory, name: 'Car')
|
124
|
+
end
|
125
|
+
|
126
|
+
shared_examples_for 'adds child documents to parent association' do
|
127
|
+
it 'adds child documents to parent association' do
|
128
|
+
manufactory.products._target.should == [product]
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
shared_examples_for 'an embedded association' do
|
133
|
+
it 'adds child documents to parent association object' do
|
134
|
+
product
|
135
|
+
manufactory.products._target.should == [product]
|
136
|
+
end
|
137
|
+
|
138
|
+
it 'adds child documents to parent association object criteria' do
|
139
|
+
product
|
140
|
+
manufactory.products.criteria.documents.should == [product]
|
141
|
+
end
|
142
|
+
|
143
|
+
it 'populates documents on parent association object' do
|
144
|
+
manufactory.products.documents.should == [product]
|
145
|
+
end
|
146
|
+
|
147
|
+
it 'returns created child when referencing embedded association' do
|
148
|
+
manufactory.products.should == [product]
|
149
|
+
end
|
150
|
+
|
151
|
+
it 'returns created child when referencing Criteria created from embedded association' do
|
152
|
+
manufactory.products.all.should be_a(Mongoid::Criteria)
|
153
|
+
manufactory.products.all.to_a.should == [product]
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
context 'when association is not loaded' do
|
158
|
+
before do
|
159
|
+
product
|
160
|
+
end
|
161
|
+
|
162
|
+
it_behaves_like 'an embedded association'
|
163
|
+
end
|
164
|
+
|
165
|
+
context 'when association is loaded' do
|
166
|
+
before do
|
167
|
+
# This query must be before the product is created
|
168
|
+
manufactory.products.where(name: "Car").first
|
169
|
+
|
170
|
+
product
|
171
|
+
end
|
172
|
+
|
173
|
+
it_behaves_like 'an embedded association'
|
174
|
+
end
|
175
|
+
end
|
62
176
|
end
|
data/spec/lite_spec_helper.rb
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
4
4
|
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), "..", "lib"))
|
5
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), "shared", "lib"))
|
5
6
|
|
6
7
|
require "mongoid"
|
7
8
|
|
@@ -12,6 +13,7 @@ require "mongoid"
|
|
12
13
|
require 'pp'
|
13
14
|
|
14
15
|
require 'support/spec_config'
|
16
|
+
require 'mrss/lite_constraints'
|
15
17
|
require "support/session_registry"
|
16
18
|
|
17
19
|
unless SpecConfig.instance.ci?
|
@@ -44,7 +46,7 @@ RSpec.configure do |config|
|
|
44
46
|
config.add_formatter(RSpec::Core::Formatters::JsonFormatter, File.join(File.dirname(__FILE__), '../tmp/rspec.json'))
|
45
47
|
end
|
46
48
|
|
47
|
-
if SpecConfig.instance.ci?
|
49
|
+
if SpecConfig.instance.ci? && !%w(1 true yes).include?(ENV['INTERACTIVE']&.downcase)
|
48
50
|
timeout = if SpecConfig.instance.app_tests?
|
49
51
|
# Allow 5 minutes per test for the app tests, since they install
|
50
52
|
# gems for Rails applications which can take a long time.
|
@@ -61,6 +63,8 @@ RSpec.configure do |config|
|
|
61
63
|
end
|
62
64
|
end
|
63
65
|
end
|
66
|
+
|
67
|
+
config.extend(Mrss::LiteConstraints)
|
64
68
|
end
|
65
69
|
|
66
70
|
# require all shared examples
|
@@ -242,6 +242,97 @@ describe Mongoid::Attributes do
|
|
242
242
|
end
|
243
243
|
end
|
244
244
|
|
245
|
+
context "when the field was not explicitly defined" do
|
246
|
+
|
247
|
+
context "when excluding with only and the field was not excluded" do
|
248
|
+
|
249
|
+
let(:from_db) do
|
250
|
+
Person.only(:_id).first
|
251
|
+
end
|
252
|
+
|
253
|
+
it "raises an error" do
|
254
|
+
expect {
|
255
|
+
from_db[:undefined_field]
|
256
|
+
}.to raise_error(ActiveModel::MissingAttributeError)
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
260
|
+
context "when excluding with without and the field was excluded" do
|
261
|
+
|
262
|
+
let(:from_db) do
|
263
|
+
Person.without(:title).first
|
264
|
+
end
|
265
|
+
|
266
|
+
it "raises an error" do
|
267
|
+
expect {
|
268
|
+
from_db[:title]
|
269
|
+
}.to raise_error(ActiveModel::MissingAttributeError)
|
270
|
+
end
|
271
|
+
end
|
272
|
+
|
273
|
+
context "when excluding with without and the field was not excluded" do
|
274
|
+
|
275
|
+
let(:from_db) do
|
276
|
+
Person.without(:title).first
|
277
|
+
end
|
278
|
+
|
279
|
+
it "returns nil" do
|
280
|
+
from_db[:undefined_field].should be nil
|
281
|
+
end
|
282
|
+
end
|
283
|
+
end
|
284
|
+
|
285
|
+
context 'when projecting with #only' do
|
286
|
+
let!(:person) do
|
287
|
+
Person.create(title: 'sir', name: { first_name: 'Jose', language: { name: 'es' } })
|
288
|
+
end
|
289
|
+
|
290
|
+
context 'when projecting an embedded association' do
|
291
|
+
let(:from_db) do
|
292
|
+
Person.only(:name).first
|
293
|
+
end
|
294
|
+
|
295
|
+
context 'when retrieving a field of the association using the dot notation' do
|
296
|
+
|
297
|
+
it 'retrieves the field' do
|
298
|
+
pending 'MONGOID-5032, fixed in 7.3'
|
299
|
+
|
300
|
+
expect(from_db['name.first_name']).to eq 'Jose'
|
301
|
+
end
|
302
|
+
end
|
303
|
+
|
304
|
+
context 'when retrieving a field of a nested association using the dot notation' do
|
305
|
+
it 'retrieves the field' do
|
306
|
+
pending 'MONGOID-5032, fixed in 7.3'
|
307
|
+
|
308
|
+
expect(from_db['name.language.name']).to eq 'es'
|
309
|
+
end
|
310
|
+
end
|
311
|
+
end
|
312
|
+
|
313
|
+
context 'when projecting a sub-association of an embedded association' do
|
314
|
+
let(:from_db) do
|
315
|
+
Person.only('name.language').first
|
316
|
+
end
|
317
|
+
|
318
|
+
context 'when retrieving a field under the projected sub-association' do
|
319
|
+
it 'retrieves the field' do
|
320
|
+
pending 'MONGOID-5032, fixed in 7.3'
|
321
|
+
|
322
|
+
expect(from_db['name.language.name']).to eq 'es'
|
323
|
+
end
|
324
|
+
end
|
325
|
+
|
326
|
+
context 'when retrieving a non-projected field' do
|
327
|
+
it 'raises MissingAttributeError' do
|
328
|
+
expect do
|
329
|
+
from_db['name.first_name']
|
330
|
+
end.to raise_error(ActiveModel::MissingAttributeError)
|
331
|
+
end
|
332
|
+
end
|
333
|
+
end
|
334
|
+
end
|
335
|
+
|
245
336
|
context "when the attribute does not exist" do
|
246
337
|
|
247
338
|
before do
|
@@ -326,6 +417,67 @@ describe Mongoid::Attributes do
|
|
326
417
|
expect(terms).to eq(true)
|
327
418
|
end
|
328
419
|
end
|
420
|
+
|
421
|
+
context 'when the field is not explicitly defined' do
|
422
|
+
let(:bar) { Bar.new }
|
423
|
+
|
424
|
+
before do
|
425
|
+
bar['missing_field'] = 42
|
426
|
+
end
|
427
|
+
|
428
|
+
it 'writes the value into attributes' do
|
429
|
+
bar.attributes.should == {'_id' => bar.id, 'missing_field' => 42}
|
430
|
+
end
|
431
|
+
|
432
|
+
it 'makes the attribute accessible via []' do
|
433
|
+
bar['missing_field'].should == 42
|
434
|
+
end
|
435
|
+
|
436
|
+
context 'when writing fields on a document with projection' do
|
437
|
+
|
438
|
+
let!(:person) do
|
439
|
+
Person.create(title: "sir")
|
440
|
+
end
|
441
|
+
|
442
|
+
context "when excluding with only and the field was not excluded" do
|
443
|
+
|
444
|
+
let(:from_db) do
|
445
|
+
Person.only(:_id).first
|
446
|
+
end
|
447
|
+
|
448
|
+
it "raises an error" do
|
449
|
+
expect {
|
450
|
+
from_db[:undefined_field] = 'x'
|
451
|
+
}.to raise_error(ActiveModel::MissingAttributeError)
|
452
|
+
end
|
453
|
+
end
|
454
|
+
|
455
|
+
context "when excluding with without and the field was excluded" do
|
456
|
+
|
457
|
+
let(:from_db) do
|
458
|
+
Person.without(:title).first
|
459
|
+
end
|
460
|
+
|
461
|
+
it "raises an error" do
|
462
|
+
expect {
|
463
|
+
from_db[:title] = 'x'
|
464
|
+
}.to raise_error(ActiveModel::MissingAttributeError)
|
465
|
+
end
|
466
|
+
end
|
467
|
+
|
468
|
+
context "when excluding with without and the field was not excluded" do
|
469
|
+
|
470
|
+
let(:from_db) do
|
471
|
+
Person.without(:title).first
|
472
|
+
end
|
473
|
+
|
474
|
+
it "writes the value" do
|
475
|
+
from_db[:undefined_field] = 'x'
|
476
|
+
from_db[:undefined_field].should == 'x'
|
477
|
+
end
|
478
|
+
end
|
479
|
+
end
|
480
|
+
end
|
329
481
|
end
|
330
482
|
|
331
483
|
describe "#_id" do
|
@@ -890,6 +1042,50 @@ describe Mongoid::Attributes do
|
|
890
1042
|
expect(person.age_before_type_cast).to eq("old")
|
891
1043
|
end
|
892
1044
|
end
|
1045
|
+
|
1046
|
+
context 'when reading fields on a document with projection' do
|
1047
|
+
|
1048
|
+
let!(:person) do
|
1049
|
+
Person.create(title: "sir")
|
1050
|
+
end
|
1051
|
+
|
1052
|
+
context "when excluding with only and the field was not excluded" do
|
1053
|
+
|
1054
|
+
let(:from_db) do
|
1055
|
+
Person.only(:_id).first
|
1056
|
+
end
|
1057
|
+
|
1058
|
+
it "raises an error" do
|
1059
|
+
expect {
|
1060
|
+
from_db.read_attribute(:undefined_field)
|
1061
|
+
}.to raise_error(ActiveModel::MissingAttributeError)
|
1062
|
+
end
|
1063
|
+
end
|
1064
|
+
|
1065
|
+
context "when excluding with without and the field was excluded" do
|
1066
|
+
|
1067
|
+
let(:from_db) do
|
1068
|
+
Person.without(:title).first
|
1069
|
+
end
|
1070
|
+
|
1071
|
+
it "raises an error" do
|
1072
|
+
expect {
|
1073
|
+
from_db.read_attribute(:title)
|
1074
|
+
}.to raise_error(ActiveModel::MissingAttributeError)
|
1075
|
+
end
|
1076
|
+
end
|
1077
|
+
|
1078
|
+
context "when excluding with without and the field was not excluded" do
|
1079
|
+
|
1080
|
+
let(:from_db) do
|
1081
|
+
Person.without(:title).first
|
1082
|
+
end
|
1083
|
+
|
1084
|
+
it "returns nil" do
|
1085
|
+
from_db.read_attribute(:undefined_field).should be nil
|
1086
|
+
end
|
1087
|
+
end
|
1088
|
+
end
|
893
1089
|
end
|
894
1090
|
|
895
1091
|
describe "#attribute_present?" do
|
@@ -1395,6 +1591,51 @@ describe Mongoid::Attributes do
|
|
1395
1591
|
expect(dictionary.description).to eq('foo')
|
1396
1592
|
end
|
1397
1593
|
end
|
1594
|
+
|
1595
|
+
context 'when writing fields on a document with projection' do
|
1596
|
+
|
1597
|
+
let!(:person) do
|
1598
|
+
Person.create(title: "sir")
|
1599
|
+
end
|
1600
|
+
|
1601
|
+
context "when excluding with only and the field was not excluded" do
|
1602
|
+
|
1603
|
+
let(:from_db) do
|
1604
|
+
Person.only(:_id).first
|
1605
|
+
end
|
1606
|
+
|
1607
|
+
it "raises an error" do
|
1608
|
+
expect {
|
1609
|
+
from_db.write_attribute(:undefined_field, 'x')
|
1610
|
+
}.to raise_error(ActiveModel::MissingAttributeError)
|
1611
|
+
end
|
1612
|
+
end
|
1613
|
+
|
1614
|
+
context "when excluding with without and the field was excluded" do
|
1615
|
+
|
1616
|
+
let(:from_db) do
|
1617
|
+
Person.without(:title).first
|
1618
|
+
end
|
1619
|
+
|
1620
|
+
it "raises an error" do
|
1621
|
+
expect {
|
1622
|
+
from_db.write_attribute(:title, 'x')
|
1623
|
+
}.to raise_error(ActiveModel::MissingAttributeError)
|
1624
|
+
end
|
1625
|
+
end
|
1626
|
+
|
1627
|
+
context "when excluding with without and the field was not excluded" do
|
1628
|
+
|
1629
|
+
let(:from_db) do
|
1630
|
+
Person.without(:title).first
|
1631
|
+
end
|
1632
|
+
|
1633
|
+
it "writes the value" do
|
1634
|
+
from_db.write_attribute(:undefined_field, 'x')
|
1635
|
+
from_db.read_attribute(:undefined_field).should == 'x'
|
1636
|
+
end
|
1637
|
+
end
|
1638
|
+
end
|
1398
1639
|
end
|
1399
1640
|
|
1400
1641
|
describe "#typed_value_for" do
|
@@ -653,12 +653,25 @@ describe Mongoid::Contextual::Atomic do
|
|
653
653
|
context.set(name: "Recoil")
|
654
654
|
end
|
655
655
|
|
656
|
-
|
657
|
-
|
656
|
+
shared_examples 'writes as expected' do
|
657
|
+
it "sets existing fields" do
|
658
|
+
expect(depeche_mode.reload.name).to eq("Recoil")
|
659
|
+
end
|
660
|
+
|
661
|
+
it "sets non existent fields" do
|
662
|
+
expect(smiths.reload.name).to eq("Recoil")
|
663
|
+
end
|
658
664
|
end
|
659
665
|
|
660
|
-
|
661
|
-
|
666
|
+
include_examples 'writes as expected'
|
667
|
+
|
668
|
+
context 'when fields being set have been projected out' do
|
669
|
+
|
670
|
+
let(:criteria) do
|
671
|
+
Band.only(:genres)
|
672
|
+
end
|
673
|
+
|
674
|
+
include_examples 'writes as expected'
|
662
675
|
end
|
663
676
|
end
|
664
677
|
|