mongoid 5.1.6 → 5.2.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 (39) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/lib/config/locales/en.yml +15 -0
  5. data/lib/mongoid.rb +5 -0
  6. data/lib/mongoid/clients/factory.rb +2 -0
  7. data/lib/mongoid/config.rb +1 -0
  8. data/lib/mongoid/contextual/map_reduce.rb +20 -97
  9. data/lib/mongoid/contextual/memory.rb +1 -0
  10. data/lib/mongoid/contextual/mongo.rb +15 -13
  11. data/lib/mongoid/errors.rb +1 -0
  12. data/lib/mongoid/errors/in_memory_collation_not_supported.rb +20 -0
  13. data/lib/mongoid/errors/mongoid_error.rb +1 -1
  14. data/lib/mongoid/extensions.rb +1 -0
  15. data/lib/mongoid/extensions/decimal128.rb +39 -0
  16. data/lib/mongoid/indexable/validators/options.rb +2 -1
  17. data/lib/mongoid/persistable/deletable.rb +3 -7
  18. data/lib/mongoid/query_cache.rb +2 -2
  19. data/lib/mongoid/version.rb +1 -1
  20. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +4 -0
  21. data/spec/app/models/band.rb +1 -0
  22. data/spec/config/mongoid.yml +5 -0
  23. data/spec/mongoid/clients/factory_spec.rb +8 -0
  24. data/spec/mongoid/clients_spec.rb +78 -1
  25. data/spec/mongoid/config_spec.rb +31 -0
  26. data/spec/mongoid/contextual/atomic_spec.rb +342 -76
  27. data/spec/mongoid/contextual/map_reduce_spec.rb +102 -135
  28. data/spec/mongoid/contextual/memory_spec.rb +316 -56
  29. data/spec/mongoid/contextual/mongo_spec.rb +367 -5
  30. data/spec/mongoid/criteria_spec.rb +19 -0
  31. data/spec/mongoid/extensions/decimal128_spec.rb +44 -0
  32. data/spec/mongoid/indexable_spec.rb +43 -0
  33. data/spec/mongoid/query_cache_spec.rb +34 -0
  34. data/spec/mongoid/relations/referenced/many_spec.rb +11 -0
  35. data/spec/mongoid/relations/referenced/many_to_many_spec.rb +11 -0
  36. data/spec/mongoid/scopable_spec.rb +12 -0
  37. data/spec/spec_helper.rb +9 -0
  38. metadata +19 -9
  39. 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|
@@ -208,7 +230,34 @@ describe Mongoid::Contextual::Mongo do
208
230
  end
209
231
  end
210
232
 
211
- context "when the selector is not contraining" do
233
+ context 'when the criteria has a collation', if: collation_supported? do
234
+
235
+ let(:criteria) do
236
+ Band.where(name: "DEPECHE MODE").collation(locale: 'en_US', strength: 2)
237
+ end
238
+
239
+ let(:context) do
240
+ described_class.new(criteria)
241
+ end
242
+
243
+ let!(:deleted) do
244
+ context.send(method)
245
+ end
246
+
247
+ it "deletes the matching documents" do
248
+ expect(Band.find(new_order.id)).to eq(new_order)
249
+ end
250
+
251
+ it "deletes the correct number of documents" do
252
+ expect(Band.count).to eq(1)
253
+ end
254
+
255
+ it "returns the number of documents deleted" do
256
+ expect(deleted).to eq(1)
257
+ end
258
+ end
259
+
260
+ context "when the selector is not constraining" do
212
261
 
213
262
  let(:criteria) do
214
263
  Band.all
@@ -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
@@ -3352,6 +3352,25 @@ describe Mongoid::Criteria do
3352
3352
  end
3353
3353
  end
3354
3354
 
3355
+ context "when querying on a BSON::Decimal128", if: decimal128_supported? do
3356
+
3357
+ let(:decimal) do
3358
+ BSON::Decimal128.new("0.0005")
3359
+ end
3360
+
3361
+ let!(:band) do
3362
+ Band.create(name: "Boards of Canada", decimal: decimal)
3363
+ end
3364
+
3365
+ let(:from_db) do
3366
+ Band.where(decimal: decimal).first
3367
+ end
3368
+
3369
+ it "finds the document by the big decimal value" do
3370
+ expect(from_db).to eq(band)
3371
+ end
3372
+ end
3373
+
3355
3374
  context 'when querying on a polymorphic relation' do
3356
3375
 
3357
3376
  let(:movie) do