mongoid 9.0.0 → 9.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +2 -0
- data/Rakefile +44 -21
- data/lib/config/locales/en.yml +20 -0
- data/lib/mongoid/association/accessors.rb +7 -2
- data/lib/mongoid/association/nested/one.rb +14 -1
- data/lib/mongoid/association/referenced/belongs_to/binding.rb +7 -1
- data/lib/mongoid/association/referenced/belongs_to/buildable.rb +1 -1
- data/lib/mongoid/association/referenced/belongs_to.rb +15 -0
- data/lib/mongoid/association/referenced/has_many.rb +9 -8
- data/lib/mongoid/association/referenced/has_one/buildable.rb +3 -8
- data/lib/mongoid/association/referenced/with_polymorphic_criteria.rb +41 -0
- data/lib/mongoid/atomic_update_preparer.rb +7 -6
- data/lib/mongoid/attributes/nested.rb +2 -1
- data/lib/mongoid/clients/sessions.rb +12 -15
- data/lib/mongoid/composable.rb +2 -0
- data/lib/mongoid/config.rb +9 -0
- data/lib/mongoid/contextual/aggregable/memory.rb +3 -2
- data/lib/mongoid/contextual/aggregable/mongo.rb +5 -2
- data/lib/mongoid/criteria/findable.rb +2 -2
- data/lib/mongoid/criteria/queryable/extensions/numeric.rb +15 -1
- data/lib/mongoid/document.rb +2 -0
- data/lib/mongoid/errors/invalid_around_callback.rb +16 -0
- data/lib/mongoid/errors/unrecognized_model_alias.rb +53 -0
- data/lib/mongoid/errors/unrecognized_resolver.rb +27 -0
- data/lib/mongoid/errors/unregistered_class.rb +47 -0
- data/lib/mongoid/errors.rb +4 -0
- data/lib/mongoid/fields.rb +13 -7
- data/lib/mongoid/identifiable.rb +28 -0
- data/lib/mongoid/interceptable.rb +18 -13
- data/lib/mongoid/model_resolver.rb +154 -0
- data/lib/mongoid/persistence_context.rb +2 -1
- data/lib/mongoid/scopable.rb +7 -1
- data/lib/mongoid/touchable.rb +1 -7
- data/lib/mongoid/traversable.rb +5 -0
- data/lib/mongoid/version.rb +1 -1
- data/spec/integration/associations/belongs_to_spec.rb +129 -0
- data/spec/integration/persistence/collection_options_spec.rb +36 -0
- data/spec/mongoid/association/embedded/embeds_many_query_spec.rb +4 -0
- data/spec/mongoid/association/referenced/belongs_to/proxy_spec.rb +1 -0
- data/spec/mongoid/association/referenced/belongs_to_spec.rb +58 -21
- data/spec/mongoid/association/referenced/has_many/buildable_spec.rb +4 -0
- data/spec/mongoid/association_spec.rb +14 -0
- data/spec/mongoid/attributes/nested_spec.rb +1 -0
- data/spec/mongoid/attributes_spec.rb +16 -0
- data/spec/mongoid/clients/transactions_spec.rb +2 -2
- data/spec/mongoid/contextual/aggregable/memory_spec.rb +11 -0
- data/spec/mongoid/contextual/aggregable/mongo_spec.rb +11 -0
- data/spec/mongoid/contextual/mongo_spec.rb +72 -3
- data/spec/mongoid/fields_spec.rb +2 -2
- data/spec/mongoid/interceptable_spec.rb +31 -0
- data/spec/mongoid/model_resolver_spec.rb +167 -0
- data/spec/mongoid/monkey_patches_spec.rb +1 -1
- data/spec/mongoid/persistence_context_spec.rb +17 -4
- data/spec/mongoid/scopable_spec.rb +88 -85
- data/spec/mongoid/serializable_spec.rb +16 -9
- data/spec/mongoid/touchable_spec.rb +75 -0
- data/spec/mongoid/touchable_spec_models.rb +16 -0
- data/spec/support/models/band.rb +1 -0
- data/spec/support/models/lat_lng.rb +6 -0
- metadata +20 -82
- checksums.yaml.gz.sig +0 -1
- data/spec/shared/LICENSE +0 -20
- data/spec/shared/bin/get-mongodb-download-url +0 -17
- data/spec/shared/bin/s3-copy +0 -45
- data/spec/shared/bin/s3-upload +0 -69
- data/spec/shared/lib/mrss/child_process_helper.rb +0 -80
- data/spec/shared/lib/mrss/cluster_config.rb +0 -231
- data/spec/shared/lib/mrss/constraints.rb +0 -378
- data/spec/shared/lib/mrss/docker_runner.rb +0 -298
- data/spec/shared/lib/mrss/eg_config_utils.rb +0 -51
- data/spec/shared/lib/mrss/event_subscriber.rb +0 -210
- data/spec/shared/lib/mrss/lite_constraints.rb +0 -238
- data/spec/shared/lib/mrss/server_version_registry.rb +0 -113
- data/spec/shared/lib/mrss/session_registry.rb +0 -69
- data/spec/shared/lib/mrss/session_registry_legacy.rb +0 -60
- data/spec/shared/lib/mrss/spec_organizer.rb +0 -179
- data/spec/shared/lib/mrss/utils.rb +0 -37
- data/spec/shared/share/Dockerfile.erb +0 -281
- data/spec/shared/share/haproxy-1.conf +0 -16
- data/spec/shared/share/haproxy-2.conf +0 -17
- data/spec/shared/shlib/config.sh +0 -27
- data/spec/shared/shlib/distro.sh +0 -74
- data/spec/shared/shlib/server.sh +0 -417
- data/spec/shared/shlib/set_env.sh +0 -146
- data.tar.gz.sig +0 -0
- metadata.gz.sig +0 -1
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
# rubocop:disable RSpec/LeakyConstantDeclaration
|
6
|
+
# rubocop:disable Lint/ConstantDefinitionInBlock
|
7
|
+
describe 'Collection options' do
|
8
|
+
before(:all) do
|
9
|
+
class CollectionOptionsCapped
|
10
|
+
include Mongoid::Document
|
11
|
+
|
12
|
+
store_in collection_options: {
|
13
|
+
capped: true,
|
14
|
+
size: 25_600
|
15
|
+
}
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
after(:all) do
|
20
|
+
CollectionOptionsCapped.collection.drop
|
21
|
+
Mongoid.deregister_model(CollectionOptionsCapped)
|
22
|
+
Object.send(:remove_const, :CollectionOptionsCapped)
|
23
|
+
end
|
24
|
+
|
25
|
+
before do
|
26
|
+
CollectionOptionsCapped.collection.drop
|
27
|
+
# We should create the collection explicitly to apply collection options.
|
28
|
+
CollectionOptionsCapped.create_collection
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'creates a document' do
|
32
|
+
expect { CollectionOptionsCapped.create! }.not_to raise_error
|
33
|
+
end
|
34
|
+
end
|
35
|
+
# rubocop:enable Lint/ConstantDefinitionInBlock
|
36
|
+
# rubocop:enable RSpec/LeakyConstantDeclaration
|
@@ -28,6 +28,10 @@ describe Mongoid::Association::Embedded::EmbedsMany do
|
|
28
28
|
expect(legislator.attributes.keys).to eq(['_id', 'a'])
|
29
29
|
end
|
30
30
|
|
31
|
+
it 'allows accessing the parent' do
|
32
|
+
expect { legislator.congress }.not_to raise_error
|
33
|
+
end
|
34
|
+
|
31
35
|
context 'when using only with $' do
|
32
36
|
before do
|
33
37
|
Patient.destroy_all
|
@@ -4,6 +4,10 @@
|
|
4
4
|
require "spec_helper"
|
5
5
|
require_relative './has_one_models'
|
6
6
|
|
7
|
+
BELONGS_TO_RESOLVER_ID__ = :__belongs_to_resolver_id
|
8
|
+
BELONGS_TO_RESOLVER = Mongoid::ModelResolver.new
|
9
|
+
Mongoid::ModelResolver.register_resolver BELONGS_TO_RESOLVER, BELONGS_TO_RESOLVER_ID__
|
10
|
+
|
7
11
|
describe Mongoid::Association::Referenced::BelongsTo do
|
8
12
|
|
9
13
|
before do
|
@@ -199,47 +203,76 @@ describe Mongoid::Association::Referenced::BelongsTo do
|
|
199
203
|
|
200
204
|
context 'when the polymorphic option is provided' do
|
201
205
|
|
202
|
-
|
206
|
+
[ true, :default ].each do |opt|
|
207
|
+
context "when the polymorphic option is #{opt.inspect}" do
|
208
|
+
let(:options) { { polymorphic: opt } }
|
209
|
+
before { association }
|
203
210
|
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
211
|
+
it 'set the polymorphic attribute on the owner class' do
|
212
|
+
expect(belonging_class.polymorphic).to be(true)
|
213
|
+
end
|
214
|
+
|
215
|
+
it 'sets up a field for the inverse type' do
|
216
|
+
expect(belonging_class.fields.keys).to include(association.inverse_type)
|
217
|
+
end
|
218
|
+
|
219
|
+
it 'uses the default resolver' do
|
220
|
+
expect(association.resolver).to be == Mongoid::ModelResolver.instance
|
221
|
+
end
|
208
222
|
end
|
223
|
+
end
|
209
224
|
|
210
|
-
|
211
|
-
|
225
|
+
[ false, nil ].each do |opt|
|
226
|
+
context "when the polymorphic option is #{opt.inspect}" do
|
227
|
+
let(:options) { { polymorphic: opt } }
|
228
|
+
|
229
|
+
it 'does not set the polymorphic attribute on the owner class' do
|
230
|
+
expect(belonging_class.polymorphic).to be(false)
|
231
|
+
end
|
232
|
+
|
233
|
+
it 'does not set up a field for the inverse type' do
|
234
|
+
expect(belonging_class.fields.keys).not_to include(association.inverse_type)
|
235
|
+
end
|
236
|
+
|
237
|
+
it 'does not use a resolver' do
|
238
|
+
expect(association.resolver).to be_nil
|
239
|
+
end
|
212
240
|
end
|
241
|
+
end
|
213
242
|
|
214
|
-
|
215
|
-
|
243
|
+
context 'when the polymorphic option is set to an unregistered id' do
|
244
|
+
let(:options) { { polymorphic: :bogus } }
|
245
|
+
|
246
|
+
# This behavior is intentional, so that the resolver can be registered after the classes
|
247
|
+
# are loaded.
|
248
|
+
it 'does not immediately raise an exception' do
|
249
|
+
expect { association }.not_to raise_error
|
216
250
|
end
|
217
251
|
|
218
|
-
it '
|
219
|
-
expect
|
252
|
+
it 'raises error when resolver is accessed' do
|
253
|
+
expect { association.resolver }.to raise_error(Mongoid::Errors::UnrecognizedResolver)
|
220
254
|
end
|
221
255
|
end
|
222
256
|
|
223
|
-
context 'when the polymorphic option is
|
257
|
+
context 'when the polymorphic option is set to a registered id' do
|
258
|
+
let(:options) { { polymorphic: BELONGS_TO_RESOLVER_ID__ } }
|
259
|
+
before { association }
|
224
260
|
|
225
|
-
|
226
|
-
|
227
|
-
polymorphic: false
|
228
|
-
}
|
261
|
+
it 'set the polymorphic attribute on the owner class' do
|
262
|
+
expect(belonging_class.polymorphic).to be(true)
|
229
263
|
end
|
230
264
|
|
231
|
-
it '
|
232
|
-
expect(belonging_class.
|
265
|
+
it 'sets up a field for the inverse type' do
|
266
|
+
expect(belonging_class.fields.keys).to include(association.inverse_type)
|
233
267
|
end
|
234
268
|
|
235
|
-
it '
|
236
|
-
expect(
|
269
|
+
it 'connects the association to the corresponding resolver' do
|
270
|
+
expect(association.resolver).to be == BELONGS_TO_RESOLVER
|
237
271
|
end
|
238
272
|
end
|
239
273
|
end
|
240
274
|
|
241
275
|
context 'when the polymorphic option is not provided' do
|
242
|
-
|
243
276
|
it 'does not set the polymorphic attribute on the owner class' do
|
244
277
|
expect(belonging_class.polymorphic).to be(false)
|
245
278
|
end
|
@@ -247,6 +280,10 @@ describe Mongoid::Association::Referenced::BelongsTo do
|
|
247
280
|
it 'does not set up a field for the inverse type' do
|
248
281
|
expect(belonging_class.fields.keys).not_to include(association.inverse_type)
|
249
282
|
end
|
283
|
+
|
284
|
+
it 'does not use a resolver' do
|
285
|
+
expect(association.resolver).to be_nil
|
286
|
+
end
|
250
287
|
end
|
251
288
|
end
|
252
289
|
|
@@ -100,6 +100,10 @@ describe Mongoid::Association::Referenced::HasMany::Buildable do
|
|
100
100
|
Post.where(association.foreign_key => object, 'ratable_type' => 'Rating')
|
101
101
|
end
|
102
102
|
|
103
|
+
before do
|
104
|
+
Post.belongs_to :ratable, polymorphic: true
|
105
|
+
end
|
106
|
+
|
103
107
|
it "adds the type to the criteria" do
|
104
108
|
expect(documents).to eq(criteria)
|
105
109
|
end
|
@@ -15,6 +15,20 @@ describe Mongoid::Association do
|
|
15
15
|
)
|
16
16
|
end
|
17
17
|
|
18
|
+
context "when class_name references an unknown class" do
|
19
|
+
context "when loading" do
|
20
|
+
it "does not raise an exception" do
|
21
|
+
expect do
|
22
|
+
class AssocationSpecModel
|
23
|
+
include Mongoid::Document
|
24
|
+
|
25
|
+
embedded_in :parent, class_name: 'SomethingBogusThatDoesNotExistYet'
|
26
|
+
end
|
27
|
+
end.not_to raise_exception
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
18
32
|
describe "#embedded?" do
|
19
33
|
|
20
34
|
let(:person) do
|
@@ -289,6 +289,22 @@ describe Mongoid::Attributes do
|
|
289
289
|
end
|
290
290
|
end
|
291
291
|
|
292
|
+
context "when given nil" do
|
293
|
+
|
294
|
+
it "returns nil" do
|
295
|
+
expect(person[nil]).to be nil
|
296
|
+
end
|
297
|
+
|
298
|
+
end
|
299
|
+
|
300
|
+
context "when given an empty string" do
|
301
|
+
|
302
|
+
it "returns nil" do
|
303
|
+
expect(person[""]).to be nil
|
304
|
+
end
|
305
|
+
|
306
|
+
end
|
307
|
+
|
292
308
|
context "when the field was not explicitly defined" do
|
293
309
|
|
294
310
|
context "when excluding with only and the field was not excluded" do
|
@@ -282,7 +282,7 @@ describe Mongoid::Clients::Sessions do
|
|
282
282
|
end
|
283
283
|
end
|
284
284
|
|
285
|
-
include_examples 'it aborts the transaction', Mongoid::Errors::
|
285
|
+
include_examples 'it aborts the transaction', Mongoid::Errors::TransactionError
|
286
286
|
end
|
287
287
|
end
|
288
288
|
end
|
@@ -591,7 +591,7 @@ describe Mongoid::Clients::Sessions do
|
|
591
591
|
end
|
592
592
|
|
593
593
|
it 'raises an error' do
|
594
|
-
expect(error).to be_a(Mongoid::Errors::
|
594
|
+
expect(error).to be_a(Mongoid::Errors::TransactionError)
|
595
595
|
end
|
596
596
|
|
597
597
|
it 'does not execute any operations' do
|
@@ -570,5 +570,16 @@ describe Mongoid::Contextual::Aggregable::Memory do
|
|
570
570
|
expect(sum).to eq(1500)
|
571
571
|
end
|
572
572
|
end
|
573
|
+
|
574
|
+
context "when provided a block with initial value" do
|
575
|
+
|
576
|
+
let(:sum) do
|
577
|
+
context.sum(500, &:likes)
|
578
|
+
end
|
579
|
+
|
580
|
+
it "returns the sum for the provided block starting from initial value" do
|
581
|
+
expect(sum).to eq(2000)
|
582
|
+
end
|
583
|
+
end
|
573
584
|
end
|
574
585
|
end
|
@@ -515,6 +515,17 @@ describe Mongoid::Contextual::Aggregable::Mongo do
|
|
515
515
|
expect(sum).to eq(1500)
|
516
516
|
end
|
517
517
|
end
|
518
|
+
|
519
|
+
context "when provided a block with initial value" do
|
520
|
+
|
521
|
+
let(:sum) do
|
522
|
+
context.sum(500, &:likes)
|
523
|
+
end
|
524
|
+
|
525
|
+
it "returns the sum for the provided block starting from initial value" do
|
526
|
+
expect(sum).to eq(2000)
|
527
|
+
end
|
528
|
+
end
|
518
529
|
end
|
519
530
|
end
|
520
531
|
|
@@ -3640,6 +3640,75 @@ describe Mongoid::Contextual::Mongo do
|
|
3640
3640
|
expect(new_order.reload.genres).to eq(["electronic"])
|
3641
3641
|
end
|
3642
3642
|
end
|
3643
|
+
|
3644
|
+
context "when operation is $pull" do
|
3645
|
+
context "when pulling single element" do
|
3646
|
+
|
3647
|
+
before do
|
3648
|
+
depeche_mode.update_attribute(:genres, ["electronic", "pop"])
|
3649
|
+
new_order.update_attribute(:genres, ["electronic", "pop"])
|
3650
|
+
context.update_all("$pull" => { genres: "electronic" })
|
3651
|
+
end
|
3652
|
+
|
3653
|
+
it "updates the first matching document" do
|
3654
|
+
expect(depeche_mode.reload.genres).to eq(["pop"])
|
3655
|
+
end
|
3656
|
+
|
3657
|
+
it "updates the last matching document" do
|
3658
|
+
expect(new_order.reload.genres).to eq(["pop"])
|
3659
|
+
end
|
3660
|
+
end
|
3661
|
+
|
3662
|
+
context "when pulling based on condition" do
|
3663
|
+
before do
|
3664
|
+
depeche_mode.update_attribute(:genres, ["electronic", "pop", "dance"])
|
3665
|
+
new_order.update_attribute(:genres, ["electronic", "pop", "dance"])
|
3666
|
+
context.update_all("$pull" => { genres: { '$in' => ["electronic", "pop"] } })
|
3667
|
+
end
|
3668
|
+
|
3669
|
+
it "updates the first matching document" do
|
3670
|
+
expect(depeche_mode.reload.genres).to eq(["dance"])
|
3671
|
+
end
|
3672
|
+
|
3673
|
+
it "updates the last matching document" do
|
3674
|
+
expect(new_order.reload.genres).to eq(["dance"])
|
3675
|
+
end
|
3676
|
+
end
|
3677
|
+
end
|
3678
|
+
|
3679
|
+
context "when operation is $pop" do
|
3680
|
+
|
3681
|
+
before do
|
3682
|
+
depeche_mode.update_attribute(:genres, ["pop", "electronic"])
|
3683
|
+
end
|
3684
|
+
|
3685
|
+
it "removes first element in array" do
|
3686
|
+
context.update_all("$pop" => { genres: -1 })
|
3687
|
+
expect(depeche_mode.reload.genres).to eq(["electronic"])
|
3688
|
+
end
|
3689
|
+
|
3690
|
+
it "removes last element in array" do
|
3691
|
+
context.update_all("$pop" => { genres: 1 })
|
3692
|
+
expect(depeche_mode.reload.genres).to eq(["pop"])
|
3693
|
+
end
|
3694
|
+
end
|
3695
|
+
|
3696
|
+
context "when operation is $pullAll" do
|
3697
|
+
|
3698
|
+
before do
|
3699
|
+
depeche_mode.update_attribute(:genres, ["pop", "electronic", "dance", "pop" ])
|
3700
|
+
new_order.update_attribute(:genres, ["electronic", "pop", "electronic", "dance"])
|
3701
|
+
context.update_all("$pullAll" => { genres: ["pop", "electronic"] })
|
3702
|
+
end
|
3703
|
+
|
3704
|
+
it "updates the first matching document" do
|
3705
|
+
expect(depeche_mode.reload.genres).to eq(["dance"])
|
3706
|
+
end
|
3707
|
+
|
3708
|
+
it "updates the last matching document" do
|
3709
|
+
expect(new_order.reload.genres).to eq(["dance"])
|
3710
|
+
end
|
3711
|
+
end
|
3643
3712
|
end
|
3644
3713
|
|
3645
3714
|
context 'when using aliased field names' do
|
@@ -3659,15 +3728,15 @@ describe Mongoid::Contextual::Mongo do
|
|
3659
3728
|
context "when the attributes must be mongoized" do
|
3660
3729
|
|
3661
3730
|
before do
|
3662
|
-
context.update_all("$set" => {
|
3731
|
+
context.update_all("$set" => { location: LatLng.new(52.30, 13.25) })
|
3663
3732
|
end
|
3664
3733
|
|
3665
3734
|
it "updates the first matching document" do
|
3666
|
-
expect(depeche_mode.reload.
|
3735
|
+
expect(depeche_mode.reload.location).to eq(LatLng.new(52.30, 13.25))
|
3667
3736
|
end
|
3668
3737
|
|
3669
3738
|
it "updates the last matching document" do
|
3670
|
-
expect(new_order.reload.
|
3739
|
+
expect(new_order.reload.location).to eq(LatLng.new(52.30, 13.25))
|
3671
3740
|
end
|
3672
3741
|
end
|
3673
3742
|
end
|
data/spec/mongoid/fields_spec.rb
CHANGED
@@ -1871,12 +1871,12 @@ describe Mongoid::Fields do
|
|
1871
1871
|
|
1872
1872
|
context 'given nil' do
|
1873
1873
|
subject { Person.database_field_name(nil) }
|
1874
|
-
it { is_expected.to eq
|
1874
|
+
it { is_expected.to eq '' }
|
1875
1875
|
end
|
1876
1876
|
|
1877
1877
|
context 'given an empty String' do
|
1878
1878
|
subject { Person.database_field_name('') }
|
1879
|
-
it { is_expected.to eq
|
1879
|
+
it { is_expected.to eq '' }
|
1880
1880
|
end
|
1881
1881
|
|
1882
1882
|
context 'given a String' do
|
@@ -2594,4 +2594,35 @@ describe Mongoid::Interceptable do
|
|
2594
2594
|
end
|
2595
2595
|
end
|
2596
2596
|
end
|
2597
|
+
|
2598
|
+
context "when around callbacks for embedded children are enabled" do
|
2599
|
+
config_override :around_callbacks_for_embeds, true
|
2600
|
+
|
2601
|
+
context "when around callback is defined without a yield" do
|
2602
|
+
class Mother
|
2603
|
+
include Mongoid::Document
|
2604
|
+
embeds_many :daughters, cascade_callbacks: true
|
2605
|
+
end
|
2606
|
+
|
2607
|
+
class Daughter
|
2608
|
+
include Mongoid::Document
|
2609
|
+
embedded_in :mother
|
2610
|
+
around_save :log_callback
|
2611
|
+
|
2612
|
+
private
|
2613
|
+
|
2614
|
+
def log_callback
|
2615
|
+
logger.debug('callback invoked')
|
2616
|
+
end
|
2617
|
+
end
|
2618
|
+
|
2619
|
+
let(:mom) { Mother.create(daughters: [ Daughter.new, Daughter.new ]) }
|
2620
|
+
|
2621
|
+
it "raises an InvalidAroundCallback error" do
|
2622
|
+
expect do
|
2623
|
+
mom.save
|
2624
|
+
end.to raise_error(Mongoid::Errors::InvalidAroundCallback)
|
2625
|
+
end
|
2626
|
+
end
|
2627
|
+
end
|
2597
2628
|
end
|
@@ -0,0 +1,167 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
require 'support/feature_sandbox'
|
5
|
+
|
6
|
+
MONGOID_MODEL_RESOLVER_KEY__ = :__separate_instance_spec_key
|
7
|
+
Mongoid::ModelResolver.register_resolver Mongoid::ModelResolver.new, MONGOID_MODEL_RESOLVER_KEY__
|
8
|
+
|
9
|
+
def quarantine(context, &block)
|
10
|
+
state = {}
|
11
|
+
|
12
|
+
context.before(:context) do
|
13
|
+
state[:quarantine] = FeatureSandbox.start_quarantine
|
14
|
+
block&.call
|
15
|
+
end
|
16
|
+
|
17
|
+
context.after(:context) do
|
18
|
+
FeatureSandbox.end_quarantine(state[:quarantine])
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe Mongoid::ModelResolver do
|
23
|
+
shared_examples 'a resolver' do |**kwargs|
|
24
|
+
it 'includes the class name when asked for all keys of the given model' do
|
25
|
+
expect(resolver.keys_for(model_class.new)).to include(model_class.name)
|
26
|
+
end
|
27
|
+
|
28
|
+
if kwargs[:with_aliases].nil?
|
29
|
+
it 'uses the class name as the default key for the given model' do
|
30
|
+
expect(resolver.default_key_for(model_class.new)).to eq model_class.name
|
31
|
+
end
|
32
|
+
elsif kwargs[:with_aliases].is_a?(Array)
|
33
|
+
it 'uses the first alias as the default key for the given model' do
|
34
|
+
expect(resolver.default_key_for(model_class.new)).to eq kwargs[:with_aliases].first
|
35
|
+
end
|
36
|
+
else
|
37
|
+
it 'uses the alias as the default key for the given model' do
|
38
|
+
expect(resolver.default_key_for(model_class.new)).to eq kwargs[:with_aliases]
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'returns the model class when queried with the class name' do
|
43
|
+
expect(resolver.model_for(model_class.name)).to eq model_class
|
44
|
+
end
|
45
|
+
|
46
|
+
Array(kwargs[:with_aliases]).each do |model_alias|
|
47
|
+
it "includes the alias #{model_alias.inspect} when asked for all keys of the given model" do
|
48
|
+
expect(resolver.keys_for(model_class.new)).to include(model_alias)
|
49
|
+
end
|
50
|
+
|
51
|
+
it "returns the model class when queried with #{model_alias.inspect}" do
|
52
|
+
expect(resolver.model_for(model_alias)).to eq model_class
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
context 'when using the default instance' do
|
58
|
+
let(:resolver) { described_class.instance }
|
59
|
+
|
60
|
+
context 'when an alias is not specified' do
|
61
|
+
quarantine(self) do
|
62
|
+
Object.class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
63
|
+
module Mongoid; module Specs; module DefaultInstance
|
64
|
+
class Vanilla; include Mongoid::Document; end
|
65
|
+
end; end; end
|
66
|
+
RUBY
|
67
|
+
end
|
68
|
+
|
69
|
+
let(:model_class) { Mongoid::Specs::DefaultInstance::Vanilla }
|
70
|
+
|
71
|
+
it_behaves_like 'a resolver'
|
72
|
+
end
|
73
|
+
|
74
|
+
context 'when one alias is specified' do
|
75
|
+
quarantine(self) do
|
76
|
+
Object.class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
77
|
+
module Mongoid; module Specs; module DefaultInstance
|
78
|
+
class Aliased
|
79
|
+
include Mongoid::Document
|
80
|
+
identify_as 'aliased'
|
81
|
+
end
|
82
|
+
end; end; end
|
83
|
+
RUBY
|
84
|
+
end
|
85
|
+
|
86
|
+
let(:model_class) { Mongoid::Specs::DefaultInstance::Aliased }
|
87
|
+
|
88
|
+
it_behaves_like 'a resolver', with_aliases: 'aliased'
|
89
|
+
end
|
90
|
+
|
91
|
+
context 'when multiple aliases are specified' do
|
92
|
+
quarantine(self) do
|
93
|
+
Object.class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
94
|
+
module Mongoid; module Specs; module DefaultInstance
|
95
|
+
class AliasedMultiple
|
96
|
+
include Mongoid::Document
|
97
|
+
identify_as 'aliased', 'alias2', 'alias3'
|
98
|
+
end
|
99
|
+
end; end; end
|
100
|
+
RUBY
|
101
|
+
end
|
102
|
+
|
103
|
+
let(:model_class) { Mongoid::Specs::DefaultInstance::AliasedMultiple }
|
104
|
+
|
105
|
+
it_behaves_like 'a resolver', with_aliases: %w[ aliased alias2 alias3 ]
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
context 'when using a separate instance' do
|
110
|
+
let(:resolver) { described_class.resolver(MONGOID_MODEL_RESOLVER_KEY__) }
|
111
|
+
|
112
|
+
it 'does not refer to the default instance' do
|
113
|
+
expect(resolver).not_to eq described_class.instance
|
114
|
+
end
|
115
|
+
|
116
|
+
context 'when an alias is not specified' do
|
117
|
+
quarantine(self) do
|
118
|
+
Object.class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
119
|
+
module Mongoid; module Specs; module SeparateInstance
|
120
|
+
class Vanilla
|
121
|
+
include Mongoid::Document
|
122
|
+
identify_as resolver: MONGOID_MODEL_RESOLVER_KEY__
|
123
|
+
end
|
124
|
+
end; end; end
|
125
|
+
RUBY
|
126
|
+
end
|
127
|
+
|
128
|
+
let(:model_class) { Mongoid::Specs::SeparateInstance::Vanilla }
|
129
|
+
|
130
|
+
it_behaves_like 'a resolver'
|
131
|
+
end
|
132
|
+
|
133
|
+
context 'when one alias is specified' do
|
134
|
+
quarantine(self) do
|
135
|
+
Object.class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
136
|
+
module Mongoid; module Specs; module SeparateInstance
|
137
|
+
class Aliased
|
138
|
+
include Mongoid::Document
|
139
|
+
identify_as 'aliased', resolver: MONGOID_MODEL_RESOLVER_KEY__
|
140
|
+
end
|
141
|
+
end; end; end
|
142
|
+
RUBY
|
143
|
+
end
|
144
|
+
|
145
|
+
let(:model_class) { Mongoid::Specs::SeparateInstance::Aliased }
|
146
|
+
|
147
|
+
it_behaves_like 'a resolver', with_aliases: 'aliased'
|
148
|
+
end
|
149
|
+
|
150
|
+
context 'when multiple aliases are specified' do
|
151
|
+
quarantine(self) do
|
152
|
+
Object.class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
153
|
+
module Mongoid; module Specs; module SeparateInstance
|
154
|
+
class AliasedMultiple
|
155
|
+
include Mongoid::Document
|
156
|
+
identify_as 'aliased', 'alias2', 'alias3', resolver: MONGOID_MODEL_RESOLVER_KEY__
|
157
|
+
end
|
158
|
+
end; end; end
|
159
|
+
RUBY
|
160
|
+
end
|
161
|
+
|
162
|
+
let(:model_class) { Mongoid::Specs::SeparateInstance::AliasedMultiple }
|
163
|
+
|
164
|
+
it_behaves_like 'a resolver', with_aliases: %w[ aliased alias2 alias3 ]
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
@@ -5,7 +5,7 @@ require 'spec_helper'
|
|
5
5
|
# @note This test ensures that we do not inadvertently introduce new monkey patches
|
6
6
|
# to Mongoid. Existing monkey patch methods which are marked with +Mongoid.deprecated+
|
7
7
|
# are excluded from this test.
|
8
|
-
RSpec.describe('Do not add monkey patches') do
|
8
|
+
RSpec.describe('Do not add monkey patches') do
|
9
9
|
classes = [
|
10
10
|
Object,
|
11
11
|
Array,
|
@@ -206,12 +206,25 @@ describe Mongoid::PersistenceContext do
|
|
206
206
|
|
207
207
|
context 'when the options are valid extra options' do
|
208
208
|
|
209
|
-
|
210
|
-
|
209
|
+
context 'collection' do
|
210
|
+
|
211
|
+
let(:options) do
|
212
|
+
{ collection: 'other' }
|
213
|
+
end
|
214
|
+
|
215
|
+
it 'sets the options on the persistence context object' do
|
216
|
+
expect(persistence_context.collection_name).to eq(options[:collection].to_sym)
|
217
|
+
end
|
211
218
|
end
|
212
219
|
|
213
|
-
|
214
|
-
|
220
|
+
context 'collection_options' do
|
221
|
+
let(:options) do
|
222
|
+
{ collection_options: { capped: true } }
|
223
|
+
end
|
224
|
+
|
225
|
+
it 'does not propagate to client options' do
|
226
|
+
expect(persistence_context.send(:client_options).key?(:collection_options)).to eq(false)
|
227
|
+
end
|
215
228
|
end
|
216
229
|
end
|
217
230
|
|