mongoid 7.1.0 → 7.1.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 (131) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/CHANGELOG.md +6 -6
  5. data/README.md +1 -1
  6. data/Rakefile +14 -5
  7. data/lib/config/locales/en.yml +5 -5
  8. data/lib/mongoid/association/accessors.rb +37 -2
  9. data/lib/mongoid/association/embedded/embeds_many.rb +2 -1
  10. data/lib/mongoid/association/embedded/embeds_one.rb +2 -1
  11. data/lib/mongoid/association/proxy.rb +1 -1
  12. data/lib/mongoid/association/referenced/belongs_to/binding.rb +1 -1
  13. data/lib/mongoid/association/referenced/belongs_to/eager.rb +38 -2
  14. data/lib/mongoid/association/referenced/eager.rb +29 -9
  15. data/lib/mongoid/association/referenced/has_one/proxy.rb +6 -1
  16. data/lib/mongoid/atomic.rb +13 -3
  17. data/lib/mongoid/clients/factory.rb +2 -2
  18. data/lib/mongoid/clients/options.rb +8 -8
  19. data/lib/mongoid/clients/sessions.rb +20 -4
  20. data/lib/mongoid/clients/storage_options.rb +5 -5
  21. data/lib/mongoid/config.rb +39 -9
  22. data/lib/mongoid/criteria.rb +23 -4
  23. data/lib/mongoid/criteria/modifiable.rb +2 -1
  24. data/lib/mongoid/criteria/queryable/extensions/numeric.rb +1 -1
  25. data/lib/mongoid/criteria/queryable/extensions/regexp.rb +6 -6
  26. data/lib/mongoid/criteria/queryable/extensions/time_with_zone.rb +12 -0
  27. data/lib/mongoid/criteria/queryable/mergeable.rb +75 -8
  28. data/lib/mongoid/criteria/queryable/pipeline.rb +3 -2
  29. data/lib/mongoid/criteria/queryable/selectable.rb +120 -13
  30. data/lib/mongoid/criteria/queryable/storable.rb +104 -99
  31. data/lib/mongoid/errors/eager_load.rb +2 -0
  32. data/lib/mongoid/errors/no_client_config.rb +2 -2
  33. data/lib/mongoid/errors/no_default_client.rb +1 -1
  34. data/lib/mongoid/extensions/hash.rb +4 -2
  35. data/lib/mongoid/extensions/regexp.rb +1 -1
  36. data/lib/mongoid/fields.rb +2 -1
  37. data/lib/mongoid/fields/validators/macro.rb +4 -1
  38. data/lib/mongoid/matchable/regexp.rb +2 -2
  39. data/lib/mongoid/persistable/pushable.rb +11 -2
  40. data/lib/mongoid/persistence_context.rb +6 -6
  41. data/lib/mongoid/query_cache.rb +61 -18
  42. data/lib/mongoid/serializable.rb +9 -3
  43. data/lib/mongoid/tasks/database.rb +38 -3
  44. data/lib/mongoid/validatable/uniqueness.rb +1 -1
  45. data/lib/mongoid/version.rb +1 -1
  46. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +32 -23
  47. data/lib/rails/generators/mongoid/model/templates/model.rb.tt +1 -1
  48. data/spec/app/models/coding.rb +4 -0
  49. data/spec/app/models/coding/pull_request.rb +12 -0
  50. data/spec/app/models/delegating_patient.rb +16 -0
  51. data/spec/app/models/passport.rb +1 -0
  52. data/spec/app/models/person.rb +2 -0
  53. data/spec/app/models/phone.rb +1 -0
  54. data/spec/app/models/publication.rb +5 -0
  55. data/spec/app/models/publication/encyclopedia.rb +12 -0
  56. data/spec/app/models/publication/review.rb +14 -0
  57. data/spec/app/models/series.rb +1 -0
  58. data/spec/app/models/wiki_page.rb +1 -0
  59. data/spec/integration/app_spec.rb +254 -0
  60. data/spec/integration/associations/embedded_spec.rb +54 -0
  61. data/spec/integration/associations/embeds_many_spec.rb +24 -0
  62. data/spec/integration/associations/embeds_one_spec.rb +24 -0
  63. data/spec/integration/associations/has_many_spec.rb +76 -0
  64. data/spec/integration/associations/has_one_spec.rb +76 -0
  65. data/spec/integration/bson_regexp_raw_spec.rb +20 -0
  66. data/spec/integration/criteria/date_field_spec.rb +41 -0
  67. data/spec/integration/criteria/logical_spec.rb +13 -0
  68. data/spec/integration/document_spec.rb +22 -0
  69. data/spec/integration/shardable_spec.rb +20 -4
  70. data/spec/lite_spec_helper.rb +12 -4
  71. data/spec/mongoid/association/accessors_spec.rb +238 -63
  72. data/spec/mongoid/association/embedded/embeds_many_models.rb +19 -0
  73. data/spec/mongoid/association/embedded/embeds_many_spec.rb +10 -0
  74. data/spec/mongoid/association/embedded/embeds_one_spec.rb +0 -2
  75. data/spec/mongoid/association/referenced/belongs_to/eager_spec.rb +193 -10
  76. data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_spec.rb +140 -1
  77. data/spec/mongoid/association/referenced/has_many/enumerable_spec.rb +105 -0
  78. data/spec/mongoid/association/referenced/has_many/proxy_spec.rb +2 -1
  79. data/spec/mongoid/clients/factory_spec.rb +8 -8
  80. data/spec/mongoid/clients/options_spec.rb +11 -11
  81. data/spec/mongoid/clients/sessions_spec.rb +8 -4
  82. data/spec/mongoid/clients/transactions_spec.rb +20 -8
  83. data/spec/mongoid/clients_spec.rb +2 -2
  84. data/spec/mongoid/contextual/atomic_spec.rb +22 -11
  85. data/spec/mongoid/contextual/geo_near_spec.rb +11 -2
  86. data/spec/mongoid/contextual/map_reduce_spec.rb +20 -5
  87. data/spec/mongoid/contextual/mongo_spec.rb +76 -53
  88. data/spec/mongoid/criteria/queryable/extensions/regexp_raw_spec.rb +1 -1
  89. data/spec/mongoid/criteria/queryable/extensions/regexp_spec.rb +7 -7
  90. data/spec/mongoid/criteria/queryable/extensions/string_spec.rb +1 -1
  91. data/spec/mongoid/criteria/queryable/extensions/time_spec.rb +19 -7
  92. data/spec/mongoid/criteria/queryable/extensions/time_with_zone_spec.rb +28 -1
  93. data/spec/mongoid/criteria/queryable/mergeable_spec.rb +45 -12
  94. data/spec/mongoid/criteria/queryable/selectable_logical_spec.rb +1051 -392
  95. data/spec/mongoid/criteria/queryable/selectable_spec.rb +52 -0
  96. data/spec/mongoid/criteria/queryable/storable_spec.rb +80 -2
  97. data/spec/mongoid/criteria_spec.rb +36 -2
  98. data/spec/mongoid/document_persistence_context_spec.rb +33 -0
  99. data/spec/mongoid/errors/no_client_config_spec.rb +2 -2
  100. data/spec/mongoid/errors/no_client_database_spec.rb +3 -3
  101. data/spec/mongoid/errors/no_client_hosts_spec.rb +3 -3
  102. data/spec/mongoid/fields_spec.rb +24 -1
  103. data/spec/mongoid/indexable_spec.rb +6 -4
  104. data/spec/mongoid/matchable/default_spec.rb +1 -1
  105. data/spec/mongoid/matchable/regexp_spec.rb +2 -2
  106. data/spec/mongoid/matchable_spec.rb +2 -2
  107. data/spec/mongoid/persistable/pushable_spec.rb +55 -1
  108. data/spec/mongoid/query_cache_spec.rb +77 -9
  109. data/spec/mongoid/relations/proxy_spec.rb +1 -1
  110. data/spec/mongoid/scopable_spec.rb +2 -1
  111. data/spec/mongoid/serializable_spec.rb +129 -18
  112. data/spec/mongoid/shardable_models.rb +1 -1
  113. data/spec/mongoid/shardable_spec.rb +2 -2
  114. data/spec/mongoid/tasks/database_rake_spec.rb +13 -13
  115. data/spec/mongoid/tasks/database_spec.rb +1 -1
  116. data/spec/shared/LICENSE +20 -0
  117. data/spec/shared/lib/mrss/child_process_helper.rb +80 -0
  118. data/spec/shared/lib/mrss/cluster_config.rb +211 -0
  119. data/spec/shared/lib/mrss/constraints.rb +312 -0
  120. data/spec/shared/lib/mrss/lite_constraints.rb +175 -0
  121. data/spec/shared/lib/mrss/spec_organizer.rb +149 -0
  122. data/spec/spec_helper.rb +2 -31
  123. data/spec/support/child_process_helper.rb +76 -0
  124. data/spec/support/cluster_config.rb +3 -3
  125. data/spec/support/constraints.rb +26 -10
  126. data/spec/support/expectations.rb +3 -1
  127. data/spec/support/helpers.rb +11 -0
  128. data/spec/support/session_registry.rb +50 -0
  129. data/spec/support/spec_config.rb +12 -4
  130. metadata +520 -473
  131. metadata.gz.sig +0 -0
@@ -7,7 +7,7 @@ describe Mongoid::Persistable::Pushable do
7
7
 
8
8
  describe "#add_to_set" do
9
9
 
10
- context "when the document is a root document" do
10
+ context "when the document is a top level document" do
11
11
 
12
12
  shared_examples_for "a unique pushable root document" do
13
13
 
@@ -65,6 +65,60 @@ describe Mongoid::Persistable::Pushable do
65
65
 
66
66
  it_behaves_like "a unique pushable root document"
67
67
  end
68
+
69
+ context 'when the host model is not saved' do
70
+ context 'when attribute exists' do
71
+ let(:person) do
72
+ Person.new(aliases: [2])
73
+ end
74
+
75
+ it 'records the change' do
76
+ person.add_to_set({aliases: 1})
77
+
78
+ expect(person.aliases).to eq([2, 1])
79
+ end
80
+ end
81
+
82
+ context 'when attribute does not exist' do
83
+ let(:person) do
84
+ Person.new
85
+ end
86
+
87
+ it 'records the change' do
88
+ person.add_to_set({aliases: 1})
89
+
90
+ expect(person.aliases).to eq([1])
91
+ end
92
+ end
93
+ end
94
+
95
+ context 'when the host model is loaded from database' do
96
+ context 'when attribute exists' do
97
+ let(:person) do
98
+ Person.create!(aliases: [2])
99
+ person = Person.last
100
+ end
101
+
102
+ it 'records the change' do
103
+ person.add_to_set({aliases: 1})
104
+
105
+ expect(person.aliases).to eq([2, 1])
106
+ end
107
+ end
108
+
109
+ context 'when attribute does not exist' do
110
+ let(:person) do
111
+ Person.create!
112
+ person = Person.last
113
+ end
114
+
115
+ it 'records the change' do
116
+ person.add_to_set({aliases: 1})
117
+
118
+ expect(person.aliases).to eq([1])
119
+ end
120
+ end
121
+ end
68
122
  end
69
123
 
70
124
  context "when the document is embedded" do
@@ -10,6 +10,20 @@ describe Mongoid::QueryCache do
10
10
  Mongoid::QueryCache.cache { spec.run }
11
11
  end
12
12
 
13
+ before(:all) do
14
+ # It is likely that there are other session leaks in the driver
15
+ # and/or Mongoid that are unrelated to the query cache. Clear the
16
+ # SessionRegistry at the start of these tests in order to detect leaks that
17
+ # occur only within the scope of these tests.
18
+ #
19
+ # Other session leaks will be detected and addressed as part of RUBY-2391.
20
+ SessionRegistry.instance.clear_registry
21
+ end
22
+
23
+ after do
24
+ SessionRegistry.instance.verify_sessions_ended!
25
+ end
26
+
13
27
  context 'when iterating over objects sharing the same base' do
14
28
 
15
29
  let(:server) do
@@ -183,7 +197,8 @@ describe Mongoid::QueryCache do
183
197
  end
184
198
  end
185
199
 
186
- context 'when the first query has a collation', if: collation_supported? do
200
+ context 'when the first query has a collation' do
201
+ min_server_version '3.4'
187
202
 
188
203
  before do
189
204
  Band.where(name: 'DEPECHE MODE').collation(locale: 'en_US', strength: 2).to_a
@@ -224,6 +239,10 @@ describe Mongoid::QueryCache do
224
239
  end
225
240
 
226
241
  before do
242
+ 10.times do |i|
243
+ game.ratings << Rating.create!(value: i+1)
244
+ end
245
+
227
246
  game.ratings.where(:value.gt => 5).asc(:id).all.to_a
228
247
  end
229
248
 
@@ -231,7 +250,9 @@ describe Mongoid::QueryCache do
231
250
 
232
251
  it "uses the cache" do
233
252
  expect_no_queries do
234
- game.ratings.where(:value.gt => 5).limit(2).asc(:id).to_a
253
+ result = game.ratings.where(:value.gt => 5).limit(2).asc(:id).to_a
254
+ expect(result.length).to eq(2)
255
+ expect(result.map { |r| r['value'] }).to eq([6, 7])
235
256
  end
236
257
  end
237
258
  end
@@ -244,14 +265,23 @@ describe Mongoid::QueryCache do
244
265
  end
245
266
 
246
267
  before do
268
+ 10.times do |i|
269
+ game.ratings << Rating.create!(value: i+1)
270
+ end
271
+
247
272
  game.ratings.where(:value.gt => 5).limit(3).asc(:id).all.to_a
248
273
  end
249
274
 
250
275
  context "when the next query has a limit" do
276
+ # Server versions older than 3.2 also perform a killCursors operation,
277
+ # which causes this test to fail.
278
+ min_server_version '3.2'
251
279
 
252
280
  it "queries again" do
253
281
  expect_query(1) do
254
- game.ratings.where(:value.gt => 5).limit(2).asc(:id).to_a
282
+ result = game.ratings.where(:value.gt => 5).limit(2).asc(:id).to_a
283
+ expect(result.length).to eq(2)
284
+ expect(result.map { |r| r['value'] }).to eq([6, 7])
255
285
  end
256
286
  end
257
287
  end
@@ -260,7 +290,9 @@ describe Mongoid::QueryCache do
260
290
 
261
291
  it "queries again" do
262
292
  expect_query(1) do
263
- game.ratings.where(:value.gt => 5).asc(:id).to_a
293
+ result = game.ratings.where(:value.gt => 5).asc(:id).to_a
294
+ expect(result.length).to eq(5)
295
+ expect(result.map { |r| r['value'] }).to eq([6, 7, 8, 9, 10])
264
296
  end
265
297
  end
266
298
  end
@@ -273,21 +305,34 @@ describe Mongoid::QueryCache do
273
305
  end
274
306
 
275
307
  before do
308
+ 10.times do |i|
309
+ game.ratings << Rating.create!(value: i+1)
310
+ end
311
+
276
312
  game.ratings.where(:value.gt => 5).asc(:id).all.to_a
277
313
  end
278
314
 
279
315
  it "does not query again" do
280
316
  expect_no_queries do
281
- game.ratings.where(:value.gt => 5).asc(:id).first
317
+ result = game.ratings.where(:value.gt => 5).asc(:id).first
318
+ expect(result['value']).to eq(6)
282
319
  end
283
320
  end
284
321
  end
285
322
 
286
323
  context "when limiting the result" do
324
+ before do
325
+ Band.destroy_all
326
+
327
+ 5.times { |i| Band.create!(name: "Band #{i}") }
328
+ Band.all.to_a
329
+ end
287
330
 
288
331
  it "does not query again" do
289
332
  expect_query(0) do
290
- Band.limit(2).all.to_a
333
+ result = Band.limit(2).all.to_a
334
+ expect(result.length).to eq(2)
335
+ expect(result.map { |r| r["name"] }).to eq(["Band 0", "Band 1"])
291
336
  end
292
337
  end
293
338
  end
@@ -295,12 +340,16 @@ describe Mongoid::QueryCache do
295
340
  context "when specifying a different skip value" do
296
341
 
297
342
  before do
298
- Band.limit(2).skip(1).all.to_a
343
+ Band.destroy_all
344
+
345
+ 5.times { |i| Band.create!(name: "Band #{i}") }
299
346
  end
300
347
 
301
348
  it "queries again" do
302
349
  expect_query(1) do
303
- Band.limit(2).skip(3).all.to_a
350
+ result = Band.limit(2).skip(3).all.to_a
351
+ expect(result.length).to eq(2)
352
+ expect(result.map { |r| r["name"] }).to eq(["Band 3", "Band 4"])
304
353
  end
305
354
  end
306
355
  end
@@ -336,6 +385,25 @@ describe Mongoid::QueryCache do
336
385
  end
337
386
  end
338
387
 
388
+ context 'when querying colleciton larger than the batch size' do
389
+ before do
390
+ Band.destroy_all
391
+ 101.times { |i| Band.create!(_id: i) }
392
+ end
393
+
394
+ it 'does not raise an exception when querying multiple times' do
395
+ expect do
396
+ results1 = Band.all.to_a
397
+ expect(results1.length).to eq(101)
398
+ expect(results1.map { |band| band["_id"] }).to eq([*0..100])
399
+
400
+ results2 = Band.all.to_a
401
+ expect(results2.length).to eq(101)
402
+ expect(results2.map { |band| band["_id"] }).to eq([*0..100])
403
+ end.not_to raise_error
404
+ end
405
+ end
406
+
339
407
  context "when query caching is enabled and the batch_size is set" do
340
408
 
341
409
  around(:each) do |example|
@@ -489,7 +557,7 @@ describe Mongoid::QueryCache do
489
557
  Mongoid::QueryCache.enabled = true
490
558
  10.times { Band.create! }
491
559
 
492
- Band.batch_size(4).all.any?
560
+ Band.batch_size(4).all.to_a
493
561
  end
494
562
 
495
563
  it 'does not cache the result' do
@@ -5,7 +5,7 @@
5
5
  #
6
6
  # describe Mongoid::Relations::Proxy do
7
7
  #
8
- # describe '#with', if: non_legacy_server? do
8
+ # describe '#with' do
9
9
  #
10
10
  # let(:circus) do
11
11
  # Circus.new
@@ -230,7 +230,8 @@ describe Mongoid::Scopable do
230
230
 
231
231
  context "when provided a criteria" do
232
232
 
233
- context 'when a collation is defined on the criteria', if: collation_supported? do
233
+ context 'when a collation is defined on the criteria' do
234
+ min_server_version '3.4'
234
235
 
235
236
  before do
236
237
  Band.scope(:tests, ->{ Band.where(name: 'TESTING').collation(locale: 'en_US', strength: 2) })
@@ -16,31 +16,117 @@ describe Mongoid::Serializable do
16
16
  end
17
17
  end
18
18
 
19
- describe ".include_root_in_json" do
19
+ %i(include_root_in_json include_root_in_json?).each do |meth|
20
+ describe ".#{meth}" do
20
21
 
21
- let(:person) do
22
- Person.new
23
- end
22
+ before do
23
+ reload_model(:Minim)
24
+ end
24
25
 
25
- context "when config set to true" do
26
+ after do
27
+ Mongoid.include_root_in_json = false
28
+ reload_model(:Minim)
29
+ end
26
30
 
27
- before do
28
- Mongoid.include_root_in_json = true
31
+ context "when global config is set to true" do
32
+
33
+ before do
34
+ Mongoid.include_root_in_json = true
35
+ end
36
+
37
+ it "returns true" do
38
+ expect(Minim.public_send(meth)).to be true
39
+ end
40
+
41
+ context 'when value is overridden to false in the model class' do
42
+ before do
43
+ Minim.include_root_in_json = false
44
+ end
45
+
46
+ it 'returns false' do
47
+ expect(Minim.public_send(meth)).to be false
48
+ end
49
+ end
29
50
  end
30
51
 
31
- it "returns true" do
32
- expect(person.include_root_in_json).to be true
52
+ context "when global config set to false" do
53
+
54
+ before do
55
+ Mongoid.include_root_in_json = false
56
+ end
57
+
58
+ it "returns false" do
59
+ expect(Minim.public_send(meth)).to be false
60
+ end
61
+
62
+ context 'when value is overridden to true in the model class' do
63
+ before do
64
+ Minim.include_root_in_json = true
65
+ end
66
+
67
+ it 'returns true' do
68
+ expect(Minim.public_send(meth)).to be true
69
+ end
70
+ end
33
71
  end
34
72
  end
35
73
 
36
- context "when config set to false" do
74
+ describe "#include_root_in_json" do
37
75
 
38
76
  before do
77
+ reload_model(:Minim)
78
+ end
79
+
80
+ after do
39
81
  Mongoid.include_root_in_json = false
82
+ reload_model(:Minim)
83
+ end
84
+
85
+ let(:minim) do
86
+ Minim.new
87
+ end
88
+
89
+ context "when global config is set to true" do
90
+
91
+ before do
92
+ Minim.include_root_in_json.should be false
93
+ Mongoid.include_root_in_json = true
94
+ end
95
+
96
+ it "returns true" do
97
+ expect(minim.public_send(meth)).to be true
98
+ end
99
+
100
+ context 'when value is overridden to false in the model class' do
101
+ before do
102
+ Minim.include_root_in_json = false
103
+ end
104
+
105
+ it 'returns false' do
106
+ expect(minim.public_send(meth)).to be false
107
+ end
108
+ end
40
109
  end
41
110
 
42
- it "returns false" do
43
- expect(person.include_root_in_json).to be false
111
+ context "when global config set to false" do
112
+
113
+ before do
114
+ Mongoid.include_root_in_json = false
115
+ end
116
+
117
+ it "returns false" do
118
+ expect(minim.public_send(meth)).to be false
119
+ end
120
+
121
+ context 'when value is overridden to true in the model class' do
122
+ before do
123
+ Minim.include_root_in_json = true
124
+ end
125
+
126
+ it 'returns true' do
127
+ expect(minim.public_send(meth)).to be true
128
+ end
129
+ end
44
130
  end
45
131
  end
46
132
  end
@@ -773,32 +859,57 @@ describe Mongoid::Serializable do
773
859
 
774
860
  describe "#to_json" do
775
861
 
776
- let(:person) do
777
- Person.new
862
+ let(:account) do
863
+ Account.new
778
864
  end
779
865
 
780
- context "when including root in json" do
866
+ context "when including root in json via Mongoid" do
781
867
 
782
868
  before do
869
+ account.include_root_in_json.should be false
783
870
  Mongoid.include_root_in_json = true
784
871
  end
785
872
 
873
+ after do
874
+ Mongoid.include_root_in_json = false
875
+ end
876
+
786
877
  it "uses the mongoid configuration" do
787
- expect(person.to_json).to include("person")
878
+ expect(JSON.parse(account.to_json)).to have_key("account")
879
+ end
880
+ end
881
+
882
+ context "when including root in json via class" do
883
+
884
+ before do
885
+ account.include_root_in_json.should be false
886
+ Account.include_root_in_json = true
887
+ end
888
+
889
+ after do
890
+ Account.include_root_in_json = false
891
+ end
892
+
893
+ it "uses the class configuration" do
894
+ expect(JSON.parse(account.to_json)).to have_key("account")
788
895
  end
789
896
  end
790
897
 
791
898
  context "when not including root in json" do
792
899
 
793
900
  before do
794
- Mongoid.include_root_in_json = false
901
+ account.include_root_in_json.should be false
795
902
  end
796
903
 
797
904
  it "uses the mongoid configuration" do
798
- expect(person.to_json).to_not include("person")
905
+ expect(JSON.parse(account.to_json)).not_to have_key("account")
799
906
  end
800
907
  end
801
908
 
909
+ let(:person) do
910
+ Person.new
911
+ end
912
+
802
913
  context "when serializing a relation directly" do
803
914
 
804
915
  context "when serializing an embeds many" do