#include <glog/logging.h>
#include <gtest/gtest.h>
#include "serializer.h"
namespace mooncake::test {
class ExampleClass {
public:
ExampleClass() : id_(0), value_(0.0), name_("") {}
ExampleClass(int id, double value, const std::string& name)
: id_(id), value_(value), name_(name) {}
template <typename T>
void serialize_to(T& serializer) const {
serializer.write(&id_, sizeof(id_));
serializer.write(&value_, sizeof(value_));
size_t name_length = name_.length();
serializer.write(&name_length, sizeof(name_length));
if (!name_.empty()) {
serializer.write(name_.data(), name_.length());
}
}
template <typename T>
static std::shared_ptr<ExampleClass> deserialize_from(T& serializer) {
try {
auto obj = std::make_shared<ExampleClass>();
serializer.read(&obj->id_, sizeof(obj->id_));
serializer.read(&obj->value_, sizeof(obj->value_));
size_t name_length;
serializer.read(&name_length, sizeof(name_length));
if (name_length > 0) {
obj->name_.resize(name_length);
serializer.read(&obj->name_[0], name_length);
}
return obj;
} catch (const std::exception& e) {
return nullptr;
}
}
int getId() const { return id_; }
double getValue() const { return value_; }
const std::string& getName() const { return name_; }
bool operator==(const ExampleClass& other) const {
return id_ == other.id_ && value_ == other.value_ &&
name_ == other.name_;
}
protected:
int id_;
double value_;
std::string name_;
};
class ExampleClassWithException {
public:
ExampleClassWithException() : value_(0) {}
ExampleClassWithException(int value) : value_(value) {}
template <typename T>
void serialize_to(T& serializer) const {
serializer.write(&value_, sizeof(value_));
}
template <typename T>
static std::shared_ptr<ExampleClassWithException> deserialize_from(
T& serializer) {
throw std::runtime_error("throw_exception");
}
private:
int value_;
};
class SerializerTest : public ::testing::Test {
protected:
void SetUp() override {
google::InitGoogleLogging("SerializerTest");
FLAGS_logtostderr = true;
}
void TearDown() override { google::ShutdownGoogleLogging(); }
};
TEST_F(SerializerTest, ExampleClassSerialization) {
ExampleClass original(42, 3.14159, "Test Object");
std::vector<SerializedByte> buffer;
ASSERT_EQ(serialize_to(original, buffer), ErrorCode::OK);
ASSERT_FALSE(buffer.empty());
auto restored = deserialize_from<ExampleClass>(buffer);
ASSERT_NE(restored, nullptr);
EXPECT_EQ(restored->getId(), original.getId());
EXPECT_DOUBLE_EQ(restored->getValue(), original.getValue());
EXPECT_EQ(restored->getName(), original.getName());
EXPECT_TRUE(*restored == original);
}
TEST_F(SerializerTest, ExampleClassSerializationWithSharedPtr) {
auto original =
std::make_shared<ExampleClass>(777, 2.718, "Shared Pointer Test");
std::vector<SerializedByte> buffer;
ASSERT_EQ(serialize_to(original, buffer), ErrorCode::OK);
auto restored = deserialize_from<ExampleClass>(buffer);
ASSERT_NE(restored, nullptr);
EXPECT_TRUE(*restored == *original);
}
TEST_F(SerializerTest, ExampleClassSerializationNullPointer) {
std::shared_ptr<ExampleClass> null_ptr = nullptr;
std::vector<SerializedByte> buffer;
ASSERT_EQ(serialize_to(null_ptr, buffer), ErrorCode::INVALID_PARAMS);
}
TEST_F(SerializerTest, ExampleClassDeserializationCorruptedBuffer) {
ExampleClass original(1, 1.0, "Test");
std::vector<SerializedByte> buffer;
ASSERT_EQ(serialize_to(original, buffer), ErrorCode::OK);
buffer.pop_back();
auto restored = deserialize_from<ExampleClass>(buffer);
EXPECT_EQ(restored, nullptr);
}
TEST_F(SerializerTest, ExampleClassDeserializationWithException) {
ExampleClassWithException original(1);
std::vector<SerializedByte> buffer;
ASSERT_EQ(serialize_to(original, buffer), ErrorCode::OK);
auto restored = deserialize_from<ExampleClassWithException>(buffer);
EXPECT_EQ(restored, nullptr);
}
}
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}