mongoid 6.0.3 → 6.1.0.rc0

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