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

413 lines
16 KiB
C++

module;
import std;
export module lsp.test.lsp_any.lsp_any;
import lsp.test.framework;
import lsp.protocol.common.basic_types;
export namespace lsp::test
{
class LSPAnyTests
{
public:
static void registerTests(TestRunner& runner);
private:
static TestResult testDefaultConstructor();
static TestResult testDecimalConstructor();
static TestResult testBooleanConstructor();
static TestResult testStringConstructor();
static TestResult testCStringConstructor();
static TestResult testNullptrConstructor();
static TestResult testLSPObjectConstructor();
static TestResult testLSPArrayConstructor();
static TestResult testCopyConstructor();
static TestResult testMoveConstructor();
static TestResult testCopyAssignment();
static TestResult testMoveAssignment();
static TestResult testDecimalAssignment();
static TestResult testBooleanAssignment();
static TestResult testStringAssignment();
static TestResult testNullptrAssignment();
static TestResult testLSPObjectAssignment();
static TestResult testLSPArrayAssignment();
static TestResult testIsMethod();
static TestResult testGetMethod();
static TestResult testVisitMethod();
static TestResult testIntegerTemplateSignedTypes();
static TestResult testIntegerTemplateUnsignedTypes();
static TestResult testIntegerTemplateBoundaries();
static TestResult testNestedLSPObject();
static TestResult testNestedLSPArray();
static TestResult testMixedNesting();
static TestResult testTypeConversion();
static TestResult testFloatPrecision();
static TestResult testLargeNumbers();
static TestResult testEmptyContainers();
};
}
namespace lsp::test
{
void LSPAnyTests::registerTests(TestRunner& runner)
{
runner.addTest("默认构造函数", testDefaultConstructor);
runner.addTest("浮点数构造函数", testDecimalConstructor);
runner.addTest("布尔构造函数", testBooleanConstructor);
runner.addTest("字符串构造函数", testStringConstructor);
runner.addTest("C字符串构造函数", testCStringConstructor);
runner.addTest("空指针构造函数", testNullptrConstructor);
runner.addTest("LSPObject构造函数", testLSPObjectConstructor);
runner.addTest("LSPArray构造函数", testLSPArrayConstructor);
runner.addTest("拷贝构造函数", testCopyConstructor);
runner.addTest("移动构造函数", testMoveConstructor);
runner.addTest("拷贝赋值", testCopyAssignment);
runner.addTest("移动赋值", testMoveAssignment);
runner.addTest("浮点数赋值", testDecimalAssignment);
runner.addTest("布尔赋值", testBooleanAssignment);
runner.addTest("字符串赋值", testStringAssignment);
runner.addTest("空指针赋值", testNullptrAssignment);
runner.addTest("LSPObject赋值", testLSPObjectAssignment);
runner.addTest("LSPArray赋值", testLSPArrayAssignment);
runner.addTest("Is类型检查", testIsMethod);
runner.addTest("Get获取值", testGetMethod);
runner.addTest("Visit访问者", testVisitMethod);
runner.addTest("有符号整数模板", testIntegerTemplateSignedTypes);
runner.addTest("无符号整数模板", testIntegerTemplateUnsignedTypes);
runner.addTest("整数边界测试", testIntegerTemplateBoundaries);
runner.addTest("嵌套LSPObject", testNestedLSPObject);
runner.addTest("嵌套LSPArray", testNestedLSPArray);
runner.addTest("混合嵌套", testMixedNesting);
runner.addTest("类型转换", testTypeConversion);
runner.addTest("浮点精度", testFloatPrecision);
runner.addTest("大数字", testLargeNumbers);
runner.addTest("空容器", testEmptyContainers);
}
TestResult LSPAnyTests::testDefaultConstructor()
{
TestResult result{ "", true, "成功" };
protocol::LSPAny any;
assertTrue(any.Is<std::nullptr_t>(), "默认构造应该是nullptr类型");
return result;
}
TestResult LSPAnyTests::testDecimalConstructor()
{
TestResult result{ "", true, "成功" };
protocol::decimal value = 3.14;
protocol::LSPAny any(value);
assertTrue(any.Is<protocol::decimal>(), "应该是decimal类型");
assertEqual(value, any.Get<protocol::decimal>(), "值应该相等");
float fValue = 2.5f;
protocol::LSPAny anyFloat(fValue);
assertTrue(anyFloat.Is<protocol::decimal>(), "float应该转为decimal类型");
return result;
}
TestResult LSPAnyTests::testBooleanConstructor()
{
TestResult result{ "", true, "成功" };
protocol::LSPAny anyTrue(true);
protocol::LSPAny anyFalse(false);
assertTrue(anyTrue.Is<protocol::boolean>(), "应该是boolean类型");
assertTrue(anyFalse.Is<protocol::boolean>(), "应该是boolean类型");
assertEqual(true, anyTrue.Get<protocol::boolean>(), "值应该是true");
assertEqual(false, anyFalse.Get<protocol::boolean>(), "值应该是false");
return result;
}
TestResult LSPAnyTests::testStringConstructor()
{
TestResult result{ "", true, "成功" };
protocol::string value = "Hello, LSP!";
protocol::LSPAny any(value);
assertTrue(any.Is<protocol::string>(), "应该是string类型");
assertEqual(value, any.Get<protocol::string>(), "值应该相等");
return result;
}
TestResult LSPAnyTests::testCStringConstructor()
{
TestResult result{ "", true, "成功" };
protocol::LSPAny any("Hello, C-string!");
assertTrue(any.Is<protocol::string>(), "C字符串应转为string类型");
assertEqual(std::string("Hello, C-string!"), any.Get<protocol::string>(), "值应该相等");
return result;
}
TestResult LSPAnyTests::testNullptrConstructor()
{
TestResult result{ "", true, "成功" };
protocol::LSPAny any(nullptr);
assertTrue(any.Is<std::nullptr_t>(), "应该是nullptr类型");
return result;
}
TestResult LSPAnyTests::testLSPObjectConstructor()
{
TestResult result{ "", true, "成功" };
protocol::LSPObject obj;
obj["key"] = protocol::LSPAny(42);
protocol::LSPAny any(obj);
assertTrue(any.Is<protocol::LSPObject>(), "应该是LSPObject类型");
assertEqual(42, any.Get<protocol::LSPObject>()["key"].Get<protocol::integer>(), "值应该相等");
return result;
}
TestResult LSPAnyTests::testLSPArrayConstructor()
{
TestResult result{ "", true, "成功" };
protocol::LSPArray arr = { protocol::LSPAny(1), protocol::LSPAny(2) };
protocol::LSPAny any(arr);
assertTrue(any.Is<protocol::LSPArray>(), "应该是LSPArray类型");
assertEqual(std::size_t(2), any.Get<protocol::LSPArray>().size(), "数组大小应为2");
return result;
}
TestResult LSPAnyTests::testCopyConstructor()
{
TestResult result{ "", true, "成功" };
protocol::LSPAny original(123);
protocol::LSPAny copy(original);
assertTrue(copy.Is<protocol::integer>(), "拷贝后类型应保持");
assertEqual(original.Get<protocol::integer>(), copy.Get<protocol::integer>(), "拷贝后的值应相等");
return result;
}
TestResult LSPAnyTests::testMoveConstructor()
{
TestResult result{ "", true, "成功" };
protocol::LSPAny original(123);
protocol::LSPAny moved(std::move(original));
assertTrue(moved.Is<protocol::integer>(), "移动后类型应保持");
assertEqual(123, moved.Get<protocol::integer>(), "移动后的值应相等");
return result;
}
TestResult LSPAnyTests::testCopyAssignment()
{
TestResult result{ "", true, "成功" };
protocol::LSPAny a(1);
protocol::LSPAny b(2);
b = a;
assertEqual(a.Get<protocol::integer>(), b.Get<protocol::integer>(), "赋值后的值应相等");
return result;
}
TestResult LSPAnyTests::testMoveAssignment()
{
TestResult result{ "", true, "成功" };
protocol::LSPAny a(1);
protocol::LSPAny b(2);
b = std::move(a);
assertEqual(1, b.Get<protocol::integer>(), "移动赋值后的值应为1");
return result;
}
TestResult LSPAnyTests::testDecimalAssignment()
{
TestResult result{ "", true, "成功" };
protocol::LSPAny any;
any = 3.14;
assertTrue(any.Is<protocol::decimal>(), "应为decimal类型");
assertEqual(3.14, any.Get<protocol::decimal>(), "值应为3.14");
return result;
}
TestResult LSPAnyTests::testBooleanAssignment()
{
TestResult result{ "", true, "成功" };
protocol::LSPAny any;
any = true;
assertTrue(any.Is<protocol::boolean>(), "应为boolean类型");
assertEqual(true, any.Get<protocol::boolean>(), "值应为true");
return result;
}
TestResult LSPAnyTests::testStringAssignment()
{
TestResult result{ "", true, "成功" };
protocol::LSPAny any;
protocol::string str = "Hello";
any = str;
assertTrue(any.Is<protocol::string>(), "应为string类型");
assertEqual(str, any.Get<protocol::string>(), "值应相等");
return result;
}
TestResult LSPAnyTests::testNullptrAssignment()
{
TestResult result{ "", true, "成功" };
protocol::LSPAny any;
any = nullptr;
assertTrue(any.Is<std::nullptr_t>(), "应为nullptr类型");
return result;
}
TestResult LSPAnyTests::testLSPObjectAssignment()
{
TestResult result{ "", true, "成功" };
protocol::LSPAny any;
protocol::LSPObject obj;
obj["key"] = protocol::LSPAny(42);
any = obj;
assertTrue(any.Is<protocol::LSPObject>(), "应为LSPObject类型");
assertEqual(42, any.Get<protocol::LSPObject>()["key"].Get<protocol::integer>(), "值应为42");
return result;
}
TestResult LSPAnyTests::testLSPArrayAssignment()
{
TestResult result{ "", true, "成功" };
protocol::LSPAny any;
protocol::LSPArray arr = { protocol::LSPAny(1), protocol::LSPAny(2) };
any = arr;
assertTrue(any.Is<protocol::LSPArray>(), "应为LSPArray类型");
assertEqual(std::size_t(2), any.Get<protocol::LSPArray>().size(), "数组大小应为2");
return result;
}
TestResult LSPAnyTests::testIsMethod()
{
TestResult result{ "", true, "成功" };
protocol::LSPAny any(42);
assertTrue(any.Is<protocol::integer>(), "应为integer类型");
assertFalse(any.Is<protocol::string>(), "不应为string类型");
return result;
}
TestResult LSPAnyTests::testGetMethod()
{
TestResult result{ "", true, "成功" };
protocol::LSPAny any(std::string("test"));
assertEqual(std::string("test"), any.Get<protocol::string>(), "获取的字符串应相等");
return result;
}
TestResult LSPAnyTests::testVisitMethod()
{
TestResult result{ "", true, "成功" };
protocol::LSPAny any(10);
int visited = 0;
any.Visit([&](const auto& val) {
if constexpr (std::is_same_v<std::remove_cvref_t<decltype(val)>, protocol::integer>)
{
visited = val;
}
});
assertEqual(10, visited, "访问者应返回相同值");
return result;
}
TestResult LSPAnyTests::testIntegerTemplateSignedTypes()
{
TestResult result{ "", true, "成功" };
protocol::LSPAny any(42);
assertTrue(any.Is<protocol::integer>(), "int应为integer类型");
protocol::LSPAny anyLong(std::int64_t(100));
assertTrue(anyLong.Is<protocol::integer>() || anyLong.Is<protocol::decimal>(), "大整数应存为integer或decimal");
return result;
}
TestResult LSPAnyTests::testIntegerTemplateUnsignedTypes()
{
TestResult result{ "", true, "成功" };
protocol::LSPAny any(42u);
assertTrue(any.Is<protocol::uinteger>(), "unsigned int应为uinteger");
protocol::LSPAny anyLarge(std::uint64_t(123456789));
assertTrue(anyLarge.Is<protocol::uinteger>() || anyLarge.Is<protocol::decimal>(), "大无符号应存为uinteger或decimal");
return result;
}
TestResult LSPAnyTests::testIntegerTemplateBoundaries()
{
TestResult result{ "", true, "成功" };
protocol::LSPAny anyMin(std::numeric_limits<protocol::integer>::min());
assertTrue(anyMin.Is<protocol::integer>(), "应为integer");
protocol::LSPAny anyMax(std::numeric_limits<protocol::integer>::max());
assertTrue(anyMax.Is<protocol::integer>(), "应为integer");
return result;
}
TestResult LSPAnyTests::testNestedLSPObject()
{
TestResult result{ "", true, "成功" };
protocol::LSPObject inner;
inner["a"] = protocol::LSPAny(1);
protocol::LSPObject outer;
outer["inner"] = protocol::LSPAny(inner);
protocol::LSPAny any(outer);
auto obj = any.Get<protocol::LSPObject>();
assertEqual(1, obj["inner"].Get<protocol::LSPObject>()["a"].Get<protocol::integer>(), "嵌套值应为1");
return result;
}
TestResult LSPAnyTests::testNestedLSPArray()
{
TestResult result{ "", true, "成功" };
protocol::LSPArray inner = { protocol::LSPAny(1) };
protocol::LSPArray outer = { protocol::LSPAny(inner) };
protocol::LSPAny any(outer);
auto arr = any.Get<protocol::LSPArray>();
assertEqual(1, arr[0].Get<protocol::LSPArray>()[0].Get<protocol::integer>(), "嵌套数组值应为1");
return result;
}
TestResult LSPAnyTests::testMixedNesting()
{
TestResult result{ "", true, "成功" };
protocol::LSPObject obj;
protocol::LSPArray arr = { protocol::LSPAny(1), protocol::LSPAny("test") };
obj["data"] = protocol::LSPAny(arr);
protocol::LSPAny any(obj);
auto recovered = any.Get<protocol::LSPObject>()["data"].Get<protocol::LSPArray>();
assertEqual(std::size_t(2), recovered.size(), "长度应为2");
return result;
}
TestResult LSPAnyTests::testTypeConversion()
{
TestResult result{ "", true, "成功" };
protocol::LSPAny any(42);
assertTrue(any.Is<protocol::integer>(), "应为integer");
any = 3.14;
assertTrue(any.Is<protocol::decimal>(), "应为decimal");
any = std::string("test");
assertTrue(any.Is<protocol::string>(), "应为string");
return result;
}
TestResult LSPAnyTests::testFloatPrecision()
{
TestResult result{ "", true, "成功" };
double value = 0.1 + 0.2;
protocol::LSPAny any(value);
assertTrue(any.Is<protocol::decimal>(), "应为decimal");
assertEqual(value, any.Get<protocol::decimal>(), "值应保持");
return result;
}
TestResult LSPAnyTests::testLargeNumbers()
{
TestResult result{ "", true, "成功" };
protocol::LSPAny any(std::numeric_limits<std::uint64_t>::max());
assertTrue(any.Is<protocol::uinteger>() || any.Is<protocol::decimal>(), "应为uinteger或decimal");
return result;
}
TestResult LSPAnyTests::testEmptyContainers()
{
TestResult result{ "", true, "成功" };
protocol::LSPAny any(protocol::LSPObject{});
assertTrue(any.Is<protocol::LSPObject>(), "空对象仍应有效");
protocol::LSPAny arr(protocol::LSPArray{});
assertTrue(arr.Is<protocol::LSPArray>(), "空数组仍应有效");
return result;
}
}