mongoid 9.0.2 → 9.0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/mongoid/attributes/readonly.rb +8 -3
- data/lib/mongoid/clients/options.rb +14 -1
- data/lib/mongoid/clients/sessions.rb +1 -0
- data/lib/mongoid/criteria/queryable/selectable.rb +1 -1
- data/lib/mongoid/equality.rb +1 -0
- data/lib/mongoid/loadable.rb +72 -8
- data/lib/mongoid/matcher.rb +15 -1
- data/lib/mongoid/persistence_context.rb +14 -9
- data/lib/mongoid/railties/controller_runtime.rb +2 -2
- data/lib/mongoid/serializable.rb +7 -7
- data/lib/mongoid/threaded.rb +96 -28
- data/lib/mongoid/timestamps/timeless.rb +4 -1
- data/lib/mongoid/touchable.rb +1 -1
- data/lib/mongoid/traversable.rb +25 -2
- data/lib/mongoid/validatable/associated.rb +5 -2
- data/lib/mongoid/version.rb +1 -1
- data/spec/integration/active_job_spec.rb +24 -20
- data/spec/integration/app_spec.rb +9 -1
- data/spec/mongoid/association/referenced/belongs_to/proxy_spec.rb +4 -0
- data/spec/mongoid/attributes/readonly_spec.rb +19 -0
- data/spec/mongoid/clients/options_spec.rb +127 -2
- data/spec/mongoid/criteria/queryable/selectable_spec.rb +29 -0
- data/spec/mongoid/equality_spec.rb +6 -0
- data/spec/mongoid/interceptable_spec.rb +12 -0
- data/spec/mongoid/interceptable_spec_models.rb +12 -0
- data/spec/mongoid/loadable_spec.rb +86 -0
- data/spec/mongoid/persistence_context_spec.rb +39 -0
- data/spec/mongoid/railties/bson_object_id_serializer_spec.rb +18 -12
- data/spec/mongoid/threaded_spec.rb +24 -5
- data/spec/mongoid/validatable/associated_spec.rb +14 -4
- data/spec/rails/controller_extension/controller_runtime_spec.rb +14 -14
- metadata +7 -8
@@ -70,13 +70,16 @@ module Mongoid
|
|
70
70
|
# Now, treating the target as an array, look at each element
|
71
71
|
# and see if it is valid, but only if it has already been
|
72
72
|
# persisted, or changed, and hasn't been flagged for destroy.
|
73
|
-
|
73
|
+
#
|
74
|
+
# use map.all? instead of just all?, because all? will do short-circuit
|
75
|
+
# evaluation and terminate on the first failed validation.
|
76
|
+
list.map do |value|
|
74
77
|
if value && !value.flagged_for_destroy? && (!value.persisted? || value.changed?)
|
75
78
|
value.validated? ? true : value.valid?
|
76
79
|
else
|
77
80
|
true
|
78
81
|
end
|
79
|
-
end
|
82
|
+
end.all?
|
80
83
|
end
|
81
84
|
|
82
85
|
document.errors.add(attribute, :invalid) unless valid
|
data/lib/mongoid/version.rb
CHANGED
@@ -2,31 +2,35 @@
|
|
2
2
|
# rubocop:todo all
|
3
3
|
|
4
4
|
require 'spec_helper'
|
5
|
-
|
6
|
-
require '
|
5
|
+
begin
|
6
|
+
require 'active_job'
|
7
|
+
require 'mongoid/railties/bson_object_id_serializer'
|
7
8
|
|
8
|
-
describe 'ActiveJob Serialization' do
|
9
|
-
|
9
|
+
describe 'ActiveJob Serialization' do
|
10
|
+
skip unless defined?(ActiveJob)
|
10
11
|
|
11
|
-
|
12
|
-
|
13
|
-
|
12
|
+
class TestBsonObjectIdSerializerJob < ActiveJob::Base
|
13
|
+
def perform(*args)
|
14
|
+
args
|
15
|
+
end
|
14
16
|
end
|
15
|
-
end
|
16
17
|
|
17
|
-
|
18
|
-
|
19
|
-
|
18
|
+
let(:band) do
|
19
|
+
Band.create!
|
20
|
+
end
|
20
21
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
22
|
+
before do
|
23
|
+
ActiveJob::Serializers.add_serializers(
|
24
|
+
[::Mongoid::Railties::ActiveJobSerializers::BsonObjectIdSerializer]
|
25
|
+
)
|
26
|
+
end
|
26
27
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
28
|
+
it 'serializes and deserializes BSON::ObjectId' do
|
29
|
+
expect do
|
30
|
+
TestBsonObjectIdSerializerJob.perform_later(band.id)
|
31
|
+
end.not_to raise_error
|
32
|
+
end
|
31
33
|
end
|
34
|
+
rescue LoadError
|
35
|
+
RSpec.context.skip 'This test requires active_job'
|
32
36
|
end
|
@@ -36,6 +36,8 @@ describe 'Mongoid application tests' do
|
|
36
36
|
context 'demo application' do
|
37
37
|
context 'sinatra' do
|
38
38
|
it 'runs' do
|
39
|
+
skip 'https://jira.mongodb.org/browse/MONGOID-5826'
|
40
|
+
|
39
41
|
clone_application(
|
40
42
|
'https://github.com/mongoid/mongoid-demo',
|
41
43
|
subdir: 'sinatra-minimal',
|
@@ -55,6 +57,8 @@ describe 'Mongoid application tests' do
|
|
55
57
|
|
56
58
|
context 'rails-api' do
|
57
59
|
it 'runs' do
|
60
|
+
skip 'https://jira.mongodb.org/browse/MONGOID-5826'
|
61
|
+
|
58
62
|
clone_application(
|
59
63
|
'https://github.com/mongoid/mongoid-demo',
|
60
64
|
subdir: 'rails-api',
|
@@ -172,7 +176,7 @@ describe 'Mongoid application tests' do
|
|
172
176
|
if (rails_version = SpecConfig.instance.rails_version) == 'master'
|
173
177
|
else
|
174
178
|
check_call(%w(gem list))
|
175
|
-
check_call(%w(gem install rails --no-document -v) + ["~> #{rails_version}.0"])
|
179
|
+
check_call(%w(gem install rails --no-document --force -v) + ["~> #{rails_version}.0"])
|
176
180
|
end
|
177
181
|
end
|
178
182
|
|
@@ -319,6 +323,10 @@ describe 'Mongoid application tests' do
|
|
319
323
|
end
|
320
324
|
|
321
325
|
def adjust_rails_defaults(rails_version: SpecConfig.instance.rails_version)
|
326
|
+
if !rails_version.match?(/^\d+\.\d+$/)
|
327
|
+
# This must be pre-release version, we trim it
|
328
|
+
rails_version = rails_version.split('.')[0..1].join('.')
|
329
|
+
end
|
322
330
|
if File.exist?('config/application.rb')
|
323
331
|
lines = IO.readlines('config/application.rb')
|
324
332
|
lines.each do |line|
|
@@ -751,6 +751,10 @@ describe Mongoid::Association::Referenced::BelongsTo::Proxy do
|
|
751
751
|
person.save!
|
752
752
|
end
|
753
753
|
|
754
|
+
# NOTE: there as a bad interdependency here, with the auto_save_spec.rb
|
755
|
+
# file. If auto_save_spec.rb runs before this, the following specs fail
|
756
|
+
# with "undefined method `nullify' for an instance of Person".
|
757
|
+
|
754
758
|
context "when parent exists" do
|
755
759
|
|
756
760
|
context "when child is destroyed" do
|
@@ -266,7 +266,26 @@ describe Mongoid::Attributes::Readonly do
|
|
266
266
|
expect(child.mother).to be_nil
|
267
267
|
end
|
268
268
|
end
|
269
|
+
end
|
270
|
+
|
271
|
+
context "when a subclass inherits readonly fields" do
|
272
|
+
let(:attributes) do
|
273
|
+
[:title, :terms]
|
274
|
+
end
|
275
|
+
|
276
|
+
before do
|
277
|
+
class OldPerson < Person
|
278
|
+
attr_readonly :age
|
279
|
+
end
|
280
|
+
end
|
269
281
|
|
282
|
+
it "ensures subclass inherits the readonly attributes from parent" do
|
283
|
+
expect(OldPerson.readonly_attributes.to_a).to include("title","terms")
|
284
|
+
end
|
285
|
+
|
286
|
+
it "ensures subclass does not modify parent's readonly attributes" do
|
287
|
+
expect(Person.readonly_attributes.to_a).not_to include("age")
|
288
|
+
end
|
270
289
|
end
|
271
290
|
end
|
272
291
|
end
|
@@ -27,7 +27,7 @@ describe Mongoid::Clients::Options, retry: 3 do
|
|
27
27
|
let(:options) { { database: 'other' } }
|
28
28
|
|
29
29
|
it 'sets the options on the client' do
|
30
|
-
expect(persistence_context.client.options['database']).to eq(options[:database])
|
30
|
+
expect(persistence_context.client.options['database'].to_s).to eq(options[:database].to_s)
|
31
31
|
end
|
32
32
|
|
33
33
|
it 'does not set the options on class level' do
|
@@ -319,7 +319,7 @@ describe Mongoid::Clients::Options, retry: 3 do
|
|
319
319
|
end
|
320
320
|
|
321
321
|
it 'sets the options on the client' do
|
322
|
-
expect(persistence_context.client.options['database']).to eq(options[:database])
|
322
|
+
expect(persistence_context.client.options['database'].to_s).to eq(options[:database].to_s)
|
323
323
|
end
|
324
324
|
|
325
325
|
it 'does not set the options on instance level' do
|
@@ -522,4 +522,129 @@ describe Mongoid::Clients::Options, retry: 3 do
|
|
522
522
|
end
|
523
523
|
end
|
524
524
|
end
|
525
|
+
|
526
|
+
context 'with global overrides' do
|
527
|
+
let(:default_subscriber) do
|
528
|
+
Mrss::EventSubscriber.new
|
529
|
+
end
|
530
|
+
|
531
|
+
let(:override_subscriber) do
|
532
|
+
Mrss::EventSubscriber.new
|
533
|
+
end
|
534
|
+
|
535
|
+
context 'when global client is overridden' do
|
536
|
+
before do
|
537
|
+
Mongoid.clients['override_client'] = { hosts: SpecConfig.instance.addresses, database: 'default_override_database' }
|
538
|
+
Mongoid.override_client('override_client')
|
539
|
+
Mongoid.client(:default).subscribe(Mongo::Monitoring::COMMAND, default_subscriber)
|
540
|
+
Mongoid.client('override_client').subscribe(Mongo::Monitoring::COMMAND, override_subscriber)
|
541
|
+
end
|
542
|
+
|
543
|
+
after do
|
544
|
+
Mongoid.client(:default).unsubscribe(Mongo::Monitoring::COMMAND, default_subscriber)
|
545
|
+
Mongoid.client('override_client').unsubscribe(Mongo::Monitoring::COMMAND, override_subscriber)
|
546
|
+
Mongoid.override_client(nil)
|
547
|
+
Mongoid.clients['override_client'] = nil
|
548
|
+
end
|
549
|
+
|
550
|
+
it 'uses the overridden client for create' do
|
551
|
+
Minim.create!
|
552
|
+
|
553
|
+
expect(override_subscriber.single_command_started_event('insert').database_name).to eq('default_override_database')
|
554
|
+
expect(default_subscriber.command_started_events('insert')).to be_empty
|
555
|
+
end
|
556
|
+
|
557
|
+
it 'uses the overridden client for queries' do
|
558
|
+
Minim.where(name: 'Dmitry').to_a
|
559
|
+
|
560
|
+
expect(override_subscriber.single_command_started_event('find').database_name).to eq('default_override_database')
|
561
|
+
expect(default_subscriber.command_started_events('find')).to be_empty
|
562
|
+
end
|
563
|
+
|
564
|
+
context 'when the client is set on the model level' do
|
565
|
+
let(:model_level_subscriber) do
|
566
|
+
Mrss::EventSubscriber.new
|
567
|
+
end
|
568
|
+
|
569
|
+
around(:example) do |example|
|
570
|
+
opts = Minim.storage_options
|
571
|
+
Minim.storage_options = Minim.storage_options.merge( { client: 'model_level_client' } )
|
572
|
+
Mongoid.clients['model_level_client'] = { hosts: SpecConfig.instance.addresses, database: 'model_level_database' }
|
573
|
+
Mongoid.client('model_level_client').subscribe(Mongo::Monitoring::COMMAND, override_subscriber)
|
574
|
+
example.run
|
575
|
+
Mongoid.client('model_level_client').unsubscribe(Mongo::Monitoring::COMMAND, override_subscriber)
|
576
|
+
Mongoid.clients['model_level_client'] = nil
|
577
|
+
Minim.storage_options = opts
|
578
|
+
end
|
579
|
+
|
580
|
+
# This behaviour is consistent with 8.x
|
581
|
+
it 'uses the overridden client for create' do
|
582
|
+
Minim.create!
|
583
|
+
|
584
|
+
expect(override_subscriber.single_command_started_event('insert').database_name).to eq('default_override_database')
|
585
|
+
expect(default_subscriber.command_started_events('insert')).to be_empty
|
586
|
+
expect(model_level_subscriber.command_started_events('insert')).to be_empty
|
587
|
+
end
|
588
|
+
|
589
|
+
# This behaviour is consistent with 8.x
|
590
|
+
it 'uses the overridden client for queries' do
|
591
|
+
Minim.where(name: 'Dmitry').to_a
|
592
|
+
|
593
|
+
expect(override_subscriber.single_command_started_event('find').database_name).to eq('default_override_database')
|
594
|
+
expect(default_subscriber.command_started_events('find')).to be_empty
|
595
|
+
expect(model_level_subscriber.command_started_events('find')).to be_empty
|
596
|
+
end
|
597
|
+
end
|
598
|
+
end
|
599
|
+
|
600
|
+
context 'when global database is overridden' do
|
601
|
+
before do
|
602
|
+
Mongoid.override_database('override_database')
|
603
|
+
Mongoid.client(:default).subscribe(Mongo::Monitoring::COMMAND, default_subscriber)
|
604
|
+
end
|
605
|
+
|
606
|
+
after do
|
607
|
+
Mongoid.client(:default).unsubscribe(Mongo::Monitoring::COMMAND, default_subscriber)
|
608
|
+
Mongoid.override_database(nil)
|
609
|
+
end
|
610
|
+
|
611
|
+
it 'uses the overridden database for create' do
|
612
|
+
Minim.create!
|
613
|
+
|
614
|
+
expect(default_subscriber.single_command_started_event('insert').database_name).to eq('override_database')
|
615
|
+
end
|
616
|
+
|
617
|
+
it 'uses the overridden database for queries' do
|
618
|
+
Minim.where(name: 'Dmitry').to_a
|
619
|
+
|
620
|
+
expect(default_subscriber.single_command_started_event('find').database_name).to eq('override_database')
|
621
|
+
end
|
622
|
+
|
623
|
+
context 'when the database is set on the model level' do
|
624
|
+
around(:example) do |example|
|
625
|
+
opts = Minim.storage_options
|
626
|
+
Minim.storage_options = Minim.storage_options.merge( { database: 'model_level_database' } )
|
627
|
+
Mongoid.clients['model_level_client'] = { hosts: SpecConfig.instance.addresses, database: 'model_level_database' }
|
628
|
+
Mongoid.client(:default).subscribe(Mongo::Monitoring::COMMAND, default_subscriber)
|
629
|
+
example.run
|
630
|
+
Mongoid.client(:default).unsubscribe(Mongo::Monitoring::COMMAND, default_subscriber)
|
631
|
+
Mongoid.clients['model_level_client'] = nil
|
632
|
+
Minim.storage_options = opts
|
633
|
+
end
|
634
|
+
|
635
|
+
# This behaviour is consistent with 8.x
|
636
|
+
it 'uses the overridden database for create' do
|
637
|
+
Minim.create!
|
638
|
+
|
639
|
+
expect(default_subscriber.single_command_started_event('insert').database_name).to eq('override_database')
|
640
|
+
end
|
641
|
+
|
642
|
+
it 'uses the overridden database for queries' do
|
643
|
+
Minim.where(name: 'Dmitry').to_a
|
644
|
+
|
645
|
+
expect(default_subscriber.single_command_started_event('find').database_name).to eq('override_database')
|
646
|
+
end
|
647
|
+
end
|
648
|
+
end
|
649
|
+
end
|
525
650
|
end
|
@@ -1939,6 +1939,35 @@ describe Mongoid::Criteria::Queryable::Selectable do
|
|
1939
1939
|
end
|
1940
1940
|
end
|
1941
1941
|
|
1942
|
+
describe "#not" do
|
1943
|
+
context "when negating a criterion" do
|
1944
|
+
let(:selection) do
|
1945
|
+
query.not(field: /value/)
|
1946
|
+
end
|
1947
|
+
|
1948
|
+
it "adds the $not selector" do
|
1949
|
+
expect(selection.selector).to eq({
|
1950
|
+
"field" => { "$not" => /value/ }
|
1951
|
+
})
|
1952
|
+
end
|
1953
|
+
|
1954
|
+
it "returns a cloned query" do
|
1955
|
+
expect(selection).to_not equal(query)
|
1956
|
+
end
|
1957
|
+
|
1958
|
+
context "when toggling negation state" do
|
1959
|
+
it "negates the negating value" do
|
1960
|
+
expect(query.negating).to be_nil
|
1961
|
+
negated_query = query.not
|
1962
|
+
expect(negated_query.negating).to be true
|
1963
|
+
double_negated_query = negated_query.not
|
1964
|
+
expect(double_negated_query.negating).to be false
|
1965
|
+
end
|
1966
|
+
end
|
1967
|
+
end
|
1968
|
+
end
|
1969
|
+
|
1970
|
+
|
1942
1971
|
describe Symbol do
|
1943
1972
|
|
1944
1973
|
describe "#all" do
|
@@ -189,6 +189,12 @@ describe Mongoid::Equality do
|
|
189
189
|
it "compares based on the document id" do
|
190
190
|
expect(first <=> second).to eq(-1)
|
191
191
|
end
|
192
|
+
|
193
|
+
it "doesn't break if one isn't a document" do
|
194
|
+
expect do
|
195
|
+
first <=> "Foo"
|
196
|
+
end.to_not raise_error
|
197
|
+
end
|
192
198
|
end
|
193
199
|
|
194
200
|
describe "#eql?" do
|
@@ -1789,6 +1789,12 @@ describe Mongoid::Interceptable do
|
|
1789
1789
|
context 'with around callbacks' do
|
1790
1790
|
config_override :around_callbacks_for_embeds, true
|
1791
1791
|
|
1792
|
+
after do
|
1793
|
+
Mongoid::Threaded.stack('interceptable').clear
|
1794
|
+
end
|
1795
|
+
|
1796
|
+
let(:stack) { Mongoid::Threaded.stack('interceptable') }
|
1797
|
+
|
1792
1798
|
let(:expected) do
|
1793
1799
|
[
|
1794
1800
|
[InterceptableSpec::CbCascadedChild, :before_validation],
|
@@ -1824,6 +1830,12 @@ describe Mongoid::Interceptable do
|
|
1824
1830
|
parent.save!
|
1825
1831
|
expect(registry.calls).to eq expected
|
1826
1832
|
end
|
1833
|
+
|
1834
|
+
it 'shows that cascaded callbacks can access Mongoid state' do
|
1835
|
+
expect(stack).to be_empty
|
1836
|
+
parent.save!
|
1837
|
+
expect(stack).not_to be_empty
|
1838
|
+
end
|
1827
1839
|
end
|
1828
1840
|
|
1829
1841
|
context 'without around callbacks' do
|
@@ -224,7 +224,19 @@ module InterceptableSpec
|
|
224
224
|
|
225
225
|
attr_accessor :callback_registry
|
226
226
|
|
227
|
+
before_save :test_mongoid_state
|
228
|
+
|
227
229
|
include CallbackTracking
|
230
|
+
|
231
|
+
private
|
232
|
+
|
233
|
+
# Helps test that cascading child callbacks have access to the Mongoid
|
234
|
+
# state objects; if the implementation uses fiber-local (instead of truly
|
235
|
+
# thread-local) variables, the related tests will fail because the
|
236
|
+
# cascading child callbacks use fibers to linearize the recursion.
|
237
|
+
def test_mongoid_state
|
238
|
+
Mongoid::Threaded.stack('interceptable').push(self)
|
239
|
+
end
|
228
240
|
end
|
229
241
|
end
|
230
242
|
|
@@ -0,0 +1,86 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Mongoid::Loadable do
|
6
|
+
let(:lib_dir) { Pathname.new('../../lib').realpath(__dir__) }
|
7
|
+
|
8
|
+
shared_context 'with ignore_patterns' do
|
9
|
+
around do |example|
|
10
|
+
saved = Mongoid.ignore_patterns
|
11
|
+
Mongoid.ignore_patterns = ignore_patterns
|
12
|
+
example.run
|
13
|
+
ensure
|
14
|
+
Mongoid.ignore_patterns = saved
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe '#ignore_patterns' do
|
19
|
+
context 'when not explicitly set' do
|
20
|
+
it 'equals the default list of ignore patterns' do
|
21
|
+
expect(Mongoid.ignore_patterns).to eq Mongoid::Loadable::DEFAULT_IGNORE_PATTERNS
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
context 'when explicitly set' do
|
26
|
+
include_context 'with ignore_patterns'
|
27
|
+
|
28
|
+
let(:ignore_patterns) { %w[ pattern1 pattern2 ] }
|
29
|
+
|
30
|
+
it 'equals the list of specified patterns' do
|
31
|
+
expect(Mongoid.ignore_patterns).to eq ignore_patterns
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe '#files_under_path' do
|
37
|
+
let(:results) { Mongoid.files_under_path(lib_dir) }
|
38
|
+
|
39
|
+
include_context 'with ignore_patterns'
|
40
|
+
|
41
|
+
context 'when ignore_patterns is empty' do
|
42
|
+
let(:ignore_patterns) { [] }
|
43
|
+
|
44
|
+
it 'returns all ruby files' do
|
45
|
+
expect(results.length).to be > 10 # should be a bunch of them
|
46
|
+
expect(results).to include('rails/mongoid')
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
context 'when ignore_patterns is not empty' do
|
51
|
+
let(:ignore_patterns) { %w[ */rails/* ] }
|
52
|
+
|
53
|
+
it 'omits the ignored paths' do
|
54
|
+
expect(results.length).to be > 10 # should be a bunch of them
|
55
|
+
expect(results).not_to include('rails/mongoid')
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
describe '#files_under_paths' do
|
61
|
+
let(:paths) { [ lib_dir.join('mongoid'), lib_dir.join('rails') ] }
|
62
|
+
let(:results) { Mongoid.files_under_paths(paths) }
|
63
|
+
|
64
|
+
include_context 'with ignore_patterns'
|
65
|
+
|
66
|
+
context 'when ignore_patterns is empty' do
|
67
|
+
let(:ignore_patterns) { [] }
|
68
|
+
|
69
|
+
it 'returns all ruby files' do
|
70
|
+
expect(results.length).to be > 10 # should be a bunch
|
71
|
+
expect(results).to include('generators/mongoid/model/model_generator')
|
72
|
+
expect(results).to include('fields/encrypted')
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
context 'when ignore_patterns is not empty' do
|
77
|
+
let(:ignore_patterns) { %w[ */model/* */fields/* ] }
|
78
|
+
|
79
|
+
it 'returns all ruby files' do
|
80
|
+
expect(results.length).to be > 10 # should be a bunch
|
81
|
+
expect(results).not_to include('generators/mongoid/model/model_generator')
|
82
|
+
expect(results).not_to include('fields/encrypted')
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -536,6 +536,20 @@ describe Mongoid::PersistenceContext do
|
|
536
536
|
end
|
537
537
|
end
|
538
538
|
end
|
539
|
+
|
540
|
+
context 'when the database is specified as a proc' do
|
541
|
+
let(:options) { { database: ->{ 'other' } } }
|
542
|
+
|
543
|
+
after { persistence_context.client.close }
|
544
|
+
|
545
|
+
it 'evaluates the proc' do
|
546
|
+
expect(persistence_context.database_name).to eq(:other)
|
547
|
+
end
|
548
|
+
|
549
|
+
it 'does not pass the proc to the client' do
|
550
|
+
expect(persistence_context.client.database.name).to eq('other')
|
551
|
+
end
|
552
|
+
end
|
539
553
|
end
|
540
554
|
|
541
555
|
describe '#client' do
|
@@ -570,6 +584,14 @@ describe Mongoid::PersistenceContext do
|
|
570
584
|
expect(persistence_context.client).to eq(Mongoid::Clients.with_name(:alternative))
|
571
585
|
end
|
572
586
|
|
587
|
+
context 'when the client option is a proc' do
|
588
|
+
let(:options) { { client: -> { :alternative } } }
|
589
|
+
|
590
|
+
it 'evaluates the proc' do
|
591
|
+
expect(persistence_context.client).to eq(Mongoid::Clients.with_name(:alternative))
|
592
|
+
end
|
593
|
+
end
|
594
|
+
|
573
595
|
context 'when there is a client override' do
|
574
596
|
persistence_context_override :client, :other
|
575
597
|
|
@@ -608,6 +630,23 @@ describe Mongoid::PersistenceContext do
|
|
608
630
|
end
|
609
631
|
end
|
610
632
|
|
633
|
+
context 'when the client is set as a proc in the storage options' do
|
634
|
+
let(:options) { {} }
|
635
|
+
|
636
|
+
before do
|
637
|
+
Band.store_in client: ->{ :alternative }
|
638
|
+
end
|
639
|
+
|
640
|
+
after do
|
641
|
+
persistence_context.client.close
|
642
|
+
Band.store_in client: nil
|
643
|
+
end
|
644
|
+
|
645
|
+
it 'uses the client option' do
|
646
|
+
expect(persistence_context.client).to eq(Mongoid::Clients.with_name(:alternative))
|
647
|
+
end
|
648
|
+
end
|
649
|
+
|
611
650
|
context 'when there is no client option set' do
|
612
651
|
|
613
652
|
let(:options) do
|
@@ -2,23 +2,29 @@
|
|
2
2
|
# rubocop:todo all
|
3
3
|
|
4
4
|
require 'spec_helper'
|
5
|
-
require 'active_job'
|
6
|
-
require 'mongoid/railties/bson_object_id_serializer'
|
7
5
|
|
8
|
-
|
6
|
+
begin
|
7
|
+
require 'active_job'
|
8
|
+
require 'mongoid/railties/bson_object_id_serializer'
|
9
9
|
|
10
|
-
let(:serializer) { Mongoid::Railties::ActiveJobSerializers::BsonObjectIdSerializer.instance }
|
11
|
-
let(:object_id) { BSON::ObjectId.new }
|
12
10
|
|
13
|
-
describe '
|
14
|
-
|
15
|
-
|
11
|
+
describe 'Mongoid::Railties::ActiveJobSerializers::BsonObjectIdSerializer' do
|
12
|
+
|
13
|
+
let(:serializer) { Mongoid::Railties::ActiveJobSerializers::BsonObjectIdSerializer.instance }
|
14
|
+
let(:object_id) { BSON::ObjectId.new }
|
15
|
+
|
16
|
+
describe '#serialize' do
|
17
|
+
it 'serializes BSON::ObjectId' do
|
18
|
+
expect(serializer.serialize(object_id)).to be_a(String)
|
19
|
+
end
|
16
20
|
end
|
17
|
-
end
|
18
21
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
+
describe '#deserialize' do
|
23
|
+
it 'deserializes BSON::ObjectId' do
|
24
|
+
expect(serializer.deserialize(serializer.serialize(object_id))).to eq(object_id)
|
25
|
+
end
|
22
26
|
end
|
23
27
|
end
|
28
|
+
rescue LoadError
|
29
|
+
RSpec.context.skip 'This test requires active_job'
|
24
30
|
end
|
@@ -36,11 +36,11 @@ describe Mongoid::Threaded do
|
|
36
36
|
context "when the stack has elements" do
|
37
37
|
|
38
38
|
before do
|
39
|
-
|
39
|
+
described_class.stack('load').push(true)
|
40
40
|
end
|
41
41
|
|
42
42
|
after do
|
43
|
-
|
43
|
+
described_class.stack('load').clear
|
44
44
|
end
|
45
45
|
|
46
46
|
it "returns true" do
|
@@ -51,7 +51,7 @@ describe Mongoid::Threaded do
|
|
51
51
|
context "when the stack has no elements" do
|
52
52
|
|
53
53
|
before do
|
54
|
-
|
54
|
+
described_class.stack('load').clear
|
55
55
|
end
|
56
56
|
|
57
57
|
it "returns false" do
|
@@ -76,7 +76,7 @@ describe Mongoid::Threaded do
|
|
76
76
|
context "when a stack has been initialized" do
|
77
77
|
|
78
78
|
before do
|
79
|
-
|
79
|
+
described_class.stack('load').push(true)
|
80
80
|
end
|
81
81
|
|
82
82
|
let(:loading) do
|
@@ -84,7 +84,7 @@ describe Mongoid::Threaded do
|
|
84
84
|
end
|
85
85
|
|
86
86
|
after do
|
87
|
-
|
87
|
+
described_class.stack('load').clear
|
88
88
|
end
|
89
89
|
|
90
90
|
it "returns the stack" do
|
@@ -341,4 +341,23 @@ describe Mongoid::Threaded do
|
|
341
341
|
end
|
342
342
|
end
|
343
343
|
end
|
344
|
+
|
345
|
+
describe '#clear_modified_documents' do
|
346
|
+
let(:session) do
|
347
|
+
double(Mongo::Session).tap do |session|
|
348
|
+
allow(session).to receive(:in_transaction?).and_return(true)
|
349
|
+
end
|
350
|
+
end
|
351
|
+
|
352
|
+
context 'when there are modified documents' do
|
353
|
+
before do
|
354
|
+
described_class.add_modified_document(session, Minim.new)
|
355
|
+
described_class.clear_modified_documents(session)
|
356
|
+
end
|
357
|
+
|
358
|
+
it 'removes the documents and keys' do
|
359
|
+
expect(described_class.modified_documents).to be_empty
|
360
|
+
end
|
361
|
+
end
|
362
|
+
end
|
344
363
|
end
|