tsl-devkit/lsp-server/test/test_lsp_any/facade_test.cppm

428 lines
14 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

module;
export module lsp.test.lsp_any.facade;
import std;
import glaze;
import lsp.test.framework;
import lsp.protocol.common.basic_types;
import lsp.codec.common;
import lsp.codec.transformer;
import lsp.codec.facade;
namespace lsp::test
{
namespace transform = lsp::codec;
// 测试用结构体
struct TestPerson
{
std::string name;
int age;
};
struct TestConfig
{
std::string version;
bool enabled;
std::vector<int> ports;
};
}
// Glaze 元数据
template<>
struct glz::meta<lsp::test::TestPerson>
{
using T = lsp::test::TestPerson;
static constexpr auto value = object(
"name",
&T::name,
"age",
&T::age);
};
template<>
struct glz::meta<lsp::test::TestConfig>
{
using T = lsp::test::TestConfig;
static constexpr auto value = object(
"version",
&T::version,
"enabled",
&T::enabled,
"ports",
&T::ports);
};
export namespace lsp::test
{
// Facade 接口测试类Serialize, Deserialize, check, debug
class FacadeTests
{
public:
static void registerTests(TestRunner& runner);
private:
// ==================== Serialize/Deserialize 测试 ====================
static TestResult testSerializeSimpleStruct();
static TestResult testSerializeComplexStruct();
static TestResult testSerializeLSPAny();
static TestResult testDeserializeSimpleStruct();
static TestResult testDeserializeComplexStruct();
static TestResult testDeserializeInvalidJSON();
static TestResult testSerializeDeserializeRoundtrip();
// ==================== check 命名空间测试 ====================
static TestResult testCheckIsObject();
static TestResult testCheckIsArray();
static TestResult testCheckIsString();
static TestResult testCheckIsNumber();
static TestResult testCheckIsBool();
static TestResult testCheckIsNull();
static TestResult testCheckMultipleTypes();
// ==================== debug 命名空间测试 ====================
static TestResult testDebugGetTypeName();
static TestResult testDebugGetIdStringInt();
static TestResult testDebugGetIdStringString();
};
}
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<TestPerson>(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<TestConfig>(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(std::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<TestPerson>(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<TestPerson>(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;
protocol::RequestId id = static_cast<protocol::integer>(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;
protocol::RequestId 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