#include #include #include #include #include #include #include "./core/serializer.h" #include "./utils/log.h" namespace chrono = std::chrono; using namespace Splash; /*************/ TEST_CASE("Testing serialized size computation") { CHECK(Serial::getSize((int)18) == sizeof(int)); CHECK(Serial::getSize((float)18.f) == sizeof(float)); CHECK(Serial::getSize((double)18.0) == sizeof(double)); std::vector vectorOfInts{1, 2, 3, 4}; CHECK(Serial::getSize(vectorOfInts) == vectorOfInts.size() * sizeof(int) + sizeof(uint32_t)); std::deque dequeOfFloat{3.14159f, 42.f, 2.71828f}; CHECK(Serial::getSize(dequeOfFloat) == dequeOfFloat.size() * sizeof(float) + sizeof(uint32_t)); std::string someText{"So long, and thanks for the fish!"}; CHECK(Serial::getSize(someText) == someText.size() * sizeof(char) + sizeof(uint32_t)); CHECK(Serial::getSize(chrono::system_clock::time_point(chrono::duration(123456))) == sizeof(int64_t)); } /*************/ TEST_CASE("Testing serialization of std::string") { const std::string someString = "Once upon a time..."; CHECK_EQ(Serial::getSize(someString), 23); // 4 (size as uint32_t) + 19 (char count) std::vector buffer; Serial::serialize(someString, buffer); CHECK_EQ(someString, Serial::deserialize(buffer)); } /*************/ TEST_CASE("Testing serialized size computation for containers of containers") { { std::vector> data; for (uint32_t i = 0; i < 4; ++i) data.push_back(std::vector({2, 4, 8, 16})); CHECK(Serial::getSize(data) == sizeof(uint32_t) + data.size() * (sizeof(uint32_t) + data[0].size() * sizeof(int))); } { std::deque> data; for (uint32_t i = 0; i < 4; ++i) data.push_back(std::deque({2, 4, 8, 16})); CHECK(Serial::getSize(data) == sizeof(uint32_t) + data.size() * (sizeof(uint32_t) + data[0].size() * sizeof(int))); } } /*************/ TEST_CASE("Testing serialized size computation for tuples") { auto testString = std::string("Show me the money"); auto data = make_tuple(3.1415f, 42, testString); CHECK(Serial::getSize(data) == sizeof(float) + sizeof(int) + sizeof(uint32_t) + testString.size()); } /*************/ TEST_CASE("Testing elementary serialization") { std::string testString("Fresh meat"); std::vector buffer; Serial::serialize((int)7243, buffer); Serial::serialize((float)3.14159f, buffer); Serial::serialize((double)2.71828, buffer); Serial::serialize(testString, buffer); Serial::serialize(chrono::system_clock::time_point(chrono::duration(123456)), buffer); auto bufferPtr = buffer.data(); CHECK(*reinterpret_cast(bufferPtr) == 7243); bufferPtr += sizeof(int); CHECK(*reinterpret_cast(bufferPtr) == 3.14159f); bufferPtr += sizeof(float); CHECK(*reinterpret_cast(bufferPtr) == 2.71828); bufferPtr += sizeof(double); auto stringLength = *reinterpret_cast(bufferPtr); CHECK(stringLength == testString.size()); bufferPtr += sizeof(uint32_t); CHECK(std::string(reinterpret_cast(bufferPtr), stringLength) == testString); bufferPtr += sizeof(char) * testString.size(); CHECK(*reinterpret_cast(bufferPtr) == 123456); } /*************/ TEST_CASE("Testing serialization of iterable containers") { { std::vector buffer; std::vector data{1, 1, 2, 3, 5, 8}; Serial::serialize(data, buffer); auto bufferPtr = reinterpret_cast(buffer.data() + sizeof(uint32_t)); CHECK(buffer.size() == Serial::getSize(data)); for (uint32_t i = 0; i < data.size(); ++i) CHECK(data[i] == bufferPtr[i]); } { std::vector buffer; std::deque data{3.14159f, 2.71828f}; Serial::serialize(data, buffer); auto bufferPtr = reinterpret_cast(buffer.data() + sizeof(uint32_t)); CHECK(buffer.size() == Serial::getSize(data)); for (uint32_t i = 0; i < data.size(); ++i) CHECK(data[i] == bufferPtr[i]); } } /*************/ TEST_CASE("Testing serialization of tuples") { auto testString = std::string("Show me the money"); std::vector buffer; auto data = make_tuple(3.14159f, 42, testString); Serial::serialize(data, buffer); auto bufferPtr = buffer.data(); CHECK(*reinterpret_cast(bufferPtr) == 3.14159f); bufferPtr += sizeof(float); CHECK(*reinterpret_cast(bufferPtr) == 42); bufferPtr += sizeof(int); auto stringLength = *reinterpret_cast(bufferPtr); CHECK(stringLength == testString.size()); bufferPtr += sizeof(uint32_t); CHECK(std::string(reinterpret_cast(bufferPtr), stringLength) == testString); } /*************/ TEST_CASE("Testing deserialization") { { std::vector buffer; Serial::serialize((int)42, buffer); CHECK(Serial::deserialize(buffer) == 42); } { std::vector buffer; std::vector data{3.14159f, 2.71828f}; Serial::serialize(data, buffer); auto outData = Serial::deserialize>(buffer); for (uint32_t i = 0; i < data.size(); ++i) CHECK(data[i] == outData[i]); } { std::vector buffer; std::deque data{1, 1, 2, 3, 5, 8, 13}; Serial::serialize(data, buffer); auto outData = Serial::deserialize>(buffer); for (uint32_t i = 0; i < data.size(); ++i) CHECK(data[i] == outData[i]); } { std::vector buffer; std::string data{"This is a good day to die"}; Serial::serialize(data, buffer); auto outData = Serial::deserialize(buffer); CHECK(data == outData); } { std::vector buffer; auto data = chrono::system_clock::time_point(chrono::duration(123456)); Serial::serialize(data, buffer); auto outData = Serial::deserialize(buffer); CHECK(data == outData); } { auto testString = std::string("Show me the money"); std::vector buffer; auto data = make_tuple(3.14159f, 42, testString); Serial::serialize(data, buffer); auto outData = Serial::deserialize>(buffer); CHECK(std::get<0>(data) == std::get<0>(outData)); CHECK(std::get<1>(data) == std::get<1>(outData)); CHECK(std::get<2>(data) == std::get<2>(outData)); } }