mongo 2.1.2 → 2.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 (140) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/README.md +10 -3
  5. data/Rakefile +1 -7
  6. data/lib/csasl/csasl.bundle +0 -0
  7. data/lib/mongo/auth/user/view.rb +1 -1
  8. data/lib/mongo/bulk_write.rb +7 -1
  9. data/lib/mongo/client.rb +17 -15
  10. data/lib/mongo/cluster.rb +4 -2
  11. data/lib/mongo/collection.rb +36 -2
  12. data/lib/mongo/collection/view.rb +24 -21
  13. data/lib/mongo/collection/view/aggregation.rb +5 -42
  14. data/lib/mongo/collection/view/builder.rb +20 -0
  15. data/lib/mongo/collection/view/builder/aggregation.rb +98 -0
  16. data/lib/mongo/collection/view/builder/find_command.rb +111 -0
  17. data/lib/mongo/collection/view/builder/flags.rb +62 -0
  18. data/lib/mongo/collection/view/builder/map_reduce.rb +134 -0
  19. data/lib/mongo/collection/view/builder/modifiers.rb +80 -0
  20. data/lib/mongo/collection/view/builder/op_query.rb +83 -0
  21. data/lib/mongo/collection/view/explainable.rb +15 -0
  22. data/lib/mongo/collection/view/immutable.rb +5 -12
  23. data/lib/mongo/collection/view/iterable.rb +24 -2
  24. data/lib/mongo/collection/view/map_reduce.rb +18 -27
  25. data/lib/mongo/collection/view/readable.rb +70 -112
  26. data/lib/mongo/collection/view/writable.rb +23 -7
  27. data/lib/mongo/cursor.rb +76 -25
  28. data/lib/mongo/cursor/builder.rb +18 -0
  29. data/lib/mongo/cursor/builder/get_more_command.rb +71 -0
  30. data/lib/mongo/cursor/builder/kill_cursors_command.rb +62 -0
  31. data/lib/mongo/cursor/builder/op_get_more.rb +61 -0
  32. data/lib/mongo/cursor/builder/op_kill_cursors.rb +56 -0
  33. data/lib/mongo/database.rb +2 -2
  34. data/lib/mongo/database/view.rb +9 -5
  35. data/lib/mongo/dbref.rb +3 -3
  36. data/lib/mongo/error.rb +1 -0
  37. data/lib/mongo/error/invalid_write_concern.rb +35 -0
  38. data/lib/mongo/grid/file/chunk.rb +2 -2
  39. data/lib/mongo/index/view.rb +5 -2
  40. data/lib/mongo/operation.rb +1 -0
  41. data/lib/mongo/operation/commands.rb +2 -0
  42. data/lib/mongo/operation/commands/aggregate.rb +39 -45
  43. data/lib/mongo/operation/commands/aggregate/result.rb +54 -68
  44. data/lib/mongo/operation/commands/collections_info.rb +38 -36
  45. data/lib/mongo/operation/commands/collections_info/result.rb +17 -15
  46. data/lib/mongo/operation/commands/command.rb +24 -22
  47. data/lib/mongo/operation/commands/find.rb +27 -0
  48. data/lib/mongo/operation/commands/find/result.rb +62 -0
  49. data/lib/mongo/operation/commands/get_more.rb +27 -0
  50. data/lib/mongo/operation/commands/get_more/result.rb +62 -0
  51. data/lib/mongo/operation/commands/indexes.rb +41 -39
  52. data/lib/mongo/operation/commands/list_collections.rb +25 -31
  53. data/lib/mongo/operation/commands/list_collections/result.rb +63 -81
  54. data/lib/mongo/operation/commands/list_indexes.rb +27 -35
  55. data/lib/mongo/operation/commands/list_indexes/result.rb +67 -85
  56. data/lib/mongo/operation/commands/map_reduce.rb +29 -37
  57. data/lib/mongo/operation/commands/map_reduce/result.rb +85 -88
  58. data/lib/mongo/operation/commands/parallel_scan.rb +29 -33
  59. data/lib/mongo/operation/commands/parallel_scan/result.rb +34 -42
  60. data/lib/mongo/operation/commands/user_query.rb +40 -38
  61. data/lib/mongo/operation/commands/users_info.rb +24 -29
  62. data/lib/mongo/operation/commands/users_info/result.rb +13 -11
  63. data/lib/mongo/operation/object_id_generator.rb +36 -0
  64. data/lib/mongo/operation/result.rb +30 -0
  65. data/lib/mongo/operation/specifiable.rb +35 -1
  66. data/lib/mongo/operation/write/bulk/bulkable.rb +4 -3
  67. data/lib/mongo/operation/write/bulk/delete/result.rb +18 -25
  68. data/lib/mongo/operation/write/bulk/legacy_mergable.rb +2 -2
  69. data/lib/mongo/operation/write/command/delete.rb +3 -2
  70. data/lib/mongo/operation/write/command/insert.rb +4 -2
  71. data/lib/mongo/operation/write/command/update.rb +6 -3
  72. data/lib/mongo/operation/write/gle.rb +2 -1
  73. data/lib/mongo/operation/write/idable.rb +19 -2
  74. data/lib/mongo/options/mapper.rb +22 -0
  75. data/lib/mongo/protocol/bit_vector.rb +3 -3
  76. data/lib/mongo/protocol/delete.rb +15 -5
  77. data/lib/mongo/protocol/get_more.rb +10 -5
  78. data/lib/mongo/protocol/insert.rb +1 -6
  79. data/lib/mongo/protocol/kill_cursors.rb +14 -1
  80. data/lib/mongo/protocol/message.rb +32 -8
  81. data/lib/mongo/protocol/serializers.rb +15 -16
  82. data/lib/mongo/protocol/update.rb +35 -12
  83. data/lib/mongo/server/connectable.rb +3 -1
  84. data/lib/mongo/server/connection.rb +5 -5
  85. data/lib/mongo/server/description.rb +8 -2
  86. data/lib/mongo/server/description/features.rb +2 -1
  87. data/lib/mongo/server/monitor.rb +1 -12
  88. data/lib/mongo/server/monitor/connection.rb +30 -26
  89. data/lib/mongo/server_selector/selectable.rb +21 -4
  90. data/lib/mongo/uri.rb +2 -0
  91. data/lib/mongo/version.rb +1 -1
  92. data/lib/mongo/write_concern.rb +21 -6
  93. data/mongo.gemspec +1 -2
  94. data/spec/mongo/bulk_write/ordered_combiner_spec.rb +13 -0
  95. data/spec/mongo/bulk_write_spec.rb +58 -0
  96. data/spec/mongo/client_spec.rb +6 -4
  97. data/spec/mongo/collection/view/builder/find_command_spec.rb +167 -0
  98. data/spec/mongo/collection/view/builder/flags_spec.rb +106 -0
  99. data/spec/mongo/collection/view/builder/modifiers_spec.rb +210 -0
  100. data/spec/mongo/collection/view/builder/op_query_spec.rb +154 -0
  101. data/spec/mongo/collection/view/explainable_spec.rb +1 -2
  102. data/spec/mongo/collection/view/immutable_spec.rb +3 -52
  103. data/spec/mongo/collection/view/map_reduce_spec.rb +12 -12
  104. data/spec/mongo/collection/view/readable_spec.rb +86 -80
  105. data/spec/mongo/collection/view_spec.rb +109 -703
  106. data/spec/mongo/collection_spec.rb +594 -11
  107. data/spec/mongo/command_monitoring_spec.rb +40 -27
  108. data/spec/mongo/cursor/builder/get_more_command_spec.rb +160 -0
  109. data/spec/mongo/cursor/builder/op_get_more_spec.rb +52 -0
  110. data/spec/mongo/cursor_spec.rb +10 -60
  111. data/spec/mongo/database_spec.rb +24 -3
  112. data/spec/mongo/dbref_spec.rb +4 -4
  113. data/spec/mongo/grid/file/chunk_spec.rb +1 -1
  114. data/spec/mongo/grid/fs_bucket_spec.rb +3 -3
  115. data/spec/mongo/index/view_spec.rb +41 -0
  116. data/spec/mongo/operation/{aggregate → commands/aggregate}/result_spec.rb +1 -1
  117. data/spec/mongo/operation/commands/aggregate_spec.rb +1 -1
  118. data/spec/mongo/operation/commands/collections_info_spec.rb +1 -1
  119. data/spec/mongo/operation/commands/command_spec.rb +1 -1
  120. data/spec/mongo/operation/commands/indexes_spec.rb +1 -1
  121. data/spec/mongo/operation/commands/map_reduce_spec.rb +1 -1
  122. data/spec/mongo/operation/write/command/delete_spec.rb +25 -0
  123. data/spec/mongo/operation/write/command/insert_spec.rb +25 -0
  124. data/spec/mongo/operation/write/command/update_spec.rb +25 -0
  125. data/spec/mongo/protocol/delete_spec.rb +4 -4
  126. data/spec/mongo/protocol/get_more_spec.rb +4 -4
  127. data/spec/mongo/protocol/insert_spec.rb +3 -3
  128. data/spec/mongo/protocol/kill_cursors_spec.rb +3 -3
  129. data/spec/mongo/protocol/query_spec.rb +7 -7
  130. data/spec/mongo/protocol/update_spec.rb +5 -5
  131. data/spec/mongo/server/description/features_spec.rb +25 -0
  132. data/spec/mongo/write_concern_spec.rb +126 -0
  133. data/spec/spec_helper.rb +9 -19
  134. data/spec/support/command_monitoring.rb +8 -0
  135. data/spec/support/command_monitoring/find.yml +53 -4
  136. data/spec/support/matchers.rb +1 -1
  137. data/spec/support/shared/protocol.rb +5 -5
  138. data/spec/support/travis.rb +1 -1
  139. metadata +43 -10
  140. metadata.gz.sig +0 -0
@@ -4,11 +4,18 @@ describe Mongo::Collection do
4
4
 
5
5
  after do
6
6
  authorized_collection.delete_many
7
+ collection_with_validator.drop()
7
8
  end
8
9
 
9
10
  let(:collection_invalid_write_concern) do
10
11
  authorized_collection.client.with(write: { w: (WRITE_CONCERN[:w] + 1) })[authorized_collection.name]
11
12
  end
13
+ let(:collection_with_validator) do
14
+ authorized_client[:validating,
15
+ :validator => { :a => { '$exists' => true } }].tap do |c|
16
+ c.create
17
+ end
18
+ end
12
19
 
13
20
  describe '#==' do
14
21
 
@@ -340,6 +347,10 @@ describe Mongo::Collection do
340
347
  collection.create
341
348
  end
342
349
 
350
+ let(:options) do
351
+ { :capped => true, :size => 1024 }
352
+ end
353
+
343
354
  after do
344
355
  collection.drop
345
356
  end
@@ -357,22 +368,62 @@ describe Mongo::Collection do
357
368
  end
358
369
  end
359
370
 
371
+ shared_examples 'a validated collection command' do
372
+
373
+ let!(:response) do
374
+ collection.create
375
+ end
376
+
377
+ let(:options) do
378
+ { :validator => { fieldName: { '$gte' => 1024 } },
379
+ :validationLevel => 'strict' }
380
+ end
381
+
382
+ let(:collection_info) do
383
+ database.list_collections.find { |i| i['name'] == 'specs' }
384
+ end
385
+
386
+ after do
387
+ collection.drop
388
+ end
389
+
390
+ it 'executes the command' do
391
+ expect(response).to be_successful
392
+ end
393
+
394
+ it 'sets the collection with validators' do
395
+ expect(collection_info['options']['validator']).to eq({ 'fieldName' => { '$gte' => 1024 } })
396
+ end
397
+
398
+ it 'creates the collection in the database' do
399
+ expect(database.collection_names).to include('specs')
400
+ end
401
+ end
402
+
360
403
  context 'when instantiating a collection directly' do
361
404
 
362
405
  let(:collection) do
363
- described_class.new(database, :specs, :capped => true, :size => 1024)
406
+ described_class.new(database, :specs, options)
364
407
  end
365
408
 
366
409
  it_behaves_like 'a capped collection command'
410
+
411
+ context 'when validators can be set', if: find_command_enabled? do
412
+ it_behaves_like 'a validated collection command'
413
+ end
367
414
  end
368
415
 
369
416
  context 'when instantiating a collection through the database' do
370
417
 
371
418
  let(:collection) do
372
- authorized_client[:specs, :capped => true, :size => 1024]
419
+ authorized_client[:specs, options]
373
420
  end
374
421
 
375
422
  it_behaves_like 'a capped collection command'
423
+
424
+ context 'when validators can be set', if: find_command_enabled? do
425
+ it_behaves_like 'a validated collection command'
426
+ end
376
427
  end
377
428
  end
378
429
  end
@@ -414,29 +465,29 @@ describe Mongo::Collection do
414
465
 
415
466
  describe '#find' do
416
467
 
417
- context 'when provided a selector' do
468
+ context 'when provided a filter' do
418
469
 
419
470
  let(:view) do
420
471
  authorized_collection.find(name: 1)
421
472
  end
422
473
 
423
- it 'returns a authorized_collection view for the selector' do
424
- expect(view.selector).to eq(name: 1)
474
+ it 'returns a authorized_collection view for the filter' do
475
+ expect(view.filter).to eq('name' => 1)
425
476
  end
426
477
  end
427
478
 
428
- context 'when provided no selector' do
479
+ context 'when provided no filter' do
429
480
 
430
481
  let(:view) do
431
482
  authorized_collection.find
432
483
  end
433
484
 
434
- it 'returns a authorized_collection view with an empty selector' do
435
- expect(view.selector).to be_empty
485
+ it 'returns a authorized_collection view with an empty filter' do
486
+ expect(view.filter).to be_empty
436
487
  end
437
488
  end
438
489
 
439
- context 'when providing a bad selector' do
490
+ context 'when providing a bad filter' do
440
491
 
441
492
  let(:view) do
442
493
  authorized_collection.find('$or' => [])
@@ -580,7 +631,7 @@ describe Mongo::Collection do
580
631
  context 'when provided :modifiers' do
581
632
 
582
633
  let(:options) do
583
- { modifiers: { :$orderby => Mongo::Index::ASCENDING } }
634
+ { modifiers: { '$orderby' => Mongo::Index::ASCENDING } }
584
635
  end
585
636
 
586
637
  it 'returns a view with modifiers set' do
@@ -653,6 +704,7 @@ describe Mongo::Collection do
653
704
 
654
705
  after do
655
706
  authorized_collection.delete_many
707
+ collection_with_validator.delete_many
656
708
  end
657
709
 
658
710
  let(:result) do
@@ -667,6 +719,37 @@ describe Mongo::Collection do
667
719
  expect(result.inserted_ids.size).to eq(2)
668
720
  end
669
721
 
722
+ context 'when the client has a custom id generator' do
723
+
724
+ let(:generator) do
725
+ Class.new do
726
+ def generate
727
+ 1
728
+ end
729
+ end.new
730
+ end
731
+
732
+ let(:custom_client) do
733
+ authorized_client.with(id_generator: generator)
734
+ end
735
+
736
+ let(:custom_collection) do
737
+ custom_client[TEST_COLL]
738
+ end
739
+
740
+ before do
741
+ custom_collection.insert_many([{ name: 'testing' }])
742
+ end
743
+
744
+ after do
745
+ custom_client.close
746
+ end
747
+
748
+ it 'inserts with the custom id' do
749
+ expect(custom_collection.find.first[:_id]).to eq(1)
750
+ end
751
+ end
752
+
670
753
  context 'when the inserts fail' do
671
754
 
672
755
  let(:result) do
@@ -679,12 +762,68 @@ describe Mongo::Collection do
679
762
  }.to raise_exception(Mongo::Error::BulkWriteError)
680
763
  end
681
764
  end
765
+
766
+ context "when the documents exceed the max bson size" do
767
+
768
+ let(:documents) do
769
+ [{ '_id' => 1, 'name' => '1'*17000000 }]
770
+ end
771
+
772
+ it 'raises a MaxBSONSize error' do
773
+ expect {
774
+ authorized_collection.insert_many(documents)
775
+ }.to raise_error(Mongo::Error::MaxBSONSize)
776
+ end
777
+ end
778
+
779
+ context 'when collection has a validator', if: find_command_enabled? do
780
+
781
+ context 'when the document is valid' do
782
+
783
+ let(:result) do
784
+ collection_with_validator.insert_many([{ a: 1 }, { a: 2 }])
785
+ end
786
+
787
+ it 'inserts successfully' do
788
+ expect(result.inserted_count).to eq(2)
789
+ end
790
+ end
791
+
792
+ context 'when the document is invalid' do
793
+
794
+ context 'when bypass_document_validation is not set' do
795
+
796
+ let(:result2) do
797
+ collection_with_validator.insert_many([{ x: 1 }, { x: 2 }])
798
+ end
799
+
800
+ it 'raises a BulkWriteError' do
801
+ expect {
802
+ result2
803
+ }.to raise_exception(Mongo::Error::BulkWriteError)
804
+ end
805
+ end
806
+
807
+ context 'when bypass_document_validation is true' do
808
+
809
+ let(:result3) do
810
+ collection_with_validator.insert_many(
811
+ [{ x: 1 }, { x: 2 }], :bypass_document_validation => true)
812
+ end
813
+
814
+ it 'inserts successfully' do
815
+ expect(result3.inserted_count).to eq(2)
816
+ end
817
+ end
818
+ end
819
+ end
682
820
  end
683
821
 
684
822
  describe '#insert_one' do
685
823
 
686
824
  after do
687
825
  authorized_collection.delete_many
826
+ collection_with_validator.delete_many
688
827
  end
689
828
 
690
829
  let(:result) do
@@ -716,6 +855,79 @@ describe Mongo::Collection do
716
855
  }.to raise_exception(Mongo::Error::OperationFailure)
717
856
  end
718
857
  end
858
+
859
+ context 'when the client has a custom id generator' do
860
+
861
+ let(:generator) do
862
+ Class.new do
863
+ def generate
864
+ 1
865
+ end
866
+ end.new
867
+ end
868
+
869
+ let(:custom_client) do
870
+ authorized_client.with(id_generator: generator)
871
+ end
872
+
873
+ let(:custom_collection) do
874
+ custom_client[TEST_COLL]
875
+ end
876
+
877
+ before do
878
+ custom_collection.insert_one({ name: 'testing' })
879
+ end
880
+
881
+ after do
882
+ custom_client.close
883
+ end
884
+
885
+ it 'inserts with the custom id' do
886
+ expect(custom_collection.find.first[:_id]).to eq(1)
887
+ end
888
+ end
889
+
890
+ context 'when collection has a validator', if: find_command_enabled? do
891
+
892
+ context 'when the document is valid' do
893
+
894
+ let(:result) do
895
+ collection_with_validator.insert_one({ a: 1 })
896
+ end
897
+
898
+ it 'inserts successfully' do
899
+ expect(result.written_count).to eq(1)
900
+ end
901
+ end
902
+
903
+ context 'when the document is invalid' do
904
+
905
+ context 'when bypass_document_validation is not set' do
906
+
907
+ let(:result2) do
908
+ collection_with_validator.insert_one({ x: 1 })
909
+ end
910
+
911
+ it 'raises a OperationFailure' do
912
+ expect {
913
+ result2
914
+ }.to raise_exception(Mongo::Error::OperationFailure)
915
+ end
916
+ end
917
+
918
+ context 'when bypass_document_validation is true' do
919
+
920
+ let(:result3) do
921
+ collection_with_validator.insert_one(
922
+ { x: 1 }, :bypass_document_validation => true)
923
+ end
924
+
925
+ it 'inserts successfully' do
926
+ expect(result3.written_count).to eq(1)
927
+ end
928
+ end
929
+ end
930
+ end
719
931
  end
720
932
 
721
933
  describe '#inspect' do
@@ -772,7 +984,7 @@ describe Mongo::Collection do
772
984
  context 'when options are provided' do
773
985
 
774
986
  let(:options) do
775
- { :allow_disk_use => true }
987
+ { :allow_disk_use => true, :bypass_document_validation => true }
776
988
  end
777
989
 
778
990
  it 'sets the options on the Aggregation object' do
@@ -973,6 +1185,37 @@ describe Mongo::Collection do
973
1185
  cursors
974
1186
  }.to raise_error(Mongo::Error::OperationFailure)
975
1187
  end
1188
+
1189
+ context 'when a read concern is provided', if: find_command_enabled? do
1190
+
1191
+ let(:result) do
1192
+ authorized_collection.with(options).parallel_scan(2)
1193
+ end
1194
+
1195
+ context 'when the read concern is valid' do
1196
+
1197
+ let(:options) do
1198
+ { read_concern: { level: 'local' }}
1199
+ end
1200
+
1201
+ it 'sends the read concern' do
1202
+ expect { result }.to_not raise_error
1203
+ end
1204
+ end
1205
+
1206
+ context 'when the read concern is not valid' do
1207
+
1208
+ let(:options) do
1209
+ { read_concern: { level: 'idontknow' }}
1210
+ end
1211
+
1212
+ it 'raises an exception' do
1213
+ expect {
1214
+ result
1215
+ }.to raise_error(Mongo::Error::OperationFailure)
1216
+ end
1217
+ end
1218
+ end
976
1219
  end
977
1220
 
978
1221
  describe '#replace_one' do
@@ -1081,6 +1324,56 @@ describe Mongo::Collection do
1081
1324
  }.to raise_exception(Mongo::Error::OperationFailure)
1082
1325
  end
1083
1326
  end
1327
+
1328
+ context 'when collection has a validator', if: find_command_enabled? do
1329
+
1330
+ before do
1331
+ collection_with_validator.insert_one({ a: 1 })
1332
+ end
1333
+
1334
+ after do
1335
+ collection_with_validator.delete_many
1336
+ end
1337
+
1338
+ context 'when the document is valid' do
1339
+
1340
+ let(:result) do
1341
+ collection_with_validator.replace_one({ a: 1 }, { a: 5 })
1342
+ end
1343
+
1344
+ it 'replaces successfully' do
1345
+ expect(result.modified_count).to eq(1)
1346
+ end
1347
+ end
1348
+
1349
+ context 'when the document is invalid' do
1350
+
1351
+ context 'when bypass_document_validation is not set' do
1352
+
1353
+ let(:result2) do
1354
+ collection_with_validator.replace_one({ a: 1 }, { x: 5 })
1355
+ end
1356
+
1357
+ it 'raises OperationFailure' do
1358
+ expect {
1359
+ result2
1360
+ }.to raise_exception(Mongo::Error::OperationFailure)
1361
+ end
1362
+ end
1363
+
1364
+ context 'when bypass_document_validation is true' do
1365
+
1366
+ let(:result3) do
1367
+ collection_with_validator.replace_one(
1368
+ { a: 1 }, { x: 1 }, :bypass_document_validation => true)
1369
+ end
1370
+
1371
+ it 'replaces successfully' do
1372
+ expect(result3.written_count).to eq(1)
1373
+ end
1374
+ end
1375
+ end
1376
+ end
1084
1377
  end
1085
1378
 
1086
1379
  describe '#update_many' do
@@ -1187,6 +1480,59 @@ describe Mongo::Collection do
1187
1480
  }.to raise_exception(Mongo::Error::OperationFailure)
1188
1481
  end
1189
1482
  end
1483
+
1484
+ context 'when collection has a validator', if: find_command_enabled? do
1485
+
1486
+ before do
1487
+ collection_with_validator.insert_many([{ a: 1 }, { a: 2 }])
1488
+ end
1489
+
1490
+ after do
1491
+ collection_with_validator.delete_many
1492
+ end
1493
+
1494
+ context 'when the document is valid' do
1495
+
1496
+ let(:result) do
1497
+ collection_with_validator.update_many(
1498
+ { :a => { '$gt' => 0 } }, '$inc' => { :a => 1 } )
1499
+ end
1500
+
1501
+ it 'updates successfully' do
1502
+ expect(result.modified_count).to eq(2)
1503
+ end
1504
+ end
1505
+
1506
+ context 'when the document is invalid' do
1507
+
1508
+ context 'when bypass_document_validation is not set' do
1509
+
1510
+ let(:result2) do
1511
+ collection_with_validator.update_many(
1512
+ { :a => { '$gt' => 0 } }, '$unset' => { :a => '' })
1513
+ end
1514
+
1515
+ it 'raises OperationFailure' do
1516
+ expect {
1517
+ result2
1518
+ }.to raise_exception(Mongo::Error::OperationFailure)
1519
+ end
1520
+ end
1521
+
1522
+ context 'when bypass_document_validation is true' do
1523
+
1524
+ let(:result3) do
1525
+ collection_with_validator.update_many(
1526
+ { :a => { '$gt' => 0 } }, { '$unset' => { :a => '' } },
1527
+ :bypass_document_validation => true)
1528
+ end
1529
+
1530
+ it 'updates successfully' do
1531
+ expect(result3.written_count).to eq(2)
1532
+ end
1533
+ end
1534
+ end
1535
+ end
1190
1536
  end
1191
1537
 
1192
1538
  describe '#update_one' do
@@ -1289,6 +1635,59 @@ describe Mongo::Collection do
1289
1635
  }.to raise_exception(Mongo::Error::OperationFailure)
1290
1636
  end
1291
1637
  end
1638
+
1639
+ context 'when collection has a validator', if: find_command_enabled? do
1640
+
1641
+ before do
1642
+ collection_with_validator.insert_one({ a: 1 })
1643
+ end
1644
+
1645
+ after do
1646
+ collection_with_validator.delete_many
1647
+ end
1648
+
1649
+ context 'when the document is valid' do
1650
+
1651
+ let(:result) do
1652
+ collection_with_validator.update_one(
1653
+ { :a => { '$gt' => 0 } }, '$inc' => { :a => 1 } )
1654
+ end
1655
+
1656
+ it 'updates successfully' do
1657
+ expect(result.modified_count).to eq(1)
1658
+ end
1659
+ end
1660
+
1661
+ context 'when the document is invalid' do
1662
+
1663
+ context 'when bypass_document_validation is not set' do
1664
+
1665
+ let(:result2) do
1666
+ collection_with_validator.update_one(
1667
+ { :a => { '$gt' => 0 } }, '$unset' => { :a => '' })
1668
+ end
1669
+
1670
+ it 'raises OperationFailure' do
1671
+ expect {
1672
+ result2
1673
+ }.to raise_exception(Mongo::Error::OperationFailure)
1674
+ end
1675
+ end
1676
+
1677
+ context 'when bypass_document_validation is true' do
1678
+
1679
+ let(:result3) do
1680
+ collection_with_validator.update_one(
1681
+ { :a => { '$gt' => 0 } }, { '$unset' => { :a => '' } },
1682
+ :bypass_document_validation => true)
1683
+ end
1684
+
1685
+ it 'updates successfully' do
1686
+ expect(result3.written_count).to eq(1)
1687
+ end
1688
+ end
1689
+ end
1690
+ end
1292
1691
  end
1293
1692
 
1294
1693
  describe '#find_one_and_delete' do
@@ -1386,6 +1785,30 @@ describe Mongo::Collection do
1386
1785
  }.to raise_exception(Mongo::Error::OperationFailure)
1387
1786
  end
1388
1787
  end
1788
+
1789
+ context 'when write_concern is provided', if: find_command_enabled? && standalone? do
1790
+
1791
+ it 'uses the write concern' do
1792
+ expect {
1793
+ authorized_collection.find_one_and_delete(selector,
1794
+ write_concern: { w: 2 })
1795
+ }.to raise_error(Mongo::Error::OperationFailure)
1796
+ end
1797
+ end
1798
+
1799
+ context 'when the collection has a write concern', if: find_command_enabled? && standalone? do
1800
+
1801
+ let(:collection) do
1802
+ authorized_collection.with(write: { w: 2 })
1803
+ end
1804
+
1805
+ it 'uses the write concern' do
1806
+ expect {
1807
+ collection.find_one_and_delete(selector,
1808
+ write_concern: { w: 2 })
1809
+ }.to raise_error(Mongo::Error::OperationFailure)
1810
+ end
1811
+ end
1389
1812
  end
1390
1813
 
1391
1814
  describe '#find_one_and_update' do
@@ -1540,6 +1963,86 @@ describe Mongo::Collection do
1540
1963
  }.to raise_exception(Mongo::Error::OperationFailure)
1541
1964
  end
1542
1965
  end
1966
+
1967
+ context 'when collection has a validator', if: find_command_enabled? do
1968
+
1969
+ before do
1970
+ collection_with_validator.insert_one({ a: 1 })
1971
+ end
1972
+
1973
+ after do
1974
+ collection_with_validator.delete_many
1975
+ end
1976
+
1977
+ context 'when the document is valid' do
1978
+
1979
+ let(:result) do
1980
+ collection_with_validator.find_one_and_update(
1981
+ { a: 1 }, { '$inc' => { :a => 1 } }, :return_document => :after)
1982
+ end
1983
+
1984
+ it 'updates successfully' do
1985
+ expect(result['a']).to eq(2)
1986
+ end
1987
+ end
1988
+
1989
+ context 'when the document is invalid' do
1990
+
1991
+ context 'when bypass_document_validation is not set' do
1992
+
1993
+ let(:result2) do
1994
+ collection_with_validator.find_one_and_update(
1995
+ { a: 1 }, { '$unset' => { :a => '' } }, :return_document => :after)
1996
+ end
1997
+
1998
+ it 'raises OperationFailure' do
1999
+ expect {
2000
+ result2
2001
+ }.to raise_exception(Mongo::Error::OperationFailure)
2002
+ end
2003
+ end
2004
+
2005
+ context 'when bypass_document_validation is true' do
2006
+
2007
+ let(:result3) do
2008
+ collection_with_validator.find_one_and_update(
2009
+ { a: 1 }, { '$unset' => { :a => '' } },
2010
+ :bypass_document_validation => true,
2011
+ :return_document => :after)
2012
+ end
2013
+
2014
+ it 'updates successfully' do
2015
+ expect(result3['a']).to be_nil
2016
+ end
2017
+ end
2018
+ end
2019
+ end
2020
+
2021
+ context 'when write_concern is provided', if: find_command_enabled? && standalone? do
2022
+
2023
+ it 'uses the write concern' do
2024
+ expect {
2025
+ authorized_collection.find_one_and_update(selector,
2026
+ { '$set' => { field: 'testing' }},
2027
+ write_concern: { w: 2 })
2028
+ }.to raise_error(Mongo::Error::OperationFailure)
2029
+ end
2030
+ end
2031
+
2032
+ context 'when the collection has a write concern', if: find_command_enabled? && standalone? do
2033
+
2034
+ let(:collection) do
2035
+ authorized_collection.with(write: { w: 2 })
2036
+ end
2037
+
2038
+ it 'uses the write concern' do
2039
+ expect {
2040
+ collection.find_one_and_update(selector,
2041
+ { '$set' => { field: 'testing' }},
2042
+ write_concern: { w: 2 })
2043
+ }.to raise_error(Mongo::Error::OperationFailure)
2044
+ end
2045
+ end
1543
2046
  end
1544
2047
 
1545
2048
  describe '#find_one_and_replace' do
@@ -1668,5 +2171,85 @@ describe Mongo::Collection do
1668
2171
  }.to raise_exception(Mongo::Error::OperationFailure)
1669
2172
  end
1670
2173
  end
2174
+
2175
+ context 'when collection has a validator', if: find_command_enabled? do
2176
+
2177
+ before do
2178
+ collection_with_validator.insert_one({ a: 1 })
2179
+ end
2180
+
2181
+ after do
2182
+ collection_with_validator.delete_many
2183
+ end
2184
+
2185
+ context 'when the document is valid' do
2186
+
2187
+ let(:result) do
2188
+ collection_with_validator.find_one_and_replace(
2189
+ { a: 1 }, { a: 5 }, :return_document => :after)
2190
+ end
2191
+
2192
+ it 'replaces successfully when document is valid' do
2193
+ expect(result[:a]).to eq(5)
2194
+ end
2195
+ end
2196
+
2197
+ context 'when the document is invalid' do
2198
+
2199
+ context 'when bypass_document_validation is not set' do
2200
+
2201
+ let(:result2) do
2202
+ collection_with_validator.find_one_and_replace(
2203
+ { a: 1 }, { x: 5 }, :return_document => :after)
2204
+ end
2205
+
2206
+ it 'raises OperationFailure' do
2207
+ expect {
2208
+ result2
2209
+ }.to raise_exception(Mongo::Error::OperationFailure)
2210
+ end
2211
+ end
2212
+
2213
+ context 'when bypass_document_validation is true' do
2214
+
2215
+ let(:result3) do
2216
+ collection_with_validator.find_one_and_replace(
2217
+ { a: 1 }, { x: 1 }, :bypass_document_validation => true,
2218
+ :return_document => :after)
2219
+ end
2220
+
2221
+ it 'replaces successfully' do
2222
+ expect(result3[:x]).to eq(1)
2223
+ expect(result3[:a]).to be_nil
2224
+ end
2225
+ end
2226
+ end
2227
+ end
2228
+
2229
+ context 'when write_concern is provided', if: find_command_enabled? && standalone? do
2230
+
2231
+ it 'uses the write concern' do
2232
+ expect {
2233
+ authorized_collection.find_one_and_replace(selector,
2234
+ { field: 'testing' },
2235
+ write_concern: { w: 2 })
2236
+ }.to raise_error(Mongo::Error::OperationFailure)
2237
+ end
2238
+ end
2239
+
2240
+ context 'when the collection has a write concern', if: find_command_enabled? && standalone? do
2241
+
2242
+ let(:collection) do
2243
+ authorized_collection.with(write: { w: 2 })
2244
+ end
2245
+
2246
+ it 'uses the write concern' do
2247
+ expect {
2248
+ collection.find_one_and_replace(selector,
2249
+ { field: 'testing' },
2250
+ write_concern: { w: 2 })
2251
+ }.to raise_error(Mongo::Error::OperationFailure)
2252
+ end
2253
+ end
1671
2254
  end
1672
2255
  end