mongo 2.1.2 → 2.2.0.rc0

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