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