mongoid 7.1.0 → 7.1.6

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