From 20b3e4d770fa2b906a7ceb970240e7431c02cd51 Mon Sep 17 00:00:00 2001 From: Matej Kenda Date: Sat, 29 Nov 2025 16:41:05 +0100 Subject: [PATCH] enh(MongoDB) More tests. --- MongoDB/include/Poco/MongoDB/Binary.h | 5 +- MongoDB/src/Binary.cpp | 6 + MongoDB/src/ObjectId.cpp | 11 +- MongoDB/testsuite/src/BSONTest.cpp | 1274 ++++++++++++++++++++ MongoDB/testsuite/src/BSONTest.h | 94 ++ MongoDB/testsuite/src/MongoDBTest.cpp | 47 +- MongoDB/testsuite/src/MongoDBTest.h | 2 - MongoDB/testsuite/src/MongoDBTestOpMsg.cpp | 99 +- MongoDB/testsuite/src/MongoDBTestSuite.cpp | 9 +- 9 files changed, 1423 insertions(+), 124 deletions(-) create mode 100644 MongoDB/testsuite/src/BSONTest.cpp create mode 100644 MongoDB/testsuite/src/BSONTest.h diff --git a/MongoDB/include/Poco/MongoDB/Binary.h b/MongoDB/include/Poco/MongoDB/Binary.h index 2b654b214..06dd1e7a0 100644 --- a/MongoDB/include/Poco/MongoDB/Binary.h +++ b/MongoDB/include/Poco/MongoDB/Binary.h @@ -58,10 +58,13 @@ public: Binary(const UUID& uuid); /// Creates a Binary containing an UUID. + Binary(const char* data, unsigned char subtype = 0); + /// Creates a Binary with the contents of the given C-string and the given subtype. + Binary(const std::string& data, unsigned char subtype = 0); /// Creates a Binary with the contents of the given string and the given subtype. - Binary(const void* data, Poco::Int32 size, unsigned char subtype = 0); + Binary(const void* data, Poco::Int32 size, unsigned char subtype); /// Creates a Binary with the contents of the given buffer and the given subtype. virtual ~Binary(); diff --git a/MongoDB/src/Binary.cpp b/MongoDB/src/Binary.cpp index 95bf8bc55..2b675128b 100644 --- a/MongoDB/src/Binary.cpp +++ b/MongoDB/src/Binary.cpp @@ -49,6 +49,12 @@ Binary::Binary(const UUID& uuid): } +Binary::Binary(const char* data, unsigned char subtype): + _buffer(reinterpret_cast(data), std::strlen(data)), + _subtype(subtype) +{ +} + Binary::Binary(const std::string& data, unsigned char subtype): _buffer(reinterpret_cast(data.data()), data.size()), diff --git a/MongoDB/src/ObjectId.cpp b/MongoDB/src/ObjectId.cpp index cc6344ac0..71f2e8343 100644 --- a/MongoDB/src/ObjectId.cpp +++ b/MongoDB/src/ObjectId.cpp @@ -14,7 +14,9 @@ #include "Poco/MongoDB/ObjectId.h" #include "Poco/Format.h" +#include "Poco/Exception.h" #include +#include namespace Poco { @@ -29,11 +31,18 @@ ObjectId::ObjectId() ObjectId::ObjectId(const std::string& id) { - poco_assert_dbg(id.size() == 24); + if (id.size() != 24) + throw Poco::InvalidArgumentException("ObjectId string must be exactly 24 hexadecimal characters"); const char* p = id.c_str(); for (std::size_t i = 0; i < 12; ++i) { + // Validate that both characters are valid hex digits + if (!std::isxdigit(static_cast(p[0])) || + !std::isxdigit(static_cast(p[1]))) + { + throw Poco::InvalidArgumentException("ObjectId string contains invalid hexadecimal characters"); + } _id[i] = fromHex(p); p += 2; } diff --git a/MongoDB/testsuite/src/BSONTest.cpp b/MongoDB/testsuite/src/BSONTest.cpp new file mode 100644 index 000000000..cf6d279a5 --- /dev/null +++ b/MongoDB/testsuite/src/BSONTest.cpp @@ -0,0 +1,1274 @@ +// +// BSONTest.cpp +// +// Copyright (c) 2004-2025, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "BSONTest.h" +#include "CppUnit/TestCaller.h" +#include "CppUnit/TestSuite.h" +#include "Poco/MongoDB/Document.h" +#include "Poco/MongoDB/Array.h" +#include "Poco/MongoDB/Binary.h" +#include "Poco/MongoDB/ObjectId.h" +#include "Poco/MongoDB/RegularExpression.h" +#include "Poco/MongoDB/JavaScriptCode.h" +#include "Poco/DateTime.h" +#include "Poco/UUIDGenerator.h" +#include +#include + + +using namespace Poco::MongoDB; +using namespace std::string_literals; + + +BSONTest::BSONTest(const std::string& name): + CppUnit::TestCase("BSON") +{ +} + + +BSONTest::~BSONTest() +{ +} + + +void BSONTest::setUp() +{ +} + + +void BSONTest::tearDown() +{ +} + + +void BSONTest::testDocumentAddGet() +{ + Document::Ptr doc = new Document(); + + // Test adding and getting various types + doc->add("string"s, "test"s); + doc->add("int32"s, static_cast(42)); + doc->add("int64"s, static_cast(9876543210LL)); + doc->add("double"s, 3.14159); + doc->add("bool"s, true); + + assertEqual(doc->get("string"), "test"); + assertEqual(doc->get("int32"), 42); + assertEqual(doc->get("int64"), 9876543210LL); + assertEqual(doc->get("double"), 3.14159); + assertEqual(doc->get("bool"), true); + + // Test get with default value + assertEqual(doc->get("nonexistent", "default"), "default"); + assertEqual(doc->get("nonexistent", 99), 99); +} + + +void BSONTest::testDocumentExists() +{ + Document::Ptr doc = new Document(); + doc->add("field1"s, "value1"s); + doc->add("field2"s, 123); + + assertTrue(doc->exists("field1")); + assertTrue(doc->exists("field2")); + assertFalse(doc->exists("field3")); + assertFalse(doc->exists("")); +} + + +void BSONTest::testDocumentRemove() +{ + Document::Ptr doc = new Document(); + doc->add("field1"s, "value1"s); + doc->add("field2"s, "value2"s); + doc->add("field3"s, "value3"s); + + assertEqual(doc->size(), 3); + assertTrue(doc->exists("field2")); + + assertTrue(doc->remove("field2"s)); + assertEqual(doc->size(), 2); + assertFalse(doc->exists("field2")); + + // Try to remove non-existent field + assertFalse(doc->remove("field2"s)); + assertFalse(doc->remove("nonexistent"s)); + + // Remaining fields should still exist + assertTrue(doc->exists("field1")); + assertTrue(doc->exists("field3")); +} + + +void BSONTest::testDocumentClear() +{ + Document::Ptr doc = new Document(); + doc->add("field1"s, "value1"s); + doc->add("field2"s, 123); + doc->add("field3"s, true); + + assertEqual(doc->size(), 3); + assertFalse(doc->empty()); + + doc->clear(); + + assertEqual(doc->size(), 0); + assertTrue(doc->empty()); + assertFalse(doc->exists("field1")); + assertFalse(doc->exists("field2")); + assertFalse(doc->exists("field3")); +} + + +void BSONTest::testDocumentSize() +{ + Document::Ptr doc = new Document(); + assertEqual(doc->size(), 0); + + doc->add("field1"s, "value1"s); + assertEqual(doc->size(), 1); + + doc->add("field2"s, 123); + assertEqual(doc->size(), 2); + + doc->add("field3"s, true); + assertEqual(doc->size(), 3); + + doc->remove("field2"s); + assertEqual(doc->size(), 2); + + doc->clear(); + assertEqual(doc->size(), 0); +} + + +void BSONTest::testDocumentElementNames() +{ + Document::Ptr doc = new Document(); + doc->add("field1"s, "value1"s); + doc->add("field2"s, 123); + doc->add("field3"s, true); + + std::vector names; + doc->elementNames(names); + + assertEqual(names.size(), 3); + assertTrue(std::find(names.begin(), names.end(), "field1") != names.end()); + assertTrue(std::find(names.begin(), names.end(), "field2") != names.end()); + assertTrue(std::find(names.begin(), names.end(), "field3") != names.end()); +} + + +void BSONTest::testNestedDocuments() +{ + Document::Ptr doc = new Document(); + doc->add("name"s, "John"s); + + // Create nested document + Document::Ptr address = new Document(); + address->add("street"s, "Main St"s); + address->add("number"s, static_cast(123)); + address->add("city"s, "New York"s); + + doc->add("address"s, address); + + // Verify nested document + assertTrue(doc->exists("address")); + Document::Ptr retrievedAddress = doc->get("address"); + assertFalse(retrievedAddress.isNull()); + assertEqual(retrievedAddress->get("street"), "Main St"); + assertEqual(retrievedAddress->get("number"), 123); + assertEqual(retrievedAddress->get("city"), "New York"); + + // Test addNewDocument + Document& contact = doc->addNewDocument("contact"); + contact.add("email"s, "john@example.com"s); + contact.add("phone"s, "+1234567890"s); + + assertTrue(doc->exists("contact")); + Document::Ptr retrievedContact = doc->get("contact"); + assertEqual(retrievedContact->get("email"), "john@example.com"); + assertEqual(retrievedContact->get("phone"), "+1234567890"); +} + + +void BSONTest::testDuplicateDocumentMembers() +{ + Document::Ptr doc = new Document(); + + // Add duplicate field names + doc->add("field"s, "first"s); + doc->add("field"s, "second"s); + doc->add("field"s, "third"s); + + // The last value should be returned when getting by name + // (due to hash map overwriting) + assertEqual(doc->get("field"), "third"); + + // Size should reflect all elements including duplicates + assertEqual(doc->size(), 3); + + // exists should return true + assertTrue(doc->exists("field")); + + // Removing should remove from both map and vector + assertTrue(doc->remove("field"s)); + + // After removal, exists should return false + assertFalse(doc->exists("field")); + + // Size should be reduced by 1 (only one element removed from vector) + assertEqual(doc->size(), 2); +} + + +void BSONTest::testArray() +{ + Array::Ptr arr = new Array(); + + arr->add("First"s); + + Poco::DateTime birthdate; + birthdate.assign(1969, 3, 9); + arr->add(birthdate.timestamp()); + + arr->add(static_cast(1993)); + arr->add(false); + + // Document-style interface + arr->add("4", "12.4E"); + + assertEqual(arr->size(), 5); + assertTrue(arr->exists("0")); + assertTrue(arr->exists("1")); + assertTrue(arr->exists("2")); + assertTrue(arr->exists("3")); + assertTrue(arr->exists("4")); + assertFalse(arr->exists("5")); + + assertEqual(arr->get(0), "First"); + assertEqual(arr->get(1).raw(), birthdate.timestamp().raw()); + assertEqual(arr->get(2), 1993); + assertEqual(arr->get(3), false); + assertEqual(arr->get(4), "12.4E"); + + // Document-style interface + assertEqual(arr->get("2"), 1993); + assertEqual(arr->get("4"), "12.4E"); +} + + +void BSONTest::testArrayIndexAccess() +{ + Array::Ptr arr = new Array(); + + arr->add("zero"s); + arr->add("one"s); + arr->add("two"s); + + assertEqual(arr->size(), 3); + assertEqual(arr->get(0), "zero"); + assertEqual(arr->get(1), "one"); + assertEqual(arr->get(2), "two"); + + // Test with default value + assertEqual(arr->get(3, "default"), "default"); + assertEqual(arr->get(10, "default"), "default"); + + // Test isType + assertTrue(arr->isType(0)); + assertTrue(arr->isType(1)); + assertFalse(arr->isType(0)); +} + + +void BSONTest::testArrayNested() +{ + Document::Ptr doc = new Document(); + + // Create nested array using addNewArray + Array& tags = doc->addNewArray("tags"); + tags.add("mongodb"s); + tags.add("database"s); + tags.add("nosql"s); + + assertTrue(doc->exists("tags")); + Array::Ptr retrievedTags = doc->get("tags"); + assertFalse(retrievedTags.isNull()); + assertEqual(retrievedTags->size(), 3); + assertEqual(retrievedTags->get(0), "mongodb"); + assertEqual(retrievedTags->get(1), "database"); + assertEqual(retrievedTags->get(2), "nosql"); + + // Create array with mixed types + Array::Ptr mixed = new Array(); + mixed->add("string"s); + mixed->add(static_cast(42)); + mixed->add(3.14); + mixed->add(true); + + doc->add("mixed", mixed); + + Array::Ptr retrievedMixed = doc->get("mixed"); + assertEqual(retrievedMixed->size(), 4); + assertEqual(retrievedMixed->get(0), "string"); + assertEqual(retrievedMixed->get(1), 42); + assertEqual(retrievedMixed->get(2), 3.14); + assertEqual(retrievedMixed->get(3), true); +} + + +void BSONTest::testDouble() +{ + Document::Ptr doc = new Document(); + + doc->add("pi", 3.14159265359); + doc->add("e", 2.71828182846); + doc->add("zero", 0.0); + doc->add("negative", -123.456); + doc->add("large", 1.7976931348623157e+308); + doc->add("small", 2.2250738585072014e-308); + + assertEqual(doc->get("pi"), 3.14159265359); + assertEqual(doc->get("e"), 2.71828182846); + assertEqual(doc->get("zero"), 0.0); + assertEqual(doc->get("negative"), -123.456); + assertEqual(doc->get("large"), 1.7976931348623157e+308); + assertEqual(doc->get("small"), 2.2250738585072014e-308); + + assertTrue(doc->isType("pi")); + assertFalse(doc->isType("pi")); +} + + +void BSONTest::testString() +{ + Document::Ptr doc = new Document(); + + doc->add("empty", ""s); + doc->add("simple", "hello"s); + doc->add("withSpaces", "hello world"s); + doc->add("withSpecial", "!@#$%^&*()"s); + doc->add("withNewline", "line1\nline2"s); + doc->add("withTab", "col1\tcol2"s); + doc->add("unicode", "Hello 世界"s); + + // Using const char* overload + doc->add("literal", "test"); + + assertEqual(doc->get("empty"), ""); + assertEqual(doc->get("simple"), "hello"); + assertEqual(doc->get("withSpaces"), "hello world"); + assertEqual(doc->get("withSpecial"), "!@#$%^&*()"); + assertEqual(doc->get("withNewline"), "line1\nline2"); + assertEqual(doc->get("withTab"), "col1\tcol2"); + assertEqual(doc->get("unicode"), "Hello 世界"); + assertEqual(doc->get("literal"), "test"); + + assertTrue(doc->isType("simple")); +} + + +void BSONTest::testBool() +{ + Document::Ptr doc = new Document(); + + doc->add("true", true); + doc->add("false", false); + + assertEqual(doc->get("true"), true); + assertEqual(doc->get("false"), false); + + assertTrue(doc->isType("true")); + assertTrue(doc->isType("false")); + assertFalse(doc->isType("true")); +} + + +void BSONTest::testInt32() +{ + Document::Ptr doc = new Document(); + + doc->add("zero", static_cast(0)); + doc->add("positive", static_cast(12345)); + doc->add("negative", static_cast(-12345)); + doc->add("max", std::numeric_limits::max()); + doc->add("min", std::numeric_limits::min()); + + assertEqual(doc->get("zero"), 0); + assertEqual(doc->get("positive"), 12345); + assertEqual(doc->get("negative"), -12345); + assertEqual(doc->get("max"), std::numeric_limits::max()); + assertEqual(doc->get("min"), std::numeric_limits::min()); + + assertTrue(doc->isType("zero")); + assertFalse(doc->isType("zero")); + assertFalse(doc->isType("zero")); +} + + +void BSONTest::testInt64() +{ + Document::Ptr doc = new Document(); + + doc->add("zero", static_cast(0)); + doc->add("positive", static_cast(9876543210LL)); + doc->add("negative", static_cast(-9876543210LL)); + doc->add("max", std::numeric_limits::max()); + doc->add("min", std::numeric_limits::min()); + + assertEqual(doc->get("zero"), 0); + assertEqual(doc->get("positive"), 9876543210LL); + assertEqual(doc->get("negative"), -9876543210LL); + assertEqual(doc->get("max"), std::numeric_limits::max()); + assertEqual(doc->get("min"), std::numeric_limits::min()); + + assertTrue(doc->isType("zero")); + assertFalse(doc->isType("zero")); + + // Test getInteger - should handle Int32, Int64, and double + doc->add("int32val", static_cast(42)); + doc->add("int64val", static_cast(9876543210LL)); + doc->add("doubleval", 123.0); + + assertEqual(doc->getInteger("int32val"), 42); + assertEqual(doc->getInteger("int64val"), 9876543210LL); + assertEqual(doc->getInteger("doubleval"), 123); +} + + +void BSONTest::testTimestamp() +{ + Document::Ptr doc = new Document(); + + Poco::Timestamp now; + Poco::DateTime dt; + dt.assign(2023, 6, 15, 10, 30, 45); + Poco::Timestamp specificTime = dt.timestamp(); + + doc->add("now", now); + doc->add("specific", specificTime); + + Poco::Timestamp retrievedNow = doc->get("now"); + Poco::Timestamp retrievedSpecific = doc->get("specific"); + + assertEqual(retrievedNow.epochMicroseconds(), now.epochMicroseconds()); + assertEqual(retrievedSpecific.epochMicroseconds(), specificTime.epochMicroseconds()); + + assertTrue(doc->isType("now")); + assertFalse(doc->isType("now")); +} + + +void BSONTest::testNull() +{ + Document::Ptr doc = new Document(); + + doc->add("nullField", NullValue()); + + assertTrue(doc->exists("nullField")); + assertTrue(doc->isType("nullField")); + assertFalse(doc->isType("nullField")); + assertFalse(doc->isType("nullField")); +} + + +void BSONTest::testBSONTimestamp() +{ + Document::Ptr doc = new Document(); + + BSONTimestamp ts1; + ts1.ts = Poco::Timestamp(); + ts1.inc = 1; + + BSONTimestamp ts2; + Poco::DateTime dt; + dt.assign(2023, 6, 15, 10, 30, 45); + ts2.ts = dt.timestamp(); + ts2.inc = 42; + + doc->add("ts1", ts1); + doc->add("ts2", ts2); + + BSONTimestamp retrieved1 = doc->get("ts1"); + BSONTimestamp retrieved2 = doc->get("ts2"); + + assertEqual(retrieved1.ts.epochMicroseconds(), ts1.ts.epochMicroseconds()); + assertEqual(retrieved1.inc, 1); + assertEqual(retrieved2.ts.epochMicroseconds(), ts2.ts.epochMicroseconds()); + assertEqual(retrieved2.inc, 42); + + assertTrue(doc->isType("ts1")); +} + + +void BSONTest::testBinaryGeneric() +{ + Document::Ptr doc = new Document(); + + // Test Binary(const std::string&, unsigned char) constructor + std::string data = "Hello, Binary World!"; + Binary::Ptr bin = new Binary(data, Binary::SUBTYPE_GENERIC); + + doc->add("binary", bin); + + assertTrue(doc->exists("binary")); + Binary::Ptr retrieved = doc->get("binary"); + assertFalse(retrieved.isNull()); + assertEqual(static_cast(retrieved->subtype()), static_cast(Binary::SUBTYPE_GENERIC)); + assertEqual(retrieved->toRawString(), data); + + // Test Binary(const char*, unsigned char) constructor with string literal + Binary::Ptr strLitBin = new Binary("String Literal", Binary::SUBTYPE_GENERIC); + doc->add("strLitBinary", strLitBin); + Binary::Ptr retrievedStrLit = doc->get("strLitBinary"); + assertEqual("String Literal", retrievedStrLit->toRawString()); + + // Test Binary(const void*, Int32, unsigned char) constructor with raw data including nulls + const char* rawData = "Raw\0Data\0Test"; + Binary::Ptr rawBin = new Binary(rawData, 13, Binary::SUBTYPE_GENERIC); + doc->add("rawBinary", rawBin); + + Binary::Ptr retrievedRaw = doc->get("rawBinary"); + assertEqual(13, retrievedRaw->buffer().size()); + assertEqual(static_cast(retrievedRaw->subtype()), static_cast(Binary::SUBTYPE_GENERIC)); +} + + +void BSONTest::testBinaryUUID() +{ + Document::Ptr doc = new Document(); + + // Create UUID + Poco::UUIDGenerator generator; + Poco::UUID uuid = generator.create(); + Binary::Ptr uuidBinary = new Binary(uuid); + + doc->add("uuid", uuidBinary); + + assertTrue(doc->exists("uuid")); + Binary::Ptr retrieved = doc->get("uuid"); + assertFalse(retrieved.isNull()); + assertEqual(static_cast(retrieved->subtype()), static_cast(Binary::SUBTYPE_UUID)); + + Poco::UUID retrievedUuid = retrieved->uuid(); + assertTrue(uuid == retrievedUuid); + + // Verify the string representation contains UUID formatting + std::string uuidStr = retrieved->toString(); + assertTrue(uuidStr.find("UUID") != std::string::npos); +} + + +void BSONTest::testBinarySubtypes() +{ + Document::Ptr doc = new Document(); + + std::string data = "test data"; + + // Test different subtypes + Binary::Ptr generic = new Binary(data, Binary::SUBTYPE_GENERIC); + Binary::Ptr function = new Binary(data, Binary::SUBTYPE_FUNCTION); + Binary::Ptr md5 = new Binary(data, Binary::SUBTYPE_MD5); + Binary::Ptr encrypted = new Binary(data, Binary::SUBTYPE_ENCRYPTED); + Binary::Ptr userDefined = new Binary(data, Binary::SUBTYPE_USER_DEFINED); + + doc->add("generic", generic); + doc->add("function", function); + doc->add("md5", md5); + doc->add("encrypted", encrypted); + doc->add("userDefined", userDefined); + + assertEqual(static_cast(doc->get("generic")->subtype()), static_cast(Binary::SUBTYPE_GENERIC)); + assertEqual(static_cast(doc->get("function")->subtype()), static_cast(Binary::SUBTYPE_FUNCTION)); + assertEqual(static_cast(doc->get("md5")->subtype()), static_cast(Binary::SUBTYPE_MD5)); + assertEqual(static_cast(doc->get("encrypted")->subtype()), static_cast(Binary::SUBTYPE_ENCRYPTED)); + assertEqual(static_cast(doc->get("userDefined")->subtype()), static_cast(Binary::SUBTYPE_USER_DEFINED)); +} + + +void BSONTest::testObjectID() +{ + ObjectId oid("536aeebba081de6815000002"); + std::string str2 = oid.toString(); + assertTrue(str2 == "536aeebba081de6815000002"); + + // Test in document + Document::Ptr doc = new Document(); + ObjectId::Ptr oidPtr = new ObjectId("507f1f77bcf86cd799439011"); + doc->add("_id", oidPtr); + + assertTrue(doc->exists("_id")); + ObjectId::Ptr retrieved = doc->get("_id"); + assertFalse(retrieved.isNull()); + assertEqual(retrieved->toString(), "507f1f77bcf86cd799439011"); +} + + +void BSONTest::testObjectIDTimestamp() +{ + // Create ObjectId with known timestamp + ObjectId oid("536aeebba081de6815000002"); + + Poco::Timestamp ts = oid.timestamp(); + + // Verify timestamp is extracted correctly + // The first 4 bytes of 536aeebb represent the timestamp + assertTrue(ts.epochTime() > 0); + + // Verify timestamp is reasonable (should be in the past) + Poco::Timestamp now; + assertTrue(ts < now); +} + + +void BSONTest::testRegularExpression() +{ + Document::Ptr doc = new Document(); + + RegularExpression::Ptr regex1 = new RegularExpression("^test.*", "i"); + RegularExpression::Ptr regex2 = new RegularExpression("[a-z]+", ""); + + doc->add("regex1", regex1); + doc->add("regex2", regex2); + + assertTrue(doc->exists("regex1")); + assertTrue(doc->exists("regex2")); + + RegularExpression::Ptr retrieved1 = doc->get("regex1"); + RegularExpression::Ptr retrieved2 = doc->get("regex2"); + + assertFalse(retrieved1.isNull()); + assertFalse(retrieved2.isNull()); + + assertEqual(retrieved1->getPattern(), "^test.*"); + assertEqual(retrieved1->getOptions(), "i"); + assertEqual(retrieved2->getPattern(), "[a-z]+"); + assertEqual(retrieved2->getOptions(), ""); + + // Test setPattern and setOptions + RegularExpression::Ptr regex3 = new RegularExpression(); + regex3->setPattern("\\d+"); + regex3->setOptions("g"); + + assertEqual(regex3->getPattern(), "\\d+"); + assertEqual(regex3->getOptions(), "g"); +} + + +void BSONTest::testJavaScriptCode() +{ + Document::Ptr doc = new Document(); + + JavaScriptCode::Ptr js1 = new JavaScriptCode(); + js1->setCode("function() { return 42; }"); + + JavaScriptCode::Ptr js2 = new JavaScriptCode(); + js2->setCode("var x = 10; var y = 20; return x + y;"); + + doc->add("js1", js1); + doc->add("js2", js2); + + assertTrue(doc->exists("js1")); + assertTrue(doc->exists("js2")); + + JavaScriptCode::Ptr retrieved1 = doc->get("js1"); + JavaScriptCode::Ptr retrieved2 = doc->get("js2"); + + assertFalse(retrieved1.isNull()); + assertFalse(retrieved2.isNull()); + + assertEqual(retrieved1->getCode(), "function() { return 42; }"); + assertEqual(retrieved2->getCode(), "var x = 10; var y = 20; return x + y;"); +} + + +void BSONTest::testDocumentSerialization() +{ + Document::Ptr doc = new Document(); + doc->add("name"s, "John Doe"s); + doc->add("age", static_cast(30)); + doc->add("salary", 50000.50); + doc->add("active", true); + + // Serialize to stream + std::stringstream ss; + Poco::BinaryWriter writer(ss, Poco::BinaryWriter::LITTLE_ENDIAN_BYTE_ORDER); + doc->write(writer); + + // Verify data was written + assertTrue(ss.str().length() > 0); + + // Deserialize from stream + ss.seekg(0, std::ios::beg); + Poco::BinaryReader reader(ss, Poco::BinaryReader::LITTLE_ENDIAN_BYTE_ORDER); + Document::Ptr doc2 = new Document(); + doc2->read(reader); + + // Verify deserialized document + assertEqual(doc2->get("name"), "John Doe"); + assertEqual(doc2->get("age"), 30); + assertEqual(doc2->get("salary"), 50000.50); + assertEqual(doc2->get("active"), true); +} + + +void BSONTest::testDocumentDeserialization() +{ + // Create and serialize a document + Document::Ptr original = new Document(); + original->add("string"s, "test"s); + original->add("int32"s, static_cast(42)); + original->add("int64"s, static_cast(9876543210LL)); + original->add("double"s, 3.14); + original->add("bool"s, false); + original->add("null", NullValue()); + + Poco::Timestamp ts; + original->add("timestamp", ts); + + std::stringstream ss; + Poco::BinaryWriter writer(ss, Poco::BinaryWriter::LITTLE_ENDIAN_BYTE_ORDER); + original->write(writer); + + // Deserialize + ss.seekg(0, std::ios::beg); + Poco::BinaryReader reader(ss, Poco::BinaryReader::LITTLE_ENDIAN_BYTE_ORDER); + Document::Ptr restored = new Document(); + restored->read(reader); + + // Verify all fields + assertEqual(restored->size(), original->size()); + assertEqual(restored->get("string"), "test"); + assertEqual(restored->get("int32"), 42); + assertEqual(restored->get("int64"), 9876543210LL); + assertEqual(restored->get("double"), 3.14); + assertEqual(restored->get("bool"), false); + assertTrue(restored->isType("null")); + // MongoDB timestamps have millisecond precision, not microsecond + assertEqual(restored->get("timestamp").epochTime(), ts.epochTime()); +} + + +void BSONTest::testArraySerialization() +{ + Array::Ptr arr = new Array(); + arr->add("first"s); + arr->add(static_cast(42)); + arr->add(3.14); + arr->add(true); + + // Serialize + std::stringstream ss; + Poco::BinaryWriter writer(ss, Poco::BinaryWriter::LITTLE_ENDIAN_BYTE_ORDER); + arr->write(writer); + + // Deserialize + ss.seekg(0, std::ios::beg); + Poco::BinaryReader reader(ss, Poco::BinaryReader::LITTLE_ENDIAN_BYTE_ORDER); + Array::Ptr restored = new Array(); + restored->read(reader); + + // Verify + assertEqual(restored->size(), 4); + assertEqual(restored->get(0), "first"); + assertEqual(restored->get(1), 42); + assertEqual(restored->get(2), 3.14); + assertEqual(restored->get(3), true); +} + + +void BSONTest::testComplexDocumentSerialization() +{ + // Create complex nested structure + Document::Ptr doc = new Document(); + doc->add("name"s, "Test Document"s); + doc->add("version", static_cast(1)); + + // Add nested document + Document::Ptr nested = new Document(); + nested->add("field1"s, "value1"s); + nested->add("field2"s, static_cast(100)); + doc->add("nested", nested); + + // Add array + Array::Ptr arr = new Array(); + arr->add("item1"s); + arr->add("item2"s); + arr->add("item3"s); + doc->add("items", arr); + + // Add binary + Binary::Ptr bin = new Binary("binary data", Binary::SUBTYPE_GENERIC); + doc->add("binary", bin); + + // Add ObjectId + ObjectId::Ptr oid = new ObjectId("507f1f77bcf86cd799439011"); + doc->add("_id", oid); + + // Serialize + std::stringstream ss; + Poco::BinaryWriter writer(ss, Poco::BinaryWriter::LITTLE_ENDIAN_BYTE_ORDER); + doc->write(writer); + + // Deserialize + ss.seekg(0, std::ios::beg); + Poco::BinaryReader reader(ss, Poco::BinaryReader::LITTLE_ENDIAN_BYTE_ORDER); + Document::Ptr restored = new Document(); + restored->read(reader); + + // Verify root fields + assertEqual("Test Document", restored->get("name")); + assertEqual(1, restored->get("version")); + + // Verify nested document + Document::Ptr restoredNested = restored->get("nested"); + assertFalse(restoredNested.isNull()); + assertEqual("value1", restoredNested->get("field1")); + assertEqual(100, restoredNested->get("field2")); + + // Verify array + Array::Ptr restoredArr = restored->get("items"); + assertFalse(restoredArr.isNull()); + assertEqual(3, restoredArr->size()); + assertEqual("item1", restoredArr->get(0)); + assertEqual("item2", restoredArr->get(1)); + assertEqual("item3", restoredArr->get(2)); + + // Verify binary + Binary::Ptr restoredBin = restored->get("binary"); + assertFalse(restoredBin.isNull()); + assertEqual("binary data", restoredBin->toRawString()); + + // Verify ObjectId + ObjectId::Ptr restoredOid = restored->get("_id"); + assertFalse(restoredOid.isNull()); + assertEqual(restoredOid->toString(), "507f1f77bcf86cd799439011"); +} + + +void BSONTest::testSimpleDocumentToString() +{ + Document::Ptr doc = new Document(); + doc->add("name"s, "John"s); + doc->add("age"s, static_cast(30)); + doc->add("active"s, true); + + std::string str = doc->toString(); + assertEqual(str, R"({"name":"John","age":30,"active":true})"); + + // Test with indentation + std::string strIndented = doc->toString(2); + std::string expected = R"({ + "name" : "John", + "age" : 30, + "active" : true +})"; + assertEqual(strIndented, expected); +} + + +void BSONTest::testNestedDocumentToString() +{ + Document::Ptr doc = new Document(); + doc->add("name"s, "Parent"s); + + Document::Ptr child = new Document(); + child->add("name"s, "Child"s); + child->add("value"s, static_cast(42)); + + doc->add("child"s, child); + + std::string str = doc->toString(); + assertEqual(str, R"({"name":"Parent","child":{"name":"Child","value":42}})"); + + // Test with indentation + std::string strIndented = doc->toString(2); + std::string expected = R"({ + "name" : "Parent", + "child" : { + "name" : "Child", + "value" : 42 + } +})"; + assertEqual(strIndented, expected); +} + + +void BSONTest::testDocumentWithArrayToString() +{ + Document::Ptr doc = new Document(); + doc->add("title"s, "Shopping List"s); + + Array::Ptr items = new Array(); + items->add("apples"s); + items->add("oranges"s); + items->add("bananas"s); + + doc->add("items"s, items); + + std::string str = doc->toString(); + assertEqual(str, R"({"title":"Shopping List","items":["apples","oranges","bananas"]})"); + + // Test with indentation + std::string strIndented = doc->toString(2); + std::string expected = R"({ + "title" : "Shopping List", + "items" : [ + "apples", + "oranges", + "bananas" + ] +})"; + assertEqual(strIndented, expected); +} + + +void BSONTest::testComplexDocumentToString() +{ + Document::Ptr doc = new Document(); + doc->add("name"s, "Complex Document"s); + doc->add("version"s, static_cast(1)); + doc->add("enabled"s, true); + doc->add("score"s, 98.5); + + // Add nested document + Document::Ptr metadata = new Document(); + metadata->add("author"s, "Test User"s); + metadata->add("created"s, static_cast(1234567890LL)); + doc->add("metadata"s, metadata); + + // Add array + Array::Ptr tags = new Array(); + tags->add("test"s); + tags->add("sample"s); + tags->add("bson"s); + doc->add("tags"s, tags); + + // Add nested array in nested document + Document::Ptr config = new Document(); + Array::Ptr options = new Array(); + options->add("option1"s); + options->add("option2"s); + config->add("options"s, options); + doc->add("config"s, config); + + std::string str = doc->toString(); + assertEqual(str, R"({"name":"Complex Document","version":1,"enabled":true,"score":98.5,"metadata":{"author":"Test User","created":1234567890},"tags":["test","sample","bson"],"config":{"options":["option1","option2"]}})"); + + // Test with indentation + std::string strIndented = doc->toString(2); + std::string expected = R"({ + "name" : "Complex Document", + "version" : 1, + "enabled" : true, + "score" : 98.5, + "metadata" : { + "author" : "Test User", + "created" : 1234567890 + }, + "tags" : [ + "test", + "sample", + "bson" + ], + "config" : { + "options" : [ + "option1", + "option2" + ] + } +})"; + assertEqual(strIndented, expected); +} + + +void BSONTest::testToStringIndentation() +{ + Document::Ptr doc = new Document(); + doc->add("field1"s, "value1"s); + + Document::Ptr nested1 = new Document(); + nested1->add("field2"s, "value2"s); + + Document::Ptr nested2 = new Document(); + nested2->add("field3"s, "value3"s); + nested1->add("nested"s, nested2); + + doc->add("nested"s, nested1); + + // Test with no indentation + std::string str0 = doc->toString(0); + assertEqual(str0, R"({"field1":"value1","nested":{"field2":"value2","nested":{"field3":"value3"}}})"); + + // Test with 2-space indentation + std::string str2 = doc->toString(2); + std::string expected2 = R"({ + "field1" : "value1", + "nested" : { + "field2" : "value2", + "nested" : { + "field3" : "value3" + } + } +})"; + assertEqual(str2, expected2); + + // Test with 4-space indentation + std::string str4 = doc->toString(4); + std::string expected4 = R"({ + "field1" : "value1", + "nested" : { + "field2" : "value2", + "nested" : { + "field3" : "value3" + } + } + })"; + assertEqual(str4, expected4); +} + + +void BSONTest::testArrayToString() +{ + Array::Ptr arr = new Array(); + arr->add("first"s); + arr->add(static_cast(42)); + arr->add(3.14); + arr->add(true); + arr->add(false); + + std::string str = arr->toString(); + assertEqual(str, R"(["first",42,3.14,true,false])"); + + // Test with indentation + std::string strIndented = arr->toString(2); + std::string expected = R"([ + "first", + 42, + 3.14, + true, + false +])"; + assertEqual(strIndented, expected); + + // Test with nested array + Array::Ptr outer = new Array(); + outer->add("outer"s); + + Array::Ptr inner = new Array(); + inner->add("inner1"s); + inner->add("inner2"s); + + outer->add(inner); + + std::string strNested = outer->toString(); + assertEqual(strNested, R"(["outer",["inner1","inner2"]])"); + + // Test nested array with indentation + std::string strNestedIndented = outer->toString(2); + std::string expectedNested = R"([ + "outer", + [ + "inner1", + "inner2" + ] +])"; + assertEqual(strNestedIndented, expectedNested); +} + + +void BSONTest::testGetNonExistent() +{ + Document::Ptr doc = new Document(); + doc->add("existing", "value"s); + + // Test get throws NotFoundException + try + { + std::string value = doc->get("nonexistent"); + fail("Should have thrown NotFoundException"); + } + catch (Poco::NotFoundException&) + { + // Expected + } + + // Test get with default doesn't throw + std::string value = doc->get("nonexistent", "default"); + assertEqual(value, "default"); + + // Test getInteger throws NotFoundException + try + { + Poco::Int64 num = doc->getInteger("nonexistent"); + fail("Should have thrown NotFoundException"); + } + catch (Poco::NotFoundException&) + { + // Expected + } +} + + +void BSONTest::testBadCast() +{ + Document::Ptr doc = new Document(); + doc->add("string"s, "not a number"s); + doc->add("number"s, static_cast(42)); + + // Try to get string as number + try + { + Poco::Int32 num = doc->get("string"); + fail("Should have thrown BadCastException"); + } + catch (Poco::BadCastException&) + { + // Expected + } + + // Try to get number as string + try + { + std::string str = doc->get("number"); + fail("Should have thrown BadCastException"); + } + catch (Poco::BadCastException&) + { + // Expected + } + + // Test get with default doesn't throw on type mismatch + Poco::Int32 num = doc->get("string", 999); + assertEqual(num, 999); +} + + +void BSONTest::testInvalidObjectID() +{ + // Test invalid hex string (wrong length) + try + { + ObjectId oid("invalid"); + fail("Should have thrown exception for invalid ObjectId"); + } + catch (Poco::Exception&) + { + // Expected + } + + // Test invalid hex string (correct length but invalid chars) + try + { + ObjectId oid("zzzzzzzzzzzzzzzzzzzzzzzz"); + fail("Should have thrown exception for invalid ObjectId"); + } + catch (Poco::Exception&) + { + // Expected + } + + // Test valid ObjectId + ObjectId validOid("507f1f77bcf86cd799439011"); + assertEqual(validOid.toString(), "507f1f77bcf86cd799439011"); +} + + +void BSONTest::testEmptyDocument() +{ + Document::Ptr doc = new Document(); + + assertTrue(doc->empty()); + assertEqual(doc->size(), 0); + + // Test serialization of empty document + std::stringstream ss; + Poco::BinaryWriter writer(ss, Poco::BinaryWriter::LITTLE_ENDIAN_BYTE_ORDER); + doc->write(writer); + + // Deserialize + ss.seekg(0, std::ios::beg); + Poco::BinaryReader reader(ss, Poco::BinaryReader::LITTLE_ENDIAN_BYTE_ORDER); + Document::Ptr restored = new Document(); + restored->read(reader); + + assertTrue(restored->empty()); + assertEqual(restored->size(), 0); +} + + +CppUnit::Test* BSONTest::suite() +{ + CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("BSONTest"); + + // Document tests + CppUnit_addTest(pSuite, BSONTest, testDocumentAddGet); + CppUnit_addTest(pSuite, BSONTest, testDocumentExists); + CppUnit_addTest(pSuite, BSONTest, testDocumentRemove); + CppUnit_addTest(pSuite, BSONTest, testDocumentClear); + CppUnit_addTest(pSuite, BSONTest, testDocumentSize); + CppUnit_addTest(pSuite, BSONTest, testDocumentElementNames); + CppUnit_addTest(pSuite, BSONTest, testNestedDocuments); + CppUnit_addTest(pSuite, BSONTest, testDuplicateDocumentMembers); + + // Array tests + CppUnit_addTest(pSuite, BSONTest, testArray); + CppUnit_addTest(pSuite, BSONTest, testArrayIndexAccess); + CppUnit_addTest(pSuite, BSONTest, testArrayNested); + + // Type tests + CppUnit_addTest(pSuite, BSONTest, testDouble); + CppUnit_addTest(pSuite, BSONTest, testString); + CppUnit_addTest(pSuite, BSONTest, testBool); + CppUnit_addTest(pSuite, BSONTest, testInt32); + CppUnit_addTest(pSuite, BSONTest, testInt64); + CppUnit_addTest(pSuite, BSONTest, testTimestamp); + CppUnit_addTest(pSuite, BSONTest, testNull); + CppUnit_addTest(pSuite, BSONTest, testBSONTimestamp); + + // Binary tests + CppUnit_addTest(pSuite, BSONTest, testBinaryGeneric); + CppUnit_addTest(pSuite, BSONTest, testBinaryUUID); + CppUnit_addTest(pSuite, BSONTest, testBinarySubtypes); + + // ObjectId tests + CppUnit_addTest(pSuite, BSONTest, testObjectID); + CppUnit_addTest(pSuite, BSONTest, testObjectIDTimestamp); + + // RegularExpression tests + CppUnit_addTest(pSuite, BSONTest, testRegularExpression); + + // JavaScriptCode tests + CppUnit_addTest(pSuite, BSONTest, testJavaScriptCode); + + // Serialization/Deserialization tests + CppUnit_addTest(pSuite, BSONTest, testDocumentSerialization); + CppUnit_addTest(pSuite, BSONTest, testDocumentDeserialization); + CppUnit_addTest(pSuite, BSONTest, testArraySerialization); + CppUnit_addTest(pSuite, BSONTest, testComplexDocumentSerialization); + + // toString tests + CppUnit_addTest(pSuite, BSONTest, testSimpleDocumentToString); + CppUnit_addTest(pSuite, BSONTest, testNestedDocumentToString); + CppUnit_addTest(pSuite, BSONTest, testDocumentWithArrayToString); + CppUnit_addTest(pSuite, BSONTest, testComplexDocumentToString); + CppUnit_addTest(pSuite, BSONTest, testToStringIndentation); + CppUnit_addTest(pSuite, BSONTest, testArrayToString); + + // Failure/Error tests + CppUnit_addTest(pSuite, BSONTest, testGetNonExistent); + CppUnit_addTest(pSuite, BSONTest, testBadCast); + CppUnit_addTest(pSuite, BSONTest, testInvalidObjectID); + CppUnit_addTest(pSuite, BSONTest, testEmptyDocument); + + return pSuite; +} diff --git a/MongoDB/testsuite/src/BSONTest.h b/MongoDB/testsuite/src/BSONTest.h new file mode 100644 index 000000000..2eb99d5c6 --- /dev/null +++ b/MongoDB/testsuite/src/BSONTest.h @@ -0,0 +1,94 @@ +// +// BSONTest.h +// +// Definition of the BSONTest class. +// +// Copyright (c) 2004-2025, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#ifndef BSONTest_INCLUDED +#define BSONTest_INCLUDED + + +#include "Poco/MongoDB/MongoDB.h" +#include "CppUnit/TestCase.h" + + +class BSONTest: public CppUnit::TestCase +{ +public: + BSONTest(const std::string& name); + virtual ~BSONTest(); + + void setUp(); + void tearDown(); + + // Document tests + void testDocumentAddGet(); + void testDocumentExists(); + void testDocumentRemove(); + void testDocumentClear(); + void testDocumentSize(); + void testDocumentElementNames(); + void testNestedDocuments(); + void testDuplicateDocumentMembers(); + + // Array tests + void testArray(); + void testArrayIndexAccess(); + void testArrayNested(); + + // Type tests + void testDouble(); + void testString(); + void testBool(); + void testInt32(); + void testInt64(); + void testTimestamp(); + void testNull(); + void testBSONTimestamp(); + + // Binary tests + void testBinaryGeneric(); + void testBinaryUUID(); + void testBinarySubtypes(); + + // ObjectId tests + void testObjectID(); + void testObjectIDTimestamp(); + + // RegularExpression tests + void testRegularExpression(); + + // JavaScriptCode tests + void testJavaScriptCode(); + + // Serialization/Deserialization tests + void testDocumentSerialization(); + void testDocumentDeserialization(); + void testArraySerialization(); + void testComplexDocumentSerialization(); + + // toString tests + void testSimpleDocumentToString(); + void testNestedDocumentToString(); + void testDocumentWithArrayToString(); + void testComplexDocumentToString(); + void testToStringIndentation(); + void testArrayToString(); + + // Failure/Error tests + void testGetNonExistent(); + void testBadCast(); + void testInvalidObjectID(); + void testEmptyDocument(); + + static CppUnit::Test* suite(); +}; + + +#endif // BSONTest_INCLUDED diff --git a/MongoDB/testsuite/src/MongoDBTest.cpp b/MongoDB/testsuite/src/MongoDBTest.cpp index 0e53fb640..56a041c5f 100644 --- a/MongoDB/testsuite/src/MongoDBTest.cpp +++ b/MongoDB/testsuite/src/MongoDBTest.cpp @@ -27,6 +27,7 @@ using namespace Poco::MongoDB; +using namespace std::string_literals; Poco::MongoDB::Connection::Ptr MongoDBTest::_mongo; @@ -54,43 +55,6 @@ void MongoDBTest::tearDown() } -void MongoDBTest::testArray() -{ - Poco::MongoDB::Array::Ptr arr = new Poco::MongoDB::Array(); - - arr->add(std::string("First")); - - Poco::DateTime birthdate; - birthdate.assign(1969, 3, 9); - arr->add(birthdate.timestamp()); - - arr->add(static_cast(1993)); - arr->add(false); - - // Document-style interface - arr->add("4", "12.4E"); - - assertEqual(arr->size(), 5); - assertTrue(arr->exists("0")); - assertTrue(arr->exists("1")); - assertTrue(arr->exists("2")); - assertTrue(arr->exists("3")); - assertTrue(arr->exists("4")); - assertFalse(arr->exists("5")); - - assertEqual(arr->get(0), "First"); - assertEqual(arr->get(1).raw(), birthdate.timestamp().raw()); - assertEqual(arr->get(2), 1993); - assertEqual(arr->get(3), false); - assertEqual(arr->get(4), "12.4E"); - - // Document-style interface - assertEqual(arr->get("2"), 1993); - assertEqual(arr->get("4"), "12.4E"); - -} - - void MongoDBTest::testBuildInfo() { Poco::MongoDB::Database db("config"); @@ -187,8 +151,8 @@ void MongoDBTest::testDBCount() request->setCommandName(OpMsgMessage::CMD_INSERT); Document::Ptr player = new Document(); - player->add("lastname", std::string("TestPlayer")); - player->add("firstname", std::string("Test")); + player->add("lastname"s, "TestPlayer"s); + player->add("firstname"s, "Test"s); request->documents().push_back(player); OpMsgMessage response; @@ -203,7 +167,7 @@ void MongoDBTest::testDBCount() request = db.createOpMsgMessage("players"); request->setCommandName(OpMsgMessage::CMD_DELETE); Document::Ptr del = new Document(); - del->add("limit", 0).addNewDocument("q").add("lastname" , std::string("TestPlayer")); + del->add("limit"s, 0).addNewDocument("q").add("lastname"s, "TestPlayer"s); request->documents().push_back(del); _mongo->sendRequest(*request, response); } @@ -235,7 +199,6 @@ CppUnit::Test* MongoDBTest::suite() CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("MongoDBTest"); CppUnit_addTest(pSuite, MongoDBTest, testObjectID); - CppUnit_addTest(pSuite, MongoDBTest, testArray); CppUnit_addTest(pSuite, MongoDBTest, testConnectURI); CppUnit_addTest(pSuite, MongoDBTest, testHello); CppUnit_addTest(pSuite, MongoDBTest, testBuildInfo); @@ -258,8 +221,6 @@ CppUnit::Test* MongoDBTest::suite() CppUnit_addTest(pSuite, MongoDBTest, testOpCmdCursorAggregate); CppUnit_addTest(pSuite, MongoDBTest, testOpCmdKillCursor); CppUnit_addTest(pSuite, MongoDBTest, testOpCmdCursorEmptyFirstBatch); - - CppUnit_addTest(pSuite, MongoDBTest, testOpCmdUUID); CppUnit_addTest(pSuite, MongoDBTest, testDBCount); diff --git a/MongoDB/testsuite/src/MongoDBTest.h b/MongoDB/testsuite/src/MongoDBTest.h index ddec78590..e791d2292 100644 --- a/MongoDB/testsuite/src/MongoDBTest.h +++ b/MongoDB/testsuite/src/MongoDBTest.h @@ -30,13 +30,11 @@ public: void tearDown(); void testObjectID(); - void testArray(); void testBuildInfo(); void testHello(); void testConnectURI(); // OP_MSG wire protocol - void testOpCmdUUID(); void testOpCmdHello(); void testOpCmdWriteRead(); void testOpCmdInsert(); diff --git a/MongoDB/testsuite/src/MongoDBTestOpMsg.cpp b/MongoDB/testsuite/src/MongoDBTestOpMsg.cpp index 510022888..f46d49d89 100644 --- a/MongoDB/testsuite/src/MongoDBTestOpMsg.cpp +++ b/MongoDB/testsuite/src/MongoDBTestOpMsg.cpp @@ -23,60 +23,7 @@ using namespace Poco::MongoDB; - - -void MongoDBTest::testOpCmdUUID() -{ - Database db("team"); - Poco::SharedPtr request = db.createOpMsgMessage("club"); - OpMsgMessage response; - - request->setCommandName(OpMsgMessage::CMD_DROP); - _mongo->sendRequest(*request, response); - - Document::Ptr club = new Document(); - club->add("name", std::string("Barcelona")); - - Poco::UUIDGenerator generator; - Poco::UUID uuid = generator.create(); - Binary::Ptr uuidBinary = new Binary(uuid); - club->add("uuid", uuidBinary); - - request->setCommandName(OpMsgMessage::CMD_INSERT); - request->documents().push_back(club); - - _mongo->sendRequest(*request, response); - - assertTrue(response.responseOk()); - - request->setCommandName(OpMsgMessage::CMD_FIND); - request->body().addNewDocument("filter").add("name", std::string("Barcelona")); - - _mongo->sendRequest(*request, response); - assertTrue(response.responseOk()); - - if ( response.documents().size() > 0 ) - { - Document::Ptr doc = response.documents()[0]; - try - { - const auto& name = doc->get("name"); - assertEquals ("Barcelona", name ); - - Binary::Ptr uuidBinary = doc->get("uuid"); - assertTrue (uuid == uuidBinary->uuid()); - } - catch(Poco::NotFoundException& nfe) - { - fail(nfe.message() + " not found."); - } - } - else - { - fail("No document returned"); - } - -} +using namespace std::string_literals; void MongoDBTest::testOpCmdHello() @@ -110,11 +57,11 @@ void MongoDBTest::testOpCmdWriteRead() request->setCommandName(OpMsgMessage::CMD_INSERT); Document::Ptr doc = new Document(); - doc->add("name", "John").add("number", -2); + doc->add("name"s, "John").add("number", -2); request->documents().push_back(doc); doc = new Document(); - doc->add("name", "Franz").add("number", -2.8); + doc->add("name"s, "Franz").add("number", -2.8); request->documents().push_back(doc); try @@ -142,20 +89,20 @@ void MongoDBTest::testOpCmdWriteRead() void MongoDBTest::testOpCmdInsert() { Document::Ptr player = new Document(); - player->add("lastname", std::string("Braem")); - player->add("firstname", std::string("Franky")); + player->add("lastname"s, "Braem"s); + player->add("firstname"s, "Franky"s); Poco::DateTime birthdate; birthdate.assign(1969, 3, 9); - player->add("birthdate", birthdate.timestamp()); + player->add("birthdate"s, birthdate.timestamp()); - player->add("start", 1993); - player->add("active", false); + player->add("start"s, 1993); + player->add("active"s, false); Poco::DateTime now; - player->add("lastupdated", now.timestamp()); + player->add("lastupdated"s, now.timestamp()); - player->add("unknown", NullValue()); + player->add("unknown"s, NullValue()); Database db("team"); Poco::SharedPtr request = db.createOpMsgMessage("players"); @@ -181,7 +128,7 @@ void MongoDBTest::testOpCmdFind() Poco::SharedPtr request = db.createOpMsgMessage("players"); request->setCommandName(OpMsgMessage::CMD_FIND); - request->body().add("limit", 1).addNewDocument("filter").add("lastname" , std::string("Braem")); + request->body().add("limit"s, 1).addNewDocument("filter").add("lastname"s, "Braem"s); OpMsgMessage response; _mongo->sendRequest(*request, response); @@ -223,20 +170,20 @@ void MongoDBTest::testOpCmdFind() void MongoDBTest::testOpCmdUnaknowledgedInsert() { Document::Ptr player = new Document(); - player->add("lastname", std::string("Braem")); - player->add("firstname", std::string("Franky")); + player->add("lastname"s, "Braem"s); + player->add("firstname"s, "Franky"s); Poco::DateTime birthdate; birthdate.assign(1969, 3, 9); - player->add("birthdate", birthdate.timestamp()); + player->add("birthdate"s, birthdate.timestamp()); - player->add("start", 1993); - player->add("active", false); + player->add("start"s, 1993); + player->add("active"s, false); Poco::DateTime now; - player->add("lastupdated", now.timestamp()); + player->add("lastupdated"s, now.timestamp()); - player->add("unknown", NullValue()); + player->add("unknown"s, NullValue()); Database db("team"); Poco::SharedPtr request = db.createOpMsgMessage("players"); @@ -269,7 +216,7 @@ void MongoDBTest::testOpCmdCursor() for(int i = 0; i < 10000; ++i) { Document::Ptr doc = new Document(); - doc->add("number", i); + doc->add("number"s, i); request->documents().push_back(doc); } _mongo->sendRequest(*request, response); @@ -309,7 +256,7 @@ void MongoDBTest::testOpCmdCursorAggregate() for(int i = 0; i < 10000; ++i) { Document::Ptr doc = new Document(); - doc->add("number", i); + doc->add("number"s, i); request->documents().push_back(doc); } _mongo->sendRequest(*request, response); @@ -356,7 +303,7 @@ void MongoDBTest::testOpCmdKillCursor() for(int i = 0; i < 10000; ++i) { Document::Ptr doc = new Document(); - doc->add("number", i); + doc->add("number"s, i); request->documents().push_back(doc); } _mongo->sendRequest(*request, response); @@ -413,7 +360,7 @@ void MongoDBTest::testOpCmdCursorEmptyFirstBatch() for(int i = 0; i < 10000; ++i) { Document::Ptr doc = new Document(); - doc->add("number", i); + doc->add("number"s, i); request->documents().push_back(doc); } _mongo->sendRequest(*request, response); @@ -453,7 +400,7 @@ void MongoDBTest::testOpCmdDelete() request->setCommandName(OpMsgMessage::CMD_DELETE); Document::Ptr del = new Document(); - del->add("limit", 0).addNewDocument("q").add("lastname" , std::string("Braem")); + del->add("limit"s, 0).addNewDocument("q").add("lastname"s, "Braem"s); request->documents().push_back(del); OpMsgMessage response; diff --git a/MongoDB/testsuite/src/MongoDBTestSuite.cpp b/MongoDB/testsuite/src/MongoDBTestSuite.cpp index 29f2a0fde..a16997879 100644 --- a/MongoDB/testsuite/src/MongoDBTestSuite.cpp +++ b/MongoDB/testsuite/src/MongoDBTestSuite.cpp @@ -10,13 +10,20 @@ #include "MongoDBTestSuite.h" #include "MongoDBTest.h" +#include "BSONTest.h" CppUnit::Test* MongoDBTestSuite::suite() { CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("MongoDBTestSuite"); - pSuite->addTest(MongoDBTest::suite()); + pSuite->addTest(BSONTest::suite()); + + CppUnit::Test* mongoTests = MongoDBTest::suite(); + if (mongoTests != nullptr) + { + pSuite->addTest(mongoTests); + } return pSuite; }