mongoid 6.0.3 → 6.1.0.rc0

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 (47) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +3 -2
  4. data/lib/config/locales/en.yml +15 -0
  5. data/lib/mongoid.rb +5 -0
  6. data/lib/mongoid/clients.rb +10 -2
  7. data/lib/mongoid/clients/factory.rb +2 -0
  8. data/lib/mongoid/config.rb +1 -0
  9. data/lib/mongoid/contextual/map_reduce.rb +20 -115
  10. data/lib/mongoid/contextual/memory.rb +1 -0
  11. data/lib/mongoid/contextual/mongo.rb +16 -13
  12. data/lib/mongoid/criteria/queryable/extensions/boolean.rb +1 -1
  13. data/lib/mongoid/criteria/queryable/optional.rb +14 -0
  14. data/lib/mongoid/errors.rb +1 -0
  15. data/lib/mongoid/errors/in_memory_collation_not_supported.rb +20 -0
  16. data/lib/mongoid/errors/mongoid_error.rb +1 -1
  17. data/lib/mongoid/extensions.rb +1 -0
  18. data/lib/mongoid/extensions/decimal128.rb +39 -0
  19. data/lib/mongoid/indexable/validators/options.rb +2 -1
  20. data/lib/mongoid/persistable/deletable.rb +3 -7
  21. data/lib/mongoid/query_cache.rb +2 -2
  22. data/lib/mongoid/relations/metadata.rb +3 -3
  23. data/lib/mongoid/relations/referenced/many.rb +2 -2
  24. data/lib/mongoid/version.rb +1 -1
  25. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +4 -0
  26. data/spec/app/models/band.rb +1 -0
  27. data/spec/config/mongoid.yml +19 -0
  28. data/spec/mongoid/clients/factory_spec.rb +8 -0
  29. data/spec/mongoid/clients_spec.rb +69 -0
  30. data/spec/mongoid/config_spec.rb +34 -2
  31. data/spec/mongoid/contextual/atomic_spec.rb +342 -76
  32. data/spec/mongoid/contextual/map_reduce_spec.rb +102 -135
  33. data/spec/mongoid/contextual/memory_spec.rb +316 -56
  34. data/spec/mongoid/contextual/mongo_spec.rb +366 -4
  35. data/spec/mongoid/criteria/queryable/optional_spec.rb +13 -0
  36. data/spec/mongoid/criteria_spec.rb +19 -0
  37. data/spec/mongoid/extensions/boolean_spec.rb +14 -0
  38. data/spec/mongoid/extensions/decimal128_spec.rb +44 -0
  39. data/spec/mongoid/indexable_spec.rb +43 -0
  40. data/spec/mongoid/query_cache_spec.rb +34 -0
  41. data/spec/mongoid/relations/metadata_spec.rb +0 -1
  42. data/spec/mongoid/relations/referenced/many_spec.rb +11 -0
  43. data/spec/mongoid/relations/referenced/many_to_many_spec.rb +11 -0
  44. data/spec/mongoid/scopable_spec.rb +12 -0
  45. data/spec/spec_helper.rb +9 -0
  46. metadata +17 -7
  47. metadata.gz.sig +0 -0
@@ -167,6 +167,28 @@ describe Mongoid::Contextual::Mongo do
167
167
  expect(count).to eq(2)
168
168
  end
169
169
  end
170
+
171
+ context 'when a collation is specified', if: collation_supported? do
172
+
173
+ let(:context) do
174
+ described_class.new(criteria)
175
+ end
176
+
177
+ context 'when the collation is specified on the criteria' do
178
+
179
+ let(:criteria) do
180
+ Band.where(name: "DEPECHE MODE").collation(locale: 'en_US', strength: 2)
181
+ end
182
+
183
+ let(:count) do
184
+ context.count
185
+ end
186
+
187
+ it 'applies the collation' do
188
+ expect(count).to eq(1)
189
+ end
190
+ end
191
+ end
170
192
  end
171
193
 
172
194
  [ :delete, :delete_all ].each do |method|
@@ -206,6 +228,33 @@ describe Mongoid::Contextual::Mongo do
206
228
  it "returns the number of documents deleted" do
207
229
  expect(deleted).to eq(1)
208
230
  end
231
+
232
+ context 'when the criteria has a collation', if: collation_supported? do
233
+
234
+ let(:criteria) do
235
+ Band.where(name: "DEPECHE MODE").collation(locale: 'en_US', strength: 2)
236
+ end
237
+
238
+ let(:context) do
239
+ described_class.new(criteria)
240
+ end
241
+
242
+ let!(:deleted) do
243
+ context.send(method)
244
+ end
245
+
246
+ it "deletes the matching documents" do
247
+ expect(Band.find(new_order.id)).to eq(new_order)
248
+ end
249
+
250
+ it "deletes the correct number of documents" do
251
+ expect(Band.count).to eq(1)
252
+ end
253
+
254
+ it "returns the number of documents deleted" do
255
+ expect(deleted).to eq(1)
256
+ end
257
+ end
209
258
  end
210
259
 
211
260
  context "when the selector is not contraining" do
@@ -266,6 +315,33 @@ describe Mongoid::Contextual::Mongo do
266
315
  it "returns the number of documents destroyed" do
267
316
  expect(destroyed).to eq(1)
268
317
  end
318
+
319
+ context 'when the criteria has a collation', if: collation_supported? do
320
+
321
+ let(:criteria) do
322
+ Band.where(name: "DEPECHE MODE").collation(locale: 'en_US', strength: 2)
323
+ end
324
+
325
+ let(:context) do
326
+ described_class.new(criteria)
327
+ end
328
+
329
+ let!(:destroyed) do
330
+ context.send(method)
331
+ end
332
+
333
+ it "destroys the matching documents" do
334
+ expect(Band.find(new_order.id)).to eq(new_order)
335
+ end
336
+
337
+ it "destroys the correct number of documents" do
338
+ expect(Band.count).to eq(1)
339
+ end
340
+
341
+ it "returns the number of documents destroyed" do
342
+ expect(destroyed).to eq(1)
343
+ end
344
+ end
269
345
  end
270
346
 
271
347
  context "when the selector is not contraining" do
@@ -340,6 +416,29 @@ describe Mongoid::Contextual::Mongo do
340
416
  expect(context.distinct(:years)).to eq([ 30, 25 ])
341
417
  end
342
418
  end
419
+
420
+ context 'when a collation is specified', if: collation_supported? do
421
+
422
+ before do
423
+ Band.create(name: 'DEPECHE MODE')
424
+ end
425
+
426
+ let(:context) do
427
+ described_class.new(criteria)
428
+ end
429
+
430
+ let(:expected_results) do
431
+ ["Depeche Mode", "New Order"]
432
+ end
433
+
434
+ let(:criteria) do
435
+ Band.where({}).collation(locale: 'en_US', strength: 2)
436
+ end
437
+
438
+ it 'applies the collation' do
439
+ expect(context.distinct(:name)).to eq(expected_results)
440
+ end
441
+ end
343
442
  end
344
443
 
345
444
  describe "#each" do
@@ -356,6 +455,29 @@ describe Mongoid::Contextual::Mongo do
356
455
  described_class.new(criteria)
357
456
  end
358
457
 
458
+ context 'when the criteria has a collation', if: collation_supported? do
459
+
460
+ let(:criteria) do
461
+ Band.where(name: "DEPECHE MODE").collation(locale: 'en_US', strength: 2)
462
+ end
463
+
464
+ it "yields mongoid documents to the block" do
465
+ context.each do |doc|
466
+ expect(doc).to be_a(Mongoid::Document)
467
+ end
468
+ end
469
+
470
+ it "iterates over the matching documents" do
471
+ context.each do |doc|
472
+ expect(doc.name).to eq("Depeche Mode")
473
+ end
474
+ end
475
+
476
+ it "returns self" do
477
+ expect(context.each{}).to be(context)
478
+ end
479
+ end
480
+
359
481
  context "when providing a block" do
360
482
 
361
483
  it "yields mongoid documents to the block" do
@@ -555,6 +677,161 @@ describe Mongoid::Contextual::Mongo do
555
677
  end
556
678
  end
557
679
 
680
+ describe "#find_one_and_replace" do
681
+
682
+ let!(:depeche) do
683
+ Band.create(name: "Depeche Mode")
684
+ end
685
+
686
+ let!(:tool) do
687
+ Band.create(name: "Tool")
688
+ end
689
+
690
+ context "when the selector matches" do
691
+
692
+ context "when not providing options" do
693
+
694
+ let(:criteria) do
695
+ Band.where(name: "Depeche Mode")
696
+ end
697
+
698
+ let(:context) do
699
+ described_class.new(criteria)
700
+ end
701
+
702
+ let!(:result) do
703
+ context.find_one_and_replace(name: 'FKA Twigs')
704
+ end
705
+
706
+ it "returns the first matching document" do
707
+ expect(result).to eq(depeche)
708
+ end
709
+
710
+ it "updates the document in the database" do
711
+ expect(depeche.reload.name).to eq('FKA Twigs')
712
+ end
713
+ end
714
+
715
+ context "when sorting" do
716
+
717
+ let(:criteria) do
718
+ Band.desc(:name)
719
+ end
720
+
721
+ let(:context) do
722
+ described_class.new(criteria)
723
+ end
724
+
725
+ let!(:result) do
726
+ context.find_one_and_replace(likes: 1)
727
+ end
728
+
729
+ it "returns the first matching document" do
730
+ expect(result).to eq(tool)
731
+ end
732
+
733
+ it "updates the document in the database" do
734
+ expect(tool.reload.likes).to eq(1)
735
+ expect(tool.reload.name).to be_nil
736
+ end
737
+ end
738
+
739
+ context "when limiting fields" do
740
+
741
+ let(:criteria) do
742
+ Band.only(:_id)
743
+ end
744
+
745
+ let(:context) do
746
+ described_class.new(criteria)
747
+ end
748
+
749
+ let!(:result) do
750
+ context.find_one_and_replace(name: 'FKA Twigs', likes: 1)
751
+ end
752
+
753
+ it "returns the first matching document" do
754
+ expect(result).to eq(depeche)
755
+ end
756
+
757
+ it "limits the returned fields" do
758
+ expect(result.name).to be_nil
759
+ end
760
+
761
+ it "updates the document in the database" do
762
+ expect(depeche.reload.likes).to eq(1)
763
+ end
764
+ end
765
+
766
+ context "when returning new" do
767
+
768
+ let(:criteria) do
769
+ Band.where(name: "Depeche Mode")
770
+ end
771
+
772
+ let(:context) do
773
+ described_class.new(criteria)
774
+ end
775
+
776
+ let!(:result) do
777
+ context.find_one_and_replace({ likes: 1 }, return_document: :after)
778
+ end
779
+
780
+ it "returns the first matching document" do
781
+ expect(result).to eq(depeche)
782
+ end
783
+
784
+ it "returns the updated document" do
785
+ expect(result.name).to be_nil
786
+ expect(result.likes).to eq(1)
787
+ end
788
+ end
789
+
790
+ context 'when a collation is specified on the criteria', if: collation_supported? do
791
+
792
+ let(:criteria) do
793
+ Band.where(name: "DEPECHE MODE").collation(locale: 'en_US', strength: 2)
794
+ end
795
+
796
+ let(:context) do
797
+ described_class.new(criteria)
798
+ end
799
+
800
+ let!(:result) do
801
+ context.find_one_and_replace({ likes: 1 }, return_document: :after)
802
+ end
803
+
804
+ it "returns the first matching document" do
805
+ expect(result).to eq(depeche)
806
+ end
807
+
808
+ it "returns the updated document" do
809
+ expect(result.likes).to eq(1)
810
+ expect(result.name).to be_nil
811
+ end
812
+ end
813
+ end
814
+
815
+ context "when the selector does not match" do
816
+
817
+ let(:criteria) do
818
+ Band.where(name: "DEPECHE MODE")
819
+ end
820
+
821
+ let(:context) do
822
+ described_class.new(criteria)
823
+ end
824
+
825
+ let(:result) do
826
+ context.find_one_and_replace(name: 'FKA Twigs')
827
+ end
828
+
829
+ it "returns nil" do
830
+ expect(result).to be_nil
831
+ end
832
+ end
833
+ end
834
+
558
835
  describe "#find_one_and_update" do
559
836
 
560
837
  let!(:depeche) do
@@ -663,10 +940,84 @@ describe Mongoid::Contextual::Mongo do
663
940
  end
664
941
  end
665
942
 
666
- context "when removing" do
943
+ context 'when a collation is specified on the criteria', if: collation_supported? do
667
944
 
668
945
  let(:criteria) do
669
- Band.where(name: "Depeche Mode")
946
+ Band.where(name: "DEPECHE MODE").collation(locale: 'en_US', strength: 2)
947
+ end
948
+
949
+ let(:context) do
950
+ described_class.new(criteria)
951
+ end
952
+
953
+ let!(:result) do
954
+ context.find_one_and_update({ "$inc" => { likes: 1 }}, return_document: :after)
955
+ end
956
+
957
+ it "returns the first matching document" do
958
+ expect(result).to eq(depeche)
959
+ end
960
+
961
+ it "returns the updated document" do
962
+ expect(result.likes).to eq(1)
963
+ end
964
+ end
965
+ end
966
+
967
+ context "when the selector does not match" do
968
+
969
+ let(:criteria) do
970
+ Band.where(name: "Placebo")
971
+ end
972
+
973
+ let(:context) do
974
+ described_class.new(criteria)
975
+ end
976
+
977
+ let(:result) do
978
+ context.find_one_and_update("$inc" => { likes: 1 })
979
+ end
980
+
981
+ it "returns nil" do
982
+ expect(result).to be_nil
983
+ end
984
+ end
985
+ end
986
+
987
+ describe "#find_one_and_delete" do
988
+
989
+ let!(:depeche) do
990
+ Band.create(name: "Depeche Mode")
991
+ end
992
+
993
+ let(:criteria) do
994
+ Band.where(name: "Depeche Mode")
995
+ end
996
+
997
+ let(:context) do
998
+ described_class.new(criteria)
999
+ end
1000
+
1001
+ let!(:result) do
1002
+ context.find_one_and_delete
1003
+ end
1004
+
1005
+ context 'when the selector matches a document' do
1006
+
1007
+ it "returns the first matching document" do
1008
+ expect(result).to eq(depeche)
1009
+ end
1010
+
1011
+ it "deletes the document from the database" do
1012
+ expect {
1013
+ depeche.reload
1014
+ }.to raise_error(Mongoid::Errors::DocumentNotFound)
1015
+ end
1016
+
1017
+ context 'when a collation is specified on the criteria', if: collation_supported? do
1018
+
1019
+ let(:criteria) do
1020
+ Band.where(name: "DEPECHE MODE").collation(locale: 'en_US', strength: 2)
670
1021
  end
671
1022
 
672
1023
  let(:context) do
@@ -689,7 +1040,7 @@ describe Mongoid::Contextual::Mongo do
689
1040
  end
690
1041
  end
691
1042
 
692
- context "when the selector does not match" do
1043
+ context 'when the selector does not match a document' do
693
1044
 
694
1045
  let(:criteria) do
695
1046
  Band.where(name: "Placebo")
@@ -700,7 +1051,7 @@ describe Mongoid::Contextual::Mongo do
700
1051
  end
701
1052
 
702
1053
  let(:result) do
703
- context.find_one_and_update("$inc" => { likes: 1 })
1054
+ context.find_one_and_delete
704
1055
  end
705
1056
 
706
1057
  it "returns nil" do
@@ -734,6 +1085,17 @@ describe Mongoid::Contextual::Mongo do
734
1085
  it "returns the first matching document" do
735
1086
  expect(context.send(method)).to eq(depeche_mode)
736
1087
  end
1088
+
1089
+ context 'when the criteria has a collation', if: collation_supported? do
1090
+
1091
+ let(:criteria) do
1092
+ Band.where(name: "DEPECHE MODE").collation(locale: 'en_US', strength: 2)
1093
+ end
1094
+
1095
+ it "returns the first matching document" do
1096
+ expect(context.send(method)).to eq(depeche_mode)
1097
+ end
1098
+ end
737
1099
  end
738
1100
 
739
1101
  context "when using .desc" do
@@ -1702,6 +1702,19 @@ describe Mongoid::Criteria::Queryable::Optional do
1702
1702
  it_behaves_like "a cloning option"
1703
1703
  end
1704
1704
 
1705
+ describe "#collation" do
1706
+
1707
+ let(:selection) do
1708
+ query.collation(locale: 'fr', strength: 2)
1709
+ end
1710
+
1711
+ it "adds the collation option" do
1712
+ expect(selection.options).to eq(collation: {'locale' => 'fr', 'strength' => 2})
1713
+ end
1714
+
1715
+ it_behaves_like "a cloning option"
1716
+ end
1717
+
1705
1718
  describe "#without" do
1706
1719
 
1707
1720
  context "when provided no options" do