mongoid 7.1.6 → 7.1.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/README.md +1 -1
  5. data/Rakefile +31 -0
  6. data/lib/mongoid.rb +1 -0
  7. data/lib/mongoid/association/embedded/embeds_many/proxy.rb +1 -1
  8. data/lib/mongoid/association/proxy.rb +1 -1
  9. data/lib/mongoid/association/referenced/has_many/enumerable.rb +1 -1
  10. data/lib/mongoid/association/referenced/has_many/proxy.rb +1 -1
  11. data/lib/mongoid/attributes.rb +8 -1
  12. data/lib/mongoid/criteria.rb +1 -1
  13. data/lib/mongoid/criteria/queryable/selector.rb +0 -4
  14. data/lib/mongoid/document.rb +3 -2
  15. data/lib/mongoid/errors/mongoid_error.rb +1 -1
  16. data/lib/mongoid/interceptable.rb +4 -2
  17. data/lib/mongoid/reloadable.rb +5 -0
  18. data/lib/mongoid/validatable/associated.rb +1 -1
  19. data/lib/mongoid/validatable/presence.rb +3 -3
  20. data/lib/mongoid/validatable/uniqueness.rb +1 -1
  21. data/lib/mongoid/version.rb +1 -1
  22. data/lib/rails/generators/mongoid/config/config_generator.rb +8 -1
  23. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +1 -1
  24. data/spec/app/models/address.rb +4 -0
  25. data/spec/app/models/customer.rb +11 -0
  26. data/spec/app/models/customer_address.rb +12 -0
  27. data/spec/app/models/dictionary.rb +6 -0
  28. data/spec/app/models/person.rb +9 -0
  29. data/spec/integration/app_spec.rb +178 -88
  30. data/spec/integration/callbacks_models.rb +49 -0
  31. data/spec/integration/callbacks_spec.rb +216 -0
  32. data/spec/integration/document_spec.rb +21 -0
  33. data/spec/lite_spec_helper.rb +6 -6
  34. data/spec/mongoid/association/embedded/embedded_in/proxy_spec.rb +50 -0
  35. data/spec/mongoid/association/embedded/embeds_many/proxy_spec.rb +17 -4
  36. data/spec/mongoid/association/referenced/belongs_to/proxy_spec.rb +17 -0
  37. data/spec/mongoid/atomic/paths_spec.rb +41 -0
  38. data/spec/mongoid/attributes_spec.rb +241 -0
  39. data/spec/mongoid/clients/options_spec.rb +2 -0
  40. data/spec/mongoid/contextual/atomic_spec.rb +17 -4
  41. data/spec/mongoid/criteria/queryable/selectable_logical_spec.rb +36 -0
  42. data/spec/mongoid/criteria_spec.rb +4 -0
  43. data/spec/mongoid/document_query_spec.rb +51 -0
  44. data/spec/mongoid/errors/mongoid_error_spec.rb +20 -8
  45. data/spec/mongoid/factory_spec.rb +2 -2
  46. data/spec/mongoid/persistable/savable_spec.rb +4 -4
  47. data/spec/mongoid/persistable/settable_spec.rb +30 -0
  48. data/spec/mongoid/persistable_spec.rb +2 -2
  49. data/spec/shared/bin/get-mongodb-download-url +17 -0
  50. data/spec/shared/bin/s3-copy +45 -0
  51. data/spec/shared/bin/s3-upload +69 -0
  52. data/spec/shared/lib/mrss/cluster_config.rb +19 -4
  53. data/spec/shared/lib/mrss/constraints.rb +62 -6
  54. data/spec/shared/lib/mrss/docker_runner.rb +271 -0
  55. data/spec/shared/lib/mrss/lite_constraints.rb +16 -0
  56. data/spec/shared/lib/mrss/server_version_registry.rb +115 -0
  57. data/spec/shared/lib/mrss/spec_organizer.rb +32 -2
  58. data/spec/shared/lib/mrss/utils.rb +15 -0
  59. data/spec/shared/share/Dockerfile.erb +322 -0
  60. data/spec/shared/share/haproxy-1.conf +16 -0
  61. data/spec/shared/share/haproxy-2.conf +17 -0
  62. data/spec/shared/shlib/distro.sh +73 -0
  63. data/spec/shared/shlib/server.sh +317 -0
  64. data/spec/shared/shlib/set_env.sh +131 -0
  65. data/spec/spec_helper.rb +3 -1
  66. data/spec/support/constraints.rb +0 -226
  67. data/spec/support/spec_config.rb +8 -0
  68. metadata +542 -480
  69. metadata.gz.sig +0 -0
  70. data/spec/support/child_process_helper.rb +0 -76
  71. data/spec/support/lite_constraints.rb +0 -22
@@ -0,0 +1,49 @@
1
+ class Galaxy
2
+ include Mongoid::Document
3
+
4
+ field :age, type: Integer
5
+
6
+ before_validation :set_age
7
+
8
+ embeds_many :stars
9
+
10
+ private
11
+
12
+ def set_age
13
+ self.age ||= 100_000
14
+ end
15
+ end
16
+
17
+ class Star
18
+ include Mongoid::Document
19
+
20
+ embedded_in :galaxy
21
+
22
+ field :age, type: Integer
23
+
24
+ before_validation :set_age
25
+
26
+ embeds_many :planets
27
+
28
+ private
29
+
30
+ def set_age
31
+ self.age ||= 42_000
32
+ end
33
+ end
34
+
35
+ class Planet
36
+ include Mongoid::Document
37
+
38
+ embedded_in :star
39
+
40
+ field :age, type: Integer
41
+
42
+ before_validation :set_age
43
+
44
+ private
45
+
46
+ def set_age
47
+ self.age ||= 2_000
48
+ end
49
+ end
@@ -0,0 +1,216 @@
1
+ # frozen_string_literal: true
2
+ # encoding: utf-8
3
+
4
+ require 'spec_helper'
5
+ require_relative './callbacks_models'
6
+
7
+ describe 'callbacks integration tests' do
8
+ context 'when modifying attributes in a callback' do
9
+
10
+ context 'when creating top-level document' do
11
+ context 'top level document' do
12
+ let(:instance) do
13
+ Galaxy.create!
14
+ end
15
+
16
+ it 'writes the attribute value into the model' do
17
+ instance.age.should == 100_000
18
+ end
19
+
20
+ it 'persists the attribute value' do
21
+ Galaxy.find(instance.id).age.should == 100_000
22
+ end
23
+ end
24
+
25
+ context 'embedded document' do
26
+ shared_examples 'persists the attribute value' do
27
+ it 'writes the attribute value into the model' do
28
+ instance.stars.first.age.should == 42_000
29
+ end
30
+
31
+ it 'persists the attribute value' do
32
+ Galaxy.find(instance.id).stars.first.age.should == 42_000
33
+ end
34
+ end
35
+
36
+ context 'set as a document instance' do
37
+ let(:instance) do
38
+ Galaxy.create!(stars: [Star.new])
39
+ end
40
+
41
+ include_examples 'persists the attribute value'
42
+ end
43
+
44
+ context 'set as attributes on parent' do
45
+ let(:instance) do
46
+ Galaxy.create!(stars: [{}])
47
+ end
48
+
49
+ include_examples 'persists the attribute value'
50
+ end
51
+ end
52
+
53
+ context 'nested embedded document' do
54
+ shared_examples 'persists the attribute value' do
55
+ it 'writes the attribute value into the model' do
56
+ instance.stars.first.planets.first.age.should == 2_000
57
+ end
58
+
59
+ it 'persists the attribute value' do
60
+ Galaxy.find(instance.id).stars.first.planets.first.age.should == 2_000
61
+ end
62
+ end
63
+
64
+ context 'set as a document instance' do
65
+ let(:instance) do
66
+ Galaxy.create!(stars: [Star.new(
67
+ planets: [Planet.new],
68
+ )])
69
+ end
70
+
71
+ include_examples 'persists the attribute value'
72
+ end
73
+
74
+ context 'set as attributes on parent' do
75
+ let(:instance) do
76
+ Galaxy.create!(stars: [
77
+ planets: [{}],
78
+ ])
79
+ end
80
+
81
+ include_examples 'persists the attribute value'
82
+ end
83
+ end
84
+ end
85
+
86
+ context 'when updating top-level document via #save' do
87
+ let!(:instance) do
88
+ Galaxy.create!
89
+ end
90
+
91
+ context 'embedded document' do
92
+ shared_examples 'persists the attribute value' do
93
+ it 'writes the attribute value into the model' do
94
+ instance.stars.first.age.should == 42_000
95
+ end
96
+
97
+ it 'persists the attribute value' do
98
+ Galaxy.find(instance.id).stars.first.age.should == 42_000
99
+ end
100
+ end
101
+
102
+ context 'set as a document instance' do
103
+ before do
104
+ instance.stars = [Star.new]
105
+ instance.save!
106
+ end
107
+
108
+ include_examples 'persists the attribute value'
109
+ end
110
+
111
+ context 'set as attributes on parent' do
112
+ before do
113
+ instance.stars = [{}]
114
+ instance.save!
115
+ end
116
+
117
+ include_examples 'persists the attribute value'
118
+ end
119
+ end
120
+
121
+ context 'nested embedded document' do
122
+ shared_examples 'persists the attribute value' do
123
+ it 'writes the attribute value into the model' do
124
+ instance.stars.first.planets.first.age.should == 2_000
125
+ end
126
+
127
+ it 'persists the attribute value' do
128
+ Galaxy.find(instance.id).stars.first.planets.first.age.should == 2_000
129
+ end
130
+ end
131
+
132
+ context 'set as a document instance' do
133
+ before do
134
+ instance.stars = [Star.new(planets: [Planet.new])]
135
+ instance.save!
136
+ end
137
+
138
+ include_examples 'persists the attribute value'
139
+ end
140
+
141
+ context 'set as attributes on parent' do
142
+ before do
143
+ instance.stars = [planets: [{}]]
144
+ instance.save!
145
+ end
146
+
147
+ include_examples 'persists the attribute value'
148
+ end
149
+ end
150
+ end
151
+
152
+ context 'when updating top-level document via #update_attributes' do
153
+ let!(:instance) do
154
+ Galaxy.create!
155
+ end
156
+
157
+ context 'embedded document' do
158
+ shared_examples 'persists the attribute value' do
159
+ it 'writes the attribute value into the model' do
160
+ instance.stars.first.age.should == 42_000
161
+ end
162
+
163
+ it 'persists the attribute value' do
164
+ Galaxy.find(instance.id).stars.first.age.should == 42_000
165
+ end
166
+ end
167
+
168
+ context 'set as a document instance' do
169
+ before do
170
+ instance.update_attributes(stars: [Star.new])
171
+ end
172
+
173
+ include_examples 'persists the attribute value'
174
+ end
175
+
176
+ context 'set as attributes on parent' do
177
+ before do
178
+ instance.update_attributes(stars: [{}])
179
+ end
180
+
181
+ include_examples 'persists the attribute value'
182
+ end
183
+ end
184
+
185
+ context 'nested embedded document' do
186
+ shared_examples 'persists the attribute value' do
187
+ it 'writes the attribute value into the model' do
188
+ instance.stars.first.planets.first.age.should == 2_000
189
+ end
190
+
191
+ it 'persists the attribute value' do
192
+ pending 'MONGOID-4476'
193
+
194
+ Galaxy.find(instance.id).stars.first.planets.first.age.should == 2_000
195
+ end
196
+ end
197
+
198
+ context 'set as a document instance' do
199
+ before do
200
+ instance.update_attributes(stars: [Star.new(planets: [Planet.new])])
201
+ end
202
+
203
+ include_examples 'persists the attribute value'
204
+ end
205
+
206
+ context 'set as attributes on parent' do
207
+ before do
208
+ instance.update_attributes(stars: [planets: [{}]])
209
+ end
210
+
211
+ include_examples 'persists the attribute value'
212
+ end
213
+ end
214
+ end
215
+ end
216
+ end
@@ -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
@@ -3,6 +3,7 @@
3
3
 
4
4
  $LOAD_PATH.unshift(File.dirname(__FILE__))
5
5
  $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), "..", "lib"))
6
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), "shared", "lib"))
6
7
 
7
8
  # Load byebug before mongoid, to place breakpoints in the lib methods.
8
9
  # But SpecConfig needs the driver code - require the driver here.
@@ -15,7 +16,7 @@ require "mongo"
15
16
  require 'pp'
16
17
 
17
18
  require 'support/spec_config'
18
- require 'support/lite_constraints'
19
+ require 'mrss/lite_constraints'
19
20
  require "support/session_registry"
20
21
 
21
22
  unless SpecConfig.instance.ci?
@@ -50,11 +51,10 @@ RSpec.configure do |config|
50
51
  config.add_formatter(RSpec::Core::Formatters::JsonFormatter, File.join(File.dirname(__FILE__), '../tmp/rspec.json'))
51
52
  end
52
53
 
53
- if SpecConfig.instance.ci?
54
+ if SpecConfig.instance.ci? && !%w(1 true yes).include?(ENV['INTERACTIVE']&.downcase)
54
55
  timeout = if SpecConfig.instance.app_tests?
55
- # Allow 5 minutes per test for the app tests, since they install
56
- # gems for Rails applications which can take a long time.
57
- 300
56
+ # App tests under JRuby take a REALLY long time (over 5 minutes per test).
57
+ 500
58
58
  else
59
59
  # Allow a max of 30 seconds per test.
60
60
  # Tests should take under 10 seconds ideally but it seems
@@ -68,7 +68,7 @@ RSpec.configure do |config|
68
68
  end
69
69
  end
70
70
 
71
- config.extend(LiteConstraints)
71
+ config.extend(Mrss::LiteConstraints)
72
72
  end
73
73
 
74
74
  # require all shared examples
@@ -507,4 +507,54 @@ describe Mongoid::Association::Embedded::EmbeddedIn::Proxy do
507
507
  end
508
508
  end
509
509
  end
510
+
511
+ context "when the same class is embedded multiple times" do
512
+
513
+ let(:customer) do
514
+ Customer.new
515
+ end
516
+
517
+ context "assignment after saving" do
518
+
519
+ it "correctly sets the association for the embedded class" do
520
+ pending 'MONGOID-5039'
521
+
522
+ customer.home_address = CustomerAddress.new
523
+ customer.work_address = CustomerAddress.new
524
+
525
+ expect(customer.home_address._association.store_as).to eq("home_address")
526
+ expect(customer.work_address._association.store_as).to eq("work_address")
527
+
528
+ expect(customer.home_address.instance_eval { _association.store_as }).to eq("home_address")
529
+ expect(customer.work_address.instance_eval { _association.store_as }).to eq("work_address")
530
+
531
+ customer.save!
532
+
533
+ customer.home_address = CustomerAddress.new
534
+ customer.work_address = CustomerAddress.new
535
+
536
+ expect(customer.home_address._association.store_as).to eq("home_address")
537
+ expect(customer.work_address._association.store_as).to eq("work_address")
538
+
539
+ expect(customer.home_address.instance_eval { _association.store_as }).to eq("home_address")
540
+ expect(customer.work_address.instance_eval { _association.store_as }).to eq("work_address")
541
+ end
542
+ end
543
+
544
+ context "inverse assignment" do
545
+
546
+ it "correctly sets the association for the embedded class" do
547
+ pending 'MONGOID-5039'
548
+
549
+ customer.work_address = CustomerAddress.new
550
+ customer.work_address.addressable = customer
551
+
552
+ expect(customer.home_address._association.store_as).to eq("home_address")
553
+ expect(customer.work_address._association.store_as).to eq("work_address")
554
+
555
+ expect(customer.home_address.instance_eval { _association.store_as }).to eq("home_address")
556
+ expect(customer.work_address.instance_eval { _association.store_as }).to eq("work_address")
557
+ end
558
+ end
559
+ end
510
560
  end
@@ -2416,13 +2416,26 @@ describe Mongoid::Association::Embedded::EmbedsMany::Proxy do
2416
2416
  end
2417
2417
 
2418
2418
  context "when providing a criteria class method" do
2419
+ context "without keyword arguments" do
2419
2420
 
2420
- let(:addresses) do
2421
- person.addresses.california
2421
+ let(:addresses) do
2422
+ person.addresses.california
2423
+ end
2424
+
2425
+ it "applies the criteria to the documents" do
2426
+ expect(addresses).to eq([ address_one ])
2427
+ end
2422
2428
  end
2423
2429
 
2424
- it "applies the criteria to the documents" do
2425
- expect(addresses).to eq([ address_one ])
2430
+ context "with keyword arguments" do
2431
+
2432
+ let(:addresses) do
2433
+ person.addresses.city_and_state(city: "Sacramento", state: "CA")
2434
+ end
2435
+
2436
+ it "applies the criteria to the documents" do
2437
+ expect(addresses).to eq([])
2438
+ end
2426
2439
  end
2427
2440
  end
2428
2441
 
@@ -1332,4 +1332,21 @@ describe Mongoid::Association::Referenced::BelongsTo::Proxy do
1332
1332
  end
1333
1333
  end
1334
1334
  end
1335
+
1336
+ describe "#method_missing" do
1337
+ let!(:person) do
1338
+ Person.create
1339
+ end
1340
+
1341
+ let!(:game) do
1342
+ Game.create(person: person)
1343
+ end
1344
+
1345
+ it 'handles keyword args' do
1346
+ expect do
1347
+ game.person.set_personal_data(ssn: '123', age: 25)
1348
+ end.not_to raise_error
1349
+ end
1350
+
1351
+ end
1335
1352
  end
@@ -268,5 +268,46 @@ describe Mongoid::Atomic::Paths do
268
268
  end
269
269
  end
270
270
  end
271
+
272
+ context "when the same class is embedded in multiple associations" do
273
+
274
+ let(:customer) do
275
+ Customer.new
276
+ end
277
+
278
+ context "assignment after saving" do
279
+
280
+ it "correctly sets the association for the embedded class" do
281
+ pending 'MONGOID-5039'
282
+
283
+ customer.home_address = CustomerAddress.new
284
+ customer.work_address = CustomerAddress.new
285
+
286
+ expect(customer.home_address.atomic_path).to eq("home_address")
287
+ expect(customer.work_address.atomic_path).to eq("work_address")
288
+
289
+ customer.save!
290
+
291
+ customer.home_address = CustomerAddress.new
292
+ customer.work_address = CustomerAddress.new
293
+
294
+ expect(customer.home_address.atomic_path).to eq("home_address")
295
+ expect(customer.work_address.atomic_path).to eq("work_address")
296
+ end
297
+ end
298
+
299
+ context "inverse assignment" do
300
+
301
+ it "correctly returns the path for each embedded class" do
302
+ pending 'MONGOID-5039'
303
+
304
+ customer.work_address = CustomerAddress.new
305
+ customer.work_address.addressable = customer
306
+
307
+ expect(customer.home_address.atomic_path).to eq("home_address")
308
+ expect(customer.work_address.atomic_path).to eq("work_address")
309
+ end
310
+ end
311
+ end
271
312
  end
272
313
  end