mongoid 7.2.5 → 7.2.6

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.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +3 -3
  3. data/lib/config/locales/en.yml +13 -0
  4. data/lib/mongoid/association/relatable.rb +2 -0
  5. data/lib/mongoid/config/environment.rb +9 -1
  6. data/lib/mongoid/contextual/atomic.rb +7 -2
  7. data/lib/mongoid/contextual/none.rb +3 -0
  8. data/lib/mongoid/criteria/queryable/selectable.rb +2 -2
  9. data/lib/mongoid/criteria/queryable/storable.rb +4 -4
  10. data/lib/mongoid/document.rb +3 -2
  11. data/lib/mongoid/errors/empty_config_file.rb +26 -0
  12. data/lib/mongoid/errors/invalid_config_file.rb +26 -0
  13. data/lib/mongoid/errors.rb +2 -0
  14. data/lib/mongoid/persistence_context.rb +3 -1
  15. data/lib/mongoid/query_cache.rb +11 -1
  16. data/lib/mongoid/tasks/database.rb +1 -1
  17. data/lib/mongoid/version.rb +1 -1
  18. data/spec/integration/contextual/empty_spec.rb +142 -0
  19. data/spec/integration/stringified_symbol_field_spec.rb +2 -2
  20. data/spec/mongoid/association/referenced/belongs_to_query_spec.rb +20 -0
  21. data/spec/mongoid/association/referenced/has_many_models.rb +17 -0
  22. data/spec/mongoid/clients/factory_spec.rb +9 -3
  23. data/spec/mongoid/clients/options_spec.rb +11 -5
  24. data/spec/mongoid/config/environment_spec.rb +86 -8
  25. data/spec/mongoid/contextual/atomic_spec.rb +64 -25
  26. data/spec/mongoid/contextual/geo_near_spec.rb +1 -1
  27. data/spec/mongoid/document_spec.rb +21 -1
  28. data/spec/mongoid/errors/invalid_config_file_spec.rb +32 -0
  29. data/spec/mongoid/persistable/updatable_spec.rb +2 -0
  30. data/spec/mongoid/query_cache_spec.rb +24 -0
  31. data/spec/shared/lib/mrss/constraints.rb +21 -4
  32. data/spec/shared/lib/mrss/event_subscriber.rb +200 -0
  33. data/spec/shared/lib/mrss/server_version_registry.rb +17 -12
  34. data/spec/shared/share/Dockerfile.erb +5 -4
  35. data/spec/shared/shlib/server.sh +71 -21
  36. data.tar.gz.sig +0 -0
  37. metadata +544 -536
  38. metadata.gz.sig +0 -0
@@ -31,8 +31,8 @@ describe "StringifiedSymbol fields" do
31
31
  end
32
32
  end
33
33
 
34
- # Using command monitoring to test that StringifiedSymbol sends a string and returns a symbol
35
- let(:client) { Order.collection.client }
34
+ # Using command monitoring to test that StringifiedSymbol sends a string and returns a symbol
35
+ let(:client) { Order.collection.client }
36
36
 
37
37
  before do
38
38
  client.subscribe(Mongo::Monitoring::COMMAND, subscriber)
@@ -35,4 +35,24 @@ describe Mongoid::Association::Referenced::BelongsTo do
35
35
  expect(school.team).to eq('Bulldogs')
36
36
  end
37
37
  end
38
+
39
+ context 'when projecting with #only while having similar inverse_of candidates' do
40
+ before do
41
+ alice = HmmOwner.create!(name: 'Alice')
42
+ bob = HmmOwner.create!(name: 'Bob')
43
+
44
+ HmmPet.create!(name: 'Rex', current_owner: bob, previous_owner: alice)
45
+ end
46
+
47
+ let(:pet) { HmmPet.where(name: 'Rex').only(:name, :previous_owner_id, 'previous_owner.name').first }
48
+
49
+ it 'populates specified fields' do
50
+ expect(pet.name).to eq('Rex')
51
+ expect(pet.previous_owner.name).to eq('Alice')
52
+ end
53
+
54
+ it 'does not try to load the inverse for an association that explicitly prevents it' do
55
+ expect { pet.previous_owner.name }.not_to raise_error
56
+ end
57
+ end
38
58
  end
@@ -24,6 +24,23 @@ class HmmAddress
24
24
  belongs_to :company, class_name: 'HmmCompany'
25
25
  end
26
26
 
27
+ class HmmOwner
28
+ include Mongoid::Document
29
+
30
+ has_many :pets, class_name: 'HmmPet', inverse_of: :current_owner
31
+
32
+ field :name, type: String
33
+ end
34
+
35
+ class HmmPet
36
+ include Mongoid::Document
37
+
38
+ belongs_to :current_owner, class_name: 'HmmOwner', inverse_of: :pets, optional: true
39
+ belongs_to :previous_owner, class_name: 'HmmOwner', inverse_of: nil, optional: true
40
+
41
+ field :name, type: String
42
+ end
43
+
27
44
  class HmmSchool
28
45
  include Mongoid::Document
29
46
 
@@ -65,9 +65,15 @@ describe Mongoid::Clients::Factory do
65
65
  expect(client).to be_a(Mongo::Client)
66
66
  end
67
67
 
68
- it 'does not produce driver warnings' do
69
- Mongo::Logger.logger.should_not receive(:warn)
70
- client
68
+ context 'not JRuby' do
69
+ # Run this test on JRuby when driver 2.16.0 is released -
70
+ # see RUBY-2771.
71
+ fails_on_jruby
72
+
73
+ it 'does not produce driver warnings' do
74
+ Mongo::Logger.logger.should_not receive(:warn)
75
+ client
76
+ end
71
77
  end
72
78
 
73
79
  let(:cluster_addresses) do
@@ -83,9 +83,11 @@ describe Mongoid::Clients::Options, retry: 3 do
83
83
 
84
84
  let!(:connections_and_cluster_during) do
85
85
  connections = nil
86
- cluster = Minim.with(options) do |klass|
86
+ cluster = nil
87
+ Minim.with(options) do |klass|
87
88
  klass.where(name: 'emily').to_a
88
89
  connections = Minim.mongo_client.database.command(serverStatus: 1).first['connections']['current']
90
+ cluster = Minim.collection.cluster
89
91
  end
90
92
  [ connections, cluster ]
91
93
  end
@@ -124,7 +126,10 @@ describe Mongoid::Clients::Options, retry: 3 do
124
126
  end
125
127
 
126
128
  it 'disconnects the new cluster when the block exits' do
127
- expect(connections_before).to eq(connections_after)
129
+ expect(cluster_after).not_to be(cluster_during)
130
+
131
+ cluster_during.connected?.should be false
132
+ cluster_before.connected?.should be true
128
133
  end
129
134
  end
130
135
 
@@ -138,13 +143,14 @@ describe Mongoid::Clients::Options, retry: 3 do
138
143
 
139
144
  it 'does not create a new cluster' do
140
145
  expect(connections_during).to eq(connections_before)
146
+
147
+ cluster_during.should be cluster_before
141
148
  end
142
149
 
143
150
  it 'does not disconnect the original cluster' do
144
- skip 'https://jira.mongodb.org/browse/MONGOID-5130'
145
-
146
- expect(connections_after).to eq(connections_before)
147
151
  expect(cluster_before).to be(cluster_after)
152
+
153
+ cluster_before.connected?.should be true
148
154
  end
149
155
  end
150
156
 
@@ -5,9 +5,19 @@ require "spec_helper"
5
5
 
6
6
  describe Mongoid::Config::Environment do
7
7
 
8
- after(:all) do
9
- Rails = RailsTemp
10
- Object.send(:remove_const, :RailsTemp)
8
+ around do |example|
9
+ if defined?(Rails)
10
+ SavedRails = Rails
11
+ example.run
12
+ Object.send(:remove_const, :Rails) if defined?(Rails)
13
+ Rails = SavedRails
14
+ Object.send(:remove_const, :SavedRails)
15
+ else
16
+ example.run
17
+ if defined?(Rails)
18
+ Object.send(:remove_const, :Rails)
19
+ end
20
+ end
11
21
  end
12
22
 
13
23
  describe "#env_name" do
@@ -24,11 +34,6 @@ describe Mongoid::Config::Environment do
24
34
  end
25
35
  end
26
36
 
27
- after do
28
- RailsTemp = Rails
29
- Object.send(:remove_const, :Rails)
30
- end
31
-
32
37
  it "returns the rails environment" do
33
38
  expect(described_class.env_name).to eq("production")
34
39
  end
@@ -86,4 +91,77 @@ describe Mongoid::Config::Environment do
86
91
  end
87
92
  end
88
93
  end
94
+
95
+ describe "#load_yaml" do
96
+ let(:path) { 'mongoid.yml' }
97
+ let(:environment) {}
98
+ before { allow(Rails).to receive('env').and_return('test') }
99
+
100
+ subject { described_class.load_yaml(path, environment) }
101
+
102
+ context 'when file not found' do
103
+ let(:path) { 'not/a/valid/path'}
104
+
105
+ it { expect { subject }.to raise_error(Errno::ENOENT) }
106
+ end
107
+
108
+ context 'when file found' do
109
+ before do
110
+ allow(File).to receive(:new).with('mongoid.yml').and_return(StringIO.new(file_contents))
111
+ end
112
+
113
+ let(:file_contents) do
114
+ <<~FILE
115
+ test:
116
+ clients: ['test']
117
+ development:
118
+ clients: ['dev']
119
+ FILE
120
+ end
121
+
122
+ context 'when file cannot be parsed as YAML' do
123
+ let(:file_contents) { "*\nbad:%123abc" }
124
+
125
+ it { expect { subject }.to raise_error(Psych::SyntaxError) }
126
+ end
127
+
128
+ context 'when file contains ERB errors' do
129
+ let(:file_contents) { '<%= foo %>' }
130
+
131
+ it { expect { subject }.to raise_error(NameError) }
132
+ end
133
+
134
+ context 'when file is empty' do
135
+ let(:file_contents) { '' }
136
+
137
+ it { expect { subject }.to raise_error(Mongoid::Errors::EmptyConfigFile) }
138
+ end
139
+
140
+ context 'when file does not contain a YAML Hash object' do
141
+ let(:file_contents) { '["this", "is", "an", "array"]' }
142
+
143
+ it { expect { subject }.to raise_error(Mongoid::Errors::InvalidConfigFile) }
144
+ end
145
+
146
+ context 'when environment not specified' do
147
+ it 'uses the rails environment' do
148
+ is_expected.to eq("clients"=>["test"])
149
+ end
150
+ end
151
+
152
+ context 'when environment is specified' do
153
+ let(:environment) { 'development' }
154
+
155
+ it 'uses the specified environment' do
156
+ is_expected.to eq("clients"=>["dev"])
157
+ end
158
+ end
159
+
160
+ context 'when environment is missing' do
161
+ let(:environment) { 'staging' }
162
+
163
+ it { is_expected.to be_nil }
164
+ end
165
+ end
166
+ end
89
167
  end
@@ -801,27 +801,28 @@ describe Mongoid::Contextual::Atomic do
801
801
  context.unset(:name)
802
802
  end
803
803
 
804
- it "unsets the first existing field" do
805
- expect(depeche_mode.reload.name).to be_nil
806
- end
807
-
808
- it "unsets the last existing field" do
809
- expect(new_order.reload.name).to be_nil
804
+ it "unsets the fields from all documents" do
805
+ depeche_mode.reload
806
+ new_order.reload
807
+ expect(depeche_mode.name).to be_nil
808
+ expect(depeche_mode.years).to_not be_nil
809
+ expect(new_order.name).to be_nil
810
+ expect(new_order.years).to_not be_nil
810
811
  end
811
812
  end
812
813
 
813
814
  context "when the field is aliased" do
814
-
815
815
  before do
816
816
  context.unset(:years)
817
817
  end
818
818
 
819
- it "unsets the first existing field" do
820
- expect(depeche_mode.reload.years).to be_nil
821
- end
822
-
823
- it "unsets the last existing field" do
824
- expect(new_order.reload.years).to be_nil
819
+ it "unsets the fields from all documents" do
820
+ depeche_mode.reload
821
+ new_order.reload
822
+ expect(depeche_mode.name).to_not be_nil
823
+ expect(depeche_mode.years).to be_nil
824
+ expect(new_order.name).to_not be_nil
825
+ expect(new_order.years).to be_nil
825
826
  end
826
827
  end
827
828
  end
@@ -829,7 +830,8 @@ describe Mongoid::Contextual::Atomic do
829
830
  context "when unsetting multiple fields" do
830
831
 
831
832
  let!(:new_order) do
832
- Band.create(name: "New Order", genres: [ "electro", "dub" ], years: 10)
833
+ Band.create(name: "New Order", genres: %w[electro dub], years: 10,
834
+ likes: 200, rating: 4.3, origin: 'Space')
833
835
  end
834
836
 
835
837
  let(:criteria) do
@@ -846,12 +848,13 @@ describe Mongoid::Contextual::Atomic do
846
848
  context.unset(:name, :genres)
847
849
  end
848
850
 
849
- it "unsets name field" do
850
- expect(new_order.reload.name).to be_nil
851
- end
852
-
853
- it "unsets genres field" do
854
- expect(new_order.reload.genres).to be_nil
851
+ it "unsets the specified fields" do
852
+ new_order.reload
853
+ expect(new_order.name).to be_nil
854
+ expect(new_order.genres).to be_nil
855
+ expect(new_order.years).to_not be_nil
856
+ expect(new_order.likes).to_not be_nil
857
+ expect(new_order.rating).to_not be_nil
855
858
  end
856
859
  end
857
860
 
@@ -861,12 +864,46 @@ describe Mongoid::Contextual::Atomic do
861
864
  context.unset(:name, :years)
862
865
  end
863
866
 
864
- it "unsets the unaliased field" do
865
- expect(new_order.reload.name).to be_nil
867
+ it "unsets the specified fields" do
868
+ new_order.reload
869
+ expect(new_order.name).to be_nil
870
+ expect(new_order.genres).to_not be_nil
871
+ expect(new_order.years).to be_nil
872
+ expect(new_order.likes).to_not be_nil
873
+ expect(new_order.rating).to_not be_nil
874
+ end
875
+ end
876
+
877
+ context "when using Hash arguments" do
878
+
879
+ before do
880
+ context.unset({ years: true, likes: "" }, { rating: false, origin: nil })
881
+ end
882
+
883
+ it "unsets the specified fields" do
884
+ new_order.reload
885
+ expect(new_order.name).to_not be_nil
886
+ expect(new_order.genres).to_not be_nil
887
+ expect(new_order.years).to be_nil
888
+ expect(new_order.likes).to be_nil
889
+ expect(new_order.rating).to be_nil
890
+ expect(new_order.origin).to be_nil
891
+ end
892
+ end
893
+
894
+ context "when mixing argument types" do
895
+
896
+ before do
897
+ context.unset(:name, [:years], { likes: "" }, { rating: false })
866
898
  end
867
899
 
868
- it "unsets the aliased field" do
869
- expect(new_order.reload.years).to be_nil
900
+ it "unsets the specified fields" do
901
+ new_order.reload
902
+ expect(new_order.name).to be_nil
903
+ expect(new_order.genres).to_not be_nil
904
+ expect(new_order.years).to be_nil
905
+ expect(new_order.likes).to be_nil
906
+ expect(new_order.rating).to be_nil
870
907
  end
871
908
  end
872
909
  end
@@ -895,7 +932,9 @@ describe Mongoid::Contextual::Atomic do
895
932
  end
896
933
 
897
934
  it "unsets the unaliased field" do
898
- expect(depeche_mode.reload.name).to be_nil
935
+ depeche_mode.reload
936
+ expect(depeche_mode.name).to be_nil
937
+ expect(depeche_mode.years).to_not be_nil
899
938
  end
900
939
  end
901
940
  end
@@ -59,7 +59,7 @@ describe Mongoid::Contextual::GeoNear do
59
59
  end
60
60
 
61
61
  it "is nil except for 4.0 sharded when it is 0" do
62
- expect(geo_near.average_distance).to be expected_value
62
+ expect(geo_near.average_distance).to eq expected_value
63
63
  end
64
64
  end
65
65
  end
@@ -501,7 +501,7 @@ describe Mongoid::Document do
501
501
  end
502
502
  end
503
503
 
504
- context ':compact option' do
504
+ context 'deprecated :compact option' do
505
505
  # Since rails 6 differs in how it treats id fields,
506
506
  # run this test on one version of rails. Currently rails 6 is in beta,
507
507
  # when it is released this version should be changed to 6.
@@ -513,6 +513,26 @@ describe Mongoid::Document do
513
513
  expect(church.as_json.keys.sort).to eq(%w(_id location name))
514
514
  end
515
515
 
516
+ context 'deprecation' do
517
+ let(:church) do
518
+ Church.create!(name: 'St. Basil')
519
+ end
520
+
521
+ let(:message) do
522
+ '#as_json :compact option is deprecated. Please call #compact on the returned Hash object instead.'
523
+ end
524
+
525
+ it 'logs a deprecation warning when :compact is given' do
526
+ expect_any_instance_of(Logger).to receive(:warn).with(message)
527
+ church.as_json(compact: true)
528
+ end
529
+
530
+ it 'does not log a deprecation warning when :compact is not given' do
531
+ expect_any_instance_of(Logger).to_not receive(:warn).with(message)
532
+ church.as_json
533
+ end
534
+ end
535
+
516
536
  context 'there is a nil valued attribute' do
517
537
  let(:church) do
518
538
  Church.create!(name: 'St. Basil')
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+ # encoding: utf-8
3
+
4
+ require "spec_helper"
5
+
6
+ describe Mongoid::Errors::InvalidConfigFile do
7
+
8
+ describe "#message" do
9
+
10
+ let(:error) do
11
+ described_class.new('/my/path')
12
+ end
13
+
14
+ it "contains the problem in the message" do
15
+ expect(error.message).to include(
16
+ "Invalid configuration file: /my/path."
17
+ )
18
+ end
19
+
20
+ it "contains the summary in the message" do
21
+ expect(error.message).to include(
22
+ "Your mongoid.yml configuration file does not contain the"
23
+ )
24
+ end
25
+
26
+ it "contains the resolution in the message" do
27
+ expect(error.message).to include(
28
+ "Ensure your configuration file contains the correct contents."
29
+ )
30
+ end
31
+ end
32
+ end