mongoid 7.3.2 → 7.3.3

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 (46) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/lib/config/locales/en.yml +13 -0
  4. data/lib/mongoid/association/referenced/has_many/enumerable.rb +3 -7
  5. data/lib/mongoid/association/relatable.rb +2 -0
  6. data/lib/mongoid/atomic.rb +26 -2
  7. data/lib/mongoid/config/environment.rb +9 -1
  8. data/lib/mongoid/contextual/atomic.rb +7 -2
  9. data/lib/mongoid/contextual/none.rb +3 -0
  10. data/lib/mongoid/criteria/queryable/selectable.rb +2 -2
  11. data/lib/mongoid/criteria/queryable/storable.rb +4 -4
  12. data/lib/mongoid/document.rb +3 -2
  13. data/lib/mongoid/errors/empty_config_file.rb +26 -0
  14. data/lib/mongoid/errors/invalid_config_file.rb +26 -0
  15. data/lib/mongoid/errors.rb +2 -0
  16. data/lib/mongoid/persistence_context.rb +3 -1
  17. data/lib/mongoid/query_cache.rb +11 -1
  18. data/lib/mongoid/tasks/database.rb +1 -1
  19. data/lib/mongoid/touchable.rb +10 -0
  20. data/lib/mongoid/version.rb +1 -1
  21. data/spec/integration/contextual/empty_spec.rb +142 -0
  22. data/spec/integration/stringified_symbol_field_spec.rb +2 -2
  23. data/spec/mongoid/association/referenced/belongs_to_query_spec.rb +20 -0
  24. data/spec/mongoid/association/referenced/has_many/enumerable_spec.rb +244 -92
  25. data/spec/mongoid/association/referenced/has_many/proxy_spec.rb +6 -6
  26. data/spec/mongoid/association/referenced/has_many_models.rb +17 -0
  27. data/spec/mongoid/clients/factory_spec.rb +9 -3
  28. data/spec/mongoid/clients/options_spec.rb +11 -5
  29. data/spec/mongoid/config/environment_spec.rb +86 -8
  30. data/spec/mongoid/config_spec.rb +89 -16
  31. data/spec/mongoid/contextual/atomic_spec.rb +64 -25
  32. data/spec/mongoid/contextual/geo_near_spec.rb +1 -1
  33. data/spec/mongoid/document_spec.rb +21 -1
  34. data/spec/mongoid/errors/invalid_config_file_spec.rb +32 -0
  35. data/spec/mongoid/persistable/updatable_spec.rb +2 -0
  36. data/spec/mongoid/query_cache_spec.rb +24 -0
  37. data/spec/mongoid/touchable_spec.rb +18 -0
  38. data/spec/mongoid/touchable_spec_models.rb +2 -0
  39. data/spec/shared/lib/mrss/constraints.rb +21 -4
  40. data/spec/shared/lib/mrss/event_subscriber.rb +200 -0
  41. data/spec/shared/lib/mrss/server_version_registry.rb +17 -12
  42. data/spec/shared/share/Dockerfile.erb +5 -4
  43. data/spec/shared/shlib/server.sh +71 -21
  44. data.tar.gz.sig +0 -0
  45. metadata +581 -573
  46. metadata.gz.sig +0 -0
@@ -1568,12 +1568,12 @@ describe Mongoid::Association::Referenced::HasMany::Proxy do
1568
1568
  end
1569
1569
 
1570
1570
  context 'when association is not loaded' do
1571
- it 'queries database on each call' do
1572
- expect_query(1) do
1573
- movie.ratings.any?.should be true
1574
- end
1571
+ before do
1572
+ movie.ratings._loaded?.should be false
1573
+ end
1575
1574
 
1576
- expect_query(1) do
1575
+ it 'does not query the database because it knows about the added models' do
1576
+ expect_no_queries do
1577
1577
  movie.ratings.any?.should be true
1578
1578
  end
1579
1579
  end
@@ -1581,7 +1581,7 @@ describe Mongoid::Association::Referenced::HasMany::Proxy do
1581
1581
 
1582
1582
  context 'when association is loaded' do
1583
1583
  it 'does not query database' do
1584
- expect_query(1) do
1584
+ expect_no_queries do
1585
1585
  movie.ratings.any?.should be true
1586
1586
  end
1587
1587
 
@@ -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
 
@@ -66,9 +66,15 @@ describe Mongoid::Clients::Factory do
66
66
  expect(client).to be_a(Mongo::Client)
67
67
  end
68
68
 
69
- it 'does not produce driver warnings' do
70
- Mongo::Logger.logger.should_not receive(:warn)
71
- client
69
+ context 'not JRuby' do
70
+ # Run this test on JRuby when driver 2.16.0 is released -
71
+ # see RUBY-2771.
72
+ fails_on_jruby
73
+
74
+ it 'does not produce driver warnings' do
75
+ Mongo::Logger.logger.should_not receive(:warn)
76
+ client
77
+ end
72
78
  end
73
79
 
74
80
  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
@@ -219,7 +219,7 @@ describe Mongoid::Config do
219
219
  expect(Mongoid::Config.discriminator_key).to be("test")
220
220
  end
221
221
 
222
- it 'is set globally' do
222
+ it 'is set globally' do
223
223
  expect(Mongoid.discriminator_key).to be("test")
224
224
  end
225
225
  end
@@ -546,34 +546,107 @@ describe Mongoid::Config do
546
546
  end
547
547
  end
548
548
 
549
- context "with an overridden database" do
550
- let(:database) do
551
- "test_purge_#{Time.now.to_i}"
549
+ describe "#purge!" do
550
+
551
+ it 'deletes models' do
552
+ House.create!(name: '1', model: 'Big')
553
+ expect(House.count).to eq(1)
554
+ Mongoid.purge!
555
+ expect(House.count).to eq(0)
552
556
  end
553
557
 
554
- before do
555
- Mongoid.override_database(database)
558
+ it 'drops collections' do
559
+ House.create!(name: '1', model: 'Big')
560
+ Band.create!(name: 'Fleet Foxes')
561
+
562
+ client = Mongoid.default_client
563
+ expect(client.collections.map(&:name).sort).to eq %w[bands houses]
564
+ Mongoid.purge!
565
+ expect(client.collections.map(&:name)).to eq []
566
+ end
567
+ end
568
+
569
+ describe "#truncate!" do
570
+
571
+ it 'deletes models' do
572
+ House.create!(name: '1', model: 'Big')
573
+ expect(House.count).to eq(1)
574
+ Mongoid.truncate!
575
+ expect(House.count).to eq(0)
576
+ end
577
+
578
+ it 'does not drop collections' do
579
+ House.create!(name: '1', model: 'Big')
580
+ Band.create!(name: 'Fleet Foxes')
581
+
582
+ client = Mongoid.default_client
583
+ expect(client.collections.map(&:name).sort).to eq %w[bands houses]
584
+ Mongoid.truncate!
585
+ expect(client.collections.map(&:name).sort).to eq %w[bands houses]
586
+ end
587
+
588
+ it 'does not drop indexes' do
589
+ User.create_indexes
590
+ expect(User.collection.indexes.map {|i| i['name'] }).to eq %w[_id_ name_1]
591
+ Mongoid.truncate!
592
+ expect(User.collection.indexes.map {|i| i['name'] }).to eq %w[_id_ name_1]
593
+ end
594
+ end
595
+
596
+ describe "#override_database" do
597
+ let(:database) do
598
+ "test_override_#{Time.now.to_i}"
556
599
  end
557
600
 
558
601
  after do
602
+ # Ensure the database override is cleared.
559
603
  Mongoid.override_database(nil)
560
604
  end
561
605
 
562
- describe "#purge!" do
563
- it 'respects persistence context overrides' do
606
+ it 'overrides document querying and persistence' do
607
+ House.create!(name: '1', model: 'Big')
608
+ expect(House.count).to eq(1)
609
+
610
+ Mongoid.override_database(database)
611
+ expect(House.count).to eq(0)
612
+
613
+ expect(Band.count).to eq(0)
614
+ Band.create!(name: 'Wolf Alice')
615
+ expect(Band.count).to eq(1)
616
+
617
+ Mongoid.override_database(nil)
618
+ expect(House.count).to eq(1)
619
+ expect(Band.count).to eq(0)
620
+ end
621
+
622
+ context '#truncate and #purge' do
623
+ before do
564
624
  House.create!(name: '1', model: 'Big')
565
625
  expect(House.count).to eq(1)
566
- Mongoid.purge!
567
- expect(House.count).to eq(0)
626
+ Mongoid.override_database(database)
568
627
  end
569
- end
570
628
 
571
- describe "#truncate!" do
572
- it 'respects persistence context overrides' do
573
- House.create!(name: '1', model: 'Big')
629
+ after do
630
+ Mongoid.override_database(nil)
574
631
  expect(House.count).to eq(1)
575
- Mongoid.truncate!
576
- expect(House.count).to eq(0)
632
+ end
633
+
634
+ context '#purge' do
635
+ it 'respects persistence context overrides' do
636
+ House.create!(name: '2', model: 'Tiny')
637
+ expect(House.count).to eq(1)
638
+ Mongoid.purge!
639
+ expect(House.count).to eq(0)
640
+ end
641
+ end
642
+
643
+ context '#truncate' do
644
+ it '#truncate! respects persistence context overrides' do
645
+ House.create!(name: '2', model: 'Tiny')
646
+ expect(House.count).to eq(1)
647
+ Mongoid.truncate!
648
+ expect(House.count).to eq(0)
649
+ end
577
650
  end
578
651
  end
579
652
  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