tsl-devkit/lsp-server/test/test_lsp_any/transformer_test.cpp

655 lines
22 KiB
C++
Raw Permalink 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.

#include "transformer_test.hpp"
#include "../../src/protocol/transform/transformer.hpp"
#include "../../src/protocol/transform/common.hpp"
#include "../../src/protocol/detail/basic_types.hpp"
#include <vector>
#include <map>
#include <optional>
namespace lsp::test
{
void TransformerTests::registerTests(TestRunner& runner)
{
// ToLSPAny 基本类型
runner.addTest("Transformer - ToLSPAny Boolean", testToLSPAnyBoolean);
runner.addTest("Transformer - ToLSPAny Integer", testToLSPAnyInteger);
runner.addTest("Transformer - ToLSPAny UInteger", testToLSPAnyUInteger);
runner.addTest("Transformer - ToLSPAny Float", testToLSPAnyFloat);
runner.addTest("Transformer - ToLSPAny Double", testToLSPAnyDouble);
runner.addTest("Transformer - ToLSPAny String", testToLSPAnyString);
runner.addTest("Transformer - ToLSPAny CString", testToLSPAnyCString);
// ToLSPAny 容器类型
runner.addTest("Transformer - ToLSPAny Vector", testToLSPAnyVector);
runner.addTest("Transformer - ToLSPAny Map", testToLSPAnyMap);
runner.addTest("Transformer - ToLSPAny Optional (有值)", testToLSPAnyOptionalValue);
runner.addTest("Transformer - ToLSPAny Optional (nullopt)", testToLSPAnyOptionalNullopt);
// ToLSPAny LSP类型
runner.addTest("Transformer - ToLSPAny LSPObject", testToLSPAnyLSPObject);
runner.addTest("Transformer - ToLSPAny LSPArray", testToLSPAnyLSPArray);
runner.addTest("Transformer - ToLSPAny LSPAny", testToLSPAnyLSPAny);
// FromLSPAny 基本类型
runner.addTest("Transformer - FromLSPAny Boolean", testFromLSPAnyBoolean);
runner.addTest("Transformer - FromLSPAny Integer", testFromLSPAnyInteger);
runner.addTest("Transformer - FromLSPAny String", testFromLSPAnyString);
runner.addTest("Transformer - FromLSPAny Double", testFromLSPAnyDouble);
// FromLSPAny 容器类型
runner.addTest("Transformer - FromLSPAny Vector", testFromLSPAnyVector);
runner.addTest("Transformer - FromLSPAny Optional (有值)", testFromLSPAnyOptionalValue);
runner.addTest("Transformer - FromLSPAny Optional (null)", testFromLSPAnyOptionalNull);
runner.addTest("Transformer - FromLSPAny LSPObject", testFromLSPAnyLSPObject);
runner.addTest("Transformer - FromLSPAny LSPArray", testFromLSPAnyLSPArray);
// 数字类型转换
runner.addTest("Transformer - 提取Integer", testExtractNumberFromInteger);
runner.addTest("Transformer - 提取UInteger", testExtractNumberFromUInteger);
runner.addTest("Transformer - 提取Decimal", testExtractNumberFromDecimal);
runner.addTest("Transformer - 跨类型数字提取", testExtractNumberCrossType);
// 错误处理
runner.addTest("Transformer - 类型不匹配错误", testFromLSPAnyTypeMismatch);
runner.addTest("Transformer - 无效数字错误", testFromLSPAnyInvalidNumber);
runner.addTest("Transformer - 无效数组错误", testFromLSPAnyInvalidArray);
// 嵌套结构
runner.addTest("Transformer - 嵌套Vector", testNestedVector);
runner.addTest("Transformer - 嵌套LSPObject", testNestedLSPObject);
runner.addTest("Transformer - 混合类型嵌套", testMixedTypeNesting);
}
// ==================== ToLSPAny 基本类型测试 ====================
TestResult TransformerTests::testToLSPAnyBoolean()
{
TestResult result;
result.passed = true;
auto any = transform::LSPAnyConverter::ToLSPAny(true);
assertTrue(any.Is<protocol::boolean>(), "应该转换为boolean类型");
assertEqual(true, any.Get<protocol::boolean>(), "值应该为true");
auto any_false = transform::LSPAnyConverter::ToLSPAny(false);
assertEqual(false, any_false.Get<protocol::boolean>(), "值应该为false");
result.message = "成功";
return result;
}
TestResult TransformerTests::testToLSPAnyInteger()
{
TestResult result;
result.passed = true;
auto any = transform::LSPAnyConverter::ToLSPAny(42);
assertTrue(any.Is<protocol::integer>(), "应该转换为integer类型");
assertEqual(42, any.Get<protocol::integer>(), "值应该为42");
auto any_negative = transform::LSPAnyConverter::ToLSPAny(-100);
assertEqual(-100, any_negative.Get<protocol::integer>(), "负数应该正确转换");
result.message = "成功";
return result;
}
TestResult TransformerTests::testToLSPAnyUInteger()
{
TestResult result;
result.passed = true;
auto any = transform::LSPAnyConverter::ToLSPAny(42u);
assertTrue(any.Is<protocol::uinteger>(), "应该转换为uinteger类型");
assertEqual(42u, any.Get<protocol::uinteger>(), "值应该为42");
result.message = "成功";
return result;
}
TestResult TransformerTests::testToLSPAnyFloat()
{
TestResult result;
result.passed = true;
auto any = transform::LSPAnyConverter::ToLSPAny(3.14f);
assertTrue(any.Is<protocol::decimal>(), "float应该转换为decimal类型");
result.message = "成功";
return result;
}
TestResult TransformerTests::testToLSPAnyDouble()
{
TestResult result;
result.passed = true;
auto any = transform::LSPAnyConverter::ToLSPAny(2.718);
assertTrue(any.Is<protocol::decimal>(), "应该转换为decimal类型");
assertEqual(2.718, any.Get<protocol::decimal>(), "值应该为2.718");
result.message = "成功";
return result;
}
TestResult TransformerTests::testToLSPAnyString()
{
TestResult result;
result.passed = true;
std::string str = "hello world";
auto any = transform::LSPAnyConverter::ToLSPAny(str);
assertTrue(any.Is<protocol::string>(), "应该转换为string类型");
assertEqual(str, any.Get<protocol::string>(), "值应该为'hello world'");
result.message = "成功";
return result;
}
TestResult TransformerTests::testToLSPAnyCString()
{
TestResult result;
result.passed = true;
auto any = transform::LSPAnyConverter::ToLSPAny("test");
assertTrue(any.Is<protocol::string>(), "C字符串应该转换为string类型");
assertEqual(std::string("test"), any.Get<protocol::string>(), "值应该为'test'");
result.message = "成功";
return result;
}
// ==================== ToLSPAny 容器类型测试 ====================
TestResult TransformerTests::testToLSPAnyVector()
{
TestResult result;
result.passed = true;
std::vector<int> vec = { 1, 2, 3, 4, 5 };
auto any = transform::LSPAnyConverter::ToLSPAny(vec);
assertTrue(any.Is<protocol::LSPArray>(), "应该转换为LSPArray类型");
const auto& arr = any.Get<protocol::LSPArray>();
assertEqual(size_t(5), arr.size(), "数组大小应该为5");
assertTrue(arr[0].Is<protocol::integer>(), "元素应该是integer类型");
assertEqual(1, arr[0].Get<protocol::integer>(), "第一个元素应该为1");
assertEqual(5, arr[4].Get<protocol::integer>(), "最后一个元素应该为5");
result.message = "成功";
return result;
}
TestResult TransformerTests::testToLSPAnyMap()
{
TestResult result;
result.passed = true;
std::map<std::string, int> map = { { "a", 1 }, { "b", 2 }, { "c", 3 } };
auto any = transform::LSPAnyConverter::ToLSPAny(map);
assertTrue(any.Is<protocol::LSPObject>(), "应该转换为LSPObject类型");
const auto& obj = any.Get<protocol::LSPObject>();
assertEqual(size_t(3), obj.size(), "对象大小应该为3");
assertTrue(obj.count("a") > 0, "应该包含键'a'");
assertEqual(1, obj.at("a").Get<protocol::integer>(), "键'a'的值应该为1");
result.message = "成功";
return result;
}
TestResult TransformerTests::testToLSPAnyOptionalValue()
{
TestResult result;
result.passed = true;
std::optional<int> opt = 100;
auto any = transform::LSPAnyConverter::ToLSPAny(opt);
assertTrue(any.Is<protocol::integer>(), "有值的optional应该转换为对应类型");
assertEqual(100, any.Get<protocol::integer>(), "值应该为100");
result.message = "成功";
return result;
}
TestResult TransformerTests::testToLSPAnyOptionalNullopt()
{
TestResult result;
result.passed = true;
std::optional<int> opt = std::nullopt;
auto any = transform::LSPAnyConverter::ToLSPAny(opt);
assertTrue(any.Is<std::nullptr_t>(), "nullopt应该转换为null");
result.message = "成功";
return result;
}
// ==================== ToLSPAny LSP类型测试 ====================
TestResult TransformerTests::testToLSPAnyLSPObject()
{
TestResult result;
result.passed = true;
protocol::LSPObject obj;
obj["key"] = protocol::LSPAny(42);
auto any = transform::LSPAnyConverter::ToLSPAny(obj);
assertTrue(any.Is<protocol::LSPObject>(), "应该保持LSPObject类型");
const auto& retrieved = any.Get<protocol::LSPObject>();
assertEqual(size_t(1), retrieved.size(), "对象应该包含1个元素");
result.message = "成功";
return result;
}
TestResult TransformerTests::testToLSPAnyLSPArray()
{
TestResult result;
result.passed = true;
protocol::LSPArray arr;
arr.push_back(protocol::LSPAny(1));
arr.push_back(protocol::LSPAny(2));
auto any = transform::LSPAnyConverter::ToLSPAny(arr);
assertTrue(any.Is<protocol::LSPArray>(), "应该保持LSPArray类型");
const auto& retrieved = any.Get<protocol::LSPArray>();
assertEqual(size_t(2), retrieved.size(), "数组应该包含2个元素");
result.message = "成功";
return result;
}
TestResult TransformerTests::testToLSPAnyLSPAny()
{
TestResult result;
result.passed = true;
protocol::LSPAny original(42);
auto any = transform::LSPAnyConverter::ToLSPAny(original);
assertTrue(any.Is<protocol::integer>(), "应该保持类型");
assertEqual(42, any.Get<protocol::integer>(), "应该保持值");
result.message = "成功";
return result;
}
// ==================== FromLSPAny 基本类型测试 ====================
TestResult TransformerTests::testFromLSPAnyBoolean()
{
TestResult result;
result.passed = true;
protocol::LSPAny any(true);
bool value = transform::LSPAnyConverter::FromLSPAny<bool>(any);
assertEqual(true, value, "应该提取出true");
protocol::LSPAny any_false(false);
bool value_false = transform::LSPAnyConverter::FromLSPAny<bool>(any_false);
assertEqual(false, value_false, "应该提取出false");
result.message = "成功";
return result;
}
TestResult TransformerTests::testFromLSPAnyInteger()
{
TestResult result;
result.passed = true;
protocol::LSPAny any(42);
int value = transform::LSPAnyConverter::FromLSPAny<int>(any);
assertEqual(42, value, "应该提取出42");
result.message = "成功";
return result;
}
TestResult TransformerTests::testFromLSPAnyString()
{
TestResult result;
result.passed = true;
protocol::LSPAny any("test string");
std::string value = transform::LSPAnyConverter::FromLSPAny<std::string>(any);
assertEqual(std::string("test string"), value, "应该提取出'test string'");
result.message = "成功";
return result;
}
TestResult TransformerTests::testFromLSPAnyDouble()
{
TestResult result;
result.passed = true;
protocol::LSPAny any(3.14159);
double value = transform::LSPAnyConverter::FromLSPAny<double>(any);
assertEqual(3.14159, value, "应该提取出3.14159");
result.message = "成功";
return result;
}
// ==================== FromLSPAny 容器类型测试 ====================
TestResult TransformerTests::testFromLSPAnyVector()
{
TestResult result;
result.passed = true;
protocol::LSPArray arr;
arr.push_back(protocol::LSPAny(10));
arr.push_back(protocol::LSPAny(20));
arr.push_back(protocol::LSPAny(30));
protocol::LSPAny any(arr);
auto vec = transform::LSPAnyConverter::FromLSPAny<std::vector<int>>(any);
assertEqual(size_t(3), vec.size(), "vector大小应该为3");
assertEqual(10, vec[0], "第一个元素应该为10");
assertEqual(20, vec[1], "第二个元素应该为20");
assertEqual(30, vec[2], "第三个元素应该为30");
result.message = "成功";
return result;
}
TestResult TransformerTests::testFromLSPAnyOptionalValue()
{
TestResult result;
result.passed = true;
protocol::LSPAny any(42);
auto opt = transform::LSPAnyConverter::FromLSPAny<std::optional<int>>(any);
assertTrue(opt.has_value(), "optional应该有值");
assertEqual(42, opt.value(), "值应该为42");
result.message = "成功";
return result;
}
TestResult TransformerTests::testFromLSPAnyOptionalNull()
{
TestResult result;
result.passed = true;
protocol::LSPAny any(nullptr);
auto opt = transform::LSPAnyConverter::FromLSPAny<std::optional<int>>(any);
assertFalse(opt.has_value(), "optional应该为nullopt");
result.message = "成功";
return result;
}
TestResult TransformerTests::testFromLSPAnyLSPObject()
{
TestResult result;
result.passed = true;
protocol::LSPObject obj;
obj["key1"] = protocol::LSPAny(100);
obj["key2"] = protocol::LSPAny("value");
protocol::LSPAny any(obj);
auto retrieved = transform::LSPAnyConverter::FromLSPAny<protocol::LSPObject>(any);
assertEqual(size_t(2), retrieved.size(), "对象应该有2个键");
assertTrue(retrieved.count("key1") > 0, "应该包含key1");
assertTrue(retrieved.count("key2") > 0, "应该包含key2");
result.message = "成功";
return result;
}
TestResult TransformerTests::testFromLSPAnyLSPArray()
{
TestResult result;
result.passed = true;
protocol::LSPArray arr;
arr.push_back(protocol::LSPAny(1));
arr.push_back(protocol::LSPAny(2));
protocol::LSPAny any(arr);
auto retrieved = transform::LSPAnyConverter::FromLSPAny<protocol::LSPArray>(any);
assertEqual(size_t(2), retrieved.size(), "数组应该有2个元素");
result.message = "成功";
return result;
}
// ==================== 数字类型转换测试 ====================
TestResult TransformerTests::testExtractNumberFromInteger()
{
TestResult result;
result.passed = true;
protocol::LSPAny any(static_cast<protocol::integer>(42));
int value = transform::LSPAnyConverter::FromLSPAny<int>(any);
assertEqual(42, value, "应该从integer提取出42");
result.message = "成功";
return result;
}
TestResult TransformerTests::testExtractNumberFromUInteger()
{
TestResult result;
result.passed = true;
protocol::LSPAny any(static_cast<protocol::uinteger>(100));
unsigned int value = transform::LSPAnyConverter::FromLSPAny<unsigned int>(any);
assertEqual(100u, value, "应该从uinteger提取出100");
result.message = "成功";
return result;
}
TestResult TransformerTests::testExtractNumberFromDecimal()
{
TestResult result;
result.passed = true;
protocol::LSPAny any(static_cast<protocol::decimal>(3.14));
double value = transform::LSPAnyConverter::FromLSPAny<double>(any);
assertEqual(3.14, value, "应该从decimal提取出3.14");
result.message = "成功";
return result;
}
TestResult TransformerTests::testExtractNumberCrossType()
{
TestResult result;
result.passed = true;
// integer -> double
protocol::LSPAny int_any(42);
double double_value = transform::LSPAnyConverter::FromLSPAny<double>(int_any);
assertEqual(42.0, double_value, "integer应该能转换为double");
// uinteger -> int
protocol::LSPAny uint_any(100u);
int int_value = transform::LSPAnyConverter::FromLSPAny<int>(uint_any);
assertEqual(100, int_value, "uinteger应该能转换为int");
result.message = "成功";
return result;
}
// ==================== 错误处理测试 ====================
TestResult TransformerTests::testFromLSPAnyTypeMismatch()
{
TestResult result;
result.passed = true;
protocol::LSPAny any(42);
try
{
// 尝试将integer提取为string应该抛出异常
(void)transform::LSPAnyConverter::FromLSPAny<std::string>(any);
result.passed = false;
result.message = "应该抛出ConversionError异常";
}
catch (const transform::ConversionError& e)
{
// 预期的异常
result.message = "成功";
}
catch (...)
{
result.passed = false;
result.message = "抛出了错误的异常类型";
}
return result;
}
TestResult TransformerTests::testFromLSPAnyInvalidNumber()
{
TestResult result;
result.passed = true;
protocol::LSPAny any("not a number");
try
{
// 尝试将string提取为int应该抛出异常
(void)transform::LSPAnyConverter::FromLSPAny<int>(any);
result.passed = false;
result.message = "应该抛出ConversionError异常";
}
catch (const transform::ConversionError& e)
{
// 预期的异常
result.message = "成功";
}
catch (...)
{
result.passed = false;
result.message = "抛出了错误的异常类型";
}
return result;
}
TestResult TransformerTests::testFromLSPAnyInvalidArray()
{
TestResult result;
result.passed = true;
protocol::LSPAny any(42);
try
{
// 尝试将integer提取为vector应该抛出异常
(void)transform::LSPAnyConverter::FromLSPAny<std::vector<int>>(any);
result.passed = false;
result.message = "应该抛出ConversionError异常";
}
catch (const transform::ConversionError& e)
{
// 预期的异常
result.message = "成功";
}
catch (...)
{
result.passed = false;
result.message = "抛出了错误的异常类型";
}
return result;
}
// ==================== 嵌套结构测试 ====================
TestResult TransformerTests::testNestedVector()
{
TestResult result;
result.passed = true;
std::vector<std::vector<int>> nested = { { 1, 2 }, { 3, 4, 5 } };
auto any = transform::LSPAnyConverter::ToLSPAny(nested);
assertTrue(any.Is<protocol::LSPArray>(), "应该转换为LSPArray");
const auto& arr = any.Get<protocol::LSPArray>();
assertEqual(size_t(2), arr.size(), "外层数组应该有2个元素");
assertTrue(arr[0].Is<protocol::LSPArray>(), "第一个元素应该是LSPArray");
auto result_vec = transform::LSPAnyConverter::FromLSPAny<std::vector<std::vector<int>>>(any);
assertEqual(size_t(2), result_vec.size(), "应该有2个子vector");
assertEqual(size_t(2), result_vec[0].size(), "第一个子vector应该有2个元素");
assertEqual(1, result_vec[0][0], "第一个元素应该为1");
result.message = "成功";
return result;
}
TestResult TransformerTests::testNestedLSPObject()
{
TestResult result;
result.passed = true;
// 直接使用 LSPObject 创建嵌套结构:{"outer": {"inner": 42}}
protocol::LSPObject innerObj;
innerObj["inner"] = protocol::LSPAny(42);
protocol::LSPObject outerObj;
outerObj["outer"] = protocol::LSPAny(innerObj);
auto any = transform::LSPAnyConverter::ToLSPAny(outerObj);
assertTrue(any.Is<protocol::LSPObject>(), "应该保持为LSPObject");
// 提取为 LSPObject然后手动检查嵌套值
auto result_obj = transform::LSPAnyConverter::FromLSPAny<protocol::LSPObject>(any);
assertTrue(result_obj.count("outer") > 0, "应该包含'outer'键");
assertTrue(result_obj.at("outer").Is<protocol::LSPObject>(), "'outer'应该是LSPObject");
const auto& inner_obj = result_obj.at("outer").Get<protocol::LSPObject>();
assertTrue(inner_obj.count("inner") > 0, "应该包含'inner'键");
assertEqual(42, inner_obj.at("inner").Get<protocol::integer>(), "嵌套值应该为42");
result.message = "成功";
return result;
}
TestResult TransformerTests::testMixedTypeNesting()
{
TestResult result;
result.passed = true;
// 直接使用 LSPArray 和 LSPObject 创建混合嵌套结构
protocol::LSPArray arr;
arr.push_back(protocol::LSPAny(1));
arr.push_back(protocol::LSPAny(nullptr)); // 表示 nullopt
arr.push_back(protocol::LSPAny(3));
protocol::LSPObject obj;
obj["data"] = protocol::LSPAny(arr);
auto any = transform::LSPAnyConverter::ToLSPAny(obj);
assertTrue(any.Is<protocol::LSPObject>(), "应该保持为LSPObject");
const auto& retrieved_obj = any.Get<protocol::LSPObject>();
const auto& retrieved_arr = retrieved_obj.at("data").Get<protocol::LSPArray>();
assertEqual(size_t(3), retrieved_arr.size(), "数组应该有3个元素");
assertTrue(retrieved_arr[0].Is<protocol::integer>(), "第一个元素应该是integer");
assertTrue(retrieved_arr[1].Is<std::nullptr_t>(), "第二个元素应该是null");
assertTrue(retrieved_arr[2].Is<protocol::integer>(), "第三个元素应该是integer");
result.message = "成功";
return result;
}
} // namespace lsp::test