mongoid 7.3.2 → 7.3.3

Sign up to get free protection for your applications and to get access to all the features.
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