413 lines
16 KiB
C++
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;
|
|
}
|
|
}
|