690 lines
23 KiB
C++
690 lines
23 KiB
C++
#include <cmath>
|
||
#include <limits>
|
||
#include "../../src/protocol/detail/basic_types.hpp"
|
||
#include "./lsp_any_test.hpp"
|
||
|
||
namespace lsp::test
|
||
{
|
||
|
||
// ==================== LSPAnyTests 实现 ====================
|
||
|
||
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;
|
||
result.passed = true;
|
||
|
||
protocol::LSPAny any;
|
||
assertTrue(any.Is<std::nullptr_t>(), "默认构造应该是nullptr类型");
|
||
|
||
result.message = "成功";
|
||
return result;
|
||
}
|
||
|
||
TestResult LSPAnyTests::testDecimalConstructor()
|
||
{
|
||
TestResult result;
|
||
result.passed = true;
|
||
|
||
protocol::decimal value = 3.14;
|
||
protocol::LSPAny any(value);
|
||
|
||
assertTrue(any.Is<protocol::decimal>(), "应该是decimal类型");
|
||
assertEqual(value, any.Get<protocol::decimal>(), "值应该相等");
|
||
|
||
// 测试 float 构造
|
||
float fValue = 2.5f;
|
||
protocol::LSPAny anyFloat(fValue);
|
||
assertTrue(anyFloat.Is<protocol::decimal>(), "float应该转为decimal类型");
|
||
|
||
result.message = "成功";
|
||
return result;
|
||
}
|
||
|
||
TestResult LSPAnyTests::testBooleanConstructor()
|
||
{
|
||
TestResult result;
|
||
result.passed = 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");
|
||
|
||
result.message = "成功";
|
||
return result;
|
||
}
|
||
|
||
TestResult LSPAnyTests::testStringConstructor()
|
||
{
|
||
TestResult result;
|
||
result.passed = true;
|
||
|
||
protocol::string value = "Hello, LSP!";
|
||
protocol::LSPAny any(value);
|
||
|
||
assertTrue(any.Is<protocol::string>(), "应该是string类型");
|
||
assertEqual(value, any.Get<protocol::string>(), "值应该相等");
|
||
|
||
result.message = "成功";
|
||
return result;
|
||
}
|
||
|
||
TestResult LSPAnyTests::testCStringConstructor()
|
||
{
|
||
TestResult result;
|
||
result.passed = true;
|
||
|
||
const char* value = "C String";
|
||
protocol::LSPAny any(value);
|
||
|
||
assertTrue(any.Is<protocol::string>(), "应该是string类型");
|
||
assertEqual(std::string(value), any.Get<protocol::string>(), "值应该相等");
|
||
|
||
result.message = "成功";
|
||
return result;
|
||
}
|
||
|
||
TestResult LSPAnyTests::testNullptrConstructor()
|
||
{
|
||
TestResult result;
|
||
result.passed = true;
|
||
|
||
protocol::LSPAny any(nullptr);
|
||
|
||
assertTrue(any.Is<std::nullptr_t>(), "应该是nullptr类型");
|
||
|
||
result.message = "成功";
|
||
return result;
|
||
}
|
||
|
||
TestResult LSPAnyTests::testLSPObjectConstructor()
|
||
{
|
||
TestResult result;
|
||
result.passed = true;
|
||
|
||
protocol::LSPObject obj;
|
||
obj["key1"] = protocol::LSPAny(42);
|
||
obj["key2"] = protocol::LSPAny("value");
|
||
|
||
protocol::LSPAny any(obj);
|
||
|
||
assertTrue(any.Is<protocol::LSPObject>(), "应该是LSPObject类型");
|
||
const auto& retrievedObj = any.Get<protocol::LSPObject>();
|
||
assertTrue(retrievedObj.count("key1") > 0, "应该包含key1");
|
||
assertTrue(retrievedObj.count("key2") > 0, "应该包含key2");
|
||
|
||
result.message = "成功";
|
||
return result;
|
||
}
|
||
|
||
TestResult LSPAnyTests::testLSPArrayConstructor()
|
||
{
|
||
TestResult result;
|
||
result.passed = true;
|
||
|
||
protocol::LSPArray arr;
|
||
arr.push_back(protocol::LSPAny(1));
|
||
arr.push_back(protocol::LSPAny(2));
|
||
arr.push_back(protocol::LSPAny(3));
|
||
|
||
protocol::LSPAny any(arr);
|
||
|
||
assertTrue(any.Is<protocol::LSPArray>(), "应该是LSPArray类型");
|
||
const auto& retrievedArr = any.Get<protocol::LSPArray>();
|
||
assertTrue(retrievedArr.size() == 3, "数组大小应该是3");
|
||
|
||
result.message = "成功";
|
||
return result;
|
||
}
|
||
|
||
// ==================== 拷贝和移动测试 ====================
|
||
|
||
TestResult LSPAnyTests::testCopyConstructor()
|
||
{
|
||
TestResult result;
|
||
result.passed = true;
|
||
|
||
protocol::LSPAny original(42);
|
||
protocol::LSPAny copy(original);
|
||
|
||
assertTrue(copy.Is<protocol::integer>(), "拷贝应该保持类型");
|
||
assertEqual(42, copy.Get<protocol::integer>(), "拷贝应该保持值");
|
||
assertEqual(42, original.Get<protocol::integer>(), "原值不应改变");
|
||
|
||
result.message = "成功";
|
||
return result;
|
||
}
|
||
|
||
TestResult LSPAnyTests::testMoveConstructor()
|
||
{
|
||
TestResult result;
|
||
result.passed = true;
|
||
|
||
protocol::LSPAny original(protocol::string("Move me"));
|
||
protocol::LSPAny moved(std::move(original));
|
||
|
||
assertTrue(moved.Is<protocol::string>(), "移动应该保持类型");
|
||
assertEqual(std::string("Move me"), moved.Get<protocol::string>(), "移动应该保持值");
|
||
|
||
result.message = "成功";
|
||
return result;
|
||
}
|
||
|
||
TestResult LSPAnyTests::testCopyAssignment()
|
||
{
|
||
TestResult result;
|
||
result.passed = true;
|
||
|
||
protocol::LSPAny original(42);
|
||
protocol::LSPAny target(nullptr);
|
||
target = original;
|
||
|
||
assertTrue(target.Is<protocol::integer>(), "赋值应该保持类型");
|
||
assertEqual(42, target.Get<protocol::integer>(), "赋值应该保持值");
|
||
|
||
result.message = "成功";
|
||
return result;
|
||
}
|
||
|
||
TestResult LSPAnyTests::testMoveAssignment()
|
||
{
|
||
TestResult result;
|
||
result.passed = true;
|
||
|
||
protocol::LSPAny original(protocol::string("Move me"));
|
||
protocol::LSPAny target(nullptr);
|
||
target = std::move(original);
|
||
|
||
assertTrue(target.Is<protocol::string>(), "移动赋值应该保持类型");
|
||
assertEqual(std::string("Move me"), target.Get<protocol::string>(), "移动赋值应该保持值");
|
||
|
||
result.message = "成功";
|
||
return result;
|
||
}
|
||
|
||
// ==================== 赋值操作符测试 ====================
|
||
|
||
TestResult LSPAnyTests::testDecimalAssignment()
|
||
{
|
||
TestResult result;
|
||
result.passed = true;
|
||
|
||
protocol::LSPAny any(nullptr);
|
||
any = 2.718;
|
||
|
||
assertTrue(any.Is<protocol::decimal>(), "赋值后应该是decimal类型");
|
||
assertEqual(2.718, any.Get<protocol::decimal>(), "赋值后值应该正确");
|
||
|
||
result.message = "成功";
|
||
return result;
|
||
}
|
||
|
||
TestResult LSPAnyTests::testBooleanAssignment()
|
||
{
|
||
TestResult result;
|
||
result.passed = true;
|
||
|
||
protocol::LSPAny any(nullptr);
|
||
any = true;
|
||
|
||
assertTrue(any.Is<protocol::boolean>(), "赋值后应该是boolean类型");
|
||
assertEqual(true, any.Get<protocol::boolean>(), "赋值后值应该正确");
|
||
|
||
result.message = "成功";
|
||
return result;
|
||
}
|
||
|
||
TestResult LSPAnyTests::testStringAssignment()
|
||
{
|
||
TestResult result;
|
||
result.passed = true;
|
||
|
||
protocol::LSPAny any(nullptr);
|
||
any = protocol::string("Assigned");
|
||
|
||
assertTrue(any.Is<protocol::string>(), "赋值后应该是string类型");
|
||
assertEqual(std::string("Assigned"), any.Get<protocol::string>(), "赋值后值应该正确");
|
||
|
||
// 测试 C 字符串赋值
|
||
any = "C String";
|
||
assertEqual(std::string("C String"), any.Get<protocol::string>(), "C字符串赋值应该正确");
|
||
|
||
result.message = "成功";
|
||
return result;
|
||
}
|
||
|
||
TestResult LSPAnyTests::testNullptrAssignment()
|
||
{
|
||
TestResult result;
|
||
result.passed = true;
|
||
|
||
protocol::LSPAny any(42);
|
||
any = nullptr;
|
||
|
||
assertTrue(any.Is<std::nullptr_t>(), "赋值后应该是nullptr类型");
|
||
|
||
result.message = "成功";
|
||
return result;
|
||
}
|
||
|
||
TestResult LSPAnyTests::testLSPObjectAssignment()
|
||
{
|
||
TestResult result;
|
||
result.passed = true;
|
||
|
||
protocol::LSPObject obj;
|
||
obj["test"] = protocol::LSPAny(999);
|
||
|
||
protocol::LSPAny any(nullptr);
|
||
any = obj;
|
||
|
||
assertTrue(any.Is<protocol::LSPObject>(), "赋值后应该是LSPObject类型");
|
||
const auto& retrievedObj = any.Get<protocol::LSPObject>();
|
||
assertTrue(retrievedObj.count("test") > 0, "应该包含test键");
|
||
|
||
result.message = "成功";
|
||
return result;
|
||
}
|
||
|
||
TestResult LSPAnyTests::testLSPArrayAssignment()
|
||
{
|
||
TestResult result;
|
||
result.passed = true;
|
||
|
||
protocol::LSPArray arr;
|
||
arr.push_back(protocol::LSPAny(10));
|
||
arr.push_back(protocol::LSPAny(20));
|
||
|
||
protocol::LSPAny any(nullptr);
|
||
any = arr;
|
||
|
||
assertTrue(any.Is<protocol::LSPArray>(), "赋值后应该是LSPArray类型");
|
||
const auto& retrievedArr = any.Get<protocol::LSPArray>();
|
||
assertTrue(retrievedArr.size() == 2, "数组大小应该是2");
|
||
|
||
result.message = "成功";
|
||
return result;
|
||
}
|
||
|
||
// ==================== 类型检查测试 ====================
|
||
|
||
TestResult LSPAnyTests::testIsMethod()
|
||
{
|
||
TestResult result;
|
||
result.passed = true;
|
||
|
||
protocol::LSPAny intAny(42);
|
||
assertTrue(intAny.Is<protocol::integer>(), "Is应该正确识别integer");
|
||
assertFalse(intAny.Is<protocol::string>(), "Is应该正确排除string");
|
||
assertFalse(intAny.Is<protocol::decimal>(), "Is应该正确排除decimal");
|
||
|
||
protocol::LSPAny strAny(protocol::string("test"));
|
||
assertTrue(strAny.Is<protocol::string>(), "Is应该正确识别string");
|
||
assertFalse(strAny.Is<protocol::integer>(), "Is应该正确排除integer");
|
||
|
||
result.message = "成功";
|
||
return result;
|
||
}
|
||
|
||
TestResult LSPAnyTests::testGetMethod()
|
||
{
|
||
TestResult result;
|
||
result.passed = true;
|
||
|
||
protocol::LSPAny any(42);
|
||
assertEqual(42, any.Get<protocol::integer>(), "Get应该返回正确的值");
|
||
|
||
// 修改值
|
||
any.Get<protocol::integer>() = 100;
|
||
assertEqual(100, any.Get<protocol::integer>(), "Get应该返回可修改的引用");
|
||
|
||
// const Get 测试
|
||
const protocol::LSPAny constAny(200);
|
||
assertEqual(200, constAny.Get<protocol::integer>(), "const Get应该正常工作");
|
||
|
||
result.message = "成功";
|
||
return result;
|
||
}
|
||
|
||
// ==================== 访问者模式测试 ====================
|
||
|
||
TestResult LSPAnyTests::testVisitMethod()
|
||
{
|
||
TestResult result;
|
||
result.passed = true;
|
||
|
||
protocol::LSPAny intAny(42);
|
||
protocol::LSPAny strAny(protocol::string("hello"));
|
||
protocol::LSPAny boolAny(true);
|
||
|
||
// 测试 const Visit
|
||
auto visitor = [](const auto& value) -> std::string {
|
||
using T = std::decay_t<decltype(value)>;
|
||
if constexpr (std::is_same_v<T, protocol::integer>)
|
||
{
|
||
return "integer:" + std::to_string(value);
|
||
}
|
||
else if constexpr (std::is_same_v<T, protocol::string>)
|
||
{
|
||
return "string:" + value;
|
||
}
|
||
else if constexpr (std::is_same_v<T, protocol::boolean>)
|
||
{
|
||
return value ? "bool:true" : "bool:false";
|
||
}
|
||
else
|
||
{
|
||
return "other";
|
||
}
|
||
};
|
||
|
||
std::string result1 = intAny.Visit(visitor);
|
||
assertEqual(std::string("integer:42"), result1, "Visit应该正确访问integer");
|
||
|
||
std::string result2 = strAny.Visit(visitor);
|
||
assertEqual(std::string("string:hello"), result2, "Visit应该正确访问string");
|
||
|
||
std::string result3 = boolAny.Visit(visitor);
|
||
assertEqual(std::string("bool:true"), result3, "Visit应该正确访问boolean");
|
||
|
||
result.message = "成功";
|
||
return result;
|
||
}
|
||
|
||
// ==================== 整数模板测试 ====================
|
||
|
||
TestResult LSPAnyTests::testIntegerTemplateSignedTypes()
|
||
{
|
||
TestResult result;
|
||
result.passed = true;
|
||
|
||
// 测试各种有符号整数类型
|
||
protocol::LSPAny anyInt8(static_cast<int8_t>(-10));
|
||
assertTrue(anyInt8.Is<protocol::integer>(), "int8_t应该转为integer");
|
||
assertEqual(-10, anyInt8.Get<protocol::integer>(), "int8_t值应该正确");
|
||
|
||
protocol::LSPAny anyInt16(static_cast<int16_t>(-1000));
|
||
assertTrue(anyInt16.Is<protocol::integer>(), "int16_t应该转为integer");
|
||
assertEqual(-1000, anyInt16.Get<protocol::integer>(), "int16_t值应该正确");
|
||
|
||
protocol::LSPAny anyInt64(static_cast<int64_t>(100000));
|
||
assertTrue(anyInt64.Is<protocol::integer>(), "int64_t应该转为integer");
|
||
assertEqual(100000, anyInt64.Get<protocol::integer>(), "int64_t值应该正确");
|
||
|
||
result.message = "成功";
|
||
return result;
|
||
}
|
||
|
||
TestResult LSPAnyTests::testIntegerTemplateUnsignedTypes()
|
||
{
|
||
TestResult result;
|
||
result.passed = true;
|
||
|
||
// 测试各种无符号整数类型 - 无符号整数应该存储为uinteger
|
||
protocol::LSPAny anyUint8(static_cast<uint8_t>(255));
|
||
assertTrue(anyUint8.Is<protocol::uinteger>(), "uint8_t应该转为uinteger");
|
||
assertEqual(255u, anyUint8.Get<protocol::uinteger>(), "uint8_t值应该正确");
|
||
|
||
protocol::LSPAny anyUint16(static_cast<uint16_t>(5000));
|
||
assertTrue(anyUint16.Is<protocol::uinteger>(), "uint16_t应该转为uinteger");
|
||
assertEqual(5000u, anyUint16.Get<protocol::uinteger>(), "uint16_t值应该正确");
|
||
|
||
protocol::LSPAny anySize(static_cast<size_t>(12345));
|
||
assertTrue(anySize.Is<protocol::uinteger>(), "size_t应该转为uinteger");
|
||
assertEqual(12345u, anySize.Get<protocol::uinteger>(), "size_t值应该正确");
|
||
|
||
result.message = "成功";
|
||
return result;
|
||
}
|
||
|
||
TestResult LSPAnyTests::testIntegerTemplateBoundaries()
|
||
{
|
||
TestResult result;
|
||
result.passed = true;
|
||
|
||
// 测试 int32 边界
|
||
protocol::LSPAny anyMax(std::numeric_limits<int32_t>::max());
|
||
assertTrue(anyMax.Is<protocol::integer>(), "int32_max应该是integer");
|
||
assertEqual(std::numeric_limits<int32_t>::max(), anyMax.Get<protocol::integer>(), "int32_max值应该正确");
|
||
|
||
protocol::LSPAny anyMin(std::numeric_limits<int32_t>::min());
|
||
assertTrue(anyMin.Is<protocol::integer>(), "int32_min应该是integer");
|
||
assertEqual(std::numeric_limits<int32_t>::min(), anyMin.Get<protocol::integer>(), "int32_min值应该正确");
|
||
|
||
// 测试超出 int32 范围的 int64
|
||
int64_t largeValue = static_cast<int64_t>(std::numeric_limits<int32_t>::max()) + 1;
|
||
protocol::LSPAny anyLarge(largeValue);
|
||
assertTrue(anyLarge.Is<protocol::decimal>(), "超出int32范围应该转为decimal");
|
||
|
||
// 测试 uint32 边界
|
||
protocol::LSPAny anyUintMax(std::numeric_limits<uint32_t>::max());
|
||
assertTrue(anyUintMax.Is<protocol::uinteger>(), "uint32_max应该是uinteger");
|
||
assertEqual(std::numeric_limits<uint32_t>::max(), anyUintMax.Get<protocol::uinteger>(), "uint32_max值应该正确");
|
||
|
||
result.message = "成功";
|
||
return result;
|
||
}
|
||
|
||
// ==================== 复杂场景测试 ====================
|
||
|
||
TestResult LSPAnyTests::testNestedLSPObject()
|
||
{
|
||
TestResult result;
|
||
result.passed = true;
|
||
|
||
protocol::LSPObject innerObj;
|
||
innerObj["inner_key"] = protocol::LSPAny(42);
|
||
|
||
protocol::LSPObject outerObj;
|
||
outerObj["outer_key"] = protocol::LSPAny(innerObj);
|
||
outerObj["name"] = protocol::LSPAny(protocol::string("test"));
|
||
|
||
protocol::LSPAny any(outerObj);
|
||
|
||
assertTrue(any.Is<protocol::LSPObject>(), "应该是LSPObject类型");
|
||
const auto& obj = any.Get<protocol::LSPObject>();
|
||
assertTrue(obj.count("outer_key") > 0, "应该包含outer_key");
|
||
assertTrue(obj.count("name") > 0, "应该包含name");
|
||
|
||
const auto& inner = obj.at("outer_key");
|
||
assertTrue(inner.Is<protocol::LSPObject>(), "嵌套值应该是LSPObject");
|
||
|
||
result.message = "成功";
|
||
return result;
|
||
}
|
||
|
||
TestResult LSPAnyTests::testNestedLSPArray()
|
||
{
|
||
TestResult result;
|
||
result.passed = true;
|
||
|
||
protocol::LSPArray innerArr;
|
||
innerArr.push_back(protocol::LSPAny(1));
|
||
innerArr.push_back(protocol::LSPAny(2));
|
||
|
||
protocol::LSPArray outerArr;
|
||
outerArr.push_back(protocol::LSPAny(innerArr));
|
||
outerArr.push_back(protocol::LSPAny(protocol::string("text")));
|
||
|
||
protocol::LSPAny any(outerArr);
|
||
|
||
assertTrue(any.Is<protocol::LSPArray>(), "应该是LSPArray类型");
|
||
const auto& arr = any.Get<protocol::LSPArray>();
|
||
assertTrue(arr.size() == 2, "外层数组大小应该是2");
|
||
assertTrue(arr[0].Is<protocol::LSPArray>(), "第一个元素应该是LSPArray");
|
||
|
||
result.message = "成功";
|
||
return result;
|
||
}
|
||
|
||
TestResult LSPAnyTests::testMixedNesting()
|
||
{
|
||
TestResult result;
|
||
result.passed = true;
|
||
|
||
protocol::LSPArray arr;
|
||
arr.push_back(protocol::LSPAny(1));
|
||
arr.push_back(protocol::LSPAny(protocol::string("two")));
|
||
arr.push_back(protocol::LSPAny(3.0));
|
||
|
||
protocol::LSPObject obj;
|
||
obj["array"] = protocol::LSPAny(arr);
|
||
obj["number"] = protocol::LSPAny(42);
|
||
obj["flag"] = protocol::LSPAny(true);
|
||
|
||
protocol::LSPAny any(obj);
|
||
|
||
assertTrue(any.Is<protocol::LSPObject>(), "应该是LSPObject类型");
|
||
const auto& retrievedObj = any.Get<protocol::LSPObject>();
|
||
assertTrue(retrievedObj.count("array") > 0, "应该包含array");
|
||
assertTrue(retrievedObj.at("array").Is<protocol::LSPArray>(), "array应该是LSPArray类型");
|
||
|
||
const auto& retrievedArr = retrievedObj.at("array").Get<protocol::LSPArray>();
|
||
assertTrue(retrievedArr.size() == 3, "数组大小应该是3");
|
||
|
||
result.message = "成功";
|
||
return result;
|
||
}
|
||
|
||
TestResult LSPAnyTests::testTypeConversion()
|
||
{
|
||
TestResult result;
|
||
result.passed = true;
|
||
|
||
protocol::LSPAny any(42);
|
||
assertTrue(any.Is<protocol::integer>(), "初始应该是integer");
|
||
|
||
// 改变类型
|
||
any = protocol::string("now a string");
|
||
assertTrue(any.Is<protocol::string>(), "现在应该是string");
|
||
assertFalse(any.Is<protocol::integer>(), "不应该再是integer");
|
||
|
||
// 再次改变
|
||
any = 3.14;
|
||
assertTrue(any.Is<protocol::decimal>(), "现在应该是decimal");
|
||
assertFalse(any.Is<protocol::string>(), "不应该再是string");
|
||
|
||
result.message = "成功";
|
||
return result;
|
||
}
|
||
|
||
// ==================== 边界情况测试 ====================
|
||
|
||
TestResult LSPAnyTests::testFloatPrecision()
|
||
{
|
||
TestResult result;
|
||
result.passed = true;
|
||
|
||
float fValue = 1.23456789f;
|
||
protocol::LSPAny anyFloat(fValue);
|
||
|
||
assertTrue(anyFloat.Is<protocol::decimal>(), "float应该转为decimal");
|
||
|
||
// 注意:float 转为 double 可能有精度变化,这里只是验证类型转换正确
|
||
protocol::decimal retrieved = anyFloat.Get<protocol::decimal>();
|
||
assertTrue(std::abs(retrieved - static_cast<double>(fValue)) < 1e-6,
|
||
"转换后的值应该接近原值");
|
||
|
||
result.message = "成功";
|
||
return result;
|
||
}
|
||
|
||
TestResult LSPAnyTests::testLargeNumbers()
|
||
{
|
||
TestResult result;
|
||
result.passed = true;
|
||
|
||
// 测试大的 uint64 值转为 decimal
|
||
uint64_t largeUint = 10000000000ULL; // 超出 uint32 范围
|
||
protocol::LSPAny anyLarge(largeUint);
|
||
|
||
assertTrue(anyLarge.Is<protocol::decimal>(), "大整数应该转为decimal");
|
||
|
||
protocol::decimal retrieved = anyLarge.Get<protocol::decimal>();
|
||
assertTrue(std::abs(retrieved - static_cast<double>(largeUint)) < 1.0,
|
||
"转换后的值应该接近原值");
|
||
|
||
result.message = "成功";
|
||
return result;
|
||
}
|
||
|
||
TestResult LSPAnyTests::testEmptyContainers()
|
||
{
|
||
TestResult result;
|
||
result.passed = true;
|
||
|
||
protocol::LSPObject emptyObj;
|
||
protocol::LSPAny anyObj(emptyObj);
|
||
|
||
assertTrue(anyObj.Is<protocol::LSPObject>(), "应该是LSPObject类型");
|
||
const auto& obj = anyObj.Get<protocol::LSPObject>();
|
||
assertTrue(obj.empty(), "对象应该为空");
|
||
|
||
protocol::LSPArray emptyArr;
|
||
protocol::LSPAny anyArr(emptyArr);
|
||
|
||
assertTrue(anyArr.Is<protocol::LSPArray>(), "应该是LSPArray类型");
|
||
const auto& arr = anyArr.Get<protocol::LSPArray>();
|
||
assertTrue(arr.empty(), "数组应该为空");
|
||
|
||
result.message = "成功";
|
||
return result;
|
||
}
|
||
|
||
} // namespace lsp::test
|