From 1497c9cb55c573b5679da37d5ae8f5fc154933cb Mon Sep 17 00:00:00 2001 From: Ezra Chung Date: Tue, 18 Nov 2025 10:06:09 -0600 Subject: [PATCH] Split collection_mocked.cpp test case into smaller functions --- .../test/v_noabi/collection_mocked.cpp | 1481 +++++++++-------- 1 file changed, 762 insertions(+), 719 deletions(-) diff --git a/src/mongocxx/test/v_noabi/collection_mocked.cpp b/src/mongocxx/test/v_noabi/collection_mocked.cpp index 278412e589..da9c203b6e 100644 --- a/src/mongocxx/test/v_noabi/collection_mocked.cpp +++ b/src/mongocxx/test/v_noabi/collection_mocked.cpp @@ -15,7 +15,6 @@ #include #include -#include #include #include @@ -27,7 +26,6 @@ #include #include #include -#include #include #include #include @@ -36,304 +34,317 @@ #include #include -#include #include #include +#include + namespace { + using namespace mongocxx; using namespace bsoncxx; using builder::basic::kvp; using builder::basic::make_document; -TEST_CASE("A default constructed collection is false-ish", "[collection]") { +TEST_CASE("A default constructed collection is false-ish", "[mongocxx][v_noabi][collection]") { collection c; REQUIRE(!c); } -TEST_CASE("Collection", "[collection]") { - // dummy_collection is the name the mocked collection_get_name returns - std::string const collection_name("dummy_collection"); - std::string const database_name("mocked_collection"); - - MOCK_CLIENT; +TEST_CASE("read_concern", "[mongocxx][v_noabi][collection]") { MOCK_DATABASE; - MOCK_COLLECTION; - MOCK_FAM; - MOCK_BULK; - MOCK_CURSOR; + MOCK_COLLECTION; // "mocked_collection.dummy_collection" client mongo_client{uri{}}; - write_concern concern; - database mongo_db = mongo_client[database_name]; - collection mongo_coll = mongo_db[collection_name]; + auto mongo_coll = mongo_client["mocked_collection"]["dummy_collection"]; REQUIRE(mongo_coll); - SECTION("Read Concern", "[collection]") { - auto collection_set_rc_called = false; - read_concern rc{}; - rc.acknowledge_level(read_concern::level::k_majority); + auto collection_set_rc_called = false; + read_concern rc{}; + rc.acknowledge_level(read_concern::level::k_majority); + + collection_set_read_concern->interpose( + [&collection_set_rc_called](::mongoc_collection_t*, ::mongoc_read_concern_t const* rc_t) { + REQUIRE(rc_t); + auto const result = libmongoc::read_concern_get_level(rc_t); + REQUIRE(result); + REQUIRE(strcmp(result, "majority") == 0); + collection_set_rc_called = true; + }); - collection_set_read_concern->interpose( - [&collection_set_rc_called](::mongoc_collection_t*, ::mongoc_read_concern_t const* rc_t) { - REQUIRE(rc_t); - auto const result = libmongoc::read_concern_get_level(rc_t); - REQUIRE(result); - REQUIRE(strcmp(result, "majority") == 0); - collection_set_rc_called = true; - }); + mongo_coll.read_concern(rc); + REQUIRE(collection_set_rc_called); +} - mongo_coll.read_concern(rc); - REQUIRE(collection_set_rc_called); - } +TEST_CASE("aggregate", "[mongocxx][v_noabi][collection]") { + MOCK_DATABASE; + MOCK_COLLECTION; // "mocked_collection.dummy_collection" + + client mongo_client{uri{}}; + auto mongo_coll = mongo_client["mocked_collection"]["dummy_collection"]; + REQUIRE(mongo_coll); auto filter_doc = make_document(kvp("_id", "wow"), kvp("foo", "bar")); - SECTION("Aggregate", "[Collection::aggregate]") { - auto const expected_allow_disk_use = true; - auto const expected_batch_size = 5678; - auto const expected_bypass_document_validation = true; - auto const expected_collation = make_document(kvp("locale", "en_US")); - auto const expected_comment = make_document(kvp("$comment", "some_comment")); - auto const expected_hint = hint("some_hint"); - auto const expected_let = make_document(kvp("x", "foo")); - auto const expected_max_time_ms = 1234; - auto const expected_read_preference = read_preference{}.mode(read_preference::read_mode::k_secondary); - - auto const expected_read_concern = make_document(kvp("level", "majority")); - auto const read_concern = [] { - mongocxx::read_concern rc; - rc.acknowledge_level(read_concern::level::k_majority); - return rc; - }(); - - auto const expected_write_concern = make_document(kvp("w", "majority"), kvp("wtimeout", 100)); - auto const write_concern = [] { - mongocxx::write_concern wc; - wc.majority(std::chrono::milliseconds(100)); - return wc; - }(); - - pipeline pipe; - options::aggregate opts; - - auto collection_aggregate_called = false; - - collection_aggregate->interpose( - [&](mongoc_collection_t*, - mongoc_query_flags_t flags, - bson_t const* pipeline, - bson_t const* options, - mongoc_read_prefs_t const* read_preference) -> mongoc_cursor_t* { - collection_aggregate_called = true; - REQUIRE(flags == MONGOC_QUERY_NONE); - - bsoncxx::array::view p(bson_get_data(pipeline), pipeline->len); - bsoncxx::document::view o(bson_get_data(options), options->len); - - bsoncxx::stdx::string_view bar( - p[0].get_document().value["$match"].get_document().value["foo"].get_string()); - std::int32_t one(p[1].get_document().value["$sort"].get_document().value["foo"].get_int32()); - - REQUIRE(bar == bsoncxx::stdx::string_view("bar")); - REQUIRE(one == 1); - - if (opts.allow_disk_use()) { - REQUIRE(o["allowDiskUse"].get_bool().value == expected_allow_disk_use); - } else { - REQUIRE(o.find("allowDiskUse") == o.end()); - } + auto const expected_allow_disk_use = true; + auto const expected_batch_size = 5678; + auto const expected_bypass_document_validation = true; + auto const expected_collation = make_document(kvp("locale", "en_US")); + auto const expected_comment = make_document(kvp("$comment", "some_comment")); + auto const expected_hint = hint("some_hint"); + auto const expected_let = make_document(kvp("x", "foo")); + auto const expected_max_time_ms = 1234; + auto const expected_read_preference = read_preference{}.mode(read_preference::read_mode::k_secondary); + + auto const expected_read_concern = make_document(kvp("level", "majority")); + auto const read_concern = [] { + mongocxx::read_concern rc; + rc.acknowledge_level(read_concern::level::k_majority); + return rc; + }(); + + auto const expected_write_concern = make_document(kvp("w", "majority"), kvp("wtimeout", 100)); + auto const write_concern = [] { + mongocxx::write_concern wc; + wc.majority(std::chrono::milliseconds(100)); + return wc; + }(); + + pipeline pipe; + options::aggregate opts; + + auto collection_aggregate_called = false; + + collection_aggregate->interpose( + [&](mongoc_collection_t*, + mongoc_query_flags_t flags, + bson_t const* pipeline, + bson_t const* options, + mongoc_read_prefs_t const* read_preference) -> mongoc_cursor_t* { + collection_aggregate_called = true; + REQUIRE(flags == MONGOC_QUERY_NONE); + + bsoncxx::array::view p(bson_get_data(pipeline), pipeline->len); + bsoncxx::document::view o(bson_get_data(options), options->len); + + bsoncxx::stdx::string_view bar( + p[0].get_document().value["$match"].get_document().value["foo"].get_string()); + std::int32_t one(p[1].get_document().value["$sort"].get_document().value["foo"].get_int32()); + + REQUIRE(bar == bsoncxx::stdx::string_view("bar")); + REQUIRE(one == 1); + + if (opts.allow_disk_use()) { + REQUIRE(o["allowDiskUse"].get_bool().value == expected_allow_disk_use); + } else { + REQUIRE(o.find("allowDiskUse") == o.end()); + } - if (opts.batch_size()) { - REQUIRE(o["batchSize"].get_int32().value == expected_batch_size); - } else { - REQUIRE(o.find("batchSize") == o.end()); - } + if (opts.batch_size()) { + REQUIRE(o["batchSize"].get_int32().value == expected_batch_size); + } else { + REQUIRE(o.find("batchSize") == o.end()); + } - if (opts.bypass_document_validation()) { - REQUIRE(o["bypassDocumentValidation"].get_bool().value == expected_bypass_document_validation); - } else { - REQUIRE(!o["bypassDocumentValidation"]); - } + if (opts.bypass_document_validation()) { + REQUIRE(o["bypassDocumentValidation"].get_bool().value == expected_bypass_document_validation); + } else { + REQUIRE(!o["bypassDocumentValidation"]); + } - if (opts.collation()) { - REQUIRE(o["collation"].get_document().value == expected_collation); - } else { - REQUIRE(o.find("collation") == o.end()); - } + if (opts.collation()) { + REQUIRE(o["collation"].get_document().value == expected_collation); + } else { + REQUIRE(o.find("collation") == o.end()); + } - if (opts.comment()) { - REQUIRE(o["comment"].get_value() == expected_comment["$comment"].get_value()); - } else { - REQUIRE(o.find("comment") == o.end()); - } + if (opts.comment()) { + REQUIRE(o["comment"].get_value() == expected_comment["$comment"].get_value()); + } else { + REQUIRE(o.find("comment") == o.end()); + } - if (opts.hint()) { - REQUIRE(o["hint"].get_value() == expected_hint.to_value()); - } else { - REQUIRE(o.find("hint") == o.end()); - } + if (opts.hint()) { + REQUIRE(o["hint"].get_value() == expected_hint.to_value()); + } else { + REQUIRE(o.find("hint") == o.end()); + } - if (opts.let()) { - REQUIRE(o["let"].get_document().value == expected_let); - } else { - REQUIRE(o.find("let") == o.end()); - } + if (opts.let()) { + REQUIRE(o["let"].get_document().value == expected_let); + } else { + REQUIRE(o.find("let") == o.end()); + } - if (opts.max_time()) { - REQUIRE(o["maxTimeMS"].get_int64().value == expected_max_time_ms); - } else { - REQUIRE(o.find("maxTimeMS") == o.end()); - } + if (opts.max_time()) { + REQUIRE(o["maxTimeMS"].get_int64().value == expected_max_time_ms); + } else { + REQUIRE(o.find("maxTimeMS") == o.end()); + } - if (opts.read_concern()) { - REQUIRE(o["readConcern"].get_document().value == expected_read_concern); - } else { - REQUIRE(o.find("readConcern") == o.end()); - } + if (opts.read_concern()) { + REQUIRE(o["readConcern"].get_document().value == expected_read_concern); + } else { + REQUIRE(o.find("readConcern") == o.end()); + } - if (opts.read_preference()) { - REQUIRE( - mongoc_read_prefs_get_mode(read_preference) == - static_cast(opts.read_preference()->mode())); - } else { - REQUIRE( - mongoc_read_prefs_get_mode(read_preference) == - mongocxx::v_noabi::conversions::read_mode_t_from_read_mode( - mongo_coll.read_preference().mode())); - } + if (opts.read_preference()) { + REQUIRE( + mongoc_read_prefs_get_mode(read_preference) == static_cast(opts.read_preference()->mode())); + } else { + REQUIRE( + mongoc_read_prefs_get_mode(read_preference) == + mongocxx::v_noabi::conversions::read_mode_t_from_read_mode(mongo_coll.read_preference().mode())); + } - if (opts.write_concern()) { - REQUIRE(o["writeConcern"].get_document().value == expected_write_concern); - } else { - REQUIRE(o.find("writeConcern") == o.end()); - } + if (opts.write_concern()) { + REQUIRE(o["writeConcern"].get_document().value == expected_write_concern); + } else { + REQUIRE(o.find("writeConcern") == o.end()); + } - return nullptr; - }); + return nullptr; + }); - pipe.match(make_document(kvp("foo", "bar"))); - pipe.sort(make_document(kvp("foo", 1))); - - SECTION("With default options") {} - - SECTION("With some options") { - opts.allow_disk_use(expected_allow_disk_use); - opts.batch_size(expected_batch_size); - opts.bypass_document_validation(expected_bypass_document_validation); - opts.collation(expected_collation.view()); - opts.comment(expected_comment["$comment"].get_value()); - opts.hint(expected_hint); - opts.let(expected_let.view()); - opts.max_time(std::chrono::milliseconds{expected_max_time_ms}); - opts.read_concern(read_concern); - opts.read_preference(expected_read_preference); - opts.write_concern(write_concern); - } + pipe.match(make_document(kvp("foo", "bar"))); + pipe.sort(make_document(kvp("foo", 1))); + SECTION("default") { mongo_coll.aggregate(pipe, opts); REQUIRE(collection_aggregate_called); } - SECTION("Count Documents", "[collection::count_documents]") { - auto collection_count_called = false; - bool success = true; - std::int64_t expected_skip = 0; - std::int64_t expected_limit = 0; - bson_t const* expected_opts = nullptr; - - collection_count_documents->interpose([&](mongoc_collection_t*, - bson_t const* filter, - bson_t const* opts, - mongoc_read_prefs_t const*, - bson_t* reply, - bson_error_t* error) { - collection_count_called = true; - bson_init(reply); - REQUIRE(bson_get_data(filter) == filter_doc.view().data()); - bson_iter_t iter; - if (expected_skip) { - REQUIRE(bson_iter_init_find(&iter, opts, "skip")); - REQUIRE(bson_iter_int64(&iter) == expected_skip); - } - if (expected_limit) { - REQUIRE(bson_iter_init_find(&iter, opts, "limit")); - REQUIRE(bson_iter_int64(&iter) == expected_limit); - } - if (expected_opts) { - bson_t opts_without_skip_or_limit = BSON_INITIALIZER; - bson_copy_to_excluding_noinit(opts, &opts_without_skip_or_limit, "skip", "limit", nullptr); - REQUIRE(bson_equal(&opts_without_skip_or_limit, expected_opts)); - bson_destroy(&opts_without_skip_or_limit); - } + SECTION("options") { + opts.allow_disk_use(expected_allow_disk_use); + opts.batch_size(expected_batch_size); + opts.bypass_document_validation(expected_bypass_document_validation); + opts.collation(expected_collation.view()); + opts.comment(expected_comment["$comment"].get_value()); + opts.hint(expected_hint); + opts.let(expected_let.view()); + opts.max_time(std::chrono::milliseconds{expected_max_time_ms}); + opts.read_concern(read_concern); + opts.read_preference(expected_read_preference); + opts.write_concern(write_concern); - if (success) - return 123; + mongo_coll.aggregate(pipe, opts); - // The caller expects the bson_error_t to have been - // initialized by the call to count in the event of an - // error. - bson_set_error(error, MONGOC_ERROR_COMMAND, MONGOC_ERROR_COMMAND_INVALID_ARG, "expected error from mock"); + REQUIRE(collection_aggregate_called); + } +} - return -1; - }); +TEST_CASE("count_documents", "[mongocxx][v_noabi][collection]") { + MOCK_DATABASE; + MOCK_COLLECTION; // "mocked_collection.dummy_collection" - SECTION("Succeeds with defaults") { - REQUIRE_NOTHROW(mongo_coll.count_documents(filter_doc.view())); - REQUIRE(collection_count_called); - } + client mongo_client{uri{}}; + auto mongo_coll = mongo_client["mocked_collection"]["dummy_collection"]; + REQUIRE(mongo_coll); - SECTION("Succeeds with options") { - options::count opts; - opts.skip(expected_skip); - opts.limit(expected_limit); - REQUIRE_NOTHROW(mongo_coll.count_documents(filter_doc.view(), opts)); - REQUIRE(collection_count_called); + auto const filter_doc = make_document(kvp("_id", "wow"), kvp("foo", "bar")); + + auto collection_count_called = false; + bool success = true; + std::int64_t expected_skip = 0; + std::int64_t expected_limit = 0; + bson_t const* expected_opts = nullptr; + + collection_count_documents->interpose([&](mongoc_collection_t*, + bson_t const* filter, + bson_t const* opts, + mongoc_read_prefs_t const*, + bson_t* reply, + bson_error_t* error) { + collection_count_called = true; + bson_init(reply); + REQUIRE(bson_get_data(filter) == filter_doc.view().data()); + bson_iter_t iter; + if (expected_skip) { + REQUIRE(bson_iter_init_find(&iter, opts, "skip")); + REQUIRE(bson_iter_int64(&iter) == expected_skip); + } + if (expected_limit) { + REQUIRE(bson_iter_init_find(&iter, opts, "limit")); + REQUIRE(bson_iter_int64(&iter) == expected_limit); + } + if (expected_opts) { + bson_t opts_without_skip_or_limit = BSON_INITIALIZER; + bson_copy_to_excluding_noinit(opts, &opts_without_skip_or_limit, "skip", "limit", nullptr); + REQUIRE(bson_equal(&opts_without_skip_or_limit, expected_opts)); + bson_destroy(&opts_without_skip_or_limit); } - SECTION("Succeeds with hint") { - options::count opts; - hint index_hint("a_1"); - opts.hint(index_hint); + if (success) + return 123; - // set our expected_opts so we check against that - scoped_bson const cmd_opts{to_scoped_bson(make_document(kvp("hint", index_hint.to_value())))}; - expected_opts = cmd_opts.bson(); + // The caller expects the bson_error_t to have been + // initialized by the call to count in the event of an + // error. + bson_set_error(error, MONGOC_ERROR_COMMAND, MONGOC_ERROR_COMMAND_INVALID_ARG, "expected error from mock"); - REQUIRE_NOTHROW(mongo_coll.count_documents(filter_doc.view(), opts)); - REQUIRE(collection_count_called); - } + return -1; + }); - SECTION("Succeeds with read_prefs") { - options::count opts; - read_preference rp; - rp.mode(read_preference::read_mode::k_secondary); - opts.read_preference(rp); - REQUIRE_NOTHROW(mongo_coll.count_documents(filter_doc.view(), opts)); - REQUIRE(collection_count_called); - } + SECTION("Succeeds with defaults") { + REQUIRE_NOTHROW(mongo_coll.count_documents(filter_doc.view())); + REQUIRE(collection_count_called); + } - SECTION("Fails") { - success = false; - REQUIRE_THROWS_AS(mongo_coll.count_documents(filter_doc.view()), operation_exception); - REQUIRE(collection_count_called); - } + SECTION("Succeeds with options") { + options::count opts; + opts.skip(expected_skip); + opts.limit(expected_limit); + REQUIRE_NOTHROW(mongo_coll.count_documents(filter_doc.view(), opts)); + REQUIRE(collection_count_called); } - SECTION("Estimated Document Count", "[collection::estimated_document_count]") { - auto collection_estimated_document_count_called = false; - bool success = true; - bson_t const* expected_opts = nullptr; + SECTION("Succeeds with hint") { + options::count opts; + hint index_hint("a_1"); + opts.hint(index_hint); - collection_estimated_document_count->interpose([&](mongoc_collection_t*, - bson_t const* opts, - mongoc_read_prefs_t const*, - bson_t* reply, - bson_error_t* error) { + // set our expected_opts so we check against that + scoped_bson const cmd_opts{to_scoped_bson(make_document(kvp("hint", index_hint.to_value())))}; + expected_opts = cmd_opts.bson(); + + REQUIRE_NOTHROW(mongo_coll.count_documents(filter_doc.view(), opts)); + REQUIRE(collection_count_called); + } + + SECTION("Succeeds with read_prefs") { + options::count opts; + read_preference rp; + rp.mode(read_preference::read_mode::k_secondary); + opts.read_preference(rp); + REQUIRE_NOTHROW(mongo_coll.count_documents(filter_doc.view(), opts)); + REQUIRE(collection_count_called); + } + + SECTION("Fails") { + success = false; + REQUIRE_THROWS_AS(mongo_coll.count_documents(filter_doc.view()), operation_exception); + REQUIRE(collection_count_called); + } +} + +TEST_CASE("estimated_document_count", "[mongocxx][v_noabi][collection]") { + MOCK_DATABASE; + MOCK_COLLECTION; // "mocked_collection.dummy_collection" + + client mongo_client{uri{}}; + auto mongo_coll = mongo_client["mocked_collection"]["dummy_collection"]; + REQUIRE(mongo_coll); + + auto collection_estimated_document_count_called = false; + bool success = true; + bson_t const* expected_opts = nullptr; + + collection_estimated_document_count->interpose( + [&](mongoc_collection_t*, bson_t const* opts, mongoc_read_prefs_t const*, bson_t* reply, bson_error_t* error) { collection_estimated_document_count_called = true; bson_init(reply); if (expected_opts) { @@ -351,49 +362,54 @@ TEST_CASE("Collection", "[collection]") { return -1; }); - SECTION("Succeeds with defaults") { - REQUIRE_NOTHROW(mongo_coll.estimated_document_count()); - REQUIRE(collection_estimated_document_count_called); - } + SECTION("Succeeds with defaults") { + REQUIRE_NOTHROW(mongo_coll.estimated_document_count()); + REQUIRE(collection_estimated_document_count_called); + } - SECTION("Succeeds with options") { - options::estimated_document_count opts; - REQUIRE_NOTHROW(mongo_coll.estimated_document_count(opts)); - REQUIRE(collection_estimated_document_count_called); - } + SECTION("Succeeds with options") { + options::estimated_document_count opts; + REQUIRE_NOTHROW(mongo_coll.estimated_document_count(opts)); + REQUIRE(collection_estimated_document_count_called); + } - SECTION("Succeeds with read_prefs") { - options::estimated_document_count opts; - read_preference rp; - rp.mode(read_preference::read_mode::k_secondary); - opts.read_preference(rp); - REQUIRE_NOTHROW(mongo_coll.estimated_document_count(opts)); - REQUIRE(collection_estimated_document_count_called); - } + SECTION("Succeeds with read_prefs") { + options::estimated_document_count opts; + read_preference rp; + rp.mode(read_preference::read_mode::k_secondary); + opts.read_preference(rp); + REQUIRE_NOTHROW(mongo_coll.estimated_document_count(opts)); + REQUIRE(collection_estimated_document_count_called); + } - SECTION("Fails") { - success = false; - REQUIRE_THROWS_AS(mongo_coll.estimated_document_count(), operation_exception); - REQUIRE(collection_estimated_document_count_called); - } + SECTION("Fails") { + success = false; + REQUIRE_THROWS_AS(mongo_coll.estimated_document_count(), operation_exception); + REQUIRE(collection_estimated_document_count_called); } +} + +TEST_CASE("find", "[mongocxx][v_noabi][collection]") { + MOCK_DATABASE; + MOCK_COLLECTION; // "mocked_collection.dummy_collection" + + client mongo_client{uri{}}; + auto mongo_coll = mongo_client["mocked_collection"]["dummy_collection"]; + REQUIRE(mongo_coll); - SECTION("Find", "[collection::find]") { - auto collection_find_called = false; - auto find_doc = make_document(kvp("a", 1)); - auto doc = find_doc.view(); - bsoncxx::stdx::optional expected_allow_partial_results; - bsoncxx::stdx::optional expected_comment{}; - bsoncxx::stdx::optional expected_cursor_type{}; - bsoncxx::stdx::optional expected_hint{}; - bsoncxx::stdx::optional expected_no_cursor_timeout; - bsoncxx::stdx::optional expected_sort{}; - bsoncxx::stdx::optional expected_read_preference{}; - - collection_find_with_opts->interpose([&](mongoc_collection_t*, - bson_t const* filter, - bson_t const* opts, - mongoc_read_prefs_t const* read_prefs) { + auto collection_find_called = false; + auto find_doc = make_document(kvp("a", 1)); + auto doc = find_doc.view(); + bsoncxx::stdx::optional expected_allow_partial_results; + bsoncxx::stdx::optional expected_comment{}; + bsoncxx::stdx::optional expected_cursor_type{}; + bsoncxx::stdx::optional expected_hint{}; + bsoncxx::stdx::optional expected_no_cursor_timeout; + bsoncxx::stdx::optional expected_sort{}; + bsoncxx::stdx::optional expected_read_preference{}; + + collection_find_with_opts->interpose( + [&](mongoc_collection_t*, bson_t const* filter, bson_t const* opts, mongoc_read_prefs_t const* read_prefs) { collection_find_called = true; bsoncxx::document::view filter_view{bson_get_data(filter), filter->len}; @@ -446,546 +462,573 @@ TEST_CASE("Collection", "[collection]") { return cursor; }); - SECTION("find succeeds") { - REQUIRE_NOTHROW(mongo_coll.find(doc)); - REQUIRE(collection_find_called); - } - - SECTION("Succeeds with allow_partial_results") { - options::find opts; - expected_allow_partial_results = true; - opts.allow_partial_results(*expected_allow_partial_results); - - REQUIRE_NOTHROW(mongo_coll.find(doc, opts)); - REQUIRE(collection_find_called); - } + SECTION("find succeeds") { + REQUIRE_NOTHROW(mongo_coll.find(doc)); + REQUIRE(collection_find_called); + } - SECTION("Succeeds with comment") { - expected_comment.emplace("my comment"); - options::find opts; - opts.comment(*expected_comment); + SECTION("Succeeds with allow_partial_results") { + options::find opts; + expected_allow_partial_results = true; + opts.allow_partial_results(*expected_allow_partial_results); - REQUIRE_NOTHROW(mongo_coll.find(doc, opts)); - REQUIRE(collection_find_called); - } + REQUIRE_NOTHROW(mongo_coll.find(doc, opts)); + REQUIRE(collection_find_called); + } - SECTION("Succeeds with cursor type") { - options::find opts; - expected_cursor_type = mongocxx::cursor::type::k_tailable; - opts.cursor_type(*expected_cursor_type); + SECTION("Succeeds with comment") { + expected_comment.emplace("my comment"); + options::find opts; + opts.comment(*expected_comment); - REQUIRE_NOTHROW(mongo_coll.find(doc, opts)); - REQUIRE(collection_find_called); - } + REQUIRE_NOTHROW(mongo_coll.find(doc, opts)); + REQUIRE(collection_find_called); + } - SECTION("Succeeds with hint") { - options::find opts; - hint index_hint("a_1"); - expected_hint = index_hint.to_value(); - opts.hint(index_hint); + SECTION("Succeeds with cursor type") { + options::find opts; + expected_cursor_type = mongocxx::cursor::type::k_tailable; + opts.cursor_type(*expected_cursor_type); - REQUIRE_NOTHROW(mongo_coll.find(doc, opts)); - REQUIRE(collection_find_called); - } + REQUIRE_NOTHROW(mongo_coll.find(doc, opts)); + REQUIRE(collection_find_called); + } - SECTION("Succeeds with no_cursor_timeout") { - options::find opts; - expected_no_cursor_timeout = true; - opts.no_cursor_timeout(*expected_no_cursor_timeout); + SECTION("Succeeds with hint") { + options::find opts; + hint index_hint("a_1"); + expected_hint = index_hint.to_value(); + opts.hint(index_hint); - REQUIRE_NOTHROW(mongo_coll.find(doc, opts)); - REQUIRE(collection_find_called); - } + REQUIRE_NOTHROW(mongo_coll.find(doc, opts)); + REQUIRE(collection_find_called); + } - SECTION("Succeeds with sort") { - options::find opts{}; - auto sort_doc = make_document(kvp("x", -1)); - expected_sort = sort_doc.view(); - opts.sort(*expected_sort); - REQUIRE_NOTHROW(mongo_coll.find(doc, opts)); - REQUIRE(collection_find_called); - } + SECTION("Succeeds with no_cursor_timeout") { + options::find opts; + expected_no_cursor_timeout = true; + opts.no_cursor_timeout(*expected_no_cursor_timeout); - SECTION("Succeeds with read preference") { - options::find opts{}; - expected_read_preference.emplace(); - expected_read_preference->mode(read_preference::read_mode::k_secondary); - opts.read_preference(*expected_read_preference); + REQUIRE_NOTHROW(mongo_coll.find(doc, opts)); + REQUIRE(collection_find_called); + } - REQUIRE_NOTHROW(mongo_coll.find(doc, opts)); - REQUIRE(collection_find_called); - } + SECTION("Succeeds with sort") { + options::find opts{}; + auto sort_doc = make_document(kvp("x", -1)); + expected_sort = sort_doc.view(); + opts.sort(*expected_sort); + REQUIRE_NOTHROW(mongo_coll.find(doc, opts)); + REQUIRE(collection_find_called); } - SECTION("Writes", "[collection::writes]") { - auto expected_order_setting = false; - auto expect_set_bypass_document_validation_called = false; - auto expected_bypass_document_validation = false; - bsoncxx::stdx::optional expected_hint{}; - - auto modification_doc = make_document(kvp("cool", "wow"), kvp("foo", "bar")); - - auto perform_checks = [&]() { - REQUIRE(collection_create_bulk_operation_called); - REQUIRE( - expect_set_bypass_document_validation_called == bulk_operation_set_bypass_document_validation_called); - REQUIRE(bulk_operation_op_called); - REQUIRE(bulk_operation_destroy_called); - }; - - collection_create_bulk_operation_with_opts->interpose( - [&](mongoc_collection_t*, bson_t const* opts) -> mongoc_bulk_operation_t* { - bson_iter_t iter; - if (expected_order_setting) { - // If the write operation is expected to set "ordered": true, then it - // should *not* be included in the bulk operations, since that is the default. - REQUIRE(!bson_iter_init_find(&iter, opts, "ordered")); - } else { - REQUIRE(bson_iter_init_find(&iter, opts, "ordered")); - REQUIRE(BSON_ITER_HOLDS_BOOL(&iter)); - REQUIRE(!bson_iter_bool(&iter)); - } - collection_create_bulk_operation_called = true; - return nullptr; - }); + SECTION("Succeeds with read preference") { + options::find opts{}; + expected_read_preference.emplace(); + expected_read_preference->mode(read_preference::read_mode::k_secondary); + opts.read_preference(*expected_read_preference); - bulk_operation_set_bypass_document_validation->interpose([&](mongoc_bulk_operation_t*, bool bypass) { - bulk_operation_set_bypass_document_validation_called = true; - REQUIRE(expected_bypass_document_validation == bypass); - }); + REQUIRE_NOTHROW(mongo_coll.find(doc, opts)); + REQUIRE(collection_find_called); + } +} - bulk_operation_execute->interpose([&](mongoc_bulk_operation_t*, bson_t* reply, bson_error_t*) { - bulk_operation_execute_called = true; - bson_init(reply); - return 1; - }); +TEST_CASE("writes", "[mongocxx][v_noabi][collection]") { + MOCK_DATABASE; + MOCK_COLLECTION; // "mocked_collection.dummy_collection" + MOCK_BULK; - bulk_operation_destroy->interpose([&](mongoc_bulk_operation_t*) { bulk_operation_destroy_called = true; }); + client mongo_client{uri{}}; + auto mongo_coll = mongo_client["mocked_collection"]["dummy_collection"]; + REQUIRE(mongo_coll); - SECTION("Insert One", "[collection::insert_one]") { - expected_order_setting = true; - bulk_operation_insert_with_opts->interpose( - [&](mongoc_bulk_operation_t*, bson_t const* doc, bson_t const*, bson_error_t*) { - bulk_operation_op_called = true; - REQUIRE(bson_get_data(doc) == filter_doc.view().data()); - return true; - }); - - mongo_coll.insert_one(filter_doc.view()); - perform_checks(); - } + auto expected_order_setting = false; + auto expect_set_bypass_document_validation_called = false; + auto expected_bypass_document_validation = false; + bsoncxx::stdx::optional expected_hint{}; - SECTION("Insert One Bypassing Validation", "[collection::insert_one]") { - expected_order_setting = true; - bulk_operation_insert_with_opts->interpose( - [&](mongoc_bulk_operation_t*, bson_t const* doc, bson_t const*, bson_error_t*) { - bulk_operation_op_called = true; - REQUIRE(bson_get_data(doc) == filter_doc.view().data()); - return true; - }); + auto const filter_doc = make_document(kvp("_id", "wow"), kvp("foo", "bar")); + auto const modification_doc = make_document(kvp("cool", "wow"), kvp("foo", "bar")); - expect_set_bypass_document_validation_called = true; - SECTION("...set to false") { - expected_bypass_document_validation = false; - } - SECTION("...set to true") { - expected_bypass_document_validation = true; - } - options::insert opts{}; - opts.bypass_document_validation(expected_bypass_document_validation); - mongo_coll.insert_one(filter_doc.view(), opts); - perform_checks(); - } + auto perform_checks = [&]() { + REQUIRE(collection_create_bulk_operation_called); + REQUIRE(expect_set_bypass_document_validation_called == bulk_operation_set_bypass_document_validation_called); + REQUIRE(bulk_operation_op_called); + REQUIRE(bulk_operation_destroy_called); + }; - SECTION("Insert Many Ordered", "[collection::insert_many]") { - bulk_operation_insert_with_opts->interpose( - [&](mongoc_bulk_operation_t*, bson_t const* doc, bson_t const*, bson_error_t*) { - bulk_operation_op_called = true; - REQUIRE(bson_get_data(doc) == filter_doc.view().data()); - return true; - }); - - // The interposed collection_create_bulk_operation_with_opts validates this setting. - SECTION("...set to false") { - expected_order_setting = false; - } - SECTION("...set to true") { - expected_order_setting = true; + collection_create_bulk_operation_with_opts->interpose( + [&](mongoc_collection_t*, bson_t const* opts) -> mongoc_bulk_operation_t* { + bson_iter_t iter; + if (expected_order_setting) { + // If the write operation is expected to set "ordered": true, then it + // should *not* be included in the bulk operations, since that is the default. + REQUIRE(!bson_iter_init_find(&iter, opts, "ordered")); + } else { + REQUIRE(bson_iter_init_find(&iter, opts, "ordered")); + REQUIRE(BSON_ITER_HOLDS_BOOL(&iter)); + REQUIRE(!bson_iter_bool(&iter)); } - options::insert opts{}; - opts.ordered(expected_order_setting); - std::vector docs{}; - docs.push_back(filter_doc.view()); - mongo_coll.insert_many(docs, opts); - perform_checks(); - } + collection_create_bulk_operation_called = true; + return nullptr; + }); - SECTION("Update One", "[collection::update_one]") { - bool upsert_option = false; - expected_order_setting = true; + bulk_operation_set_bypass_document_validation->interpose([&](mongoc_bulk_operation_t*, bool bypass) { + bulk_operation_set_bypass_document_validation_called = true; + REQUIRE(expected_bypass_document_validation == bypass); + }); - bulk_operation_update_one_with_opts->interpose([&](mongoc_bulk_operation_t*, - bson_t const* query, - bson_t const* update, - bson_t const* options, - bson_error_t*) { - bulk_operation_op_called = true; - REQUIRE(bson_get_data(query) == filter_doc.view().data()); - REQUIRE(bson_get_data(update) == modification_doc.view().data()); + bulk_operation_execute->interpose([&](mongoc_bulk_operation_t*, bson_t* reply, bson_error_t*) { + bulk_operation_execute_called = true; + bson_init(reply); + return 1; + }); - bsoncxx::document::view options_view{bson_get_data(options), options->len}; + bulk_operation_destroy->interpose([&](mongoc_bulk_operation_t*) { bulk_operation_destroy_called = true; }); - bsoncxx::document::element upsert = options_view["upsert"]; - if (upsert_option) { - REQUIRE(upsert); - REQUIRE(upsert.type() == bsoncxx::type::k_bool); - REQUIRE(upsert.get_bool().value); - } else { - // Allow either no "upsert" option, or an "upsert" option set to false. - if (upsert) { - REQUIRE(upsert); - REQUIRE(upsert.type() == bsoncxx::type::k_bool); - REQUIRE(!upsert.get_bool().value); - } - } + SECTION("Insert One") { + expected_order_setting = true; + bulk_operation_insert_with_opts->interpose( + [&](mongoc_bulk_operation_t*, bson_t const* doc, bson_t const*, bson_error_t*) { + bulk_operation_op_called = true; + REQUIRE(bson_get_data(doc) == filter_doc.view().data()); + return true; + }); - if (expected_hint) { - REQUIRE(options_view["hint"].get_string() == expected_hint->get_string()); - } else { - REQUIRE(!options_view["hint"]); - } + mongo_coll.insert_one(filter_doc.view()); + perform_checks(); + } + SECTION("Insert One Bypassing Validation") { + expected_order_setting = true; + bulk_operation_insert_with_opts->interpose( + [&](mongoc_bulk_operation_t*, bson_t const* doc, bson_t const*, bson_error_t*) { + bulk_operation_op_called = true; + REQUIRE(bson_get_data(doc) == filter_doc.view().data()); return true; }); - options::update options; + expect_set_bypass_document_validation_called = true; + SECTION("...set to false") { + expected_bypass_document_validation = false; + } + SECTION("...set to true") { + expected_bypass_document_validation = true; + } + options::insert opts{}; + opts.bypass_document_validation(expected_bypass_document_validation); + mongo_coll.insert_one(filter_doc.view(), opts); + perform_checks(); + } - SECTION("Default Options") {} + SECTION("Insert Many Ordered") { + bulk_operation_insert_with_opts->interpose( + [&](mongoc_bulk_operation_t*, bson_t const* doc, bson_t const*, bson_error_t*) { + bulk_operation_op_called = true; + REQUIRE(bson_get_data(doc) == filter_doc.view().data()); + return true; + }); - SECTION("Upsert true") { - upsert_option = true; - expected_order_setting = true; - options.upsert(upsert_option); - } + // The interposed collection_create_bulk_operation_with_opts validates this setting. + SECTION("...set to false") { + expected_order_setting = false; + } + SECTION("...set to true") { + expected_order_setting = true; + } + options::insert opts{}; + opts.ordered(expected_order_setting); + std::vector docs{}; + docs.push_back(filter_doc.view()); + mongo_coll.insert_many(docs, opts); + perform_checks(); + } - SECTION("Upsert false") { - upsert_option = false; - expected_order_setting = true; - options.upsert(upsert_option); + SECTION("Update One") { + bool upsert_option = false; + expected_order_setting = true; + + bulk_operation_update_one_with_opts->interpose([&](mongoc_bulk_operation_t*, + bson_t const* query, + bson_t const* update, + bson_t const* options, + bson_error_t*) { + bulk_operation_op_called = true; + REQUIRE(bson_get_data(query) == filter_doc.view().data()); + REQUIRE(bson_get_data(update) == modification_doc.view().data()); + + bsoncxx::document::view options_view{bson_get_data(options), options->len}; + + bsoncxx::document::element upsert = options_view["upsert"]; + if (upsert_option) { + REQUIRE(upsert); + REQUIRE(upsert.type() == bsoncxx::type::k_bool); + REQUIRE(upsert.get_bool().value); + } else { + // Allow either no "upsert" option, or an "upsert" option set to false. + if (upsert) { + REQUIRE(upsert); + REQUIRE(upsert.type() == bsoncxx::type::k_bool); + REQUIRE(!upsert.get_bool().value); + } } - SECTION("With hint") { - hint index_hint("a_1"); - expected_hint = index_hint.to_value(); - options.hint(index_hint); + if (expected_hint) { + REQUIRE(options_view["hint"].get_string() == expected_hint->get_string()); + } else { + REQUIRE(!options_view["hint"]); } - SECTION("With bypass_document_validation") { - expect_set_bypass_document_validation_called = true; - expected_bypass_document_validation = true; - expected_order_setting = true; - options.bypass_document_validation(expected_bypass_document_validation); - } + return true; + }); - SECTION("Write Concern provided") { - options.write_concern(concern); - } + options::update options; + SECTION("Default Options") { mongo_coll.update_one(filter_doc.view(), modification_doc.view(), options); REQUIRE(bulk_operation_execute_called); perform_checks(); } - SECTION("Insert One Error", "[collection::insert_one]") { + SECTION("Upsert true") { + upsert_option = true; expected_order_setting = true; - bulk_operation_insert_with_opts->interpose( - [&](mongoc_bulk_operation_t*, bson_t const*, bson_t const*, bson_error_t* err) { - bulk_operation_op_called = true; - bson_set_error(err, MONGOC_ERROR_BSON, MONGOC_ERROR_BSON_INVALID, "err"); - return false; - }); - - REQUIRE_THROWS_AS(mongo_coll.insert_one(filter_doc.view()), mongocxx::logic_error); - REQUIRE(!bulk_operation_execute_called); + options.upsert(upsert_option); + + mongo_coll.update_one(filter_doc.view(), modification_doc.view(), options); + REQUIRE(bulk_operation_execute_called); perform_checks(); } - SECTION("Insert Many Error", "[collection::insert_many]") { + SECTION("Upsert false") { + upsert_option = false; expected_order_setting = true; - bulk_operation_insert_with_opts->interpose( - [&](mongoc_bulk_operation_t*, bson_t const*, bson_t const*, bson_error_t* err) { - bulk_operation_op_called = true; - bson_set_error(err, MONGOC_ERROR_BSON, MONGOC_ERROR_BSON_INVALID, "err"); - return false; - }); - - std::vector docs{}; - docs.push_back(filter_doc.view()); - expected_order_setting = true; - REQUIRE_THROWS_AS(mongo_coll.insert_many(docs), mongocxx::logic_error); - REQUIRE(!bulk_operation_execute_called); + options.upsert(upsert_option); + + mongo_coll.update_one(filter_doc.view(), modification_doc.view(), options); + REQUIRE(bulk_operation_execute_called); perform_checks(); } - SECTION("Update One Error", "[collection::update_one]") { - expected_order_setting = true; - bulk_operation_update_one_with_opts->interpose( - [&](mongoc_bulk_operation_t*, bson_t const*, bson_t const*, bson_t const*, bson_error_t* err) { - bulk_operation_op_called = true; - bson_set_error(err, MONGOC_ERROR_BSON, MONGOC_ERROR_BSON_INVALID, "err"); - return false; - }); - - REQUIRE_THROWS_AS(mongo_coll.update_one(filter_doc.view(), modification_doc.view()), mongocxx::logic_error); - REQUIRE(!bulk_operation_execute_called); + SECTION("With hint") { + hint index_hint("a_1"); + expected_hint = index_hint.to_value(); + options.hint(index_hint); + + mongo_coll.update_one(filter_doc.view(), modification_doc.view(), options); + REQUIRE(bulk_operation_execute_called); perform_checks(); } - SECTION("Update Many", "[collection::update_many]") { - bool upsert_option = false; + SECTION("With bypass_document_validation") { + expect_set_bypass_document_validation_called = true; + expected_bypass_document_validation = true; expected_order_setting = true; + options.bypass_document_validation(expected_bypass_document_validation); + + mongo_coll.update_one(filter_doc.view(), modification_doc.view(), options); + REQUIRE(bulk_operation_execute_called); + perform_checks(); + } - bulk_operation_update_many_with_opts->interpose([&](mongoc_bulk_operation_t*, - bson_t const* query, - bson_t const* update, - bson_t const* options, - bson_error_t*) { + SECTION("Write Concern provided") { + write_concern concern; + options.write_concern(concern); + + mongo_coll.update_one(filter_doc.view(), modification_doc.view(), options); + REQUIRE(bulk_operation_execute_called); + perform_checks(); + } + } + + SECTION("Insert One Error") { + expected_order_setting = true; + bulk_operation_insert_with_opts->interpose( + [&](mongoc_bulk_operation_t*, bson_t const*, bson_t const*, bson_error_t* err) { bulk_operation_op_called = true; - REQUIRE(bson_get_data(query) == filter_doc.view().data()); - REQUIRE(bson_get_data(update) == modification_doc.view().data()); + bson_set_error(err, MONGOC_ERROR_BSON, MONGOC_ERROR_BSON_INVALID, "err"); + return false; + }); - bsoncxx::document::view options_view{bson_get_data(options), options->len}; + REQUIRE_THROWS_AS(mongo_coll.insert_one(filter_doc.view()), mongocxx::logic_error); + REQUIRE(!bulk_operation_execute_called); + perform_checks(); + } - bsoncxx::document::element upsert = options_view["upsert"]; - if (upsert_option) { - REQUIRE(upsert); - REQUIRE(upsert.type() == bsoncxx::type::k_bool); - REQUIRE(upsert.get_bool().value); - } else { - // Allow either no "upsert" option, or an "upsert" option set to false. - if (upsert) { - REQUIRE(upsert); - REQUIRE(upsert.type() == bsoncxx::type::k_bool); - REQUIRE(!upsert.get_bool().value); - } - } + SECTION("Insert Many Error") { + expected_order_setting = true; + bulk_operation_insert_with_opts->interpose( + [&](mongoc_bulk_operation_t*, bson_t const*, bson_t const*, bson_error_t* err) { + bulk_operation_op_called = true; + bson_set_error(err, MONGOC_ERROR_BSON, MONGOC_ERROR_BSON_INVALID, "err"); + return false; + }); - if (expected_hint) { - REQUIRE(options_view["hint"].get_string() == expected_hint->get_string()); - } else { - REQUIRE(!options_view["hint"]); - } + std::vector docs{}; + docs.push_back(filter_doc.view()); + expected_order_setting = true; + REQUIRE_THROWS_AS(mongo_coll.insert_many(docs), mongocxx::logic_error); + REQUIRE(!bulk_operation_execute_called); + perform_checks(); + } - return true; + SECTION("Update One Error") { + expected_order_setting = true; + bulk_operation_update_one_with_opts->interpose( + [&](mongoc_bulk_operation_t*, bson_t const*, bson_t const*, bson_t const*, bson_error_t* err) { + bulk_operation_op_called = true; + bson_set_error(err, MONGOC_ERROR_BSON, MONGOC_ERROR_BSON_INVALID, "err"); + return false; }); - options::update options; + REQUIRE_THROWS_AS(mongo_coll.update_one(filter_doc.view(), modification_doc.view()), mongocxx::logic_error); + REQUIRE(!bulk_operation_execute_called); + perform_checks(); + } - SECTION("Default Options") { - upsert_option = false; + SECTION("Update Many") { + bool upsert_option = false; + expected_order_setting = true; + + bulk_operation_update_many_with_opts->interpose([&](mongoc_bulk_operation_t*, + bson_t const* query, + bson_t const* update, + bson_t const* options, + bson_error_t*) { + bulk_operation_op_called = true; + REQUIRE(bson_get_data(query) == filter_doc.view().data()); + REQUIRE(bson_get_data(update) == modification_doc.view().data()); + + bsoncxx::document::view options_view{bson_get_data(options), options->len}; + + bsoncxx::document::element upsert = options_view["upsert"]; + if (upsert_option) { + REQUIRE(upsert); + REQUIRE(upsert.type() == bsoncxx::type::k_bool); + REQUIRE(upsert.get_bool().value); + } else { + // Allow either no "upsert" option, or an "upsert" option set to false. + if (upsert) { + REQUIRE(upsert); + REQUIRE(upsert.type() == bsoncxx::type::k_bool); + REQUIRE(!upsert.get_bool().value); + } } - SECTION("Upsert true") { - upsert_option = true; - options.upsert(upsert_option); + if (expected_hint) { + REQUIRE(options_view["hint"].get_string() == expected_hint->get_string()); + } else { + REQUIRE(!options_view["hint"]); } - SECTION("Upsert false") { - upsert_option = false; - options.upsert(upsert_option); - } + return true; + }); - SECTION("With hint") { - hint index_hint("a_1"); - expected_hint = index_hint.to_value(); - options.hint(index_hint); - } + options::update options; - mongo_coll.update_many(filter_doc.view(), modification_doc.view(), options); - REQUIRE(bulk_operation_execute_called); - perform_checks(); + SECTION("Default Options") { + upsert_option = false; } - SECTION("Update Many Error", "[collection::update_many]") { - expected_order_setting = true; - bulk_operation_update_many_with_opts->interpose( - [&](mongoc_bulk_operation_t*, bson_t const*, bson_t const*, bson_t const*, bson_error_t* err) { - bulk_operation_op_called = true; - bson_set_error(err, MONGOC_ERROR_BSON, MONGOC_ERROR_BSON_INVALID, "err"); - return false; - }); - - REQUIRE_THROWS_AS( - mongo_coll.update_many(filter_doc.view(), modification_doc.view()), mongocxx::logic_error); - REQUIRE(!bulk_operation_execute_called); - perform_checks(); + SECTION("Upsert true") { + upsert_option = true; + options.upsert(upsert_option); } - SECTION("Replace One", "[collection::replace_one]") { - bool upsert_option = false; - expected_order_setting = true; + SECTION("Upsert false") { + upsert_option = false; + options.upsert(upsert_option); + } + + SECTION("With hint") { + hint index_hint("a_1"); + expected_hint = index_hint.to_value(); + options.hint(index_hint); + } + + mongo_coll.update_many(filter_doc.view(), modification_doc.view(), options); + REQUIRE(bulk_operation_execute_called); + perform_checks(); + } - bulk_operation_replace_one_with_opts->interpose([&](mongoc_bulk_operation_t*, - bson_t const* query, - bson_t const* update, - bson_t const* options, - bson_error_t*) { + SECTION("Update Many Error") { + expected_order_setting = true; + bulk_operation_update_many_with_opts->interpose( + [&](mongoc_bulk_operation_t*, bson_t const*, bson_t const*, bson_t const*, bson_error_t* err) { bulk_operation_op_called = true; - REQUIRE(bson_get_data(query) == filter_doc.view().data()); - REQUIRE(bson_get_data(update) == modification_doc.view().data()); + bson_set_error(err, MONGOC_ERROR_BSON, MONGOC_ERROR_BSON_INVALID, "err"); + return false; + }); - bsoncxx::document::view options_view{bson_get_data(options), options->len}; + REQUIRE_THROWS_AS(mongo_coll.update_many(filter_doc.view(), modification_doc.view()), mongocxx::logic_error); + REQUIRE(!bulk_operation_execute_called); + perform_checks(); + } - bsoncxx::document::element upsert = options_view["upsert"]; - if (upsert_option) { + SECTION("Replace One") { + bool upsert_option = false; + expected_order_setting = true; + + bulk_operation_replace_one_with_opts->interpose([&](mongoc_bulk_operation_t*, + bson_t const* query, + bson_t const* update, + bson_t const* options, + bson_error_t*) { + bulk_operation_op_called = true; + REQUIRE(bson_get_data(query) == filter_doc.view().data()); + REQUIRE(bson_get_data(update) == modification_doc.view().data()); + + bsoncxx::document::view options_view{bson_get_data(options), options->len}; + + bsoncxx::document::element upsert = options_view["upsert"]; + if (upsert_option) { + REQUIRE(upsert); + REQUIRE(upsert.type() == bsoncxx::type::k_bool); + REQUIRE(upsert.get_bool().value); + } else { + // Allow either no "upsert" option, or an "upsert" option set to false. + if (upsert) { REQUIRE(upsert); REQUIRE(upsert.type() == bsoncxx::type::k_bool); - REQUIRE(upsert.get_bool().value); - } else { - // Allow either no "upsert" option, or an "upsert" option set to false. - if (upsert) { - REQUIRE(upsert); - REQUIRE(upsert.type() == bsoncxx::type::k_bool); - REQUIRE(!upsert.get_bool().value); - } + REQUIRE(!upsert.get_bool().value); } + } + + if (expected_hint) { + REQUIRE(options_view["hint"].get_string() == expected_hint->get_string()); + } else { + REQUIRE(!options_view["hint"]); + } + + return true; + }); + + options::replace options; + + SECTION("Default Options") { + upsert_option = false; + } + + SECTION("Upsert true") { + upsert_option = true; + options.upsert(upsert_option); + } + + SECTION("Upsert false") { + upsert_option = false; + options.upsert(upsert_option); + } + + SECTION("With hint") { + hint index_hint("a_1"); + expected_hint = index_hint.to_value(); + options.hint(index_hint); + } + + mongo_coll.replace_one(filter_doc.view(), modification_doc.view(), options); + REQUIRE(bulk_operation_execute_called); + perform_checks(); + } + + SECTION("Replace One Error") { + expected_order_setting = true; + bulk_operation_replace_one_with_opts->interpose( + [&](mongoc_bulk_operation_t*, bson_t const*, bson_t const*, bson_t const*, bson_error_t* err) { + bulk_operation_op_called = true; + bson_set_error(err, MONGOC_ERROR_BSON, MONGOC_ERROR_BSON_INVALID, "err"); + return false; + }); + REQUIRE_THROWS_AS(mongo_coll.replace_one(filter_doc.view(), modification_doc.view()), mongocxx::logic_error); + REQUIRE(!bulk_operation_execute_called); + perform_checks(); + } + + SECTION("Delete One") { + expected_order_setting = true; + bulk_operation_remove_one_with_opts->interpose( + [&](mongoc_bulk_operation_t*, bson_t const* doc, bson_t const* options, bson_error_t*) { + bulk_operation_op_called = true; + REQUIRE(bson_get_data(doc) == filter_doc.view().data()); + + bsoncxx::document::view options_view{bson_get_data(options), options->len}; if (expected_hint) { + CAPTURE(to_json(options_view)); REQUIRE(options_view["hint"].get_string() == expected_hint->get_string()); } else { REQUIRE(!options_view["hint"]); } - return true; }); - options::replace options; - - SECTION("Default Options") { - upsert_option = false; - } - - SECTION("Upsert true") { - upsert_option = true; - options.upsert(upsert_option); - } - - SECTION("Upsert false") { - upsert_option = false; - options.upsert(upsert_option); - } + options::delete_options options; + SECTION("With hint") { + hint index_hint("a_1"); + expected_hint = index_hint.to_value(); + options.hint(index_hint); + } - SECTION("With hint") { - hint index_hint("a_1"); - expected_hint = index_hint.to_value(); - options.hint(index_hint); - } + mongo_coll.delete_one(filter_doc.view(), options); + REQUIRE(bulk_operation_execute_called); + perform_checks(); + } - mongo_coll.replace_one(filter_doc.view(), modification_doc.view(), options); - REQUIRE(bulk_operation_execute_called); - perform_checks(); - } + SECTION("Delete One Error") { + expected_order_setting = true; + bulk_operation_remove_one_with_opts->interpose( + [&](mongoc_bulk_operation_t*, bson_t const*, bson_t const*, bson_error_t* err) { + bulk_operation_op_called = true; + bson_set_error(err, MONGOC_ERROR_BSON, MONGOC_ERROR_BSON_INVALID, "err"); + return false; + }); - SECTION("Replace One Error", "[collection::update_one]") { - expected_order_setting = true; - bulk_operation_replace_one_with_opts->interpose( - [&](mongoc_bulk_operation_t*, bson_t const*, bson_t const*, bson_t const*, bson_error_t* err) { - bulk_operation_op_called = true; - bson_set_error(err, MONGOC_ERROR_BSON, MONGOC_ERROR_BSON_INVALID, "err"); - return false; - }); - - REQUIRE_THROWS_AS( - mongo_coll.replace_one(filter_doc.view(), modification_doc.view()), mongocxx::logic_error); - REQUIRE(!bulk_operation_execute_called); - perform_checks(); - } + REQUIRE_THROWS_AS(mongo_coll.delete_one(filter_doc.view()), mongocxx::logic_error); + REQUIRE(!bulk_operation_execute_called); + perform_checks(); + } - SECTION("Delete One", "[collection::delete_one]") { - expected_order_setting = true; - bulk_operation_remove_one_with_opts->interpose( - [&](mongoc_bulk_operation_t*, bson_t const* doc, bson_t const* options, bson_error_t*) { - bulk_operation_op_called = true; - REQUIRE(bson_get_data(doc) == filter_doc.view().data()); - - bsoncxx::document::view options_view{bson_get_data(options), options->len}; - if (expected_hint) { - CAPTURE(to_json(options_view)); - REQUIRE(options_view["hint"].get_string() == expected_hint->get_string()); - } else { - REQUIRE(!options_view["hint"]); - } - return true; - }); - - options::delete_options options; - SECTION("With hint") { - hint index_hint("a_1"); - expected_hint = index_hint.to_value(); - options.hint(index_hint); - } + SECTION("Delete Many") { + expected_order_setting = true; + bulk_operation_remove_many_with_opts->interpose( + [&](mongoc_bulk_operation_t*, bson_t const* doc, bson_t const* options, bson_error_t*) { + bulk_operation_op_called = true; + REQUIRE(bson_get_data(doc) == filter_doc.view().data()); - mongo_coll.delete_one(filter_doc.view(), options); - REQUIRE(bulk_operation_execute_called); - perform_checks(); - } + bsoncxx::document::view options_view{bson_get_data(options), options->len}; + if (expected_hint) { + CAPTURE(to_json(options_view)); + REQUIRE(options_view["hint"].get_string() == expected_hint->get_string()); + } else { + REQUIRE(!options_view["hint"]); + } + return true; + }); - SECTION("Delete One Error", "[collection::delete_one]") { - expected_order_setting = true; - bulk_operation_remove_one_with_opts->interpose( - [&](mongoc_bulk_operation_t*, bson_t const*, bson_t const*, bson_error_t* err) { - bulk_operation_op_called = true; - bson_set_error(err, MONGOC_ERROR_BSON, MONGOC_ERROR_BSON_INVALID, "err"); - return false; - }); - - REQUIRE_THROWS_AS(mongo_coll.delete_one(filter_doc.view()), mongocxx::logic_error); - REQUIRE(!bulk_operation_execute_called); - perform_checks(); + options::delete_options options; + SECTION("With hint") { + hint index_hint("a_1"); + expected_hint = index_hint.to_value(); + options.hint(index_hint); } - SECTION("Delete Many", "[collection::delete_many]") { - expected_order_setting = true; - bulk_operation_remove_many_with_opts->interpose( - [&](mongoc_bulk_operation_t*, bson_t const* doc, bson_t const* options, bson_error_t*) { - bulk_operation_op_called = true; - REQUIRE(bson_get_data(doc) == filter_doc.view().data()); - - bsoncxx::document::view options_view{bson_get_data(options), options->len}; - if (expected_hint) { - CAPTURE(to_json(options_view)); - REQUIRE(options_view["hint"].get_string() == expected_hint->get_string()); - } else { - REQUIRE(!options_view["hint"]); - } - return true; - }); - - options::delete_options options; - SECTION("With hint") { - hint index_hint("a_1"); - expected_hint = index_hint.to_value(); - options.hint(index_hint); - } + mongo_coll.delete_many(filter_doc.view(), options); + REQUIRE(bulk_operation_execute_called); + perform_checks(); + } - mongo_coll.delete_many(filter_doc.view(), options); - REQUIRE(bulk_operation_execute_called); - perform_checks(); - } + SECTION("Delete Many Error") { + expected_order_setting = true; + bulk_operation_remove_many_with_opts->interpose( + [&](mongoc_bulk_operation_t*, bson_t const*, bson_t const*, bson_error_t* err) { + bulk_operation_op_called = true; + bson_set_error(err, MONGOC_ERROR_BSON, MONGOC_ERROR_BSON_INVALID, "err"); + return false; + }); - SECTION("Delete Many Error", "[collection::delete_one]") { - expected_order_setting = true; - bulk_operation_remove_many_with_opts->interpose( - [&](mongoc_bulk_operation_t*, bson_t const*, bson_t const*, bson_error_t* err) { - bulk_operation_op_called = true; - bson_set_error(err, MONGOC_ERROR_BSON, MONGOC_ERROR_BSON_INVALID, "err"); - return false; - }); - - REQUIRE_THROWS_AS(mongo_coll.delete_many(filter_doc.view()), mongocxx::logic_error); - REQUIRE(!bulk_operation_execute_called); - perform_checks(); - } + REQUIRE_THROWS_AS(mongo_coll.delete_many(filter_doc.view()), mongocxx::logic_error); + REQUIRE(!bulk_operation_execute_called); + perform_checks(); } } + } // namespace