mongoid 7.1.2 → 7.1.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/Rakefile +14 -0
  5. data/lib/config/locales/en.yml +1 -1
  6. data/lib/mongoid/association/accessors.rb +37 -2
  7. data/lib/mongoid/association/referenced/belongs_to/binding.rb +1 -1
  8. data/lib/mongoid/clients/factory.rb +2 -2
  9. data/lib/mongoid/clients/options.rb +8 -8
  10. data/lib/mongoid/clients/sessions.rb +20 -4
  11. data/lib/mongoid/clients/storage_options.rb +5 -5
  12. data/lib/mongoid/criteria/queryable/extensions/regexp.rb +3 -3
  13. data/lib/mongoid/criteria/queryable/extensions/time_with_zone.rb +12 -0
  14. data/lib/mongoid/errors/no_client_config.rb +2 -2
  15. data/lib/mongoid/errors/no_default_client.rb +1 -1
  16. data/lib/mongoid/fields/validators/macro.rb +4 -1
  17. data/lib/mongoid/query_cache.rb +21 -9
  18. data/lib/mongoid/tasks/database.rb +38 -3
  19. data/lib/mongoid/version.rb +1 -1
  20. data/spec/app/models/passport.rb +1 -0
  21. data/spec/app/models/phone.rb +1 -0
  22. data/spec/integration/app_spec.rb +76 -14
  23. data/spec/integration/associations/has_many_spec.rb +34 -0
  24. data/spec/integration/associations/has_one_spec.rb +34 -0
  25. data/spec/integration/bson_regexp_raw_spec.rb +20 -0
  26. data/spec/integration/criteria/date_field_spec.rb +41 -0
  27. data/spec/integration/shardable_spec.rb +20 -4
  28. data/spec/mongoid/association/accessors_spec.rb +238 -63
  29. data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_spec.rb +138 -0
  30. data/spec/mongoid/association/referenced/has_many/enumerable_spec.rb +105 -0
  31. data/spec/mongoid/clients/factory_spec.rb +8 -8
  32. data/spec/mongoid/clients/options_spec.rb +9 -9
  33. data/spec/mongoid/contextual/geo_near_spec.rb +11 -2
  34. data/spec/mongoid/criteria/queryable/extensions/regexp_raw_spec.rb +1 -1
  35. data/spec/mongoid/criteria/queryable/extensions/time_spec.rb +19 -7
  36. data/spec/mongoid/criteria/queryable/extensions/time_with_zone_spec.rb +28 -1
  37. data/spec/mongoid/errors/no_client_config_spec.rb +2 -2
  38. data/spec/mongoid/errors/no_client_database_spec.rb +3 -3
  39. data/spec/mongoid/errors/no_client_hosts_spec.rb +3 -3
  40. data/spec/mongoid/fields_spec.rb +24 -1
  41. data/spec/mongoid/query_cache_spec.rb +60 -7
  42. metadata +487 -479
  43. metadata.gz.sig +0 -0
@@ -1757,6 +1757,43 @@ describe Mongoid::Association::Referenced::HasAndBelongsToMany::Proxy do
1757
1757
  end
1758
1758
  end
1759
1759
 
1760
+ describe "#any?" do
1761
+
1762
+ let(:person) do
1763
+ Person.create
1764
+ end
1765
+
1766
+ context "when nothing exists on the relation" do
1767
+
1768
+ context "when no document is added" do
1769
+
1770
+ let!(:sandwich) do
1771
+ Sandwich.create!
1772
+ end
1773
+
1774
+ it "returns false" do
1775
+ expect(sandwich.meats.any?).to be false
1776
+ end
1777
+ end
1778
+
1779
+ context "when the document is destroyed" do
1780
+
1781
+ before do
1782
+ Meat.create!
1783
+ end
1784
+
1785
+ let!(:sandwich) do
1786
+ Sandwich.create!
1787
+ end
1788
+
1789
+ it "returns false" do
1790
+ sandwich.destroy
1791
+ expect(sandwich.meats.any?).to be false
1792
+ end
1793
+ end
1794
+ end
1795
+ end
1796
+
1760
1797
  context "when documents have been persisted" do
1761
1798
 
1762
1799
  let!(:preference) do
@@ -1846,6 +1883,107 @@ describe Mongoid::Association::Referenced::HasAndBelongsToMany::Proxy do
1846
1883
  end
1847
1884
  end
1848
1885
 
1886
+ describe "#any?" do
1887
+
1888
+ let(:sandwich) do
1889
+ Sandwich.create
1890
+ end
1891
+
1892
+ context "when nothing exists on the relation" do
1893
+
1894
+ context "when no document is added" do
1895
+
1896
+ let!(:sandwich) do
1897
+ Sandwich.create!
1898
+ end
1899
+
1900
+ it "returns false" do
1901
+ expect(sandwich.meats.any?).to be false
1902
+ end
1903
+ end
1904
+
1905
+ context "when the document is destroyed" do
1906
+
1907
+ before do
1908
+ Meat.create!
1909
+ end
1910
+
1911
+ let!(:sandwich) do
1912
+ Sandwich.create!
1913
+ end
1914
+
1915
+ it "returns false" do
1916
+ sandwich.destroy
1917
+ expect(sandwich.meats.any?).to be false
1918
+ end
1919
+ end
1920
+ end
1921
+
1922
+ context "when appending to a relation and _loaded/_unloaded are empty" do
1923
+
1924
+ let!(:sandwich) do
1925
+ Sandwich.create!
1926
+ end
1927
+
1928
+ before do
1929
+ sandwich.meats << Meat.new
1930
+ end
1931
+
1932
+ it "returns true" do
1933
+ expect(sandwich.meats.any?).to be true
1934
+ end
1935
+ end
1936
+
1937
+ context "when appending to a relation in a transaction" do
1938
+ require_transaction_support
1939
+
1940
+ let!(:sandwich) do
1941
+ Sandwich.create!
1942
+ end
1943
+
1944
+ it "returns true" do
1945
+ sandwich.with_session do |session|
1946
+ session.with_transaction do
1947
+ expect{ sandwich.meats << Meat.new }.to_not raise_error
1948
+ expect(sandwich.meats.any?).to be true
1949
+ end
1950
+ end
1951
+ end
1952
+ end
1953
+
1954
+ context "when documents have been persisted" do
1955
+
1956
+ let!(:meat) do
1957
+ sandwich.meats.create
1958
+ end
1959
+
1960
+ it "returns true" do
1961
+ expect(sandwich.meats.any?).to be true
1962
+ end
1963
+ end
1964
+
1965
+ context "when documents have not been persisted" do
1966
+
1967
+ let!(:meat) do
1968
+ sandwich.meats.build
1969
+ end
1970
+
1971
+ it "returns false" do
1972
+ expect(sandwich.meats.any?).to be true
1973
+ end
1974
+ end
1975
+
1976
+ context "when new documents exist in the database" do
1977
+ before do
1978
+ Meat.create(sandwiches: [sandwich])
1979
+ end
1980
+
1981
+ it "returns true" do
1982
+ expect(sandwich.meats.any?).to be true
1983
+ end
1984
+ end
1985
+ end
1986
+
1849
1987
  [ :create, :create! ].each do |method|
1850
1988
 
1851
1989
  describe "##{method}" do
@@ -256,6 +256,111 @@ describe Mongoid::Association::Referenced::HasMany::Targets::Enumerable do
256
256
  end
257
257
  end
258
258
  end
259
+
260
+ context "when the documents have been loaded" do
261
+ let(:criteria) do
262
+ Post.where(person_id: person.id)
263
+ end
264
+
265
+ let!(:enumerable) do
266
+ described_class.new(criteria)
267
+ end
268
+
269
+ before do
270
+ enumerable.load_all!
271
+ end
272
+
273
+ it "is _loaded" do
274
+ expect(enumerable._loaded?).to be true
275
+ end
276
+
277
+ context "when a block is given" do
278
+ it "returns true when the predicate is true" do
279
+ expect(
280
+ enumerable.any? { |doc| true }
281
+ ).to be true
282
+ end
283
+
284
+ it "returns false when the predicate is false" do
285
+ expect(
286
+ enumerable.any? { |doc| false }
287
+ ).to be false
288
+ end
289
+ end
290
+
291
+ context "when an argument is given" do
292
+ ruby_version_gte '2.5'
293
+
294
+ it "returns true when the argument is true" do
295
+ expect(enumerable.any?(Post)).to be true
296
+ end
297
+
298
+ it "returns false when the argument is false" do
299
+ expect(enumerable.any?(Sandwich)).to be false
300
+ end
301
+ end
302
+
303
+ context "when both an argument and a block are given" do
304
+ ruby_version_gte '2.5'
305
+
306
+ it "gives precedence to the pattern" do
307
+ expect(
308
+ enumerable.any?(Post) { |doc| false }
309
+ ).to be true
310
+ end
311
+ end
312
+ end
313
+
314
+ context "when the documents are not loaded" do
315
+
316
+ let(:criteria) do
317
+ Post.where(person_id: person.id)
318
+ end
319
+
320
+ let!(:enumerable) do
321
+ described_class.new(criteria)
322
+ end
323
+
324
+ it "is not _loaded" do
325
+ expect(enumerable._loaded?).to be false
326
+ end
327
+
328
+ context "when a block is given" do
329
+ it "returns true when the predicate is true" do
330
+ expect(
331
+ enumerable.any? { |doc| true }
332
+ ).to be true
333
+ end
334
+
335
+ it "returns false when the predicate is false" do
336
+ expect(
337
+ enumerable.any? { |doc| false }
338
+ ).to be false
339
+ end
340
+ end
341
+
342
+ context "when an argument is given" do
343
+ ruby_version_gte '2.5'
344
+
345
+ it "returns true when the argument is true" do
346
+ expect(enumerable.any?(Post)).to be true
347
+ end
348
+
349
+ it "returns false when the argument is false" do
350
+ expect(enumerable.any?(Sandwich)).to be false
351
+ end
352
+ end
353
+
354
+ context "when both an argument and a block are given" do
355
+ ruby_version_gte '2.5'
356
+
357
+ it "gives precedence to the pattern" do
358
+ expect(
359
+ enumerable.any?(Post) { |doc| false }
360
+ ).to be true
361
+ end
362
+ end
363
+ end
259
364
  end
260
365
 
261
366
  describe "#clear" do
@@ -41,7 +41,7 @@ describe Mongoid::Clients::Factory do
41
41
  let(:config) do
42
42
  {
43
43
  default: { hosts: SpecConfig.instance.addresses, database: database_id },
44
- secondary: { hosts: SpecConfig.instance.addresses, database: database_id }
44
+ analytics: { hosts: SpecConfig.instance.addresses, database: database_id }
45
45
  }
46
46
  end
47
47
 
@@ -54,7 +54,7 @@ describe Mongoid::Clients::Factory do
54
54
  end
55
55
 
56
56
  let(:client) do
57
- described_class.create(:secondary)
57
+ described_class.create(:analytics)
58
58
  end
59
59
 
60
60
  let(:cluster) do
@@ -81,7 +81,7 @@ describe Mongoid::Clients::Factory do
81
81
  let(:config) do
82
82
  {
83
83
  default: { hosts: [ "127.0.0.1" ], database: database_id },
84
- secondary: { hosts: [ "127.0.0.1" ], database: database_id }
84
+ analytics: { hosts: [ "127.0.0.1" ], database: database_id }
85
85
  }
86
86
  end
87
87
 
@@ -94,7 +94,7 @@ describe Mongoid::Clients::Factory do
94
94
  end
95
95
 
96
96
  let(:client) do
97
- described_class.create(:secondary)
97
+ described_class.create(:analytics)
98
98
  end
99
99
 
100
100
  let(:default) do
@@ -125,7 +125,7 @@ describe Mongoid::Clients::Factory do
125
125
  let(:config) do
126
126
  {
127
127
  default: { hosts: [ "127.0.0.1:27017" ], database: database_id },
128
- secondary: { uri: "mongodb://127.0.0.1:27017/mongoid_test" }
128
+ analytics: { uri: "mongodb://127.0.0.1:27017/mongoid_test" }
129
129
  }
130
130
  end
131
131
 
@@ -138,7 +138,7 @@ describe Mongoid::Clients::Factory do
138
138
  end
139
139
 
140
140
  let(:client) do
141
- described_class.create(:secondary)
141
+ described_class.create(:analytics)
142
142
  end
143
143
 
144
144
  let(:cluster) do
@@ -163,7 +163,7 @@ describe Mongoid::Clients::Factory do
163
163
  let(:config) do
164
164
  {
165
165
  default: { hosts: [ "127.0.0.1:1234" ], database: database_id, server_selection_timeout: 1 },
166
- secondary: { uri: "mongodb://127.0.0.1:1234,127.0.0.1:5678/mongoid_test?serverSelectionTimeoutMS=1000" }
166
+ analytics: { uri: "mongodb://127.0.0.1:1234,127.0.0.1:5678/mongoid_test?serverSelectionTimeoutMS=1000" }
167
167
  }
168
168
  end
169
169
 
@@ -176,7 +176,7 @@ describe Mongoid::Clients::Factory do
176
176
  end
177
177
 
178
178
  let(:client) do
179
- described_class.create(:secondary)
179
+ described_class.create(:analytics)
180
180
  end
181
181
 
182
182
  let(:cluster) do
@@ -151,7 +151,7 @@ describe Mongoid::Clients::Options, retry: 3 do
151
151
  let(:config) do
152
152
  {
153
153
  default: { hosts: SpecConfig.instance.addresses, database: database_id },
154
- secondary: { uri: "mongodb://#{SpecConfig.instance.addresses.first}/secondary-db?connectTimeoutMS=3000" }
154
+ analytics: { uri: "mongodb://#{SpecConfig.instance.addresses.first}/analytics-db?connectTimeoutMS=3000" }
155
155
  }
156
156
  end
157
157
 
@@ -164,14 +164,14 @@ describe Mongoid::Clients::Options, retry: 3 do
164
164
  end
165
165
 
166
166
  let(:persistence_context) do
167
- Minim.with(client: :secondary) do |klass|
167
+ Minim.with(client: :analytics) do |klass|
168
168
  klass.persistence_context
169
169
  end
170
170
  end
171
171
 
172
172
  it 'uses the database specified in the uri' do
173
- expect(persistence_context.database_name).to eq('secondary-db')
174
- expect(persistence_context.client.database.name).to eq('secondary-db')
173
+ expect(persistence_context.database_name).to eq('analytics-db')
174
+ expect(persistence_context.client.database.name).to eq('analytics-db')
175
175
  end
176
176
 
177
177
  it 'uses the options specified in the uri' do
@@ -344,8 +344,8 @@ describe Mongoid::Clients::Options, retry: 3 do
344
344
  let(:config) do
345
345
  {
346
346
  default: { hosts: SpecConfig.instance.addresses, database: database_id },
347
- secondary: {
348
- uri: "mongodb://#{SpecConfig.instance.addresses.first}/secondary-db",
347
+ analytics: {
348
+ uri: "mongodb://#{SpecConfig.instance.addresses.first}/analytics-db",
349
349
  options: {
350
350
  server_selection_timeout: 0.5,
351
351
  },
@@ -358,14 +358,14 @@ describe Mongoid::Clients::Options, retry: 3 do
358
358
  end
359
359
 
360
360
  let(:persistence_context) do
361
- test_model.with(client: :secondary) do |object|
361
+ test_model.with(client: :analytics) do |object|
362
362
  object.persistence_context
363
363
  end
364
364
  end
365
365
 
366
366
  it 'uses the database specified in the uri' do
367
- expect(persistence_context.database_name).to eq('secondary-db')
368
- expect(persistence_context.client.database.name).to eq('secondary-db')
367
+ expect(persistence_context.database_name).to eq('analytics-db')
368
+ expect(persistence_context.client.database.name).to eq('analytics-db')
369
369
  end
370
370
  end
371
371
 
@@ -49,8 +49,17 @@ describe Mongoid::Contextual::GeoNear do
49
49
  described_class.new(collection, criteria, [ 52, 13 ])
50
50
  end
51
51
 
52
- it "returns 0.0" do
53
- expect(geo_near.average_distance).to be_nil
52
+ let(:expected_value) do
53
+ if ClusterConfig.instance.fcv_ish == '4.0' && ClusterConfig.instance.topology == :sharded
54
+ # https://jira.mongodb.org/browse/SERVER-50074
55
+ 0.0
56
+ else
57
+ nil
58
+ end
59
+ end
60
+
61
+ it "is nil except for 4.0 sharded when it is 0" do
62
+ expect(geo_near.average_distance).to be expected_value
54
63
  end
55
64
  end
56
65
  end
@@ -3,7 +3,7 @@
3
3
 
4
4
  require "spec_helper"
5
5
 
6
- describe Mongoid::Criteria::Queryable::Extensions::Regexp::Raw do
6
+ describe Mongoid::Criteria::Queryable::Extensions::Regexp::Raw_ do
7
7
 
8
8
  describe ".evolve" do
9
9
 
@@ -354,23 +354,35 @@ describe Time do
354
354
 
355
355
  describe "#__evolve_date__" do
356
356
 
357
- let(:time) do
358
- Time.new(2010, 1, 1, 12, 0, 0)
359
- end
360
-
361
357
  let(:evolved) do
362
358
  time.__evolve_date__
363
359
  end
364
360
 
365
- it "returns midnight utc" do
366
- expect(evolved).to eq(Time.utc(2010, 1, 1, 0, 0, 0))
361
+ context 'beginning of day' do
362
+ let(:time) do
363
+ Time.new(2010, 1, 1, 0, 0, 1).freeze
364
+ end
365
+
366
+ it "returns midnight utc" do
367
+ expect(evolved).to eq(Time.utc(2010, 1, 1, 0, 0, 0))
368
+ end
369
+ end
370
+
371
+ context 'end of day' do
372
+ let(:time) do
373
+ Time.new(2010, 1, 1, 23, 59, 59).freeze
374
+ end
375
+
376
+ it "returns midnight utc" do
377
+ expect(evolved).to eq(Time.utc(2010, 1, 1, 0, 0, 0))
378
+ end
367
379
  end
368
380
  end
369
381
 
370
382
  describe "#__evolve_time__" do
371
383
 
372
384
  let(:time) do
373
- Time.new(2010, 1, 1, 12, 0, 0)
385
+ Time.new(2010, 1, 1, 12, 0, 0).freeze
374
386
  end
375
387
 
376
388
  let(:evolved) do