#include #include "facade_test.hpp" #include "../../src/protocol/transform/facade.hpp" #include "../../src/protocol/detail/basic_types.hpp" namespace lsp::test { // 测试用结构体 struct TestPerson { std::string name; int age; }; struct TestConfig { std::string version; bool enabled; std::vector ports; }; } // Glaze 元数据 template<> struct glz::meta { using T = lsp::test::TestPerson; static constexpr auto value = object( "name", &T::name, "age", &T::age ); }; template<> struct glz::meta { using T = lsp::test::TestConfig; static constexpr auto value = object( "version", &T::version, "enabled", &T::enabled, "ports", &T::ports ); }; namespace lsp::test { void FacadeTests::registerTests(TestRunner& runner) { // Serialize/Deserialize 测试 runner.addTest("Facade - 序列化简单结构体", testSerializeSimpleStruct); runner.addTest("Facade - 序列化复杂结构体", testSerializeComplexStruct); runner.addTest("Facade - 序列化LSPAny", testSerializeLSPAny); runner.addTest("Facade - 反序列化简单结构体", testDeserializeSimpleStruct); runner.addTest("Facade - 反序列化复杂结构体", testDeserializeComplexStruct); runner.addTest("Facade - 反序列化无效JSON", testDeserializeInvalidJSON); runner.addTest("Facade - 序列化反序列化往返", testSerializeDeserializeRoundtrip); // check 命名空间测试 runner.addTest("Facade - Check IsObject", testCheckIsObject); runner.addTest("Facade - Check IsArray", testCheckIsArray); runner.addTest("Facade - Check IsString", testCheckIsString); runner.addTest("Facade - Check IsNumber", testCheckIsNumber); runner.addTest("Facade - Check IsBool", testCheckIsBool); runner.addTest("Facade - Check IsNull", testCheckIsNull); runner.addTest("Facade - Check 多类型检查", testCheckMultipleTypes); // debug 命名空间测试 runner.addTest("Facade - Debug GetTypeName", testDebugGetTypeName); runner.addTest("Facade - Debug GetIdString (int)", testDebugGetIdStringInt); runner.addTest("Facade - Debug GetIdString (string)", testDebugGetIdStringString); } // ==================== Serialize/Deserialize 测试 ==================== TestResult FacadeTests::testSerializeSimpleStruct() { TestResult result; result.passed = true; TestPerson person{"Alice", 30}; auto json_opt = transform::Serialize(person); assertTrue(json_opt.has_value(), "序列化应该成功"); const auto& json = json_opt.value(); assertTrue(json.find("Alice") != std::string::npos, "JSON应该包含'Alice'"); assertTrue(json.find("30") != std::string::npos, "JSON应该包含'30'"); result.message = "成功"; return result; } TestResult FacadeTests::testSerializeComplexStruct() { TestResult result; result.passed = true; TestConfig config{"1.0.0", true, {8080, 8081, 8082}}; auto json_opt = transform::Serialize(config); assertTrue(json_opt.has_value(), "序列化应该成功"); const auto& json = json_opt.value(); assertTrue(json.find("1.0.0") != std::string::npos, "JSON应该包含版本号"); assertTrue(json.find("true") != std::string::npos, "JSON应该包含enabled"); assertTrue(json.find("8080") != std::string::npos, "JSON应该包含端口"); result.message = "成功"; return result; } TestResult FacadeTests::testSerializeLSPAny() { TestResult result; result.passed = true; protocol::LSPObject obj; obj["key"] = protocol::LSPAny(42); obj["name"] = protocol::LSPAny("test"); protocol::LSPAny any(obj); auto json_opt = transform::Serialize(any); assertTrue(json_opt.has_value(), "序列化LSPAny应该成功"); result.message = "成功"; return result; } TestResult FacadeTests::testDeserializeSimpleStruct() { TestResult result; result.passed = true; std::string json = R"({"name":"Bob","age":25})"; auto person_opt = transform::Deserialize(json); assertTrue(person_opt.has_value(), "反序列化应该成功"); const auto& person = person_opt.value(); assertEqual(std::string("Bob"), person.name, "名字应该为'Bob'"); assertEqual(25, person.age, "年龄应该为25"); result.message = "成功"; return result; } TestResult FacadeTests::testDeserializeComplexStruct() { TestResult result; result.passed = true; std::string json = R"({"version":"2.0.0","enabled":false,"ports":[9000,9001,9002]})"; auto config_opt = transform::Deserialize(json); assertTrue(config_opt.has_value(), "反序列化应该成功"); const auto& config = config_opt.value(); assertEqual(std::string("2.0.0"), config.version, "版本应该为'2.0.0'"); assertEqual(false, config.enabled, "enabled应该为false"); assertEqual(size_t(3), config.ports.size(), "应该有3个端口"); assertEqual(9000, config.ports[0], "第一个端口应该为9000"); result.message = "成功"; return result; } TestResult FacadeTests::testDeserializeInvalidJSON() { TestResult result; result.passed = true; std::string json = R"({"invalid json syntax)"; auto person_opt = transform::Deserialize(json); assertFalse(person_opt.has_value(), "反序列化无效JSON应该失败"); result.message = "成功"; return result; } TestResult FacadeTests::testSerializeDeserializeRoundtrip() { TestResult result; result.passed = true; TestPerson original{"Charlie", 35}; auto json_opt = transform::Serialize(original); assertTrue(json_opt.has_value(), "序列化应该成功"); auto person_opt = transform::Deserialize(json_opt.value()); assertTrue(person_opt.has_value(), "反序列化应该成功"); const auto& restored = person_opt.value(); assertEqual(original.name, restored.name, "名字应该保持一致"); assertEqual(original.age, restored.age, "年龄应该保持一致"); result.message = "成功"; return result; } // ==================== check 命名空间测试 ==================== TestResult FacadeTests::testCheckIsObject() { TestResult result; result.passed = true; protocol::LSPObject obj; obj["key"] = protocol::LSPAny(1); protocol::LSPAny any(obj); assertTrue(transform::check::IsObject(any), "应该识别为object"); protocol::LSPAny not_obj(42); assertFalse(transform::check::IsObject(not_obj), "integer不应该识别为object"); result.message = "成功"; return result; } TestResult FacadeTests::testCheckIsArray() { TestResult result; result.passed = true; protocol::LSPArray arr; arr.push_back(protocol::LSPAny(1)); protocol::LSPAny any(arr); assertTrue(transform::check::IsArray(any), "应该识别为array"); protocol::LSPAny not_arr("string"); assertFalse(transform::check::IsArray(not_arr), "string不应该识别为array"); result.message = "成功"; return result; } TestResult FacadeTests::testCheckIsString() { TestResult result; result.passed = true; protocol::LSPAny any("hello"); assertTrue(transform::check::IsString(any), "应该识别为string"); protocol::LSPAny not_str(42); assertFalse(transform::check::IsString(not_str), "integer不应该识别为string"); result.message = "成功"; return result; } TestResult FacadeTests::testCheckIsNumber() { TestResult result; result.passed = true; protocol::LSPAny int_any(42); assertTrue(transform::check::IsNumber(int_any), "integer应该是数字"); protocol::LSPAny uint_any(100u); assertTrue(transform::check::IsNumber(uint_any), "uinteger应该是数字"); protocol::LSPAny decimal_any(3.14); assertTrue(transform::check::IsNumber(decimal_any), "decimal应该是数字"); protocol::LSPAny not_num("string"); assertFalse(transform::check::IsNumber(not_num), "string不应该是数字"); result.message = "成功"; return result; } TestResult FacadeTests::testCheckIsBool() { TestResult result; result.passed = true; protocol::LSPAny any(true); assertTrue(transform::check::IsBool(any), "应该识别为bool"); protocol::LSPAny not_bool(42); assertFalse(transform::check::IsBool(not_bool), "integer不应该识别为bool"); result.message = "成功"; return result; } TestResult FacadeTests::testCheckIsNull() { TestResult result; result.passed = true; protocol::LSPAny any(nullptr); assertTrue(transform::check::IsNull(any), "应该识别为null"); protocol::LSPAny not_null(42); assertFalse(transform::check::IsNull(not_null), "integer不应该识别为null"); result.message = "成功"; return result; } TestResult FacadeTests::testCheckMultipleTypes() { TestResult result; result.passed = true; // 测试一个值不能同时是多种类型 protocol::LSPAny any(42); assertTrue(transform::check::IsNumber(any), "应该是数字"); assertFalse(transform::check::IsString(any), "不应该是字符串"); assertFalse(transform::check::IsBool(any), "不应该是布尔值"); assertFalse(transform::check::IsNull(any), "不应该是null"); assertFalse(transform::check::IsArray(any), "不应该是数组"); assertFalse(transform::check::IsObject(any), "不应该是对象"); result.message = "成功"; return result; } // ==================== debug 命名空间测试 ==================== TestResult FacadeTests::testDebugGetTypeName() { TestResult result; result.passed = true; protocol::LSPAny obj_any(protocol::LSPObject{}); assertEqual(std::string("LSPObject"), transform::debug::GetTypeName(obj_any), "类型名应该为'LSPObject'"); protocol::LSPAny arr_any(protocol::LSPArray{}); assertEqual(std::string("LSPArray"), transform::debug::GetTypeName(arr_any), "类型名应该为'LSPArray'"); protocol::LSPAny str_any("test"); assertEqual(std::string("string"), transform::debug::GetTypeName(str_any), "类型名应该为'string'"); protocol::LSPAny int_any(42); assertEqual(std::string("integer"), transform::debug::GetTypeName(int_any), "类型名应该为'integer'"); protocol::LSPAny uint_any(100u); assertEqual(std::string("uinteger"), transform::debug::GetTypeName(uint_any), "类型名应该为'uinteger'"); protocol::LSPAny decimal_any(3.14); assertEqual(std::string("decimal"), transform::debug::GetTypeName(decimal_any), "类型名应该为'decimal'"); protocol::LSPAny bool_any(true); assertEqual(std::string("boolean"), transform::debug::GetTypeName(bool_any), "类型名应该为'boolean'"); protocol::LSPAny null_any(nullptr); assertEqual(std::string("null"), transform::debug::GetTypeName(null_any), "类型名应该为'null'"); result.message = "成功"; return result; } TestResult FacadeTests::testDebugGetIdStringInt() { TestResult result; result.passed = true; std::variant id = 123; std::string id_str = transform::debug::GetIdString(id); assertEqual(std::string("123"), id_str, "int id应该转换为'123'"); result.message = "成功"; return result; } TestResult FacadeTests::testDebugGetIdStringString() { TestResult result; result.passed = true; std::variant id = std::string("abc-123-def"); std::string id_str = transform::debug::GetIdString(id); assertEqual(std::string("abc-123-def"), id_str, "string id应该保持为'abc-123-def'"); result.message = "成功"; return result; } } // namespace lsp::test