From bbdc1435ce82c34764b4c1d89776e5e92ec397f6 Mon Sep 17 00:00:00 2001 From: ChestnutYueyue <952134128@qq.com> Date: Sun, 1 Mar 2026 22:53:28 +0800 Subject: [PATCH] =?UTF-8?q?refactor(tests):=20=E7=A7=BB=E9=99=A4=E6=B5=8B?= =?UTF-8?q?=E8=AF=95=E5=A5=97=E4=BB=B6=E5=8F=8A=E7=9B=B8=E5=85=B3=E9=85=8D?= =?UTF-8?q?=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 移除整个tests目录及其内容,包括测试代码、构建脚本和文档 同时更新xmake.lua移除测试套件配置 重构src/resource/material.cpp代码格式 --- src/resource/material.cpp | 104 ++++--- tests/README.md | 139 --------- tests/main.cpp | 7 - tests/test_context.cpp | 408 ------------------------- tests/test_event_bus.cpp | 534 --------------------------------- tests/test_module_registry.cpp | 322 -------------------- tests/test_plugin_loader.cpp | 413 ------------------------- tests/test_timer_module.cpp | 405 ------------------------- tests/xmake.lua | 59 ---- xmake.lua | 4 - 10 files changed, 54 insertions(+), 2341 deletions(-) delete mode 100644 tests/README.md delete mode 100644 tests/main.cpp delete mode 100644 tests/test_context.cpp delete mode 100644 tests/test_event_bus.cpp delete mode 100644 tests/test_module_registry.cpp delete mode 100644 tests/test_plugin_loader.cpp delete mode 100644 tests/test_timer_module.cpp delete mode 100644 tests/xmake.lua diff --git a/src/resource/material.cpp b/src/resource/material.cpp index 5003206..5546146 100644 --- a/src/resource/material.cpp +++ b/src/resource/material.cpp @@ -6,82 +6,86 @@ Material::Material() = default; Material::~Material() = default; -void Material::setShader(Ptr shader) { - shader_ = shader; +void Material::setShader(Ptr shader) { shader_ = shader; } + +void Material::setBool(const std::string &name, bool value) { + properties_[name] = value; } -void Material::setBool(const std::string& name, bool value) { - properties_[name] = value; +void Material::setInt(const std::string &name, int value) { + properties_[name] = value; } -void Material::setInt(const std::string& name, int value) { - properties_[name] = value; +void Material::setFloat(const std::string &name, float value) { + properties_[name] = value; } -void Material::setFloat(const std::string& name, float value) { - properties_[name] = value; +void Material::setVec2(const std::string &name, const Vec2 &value) { + properties_[name] = value; } -void Material::setVec2(const std::string& name, const Vec2& value) { - properties_[name] = value; +void Material::setVec3(const std::string &name, const Vec3 &value) { + properties_[name] = value; } -void Material::setVec3(const std::string& name, const Vec3& value) { - properties_[name] = value; +void Material::setColor(const std::string &name, const Color &value) { + properties_[name] = value; } -void Material::setColor(const std::string& name, const Color& value) { - properties_[name] = value; -} - -void Material::setTexture(const std::string& name, Ptr texture) { - properties_[name] = texture; +void Material::setTexture(const std::string &name, Ptr texture) { + properties_[name] = texture; } void Material::apply() { - if (!shader_) return; + if (!shader_) + return; - shader_->use(); - applyProperties(); + shader_->use(); + applyProperties(); } void Material::applyProperties() { - if (!shader_) return; + if (!shader_) + return; - textureUnit_ = 0; + textureUnit_ = 0; - for (const auto& [name, prop] : properties_) { - std::visit([this, &name](auto&& value) { - using T = std::decay_t; + for (const auto &pair : properties_) { + const auto &name = pair.first; + const auto &prop = pair.second; + std::visit( + [this, &name](auto &&value) { + using T = std::decay_t; - if constexpr (std::is_same_v) { - shader_->setBool(name, value); - } else if constexpr (std::is_same_v) { - shader_->setInt(name, value); - } else if constexpr (std::is_same_v) { - shader_->setFloat(name, value); - } else if constexpr (std::is_same_v) { - shader_->setVec2(name, value); - } else if constexpr (std::is_same_v) { - shader_->setVec3(name, value); - } else if constexpr (std::is_same_v) { - shader_->setColor(name, value); - } else if constexpr (std::is_same_v>) { - if (value) { - value->bind(textureUnit_); - shader_->setInt(name, textureUnit_); - textureUnit_++; - } + if constexpr (std::is_same_v) { + shader_->setBool(name, value); + } else if constexpr (std::is_same_v) { + shader_->setInt(name, value); + } else if constexpr (std::is_same_v) { + shader_->setFloat(name, value); + } else if constexpr (std::is_same_v) { + shader_->setVec2(name, value); + } else if constexpr (std::is_same_v) { + shader_->setVec3(name, value); + } else if constexpr (std::is_same_v) { + shader_->setColor(name, value); + } else if constexpr (std::is_same_v>) { + if (value) { + value->bind(textureUnit_); + shader_->setInt(name, textureUnit_); + textureUnit_++; } - }, prop); - } + } + }, + prop); + } } Ptr Material::clone() const { - Ptr newMat = makePtr(); - newMat->setShader(shader_); - newMat->properties_ = properties_; - return newMat; + Ptr newMat = makePtr(); + newMat->setShader(shader_); + newMat->properties_ = properties_; + return newMat; } } // namespace extra2d diff --git a/tests/README.md b/tests/README.md deleted file mode 100644 index 6fa04f3..0000000 --- a/tests/README.md +++ /dev/null @@ -1,139 +0,0 @@ -# Extra2D 测试套件 - -## 概述 - -本测试套件包含对 Extra2D 引擎核心模块的单元测试和集成测试。 - -## 测试框架 - -使用自定义轻量级测试框架,位于 `test_framework.h`。 - -### 特性 -- 自动测试注册和发现 -- 支持测试套件组织 -- 丰富的断言宏 -- 详细的测试报告 - -## 测试文件说明 - -| 文件 | 描述 | 测试数量 | -|------|------|----------| -| `test_timer_module.cpp` | 定时器模块测试 | 20+ | -| `test_event_bus.cpp` | 事件总线测试 | 20+ | -| `test_module_registry.cpp` | 模块注册表测试 | 12+ | -| `test_plugin_loader.cpp` | 插件加载器测试 | 15+ | -| `test_context.cpp` | Context 集成测试 | 15+ | - -## 构建和运行 - -### 构建测试 - -```bash -# 配置并构建测试 -xmake f --tests=y -xmake - -# 或者显式指定平台 -xmake f -p mingw --tests=y -xmake -``` - -### 运行测试 - -```bash -# 运行所有测试 -xmake run extra2d_tests - -# 或者在构建目录中直接运行 -./build/mingw/x86_64/debug/extra2d_tests.exe -``` - -## 测试覆盖范围 - -### TimerModule 测试 -- 基础属性和生命周期 -- 一次性定时器(scheduleOnce) -- 重复定时器(scheduleRepeat) -- 每帧更新定时器(scheduleUpdate) -- 暂停和恢复功能 -- 时间缩放效果 -- 多定时器管理 -- 边界条件处理 - -### EventBus 测试 -- 基础事件广播 -- 多监听器支持 -- 监听器启用/禁用 -- 带参数事件 -- 不同事件类型 -- 监听器生命周期(RAII) -- 输入事件(键盘、鼠标、触摸) -- 窗口事件 -- 游戏手柄事件 -- 性能测试 - -### ModuleRegistry 测试 -- 基础注册/注销操作 -- 重复注册处理 -- 按类型获取模块 -- 初始化和关闭顺序 -- 优先级排序 -- 空注册表处理 - -### PluginLoader 测试 -- 基础注册/卸载操作 -- 插件加载和卸载 -- 依赖关系解析 -- 加载顺序验证 -- 缺失依赖处理 -- 循环依赖处理 -- 复杂依赖图 - -### Context 集成测试 -- 创建和销毁 -- 初始化和关闭 -- 时间推进 -- 停止请求 -- 组件访问(模块、插件、定时器) -- 事件广播 -- 多 Context 支持 -- 定时器集成 -- 完整生命周期 -- 性能测试 - -## 添加新测试 - -使用 `TEST` 宏添加新测试: - -```cpp -#include "test_framework.h" -#include - -using namespace extra2d; -using namespace extra2d::test; - -TEST(SuiteName, TestName) { - // 测试代码 - ASSERT_EQ(expected, actual); - ASSERT_TRUE(condition); - ASSERT_NOT_NULL(ptr); -} -``` - -## 断言宏 - -- `ASSERT_TRUE(expr)` - 断言表达式为 true -- `ASSERT_FALSE(expr)` - 断言表达式为 false -- `ASSERT_EQ(expected, actual)` - 断言相等 -- `ASSERT_NE(expected, actual)` - 断言不相等 -- `ASSERT_NULL(ptr)` - 断言指针为 null -- `ASSERT_NOT_NULL(ptr)` - 断言指针不为 null -- `ASSERT_THROW(expr, ExceptionType)` - 断言抛出异常 -- `ASSERT_NO_THROW(expr)` - 断言不抛出异常 - -## 注意事项 - -1. 测试使用静态注册,自动发现并运行 -2. 每个测试用例独立运行,互不影响 -3. 测试框架会捕获异常并报告错误 -4. 支持测试跳过(skip)功能 diff --git a/tests/main.cpp b/tests/main.cpp deleted file mode 100644 index 61c10ef..0000000 --- a/tests/main.cpp +++ /dev/null @@ -1,7 +0,0 @@ -#include - -// GoogleTest 主入口 -int main(int argc, char **argv) { - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} diff --git a/tests/test_context.cpp b/tests/test_context.cpp deleted file mode 100644 index d25457b..0000000 --- a/tests/test_context.cpp +++ /dev/null @@ -1,408 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -using namespace extra2d; -using extra2d::event::Listener; - -// ============================================================================ -// Context 基础测试 -// ============================================================================ - -TEST(Context, CreateAndDestroy) { - auto context = Context::create(); - EXPECT_NE(nullptr, context.get()); -} - -TEST(Context, InitShutdown) { - auto context = Context::create(); - - EXPECT_FALSE(context->isRunning()); - - EXPECT_TRUE(context->init()); - EXPECT_TRUE(context->isRunning()); - - context->shutdown(); - EXPECT_FALSE(context->isRunning()); -} - -TEST(Context, TickAdvancesTime) { - auto context = Context::create(); - context->init(); - - EXPECT_EQ(0.0f, context->totalTime()); - EXPECT_EQ(0, context->frameCount()); - - context->tick(0.016f); - EXPECT_NEAR(0.016f, context->totalTime(), 0.0001f); - EXPECT_EQ(1, context->frameCount()); - - context->tick(0.016f); - EXPECT_NEAR(0.032f, context->totalTime(), 0.0001f); - EXPECT_EQ(2, context->frameCount()); - - context->shutdown(); -} - -TEST(Context, StopRequest) { - auto context = Context::create(); - context->init(); - - EXPECT_TRUE(context->isRunning()); - - context->stop(); - EXPECT_FALSE(context->isRunning()); - - context->shutdown(); -} - -// ============================================================================ -// Context 组件访问测试 -// ============================================================================ - -TEST(Context, AccessModules) { - auto context = Context::create(); - context->init(); - - // 访问模块注册表 - ModuleRegistry& modules = context->modules(); - // 至少应有 TimerModule - EXPECT_TRUE(modules.hasModule("Timer")); - - context->shutdown(); -} - -TEST(Context, AccessPlugins) { - auto context = Context::create(); - context->init(); - - // 访问插件加载器 - PluginLoader& plugins = context->plugins(); - // 初始时应该没有插件 - EXPECT_EQ(0, plugins.getPluginCount()); - - context->shutdown(); -} - -TEST(Context, AccessTimer) { - auto context = Context::create(); - context->init(); - - // 访问定时器模块 - TimerModule& timer = context->timer(); - EXPECT_STREQ("Timer", timer.name()); - - context->shutdown(); -} - -// ============================================================================ -// 事件总线集成测试 -// ============================================================================ - -TEST(Context, EventsBroadcastOnTick) { - auto context = Context::create(); - context->init(); - - int updateCount = 0; - int lateUpdateCount = 0; - float receivedDt = 0.0f; - - Listener updateListener; - updateListener.bind([&](float dt) { - updateCount++; - receivedDt = dt; - }); - - Listener lateUpdateListener; - lateUpdateListener.bind([&](float dt) { - lateUpdateCount++; - }); - - context->tick(0.016f); - - EXPECT_EQ(1, updateCount); - EXPECT_EQ(1, lateUpdateCount); - EXPECT_NEAR(0.016f, receivedDt, 0.0001f); - - context->shutdown(); -} - -TEST(Context, InitEvent) { - auto context = Context::create(); - - bool initReceived = false; - Listener initListener; - initListener.bind([&]() { - initReceived = true; - }); - - context->init(); - EXPECT_TRUE(initReceived); - - context->shutdown(); -} - -TEST(Context, ShutdownEvent) { - auto context = Context::create(); - context->init(); - - bool shutdownReceived = false; - Listener shutdownListener; - shutdownListener.bind([&]() { - shutdownReceived = true; - }); - - context->shutdown(); - EXPECT_TRUE(shutdownReceived); -} - -// ============================================================================ -// 多Context测试 -// ============================================================================ - -TEST(Context, MultipleContexts) { - auto context1 = Context::create(); - auto context2 = Context::create(); - - EXPECT_NE(context1.get(), context2.get()); - - context1->init(); - context2->init(); - - // 两个Context应该是独立的 - EXPECT_EQ(0.0f, context1->totalTime()); - EXPECT_EQ(0.0f, context2->totalTime()); - - context1->tick(0.016f); - EXPECT_NEAR(0.016f, context1->totalTime(), 0.0001f); - EXPECT_EQ(0.0f, context2->totalTime()); // context2 不应受影响 - - context1->shutdown(); - context2->shutdown(); -} - -// ============================================================================ -// 定时器集成测试 -// ============================================================================ - -TEST(Context, TimerIntegration) { - auto context = Context::create(); - context->init(); - - int timerCount = 0; - TimerId id = context->timer().scheduleOnce(0.05f, [&]() { - timerCount++; - }); - - EXPECT_NE(INVALID_TIMER_ID, id); - - // 模拟多帧 - for (int i = 0; i < 10; i++) { - context->tick(0.016f); // 约 16ms 每帧 - } - - EXPECT_EQ(1, timerCount); - - context->shutdown(); -} - -TEST(Context, TimerWithTimeScale) { - auto context = Context::create(); - context->init(); - - int timerCount = 0; - context->timer().setTimeScale(2.0f); - - context->timer().scheduleOnce(0.1f, [&]() { - timerCount++; - }); - - // 实际经过 0.05 秒,但时间缩放为 2.0,效果相当于 0.1 秒 - context->tick(0.05f); - - EXPECT_EQ(1, timerCount); - - context->shutdown(); -} - -// ============================================================================ -// 完整生命周期测试 -// ============================================================================ - -TEST(Context, FullLifecycle) { - std::vector eventLog; - - auto context = Context::create(); - - // 注册事件监听器 - Listener initListener; - initListener.bind([&]() { - eventLog.push_back("Init"); - }); - - Listener updateListener; - updateListener.bind([&](float dt) { - if (eventLog.empty() || eventLog.back() != "Update") { - eventLog.push_back("Update"); - } - }); - - Listener lateUpdateListener; - lateUpdateListener.bind([&](float dt) { - if (eventLog.empty() || eventLog.back() != "LateUpdate") { - eventLog.push_back("LateUpdate"); - } - }); - - Listener shutdownListener; - shutdownListener.bind([&]() { - eventLog.push_back("Shutdown"); - }); - - // 初始化 - context->init(); - EXPECT_EQ(1, eventLog.size()); - EXPECT_EQ("Init", eventLog[0]); - - // 运行几帧 - for (int i = 0; i < 3; i++) { - context->tick(0.016f); - } - - EXPECT_EQ(7, eventLog.size()); // Init + 3*(Update + LateUpdate) - EXPECT_EQ("Update", eventLog[1]); - EXPECT_EQ("LateUpdate", eventLog[2]); - - // 关闭 - context->shutdown(); - EXPECT_EQ(8, eventLog.size()); - EXPECT_EQ("Shutdown", eventLog[7]); -} - -// ============================================================================ -// 模块和插件集成测试 -// ============================================================================ - -TEST(Context, ModuleRegistration) { - auto context = Context::create(); - - // 创建一个测试模块 - class TestModule : public IModule { - public: - const char* name() const override { return "TestModule"; } - ModuleType type() const override { return ModuleType::Feature; } - - bool init() override { - initCalled = true; - return true; - } - - void shutdown() override { - shutdownCalled = true; - } - - bool initCalled = false; - bool shutdownCalled = false; - }; - - TestModule testModule; - - // 在初始化前注册模块 - context->modules().registerModule(&testModule); - - context->init(); - - EXPECT_TRUE(testModule.initCalled); - - context->shutdown(); - - EXPECT_TRUE(testModule.shutdownCalled); -} - -TEST(Context, PluginRegistration) { - auto context = Context::create(); - - // 创建一个测试插件 - class TestPlugin : public IPlugin { - public: - const PluginInfo& getInfo() const override { return info_; } - - bool load() override { - loadCalled = true; - return true; - } - - void unload() override { - unloadCalled = true; - } - - PluginInfo info_{"TestPlugin", "1.0.0"}; - bool loadCalled = false; - bool unloadCalled = false; - }; - - TestPlugin testPlugin; - - // 在初始化前注册插件 - context->plugins().registerPlugin(&testPlugin); - - context->init(); - - EXPECT_TRUE(testPlugin.loadCalled); - - context->shutdown(); - - EXPECT_TRUE(testPlugin.unloadCalled); -} - -// ============================================================================ -// 性能测试 -// ============================================================================ - -TEST(Context, HighFrequencyTick) { - auto context = Context::create(); - context->init(); - - int updateCount = 0; - - Listener listener; - listener.bind([&](float dt) { - updateCount++; - }); - - const int iterations = 1000; - for (int i = 0; i < iterations; i++) { - context->tick(0.016f); - } - - EXPECT_EQ(iterations, updateCount); - EXPECT_EQ(iterations, context->frameCount()); - - context->shutdown(); -} - -TEST(Context, MultipleTimers) { - auto context = Context::create(); - context->init(); - - int count1 = 0, count2 = 0, count3 = 0; - - context->timer().scheduleOnce(0.05f, [&]() { count1++; }); - context->timer().scheduleOnce(0.1f, [&]() { count2++; }); - context->timer().scheduleRepeat(0.03f, 5, [&]() { count3++; }); - - // 运行足够长的时间 - for (int i = 0; i < 20; i++) { - context->tick(0.016f); - } - - EXPECT_EQ(1, count1); - EXPECT_EQ(1, count2); - EXPECT_EQ(5, count3); - - context->shutdown(); -} diff --git a/tests/test_event_bus.cpp b/tests/test_event_bus.cpp deleted file mode 100644 index 0b81db0..0000000 --- a/tests/test_event_bus.cpp +++ /dev/null @@ -1,534 +0,0 @@ -#include -#include -#include - -using namespace extra2d; -using extra2d::event::broadcast; -using extra2d::event::Listener; - -// ============================================================================ -// 基础事件测试 -// ============================================================================ - -TEST(EventBus, BasicBroadcast) { - int received = 0; - - { - Listener listener; - listener.bind([&received]() { - received++; - }); - - // 广播事件 - broadcast(); - EXPECT_EQ(1, received); - - // 再次广播 - broadcast(); - EXPECT_EQ(2, received); - } - - // 监听器销毁后不应再接收 - broadcast(); - EXPECT_EQ(2, received); -} - -TEST(EventBus, MultipleListeners) { - int count1 = 0, count2 = 0, count3 = 0; - - Listener listener1; - listener1.bind([&count1](float dt) { - count1++; - }); - - Listener listener2; - listener2.bind([&count2](float dt) { - count2++; - }); - - Listener listener3; - listener3.bind([&count3](float dt) { - count3++; - }); - - broadcast(0.016f); - - EXPECT_EQ(1, count1); - EXPECT_EQ(1, count2); - EXPECT_EQ(1, count3); -} - -TEST(EventBus, ListenerEnableDisable) { - int count = 0; - - Listener listener; - listener.bind([&count]() { - count++; - }); - - // 默认启用 - broadcast(); - EXPECT_EQ(1, count); - - // 禁用 - listener.disable(); - EXPECT_FALSE(listener.isEnabled()); - broadcast(); - EXPECT_EQ(1, count); // 不应增加 - - // 重新启用 - listener.enable(); - EXPECT_TRUE(listener.isEnabled()); - broadcast(); - EXPECT_EQ(2, count); -} - -TEST(EventBus, ListenerReset) { - int count = 0; - - Listener listener; - listener.bind([&count]() { - count++; - }); - - broadcast(); - EXPECT_EQ(1, count); - - // 重置回调 - listener.reset(); - broadcast(); - EXPECT_EQ(1, count); // 不应增加 -} - -// ============================================================================ -// 带参数事件测试 -// ============================================================================ - -TEST(EventBus, EventWithParameters) { - float receivedDt = 0.0f; - - Listener listener; - listener.bind([&receivedDt](float dt) { - receivedDt = dt; - }); - - broadcast(0.016f); - EXPECT_NEAR(0.016f, receivedDt, 0.0001f); - - broadcast(0.033f); - EXPECT_NEAR(0.033f, receivedDt, 0.0001f); -} - -TEST(EventBus, EventWithMultipleParameters) { - int receivedWidth = 0, receivedHeight = 0; - - Listener listener; - listener.bind([&receivedWidth, &receivedHeight](int32 width, int32 height) { - receivedWidth = width; - receivedHeight = height; - }); - - broadcast(1920, 1080); - EXPECT_EQ(1920, receivedWidth); - EXPECT_EQ(1080, receivedHeight); - - broadcast(1280, 720); - EXPECT_EQ(1280, receivedWidth); - EXPECT_EQ(720, receivedHeight); -} - -// ============================================================================ -// 不同事件类型测试 -// ============================================================================ - -TEST(EventBus, DifferentEventTypes) { - int initCount = 0; - int updateCount = 0; - int shutdownCount = 0; - - Listener listener1; - listener1.bind([&initCount]() { - initCount++; - }); - - Listener listener2; - listener2.bind([&updateCount](float dt) { - updateCount++; - }); - - Listener listener3; - listener3.bind([&shutdownCount]() { - shutdownCount++; - }); - - // 广播不同类型的事件 - broadcast(); - EXPECT_EQ(1, initCount); - EXPECT_EQ(0, updateCount); - EXPECT_EQ(0, shutdownCount); - - broadcast(0.016f); - EXPECT_EQ(1, initCount); - EXPECT_EQ(1, updateCount); - EXPECT_EQ(0, shutdownCount); - - broadcast(); - EXPECT_EQ(1, initCount); - EXPECT_EQ(1, updateCount); - EXPECT_EQ(1, shutdownCount); -} - -// ============================================================================ -// 监听器生命周期测试 -// ============================================================================ - -TEST(EventBus, ListenerAutoUnregister) { - int count = 0; - - { - Listener listener; - listener.bind([&count]() { - count++; - }); - - broadcast(); - EXPECT_EQ(1, count); - } // listener 在这里销毁 - - // 再次广播,不应触发 - broadcast(); - EXPECT_EQ(1, count); -} - -TEST(EventBus, ListenerOrder) { - std::vector order; - - Listener listener1; - listener1.bind([&order]() { - order.push_back(1); - }); - - Listener listener2; - listener2.bind([&order]() { - order.push_back(2); - }); - - Listener listener3; - listener3.bind([&order]() { - order.push_back(3); - }); - - broadcast(); - - EXPECT_EQ(3, order.size()); - EXPECT_EQ(1, order[0]); - EXPECT_EQ(2, order[1]); - EXPECT_EQ(3, order[2]); -} - -// ============================================================================ -// 复杂场景测试 -// ============================================================================ - -TEST(EventBus, AddListenerDuringBroadcast) { - // 这个测试验证在广播期间添加监听器的行为 - int count1 = 0; - int count2 = 0; - - Listener* listener2 = nullptr; - - Listener listener1; - listener1.bind([&]() { - count1++; - // 在回调中创建新监听器 - if (!listener2) { - listener2 = new Listener(); - listener2->bind([&count2]() { - count2++; - }); - } - }); - - broadcast(); - EXPECT_EQ(1, count1); - // 新监听器在当前广播中不应被触发 - EXPECT_EQ(0, count2); - - // 下一次广播,新监听器应该被触发 - broadcast(); - EXPECT_EQ(2, count1); - EXPECT_EQ(1, count2); - - delete listener2; -} - -TEST(EventBus, RemoveListenerDuringBroadcast) { - int count1 = 0, count2 = 0, count3 = 0; - - Listener listener1; - listener1.bind([&]() { - count1++; - }); - - { - Listener listener2; - listener2.bind([&]() { - count2++; - }); - - Listener listener3; - listener3.bind([&]() { - count3++; - }); - - broadcast(); - EXPECT_EQ(1, count1); - EXPECT_EQ(1, count2); - EXPECT_EQ(1, count3); - } // listener2 和 listener3 在这里销毁 - - // 再次广播 - broadcast(); - EXPECT_EQ(2, count1); - EXPECT_EQ(1, count2); // 不应增加 - EXPECT_EQ(1, count3); // 不应增加 -} - -// ============================================================================ -// 输入事件测试 -// ============================================================================ - -TEST(EventBus, InputEvents) { - int keyDownCode = -1; - int keyUpCode = -1; - int mouseButton = -1; - int mouseX = -1, mouseY = -1; - - Listener keyDownListener; - keyDownListener.bind([&keyDownCode](int32 key) { - keyDownCode = key; - }); - - Listener keyUpListener; - keyUpListener.bind([&keyUpCode](int32 key) { - keyUpCode = key; - }); - - Listener mouseDownListener; - mouseDownListener.bind([&mouseButton, &mouseX, &mouseY](int32 button, int32 x, int32 y) { - mouseButton = button; - mouseX = x; - mouseY = y; - }); - - // 模拟输入事件 - broadcast(65); // 'A' key - EXPECT_EQ(65, keyDownCode); - - broadcast(65); - EXPECT_EQ(65, keyUpCode); - - broadcast(0, 100, 200); // 左键点击 - EXPECT_EQ(0, mouseButton); - EXPECT_EQ(100, mouseX); - EXPECT_EQ(200, mouseY); -} - -TEST(EventBus, MouseMoveEvent) { - int receivedX = -1, receivedY = -1; - - Listener listener; - listener.bind([&receivedX, &receivedY](int32 x, int32 y) { - receivedX = x; - receivedY = y; - }); - - broadcast(500, 300); - EXPECT_EQ(500, receivedX); - EXPECT_EQ(300, receivedY); -} - -TEST(EventBus, MouseWheelEvent) { - int receivedDelta = 0; - - Listener listener; - listener.bind([&receivedDelta](int32 delta) { - receivedDelta = delta; - }); - - broadcast(120); - EXPECT_EQ(120, receivedDelta); - - broadcast(-120); - EXPECT_EQ(-120, receivedDelta); -} - -// ============================================================================ -// 窗口事件测试 -// ============================================================================ - -TEST(EventBus, WindowEvents) { - bool focusReceived = false; - bool blurReceived = false; - bool showReceived = false; - bool hideReceived = false; - bool closeReceived = false; - int resizeWidth = 0, resizeHeight = 0; - - Listener focusListener; - focusListener.bind([&focusReceived]() { - focusReceived = true; - }); - - Listener blurListener; - blurListener.bind([&blurReceived]() { - blurReceived = true; - }); - - Listener showListener; - showListener.bind([&showReceived]() { - showReceived = true; - }); - - Listener hideListener; - hideListener.bind([&hideReceived]() { - hideReceived = true; - }); - - Listener closeListener; - closeListener.bind([&closeReceived]() { - closeReceived = true; - }); - - Listener resizeListener; - resizeListener.bind([&resizeWidth, &resizeHeight](int32 width, int32 height) { - resizeWidth = width; - resizeHeight = height; - }); - - broadcast(); - EXPECT_TRUE(focusReceived); - - broadcast(); - EXPECT_TRUE(blurReceived); - - broadcast(); - EXPECT_TRUE(showReceived); - - broadcast(); - EXPECT_TRUE(hideReceived); - - broadcast(); - EXPECT_TRUE(closeReceived); - - broadcast(800, 600); - EXPECT_EQ(800, resizeWidth); - EXPECT_EQ(600, resizeHeight); -} - -// ============================================================================ -// 触摸事件测试 -// ============================================================================ - -TEST(EventBus, TouchEvents) { - int touchId = -1; - int touchX = -1, touchY = -1; - - Listener touchBeginListener; - touchBeginListener.bind([&touchId, &touchX, &touchY](int32 id, int32 x, int32 y) { - touchId = id; - touchX = x; - touchY = y; - }); - - broadcast(0, 100, 200); - EXPECT_EQ(0, touchId); - EXPECT_EQ(100, touchX); - EXPECT_EQ(200, touchY); - - Listener touchMoveListener; - touchMoveListener.bind([&touchId, &touchX, &touchY](int32 id, int32 x, int32 y) { - touchId = id; - touchX = x; - touchY = y; - }); - - broadcast(0, 150, 250); - EXPECT_EQ(0, touchId); - EXPECT_EQ(150, touchX); - EXPECT_EQ(250, touchY); - - Listener touchEndListener; - touchEndListener.bind([&touchId, &touchX, &touchY](int32 id, int32 x, int32 y) { - touchId = id; - touchX = x; - touchY = y; - }); - - broadcast(0, 150, 250); - EXPECT_EQ(0, touchId); - EXPECT_EQ(150, touchX); - EXPECT_EQ(250, touchY); -} - -// ============================================================================ -// 游戏手柄事件测试 -// ============================================================================ - -TEST(EventBus, GamepadEvents) { - int connectedDeviceId = -1; - int disconnectedDeviceId = -1; - - Listener connectListener; - connectListener.bind([&connectedDeviceId](int32 deviceId) { - connectedDeviceId = deviceId; - }); - - Listener disconnectListener; - disconnectListener.bind([&disconnectedDeviceId](int32 deviceId) { - disconnectedDeviceId = deviceId; - }); - - broadcast(0); - EXPECT_EQ(0, connectedDeviceId); - - broadcast(0); - EXPECT_EQ(0, disconnectedDeviceId); -} - -// ============================================================================ -// 性能测试 -// ============================================================================ - -TEST(EventBus, HighFrequencyBroadcast) { - const int iterations = 10000; - int count = 0; - - Listener listener; - listener.bind([&count](float dt) { - count++; - }); - - for (int i = 0; i < iterations; i++) { - broadcast(0.016f); - } - - EXPECT_EQ(iterations, count); -} - -TEST(EventBus, ManyListeners) { - const int listenerCount = 100; - int totalCount = 0; - - std::vector>> listeners; - for (int i = 0; i < listenerCount; i++) { - auto listener = std::make_unique>(); - listener->bind([&totalCount]() { - totalCount++; - }); - listeners.push_back(std::move(listener)); - } - - broadcast(); - EXPECT_EQ(listenerCount, totalCount); -} diff --git a/tests/test_module_registry.cpp b/tests/test_module_registry.cpp deleted file mode 100644 index e3e0f21..0000000 --- a/tests/test_module_registry.cpp +++ /dev/null @@ -1,322 +0,0 @@ -#include -#include -#include -#include - -using namespace extra2d; - -// ============================================================================ -// 测试用模块类 -// ============================================================================ - -class TestModule : public IModule { -public: - TestModule(const char* name, ModuleType type, int priority) - : name_(name), type_(type), priority_(priority) {} - - const char* name() const override { return name_.c_str(); } - ModuleType type() const override { return type_; } - int priority() const override { return priority_; } - - bool init() override { - initCalled = true; - return initResult; - } - - void shutdown() override { - shutdownCalled = true; - } - - std::string name_; - ModuleType type_; - int priority_; - bool initCalled = false; - bool shutdownCalled = false; - bool initResult = true; -}; - -// ============================================================================ -// ModuleRegistry 基础测试 -// ============================================================================ - -TEST(ModuleRegistry, BasicOperations) { - ModuleRegistry registry; - - TestModule module1("Module1", ModuleType::Feature, 0); - TestModule module2("Module2", ModuleType::System, 10); - - // 注册模块 - registry.registerModule(&module1); - EXPECT_EQ(1, registry.getModuleCount()); - EXPECT_TRUE(registry.hasModule("Module1")); - - registry.registerModule(&module2); - EXPECT_EQ(2, registry.getModuleCount()); - EXPECT_TRUE(registry.hasModule("Module2")); - - // 获取模块 - EXPECT_EQ(&module1, registry.getModule("Module1")); - EXPECT_EQ(&module2, registry.getModule("Module2")); - EXPECT_EQ(nullptr, registry.getModule("NonExistent")); - - // 注销模块 - registry.unregisterModule("Module1"); - EXPECT_EQ(1, registry.getModuleCount()); - EXPECT_FALSE(registry.hasModule("Module1")); - EXPECT_TRUE(registry.hasModule("Module2")); -} - -TEST(ModuleRegistry, DuplicateRegistration) { - ModuleRegistry registry; - - TestModule module1("SameName", ModuleType::Feature, 0); - TestModule module2("SameName", ModuleType::System, 10); - - registry.registerModule(&module1); - EXPECT_EQ(1, registry.getModuleCount()); - - // 重复注册同名模块,后注册的应覆盖 - registry.registerModule(&module2); - EXPECT_EQ(1, registry.getModuleCount()); - EXPECT_EQ(&module2, registry.getModule("SameName")); -} - -TEST(ModuleRegistry, GetAllModules) { - ModuleRegistry registry; - - TestModule module1("Module1", ModuleType::Feature, 0); - TestModule module2("Module2", ModuleType::System, 10); - TestModule module3("Module3", ModuleType::Core, 5); - - registry.registerModule(&module1); - registry.registerModule(&module2); - registry.registerModule(&module3); - - auto allModules = registry.getAllModules(); - EXPECT_EQ(3, allModules.size()); -} - -TEST(ModuleRegistry, GetModulesByType) { - ModuleRegistry registry; - - TestModule coreModule("CoreModule", ModuleType::Core, 0); - TestModule systemModule1("SystemModule1", ModuleType::System, 10); - TestModule systemModule2("SystemModule2", ModuleType::System, 20); - TestModule featureModule("FeatureModule", ModuleType::Feature, 5); - - registry.registerModule(&coreModule); - registry.registerModule(&systemModule1); - registry.registerModule(&systemModule2); - registry.registerModule(&featureModule); - - auto coreModules = registry.getModulesByType(ModuleType::Core); - EXPECT_EQ(1, coreModules.size()); - - auto systemModules = registry.getModulesByType(ModuleType::System); - EXPECT_EQ(2, systemModules.size()); - - auto featureModules = registry.getModulesByType(ModuleType::Feature); - EXPECT_EQ(1, featureModules.size()); - - auto extensionModules = registry.getModulesByType(ModuleType::Extension); - EXPECT_EQ(0, extensionModules.size()); -} - -// ============================================================================ -// 初始化和关闭测试 -// ============================================================================ - -TEST(ModuleRegistry, InitShutdown) { - ModuleRegistry registry; - - TestModule module1("Module1", ModuleType::Feature, 0); - TestModule module2("Module2", ModuleType::System, 10); - - registry.registerModule(&module1); - registry.registerModule(&module2); - - // 初始化所有模块 - EXPECT_TRUE(registry.initAll()); - EXPECT_TRUE(module1.initCalled); - EXPECT_TRUE(module2.initCalled); - - // 关闭所有模块 - registry.shutdownAll(); - EXPECT_TRUE(module1.shutdownCalled); - EXPECT_TRUE(module2.shutdownCalled); -} - -TEST(ModuleRegistry, InitFailure) { - ModuleRegistry registry; - - TestModule module1("Module1", ModuleType::Feature, 0); - TestModule module2("Module2", ModuleType::System, 10); - module2.initResult = false; // 模拟初始化失败 - - registry.registerModule(&module1); - registry.registerModule(&module2); - - // 初始化应失败 - EXPECT_FALSE(registry.initAll()); - EXPECT_TRUE(module1.initCalled); - EXPECT_TRUE(module2.initCalled); -} - -TEST(ModuleRegistry, PriorityOrder) { - ModuleRegistry registry; - - std::vector initOrder; - std::vector shutdownOrder; - - class OrderTrackingModule : public IModule { - public: - OrderTrackingModule(const char* name, int priority, - std::vector& initVec, - std::vector& shutdownVec) - : name_(name), priority_(priority), - initOrder_(initVec), shutdownOrder_(shutdownVec) {} - - const char* name() const override { return name_.c_str(); } - int priority() const override { return priority_; } - - bool init() override { - initOrder_.push_back(name_); - return true; - } - - void shutdown() override { - shutdownOrder_.push_back(name_); - } - - std::string name_; - int priority_; - std::vector& initOrder_; - std::vector& shutdownOrder_; - }; - - OrderTrackingModule module1("LowPriority", 100, initOrder, shutdownOrder); - OrderTrackingModule module2("HighPriority", 10, initOrder, shutdownOrder); - OrderTrackingModule module3("MediumPriority", 50, initOrder, shutdownOrder); - - registry.registerModule(&module1); - registry.registerModule(&module2); - registry.registerModule(&module3); - - registry.initAll(); - - // 初始化应按优先级顺序(数值小的先初始化) - EXPECT_EQ(3, initOrder.size()); - EXPECT_EQ("HighPriority", initOrder[0]); - EXPECT_EQ("MediumPriority", initOrder[1]); - EXPECT_EQ("LowPriority", initOrder[2]); - - registry.shutdownAll(); - - // 关闭应按优先级逆序(数值大的先关闭) - EXPECT_EQ(3, shutdownOrder.size()); - EXPECT_EQ("LowPriority", shutdownOrder[0]); - EXPECT_EQ("MediumPriority", shutdownOrder[1]); - EXPECT_EQ("HighPriority", shutdownOrder[2]); -} - -// ============================================================================ -// 空注册表测试 -// ============================================================================ - -TEST(ModuleRegistry, EmptyRegistry) { - ModuleRegistry registry; - - EXPECT_EQ(0, registry.getModuleCount()); - EXPECT_FALSE(registry.hasModule("AnyModule")); - EXPECT_EQ(nullptr, registry.getModule("AnyModule")); - - auto allModules = registry.getAllModules(); - EXPECT_EQ(0, allModules.size()); - - // 空注册表的初始化和关闭不应崩溃 - EXPECT_TRUE(registry.initAll()); - registry.shutdownAll(); -} - -TEST(ModuleRegistry, UnregisterNonExistent) { - ModuleRegistry registry; - - // 注销不存在的模块不应崩溃 - EXPECT_NO_THROW(registry.unregisterModule("NonExistent")); -} - -// ============================================================================ -// 模块生命周期测试 -// ============================================================================ - -TEST(ModuleRegistry, ModuleLifecycle) { - ModuleRegistry registry; - - enum class State { Created, Initialized, Running, Shutdown }; - - class LifecycleModule : public IModule { - public: - LifecycleModule(const char* name, State& state) - : name_(name), state_(state) { - state_ = State::Created; - } - - const char* name() const override { return name_.c_str(); } - - bool init() override { - state_ = State::Initialized; - return true; - } - - void shutdown() override { - state_ = State::Shutdown; - } - - std::string name_; - State& state_; - }; - - State state = State::Created; - LifecycleModule module("Lifecycle", state); - - EXPECT_EQ(State::Created, state); - - registry.registerModule(&module); - registry.initAll(); - EXPECT_EQ(State::Initialized, state); - - registry.shutdownAll(); - EXPECT_EQ(State::Shutdown, state); -} - -// ============================================================================ -// 混合类型模块测试 -// ============================================================================ - -TEST(ModuleRegistry, MixedModuleTypes) { - ModuleRegistry registry; - - TestModule coreModule("Core", ModuleType::Core, Pri::System); - TestModule systemModule("System", ModuleType::System, Pri::Window); - TestModule featureModule("Feature", ModuleType::Feature, 0); - TestModule extensionModule("Extension", ModuleType::Extension, 100); - - registry.registerModule(&coreModule); - registry.registerModule(&systemModule); - registry.registerModule(&featureModule); - registry.registerModule(&extensionModule); - - EXPECT_EQ(4, registry.getModuleCount()); - - EXPECT_TRUE(registry.initAll()); - EXPECT_TRUE(coreModule.initCalled); - EXPECT_TRUE(systemModule.initCalled); - EXPECT_TRUE(featureModule.initCalled); - EXPECT_TRUE(extensionModule.initCalled); - - registry.shutdownAll(); - EXPECT_TRUE(coreModule.shutdownCalled); - EXPECT_TRUE(systemModule.shutdownCalled); - EXPECT_TRUE(featureModule.shutdownCalled); - EXPECT_TRUE(extensionModule.shutdownCalled); -} diff --git a/tests/test_plugin_loader.cpp b/tests/test_plugin_loader.cpp deleted file mode 100644 index 3a67968..0000000 --- a/tests/test_plugin_loader.cpp +++ /dev/null @@ -1,413 +0,0 @@ -#include -#include -#include -#include - -using namespace extra2d; - -// ============================================================================ -// 测试用插件类 -// ============================================================================ - -class TestPlugin : public IPlugin { -public: - TestPlugin(const char* name, const char* version = "1.0.0", - const std::vector& deps = {}) - : name_(name), version_(version), dependencies_(deps) { - info_.name = name; - info_.version = version; - info_.dependencies = deps; - } - - const PluginInfo& getInfo() const override { return info_; } - - bool load() override { - loadCalled = true; - return loadResult; - } - - void unload() override { - unloadCalled = true; - } - - std::vector getDependencies() const override { - return dependencies_; - } - - std::string name_; - std::string version_; - std::vector dependencies_; - PluginInfo info_; - bool loadCalled = false; - bool unloadCalled = false; - bool loadResult = true; -}; - -// ============================================================================ -// PluginLoader 基础测试 -// ============================================================================ - -TEST(PluginLoader, BasicOperations) { - PluginLoader loader; - - TestPlugin plugin1("Plugin1"); - TestPlugin plugin2("Plugin2", "2.0.0"); - - // 注册插件 - loader.registerPlugin(&plugin1); - EXPECT_EQ(1, loader.getPluginCount()); - EXPECT_TRUE(loader.hasPlugin("Plugin1")); - - loader.registerPlugin(&plugin2); - EXPECT_EQ(2, loader.getPluginCount()); - EXPECT_TRUE(loader.hasPlugin("Plugin2")); - - // 获取插件 - EXPECT_EQ(&plugin1, loader.getPlugin("Plugin1")); - EXPECT_EQ(&plugin2, loader.getPlugin("Plugin2")); - EXPECT_EQ(nullptr, loader.getPlugin("NonExistent")); - - // 卸载插件 - loader.unloadPlugin("Plugin1"); - EXPECT_EQ(1, loader.getPluginCount()); - EXPECT_FALSE(loader.hasPlugin("Plugin1")); - EXPECT_TRUE(loader.hasPlugin("Plugin2")); -} - -TEST(PluginLoader, DuplicateRegistration) { - PluginLoader loader; - - TestPlugin plugin1("SameName", "1.0.0"); - TestPlugin plugin2("SameName", "2.0.0"); - - loader.registerPlugin(&plugin1); - EXPECT_EQ(1, loader.getPluginCount()); - - // 重复注册同名插件,后注册的应覆盖 - loader.registerPlugin(&plugin2); - EXPECT_EQ(1, loader.getPluginCount()); - - IPlugin* retrieved = loader.getPlugin("SameName"); - EXPECT_NE(nullptr, retrieved); - EXPECT_EQ("2.0.0", retrieved->getInfo().version); -} - -TEST(PluginLoader, GetAllPlugins) { - PluginLoader loader; - - TestPlugin plugin1("Plugin1"); - TestPlugin plugin2("Plugin2"); - TestPlugin plugin3("Plugin3"); - - loader.registerPlugin(&plugin1); - loader.registerPlugin(&plugin2); - loader.registerPlugin(&plugin3); - - auto allPlugins = loader.getAllPlugins(); - EXPECT_EQ(3, allPlugins.size()); -} - -// ============================================================================ -// 加载和卸载测试 -// ============================================================================ - -TEST(PluginLoader, LoadUnload) { - PluginLoader loader; - - TestPlugin plugin1("Plugin1"); - TestPlugin plugin2("Plugin2"); - - loader.registerPlugin(&plugin1); - loader.registerPlugin(&plugin2); - - // 加载所有插件 - EXPECT_TRUE(loader.initAll()); - EXPECT_TRUE(plugin1.loadCalled); - EXPECT_TRUE(plugin2.loadCalled); - - // 卸载所有插件 - loader.shutdownAll(); - EXPECT_TRUE(plugin1.unloadCalled); - EXPECT_TRUE(plugin2.unloadCalled); -} - -TEST(PluginLoader, LoadFailure) { - PluginLoader loader; - - TestPlugin plugin1("Plugin1"); - TestPlugin plugin2("Plugin2"); - plugin2.loadResult = false; // 模拟加载失败 - - loader.registerPlugin(&plugin1); - loader.registerPlugin(&plugin2); - - // 加载应失败 - EXPECT_FALSE(loader.initAll()); - EXPECT_TRUE(plugin1.loadCalled); - EXPECT_TRUE(plugin2.loadCalled); -} - -// ============================================================================ -// 依赖关系测试 -// ============================================================================ - -TEST(PluginLoader, Dependencies) { - PluginLoader loader; - - // PluginC 依赖 PluginB,PluginB 依赖 PluginA - TestPlugin pluginA("PluginA"); - TestPlugin pluginB("PluginB", "1.0.0", {"PluginA"}); - TestPlugin pluginC("PluginC", "1.0.0", {"PluginB"}); - - loader.registerPlugin(&pluginC); - loader.registerPlugin(&pluginB); - loader.registerPlugin(&pluginA); - - // 所有插件都应能加载(依赖会自动解析) - EXPECT_TRUE(loader.initAll()); - EXPECT_TRUE(pluginA.loadCalled); - EXPECT_TRUE(pluginB.loadCalled); - EXPECT_TRUE(pluginC.loadCalled); - - loader.shutdownAll(); -} - -TEST(PluginLoader, MissingDependency) { - PluginLoader loader; - - // PluginB 依赖不存在的 PluginA - TestPlugin pluginB("PluginB", "1.0.0", {"PluginA"}); - - loader.registerPlugin(&pluginB); - - // 加载应失败(依赖未满足) - EXPECT_FALSE(loader.initAll()); - EXPECT_FALSE(pluginB.loadCalled); -} - -TEST(PluginLoader, CircularDependency) { - PluginLoader loader; - - // A 依赖 B,B 依赖 A(循环依赖) - TestPlugin pluginA("PluginA", "1.0.0", {"PluginB"}); - TestPlugin pluginB("PluginB", "1.0.0", {"PluginA"}); - - loader.registerPlugin(&pluginA); - loader.registerPlugin(&pluginB); - - // 循环依赖应能处理(目前实现可能不检测循环,但至少不应崩溃) - // 注意:根据实现不同,这可能成功或失败 - loader.initAll(); - loader.shutdownAll(); -} - -TEST(PluginLoader, DependencyLoadOrder) { - PluginLoader loader; - - std::vector loadOrder; - std::vector unloadOrder; - - class OrderTrackingPlugin : public IPlugin { - public: - OrderTrackingPlugin(const char* name, - const std::vector& deps, - std::vector& loadVec, - std::vector& unloadVec) - : name_(name), loadOrder_(loadVec), unloadOrder_(unloadVec) { - info_.name = name; - info_.dependencies = deps; - } - - const PluginInfo& getInfo() const override { return info_; } - - bool load() override { - loadOrder_.push_back(name_); - return true; - } - - void unload() override { - unloadOrder_.push_back(name_); - } - - std::string name_; - PluginInfo info_; - std::vector& loadOrder_; - std::vector& unloadOrder_; - }; - - // C 依赖 B,B 依赖 A - OrderTrackingPlugin pluginC("PluginC", {"PluginB"}, loadOrder, unloadOrder); - OrderTrackingPlugin pluginA("PluginA", {}, loadOrder, unloadOrder); - OrderTrackingPlugin pluginB("PluginB", {"PluginA"}, loadOrder, unloadOrder); - - loader.registerPlugin(&pluginC); - loader.registerPlugin(&pluginA); - loader.registerPlugin(&pluginB); - - loader.initAll(); - - // 加载顺序应满足依赖关系 - EXPECT_EQ(3, loadOrder.size()); - // A 必须在 B 之前加载 - auto aPos = std::find(loadOrder.begin(), loadOrder.end(), "PluginA"); - auto bPos = std::find(loadOrder.begin(), loadOrder.end(), "PluginB"); - auto cPos = std::find(loadOrder.begin(), loadOrder.end(), "PluginC"); - EXPECT_TRUE(aPos < bPos); - EXPECT_TRUE(bPos < cPos); - - loader.shutdownAll(); - - // 卸载顺序应与加载顺序相反 - EXPECT_EQ(3, unloadOrder.size()); -} - -// ============================================================================ -// 空加载器测试 -// ============================================================================ - -TEST(PluginLoader, EmptyLoader) { - PluginLoader loader; - - EXPECT_EQ(0, loader.getPluginCount()); - EXPECT_FALSE(loader.hasPlugin("AnyPlugin")); - EXPECT_EQ(nullptr, loader.getPlugin("AnyPlugin")); - - auto allPlugins = loader.getAllPlugins(); - EXPECT_EQ(0, allPlugins.size()); - - // 空加载器的初始化和关闭不应崩溃 - EXPECT_TRUE(loader.initAll()); - loader.shutdownAll(); -} - -TEST(PluginLoader, UnloadNonExistent) { - PluginLoader loader; - - // 卸载不存在的插件不应崩溃 - EXPECT_NO_THROW(loader.unloadPlugin("NonExistent")); -} - -// ============================================================================ -// 搜索路径测试 -// ============================================================================ - -TEST(PluginLoader, SearchPaths) { - PluginLoader loader; - - // 添加搜索路径 - loader.addSearchPath("/usr/lib/extra2d/plugins"); - loader.addSearchPath("/home/user/.extra2d/plugins"); - loader.addSearchPath("./plugins"); - - // 搜索路径功能主要用于动态库加载,这里只验证不崩溃 - EXPECT_NO_THROW(loader.loadPluginsFromDirectory("./non_existent_dir")); -} - -// ============================================================================ -// 插件信息测试 -// ============================================================================ - -TEST(PluginLoader, PluginInfo) { - PluginLoader loader; - - TestPlugin plugin("TestPlugin", "1.2.3"); - plugin.info_.author = "Test Author"; - plugin.info_.description = "Test Description"; - plugin.info_.dependencies = {"Dep1", "Dep2"}; - - loader.registerPlugin(&plugin); - - IPlugin* retrieved = loader.getPlugin("TestPlugin"); - EXPECT_NE(nullptr, retrieved); - - const PluginInfo& info = retrieved->getInfo(); - EXPECT_EQ("TestPlugin", info.name); - EXPECT_EQ("1.2.3", info.version); - EXPECT_EQ("Test Author", info.author); - EXPECT_EQ("Test Description", info.description); - EXPECT_EQ(2, info.dependencies.size()); - EXPECT_EQ("Dep1", info.dependencies[0]); - EXPECT_EQ("Dep2", info.dependencies[1]); -} - -// ============================================================================ -// 插件生命周期测试 -// ============================================================================ - -TEST(PluginLoader, PluginLifecycle) { - PluginLoader loader; - - enum class State { Created, Loaded, Running, Unloaded }; - - class LifecyclePlugin : public IPlugin { - public: - LifecyclePlugin(const char* name, State& state) - : name_(name), state_(state) { - state_ = State::Created; - info_.name = name; - } - - const PluginInfo& getInfo() const override { return info_; } - - bool load() override { - state_ = State::Loaded; - return true; - } - - void unload() override { - state_ = State::Unloaded; - } - - std::string name_; - State& state_; - PluginInfo info_; - }; - - State state = State::Created; - LifecyclePlugin plugin("Lifecycle", state); - - EXPECT_EQ(State::Created, state); - - loader.registerPlugin(&plugin); - loader.initAll(); - EXPECT_EQ(State::Loaded, state); - - loader.shutdownAll(); - EXPECT_EQ(State::Unloaded, state); -} - -// ============================================================================ -// 复杂依赖测试 -// ============================================================================ - -TEST(PluginLoader, ComplexDependencies) { - PluginLoader loader; - - // 创建复杂的依赖图: - // A -> B -> D - // A -> C -> D - // E (独立) - - TestPlugin pluginA("A", "1.0.0", {}); - TestPlugin pluginB("B", "1.0.0", {"A"}); - TestPlugin pluginC("C", "1.0.0", {"A"}); - TestPlugin pluginD("D", "1.0.0", {"B", "C"}); - TestPlugin pluginE("E", "1.0.0", {}); - - // 乱序注册 - loader.registerPlugin(&pluginD); - loader.registerPlugin(&pluginB); - loader.registerPlugin(&pluginE); - loader.registerPlugin(&pluginC); - loader.registerPlugin(&pluginA); - - // 所有插件都应能加载 - EXPECT_TRUE(loader.initAll()); - EXPECT_TRUE(pluginA.loadCalled); - EXPECT_TRUE(pluginB.loadCalled); - EXPECT_TRUE(pluginC.loadCalled); - EXPECT_TRUE(pluginD.loadCalled); - EXPECT_TRUE(pluginE.loadCalled); - - loader.shutdownAll(); -} diff --git a/tests/test_timer_module.cpp b/tests/test_timer_module.cpp deleted file mode 100644 index a51c728..0000000 --- a/tests/test_timer_module.cpp +++ /dev/null @@ -1,405 +0,0 @@ -#include -#include - -using namespace extra2d; - -// ============================================================================ -// TimerModule 基础测试 -// ============================================================================ - -TEST(TimerModule, BasicProperties) { - TimerModule timer; - - // 测试基本属性 - EXPECT_STREQ("Timer", timer.name()); - EXPECT_EQ(ModuleType::Core, timer.type()); - EXPECT_EQ(Pri::System, timer.priority()); -} - -TEST(TimerModule, InitShutdown) { - TimerModule timer; - - // 测试初始化和关闭 - EXPECT_TRUE(timer.init()); - timer.shutdown(); -} - -TEST(TimerModule, TimeScale) { - TimerModule timer; - - // 测试时间缩放默认值 - EXPECT_FLOAT_EQ(1.0f, timer.getTimeScale()); - - // 测试设置时间缩放 - timer.setTimeScale(2.0f); - EXPECT_FLOAT_EQ(2.0f, timer.getTimeScale()); - - timer.setTimeScale(0.5f); - EXPECT_FLOAT_EQ(0.5f, timer.getTimeScale()); - - // 测试边界值 - timer.setTimeScale(0.0f); - EXPECT_FLOAT_EQ(0.0f, timer.getTimeScale()); -} - -// ============================================================================ -// 一次性定时器测试 -// ============================================================================ - -TEST(TimerModule, ScheduleOnce) { - TimerModule timer; - timer.init(); - - bool called = false; - TimerId id = timer.scheduleOnce(0.1f, [&called]() { - called = true; - }); - - EXPECT_NE(INVALID_TIMER_ID, id); - EXPECT_EQ(1, timer.getActiveCount()); - - // 模拟时间流逝(未到达触发时间) - timer.update(0.05f); - EXPECT_FALSE(called); - EXPECT_EQ(1, timer.getActiveCount()); - - // 模拟时间流逝(到达触发时间) - timer.update(0.05f); - EXPECT_TRUE(called); - EXPECT_EQ(0, timer.getActiveCount()); - - timer.shutdown(); -} - -TEST(TimerModule, ScheduleOnceImmediate) { - TimerModule timer; - timer.init(); - - bool called = false; - TimerId id = timer.scheduleOnce(0.0f, [&called]() { - called = true; - }); - - EXPECT_NE(INVALID_TIMER_ID, id); - - // 立即触发 - timer.update(0.0f); - EXPECT_TRUE(called); - - timer.shutdown(); -} - -TEST(TimerModule, CancelTimer) { - TimerModule timer; - timer.init(); - - bool called = false; - TimerId id = timer.scheduleOnce(0.1f, [&called]() { - called = true; - }); - - // 取消定时器 - timer.cancel(id); - - // 模拟时间流逝 - timer.update(0.2f); - EXPECT_FALSE(called); - EXPECT_EQ(0, timer.getActiveCount()); - - timer.shutdown(); -} - -TEST(TimerModule, CancelInvalidTimer) { - TimerModule timer; - timer.init(); - - // 取消不存在的定时器不应崩溃 - EXPECT_NO_THROW(timer.cancel(99999)); - - timer.shutdown(); -} - -// ============================================================================ -// 重复定时器测试 -// ============================================================================ - -TEST(TimerModule, ScheduleRepeat) { - TimerModule timer; - timer.init(); - - int callCount = 0; - TimerId id = timer.scheduleRepeat(0.1f, 3, [&callCount]() { - callCount++; - }); - - EXPECT_NE(INVALID_TIMER_ID, id); - - // 第一次触发 - timer.update(0.1f); - EXPECT_EQ(1, callCount); - - // 第二次触发 - timer.update(0.1f); - EXPECT_EQ(2, callCount); - - // 第三次触发 - timer.update(0.1f); - EXPECT_EQ(3, callCount); - - // 定时器应已自动移除 - EXPECT_EQ(0, timer.getActiveCount()); - - timer.shutdown(); -} - -TEST(TimerModule, ScheduleRepeatInfinite) { - TimerModule timer; - timer.init(); - - int callCount = 0; - TimerId id = timer.scheduleRepeat(0.1f, 0, [&callCount]() { - callCount++; - }); - - // 触发多次 - for (int i = 0; i < 10; i++) { - timer.update(0.1f); - } - - EXPECT_EQ(10, callCount); - EXPECT_EQ(1, timer.getActiveCount()); - - // 取消无限定时器 - timer.cancel(id); - EXPECT_EQ(0, timer.getActiveCount()); - - timer.shutdown(); -} - -// ============================================================================ -// 每帧更新定时器测试 -// ============================================================================ - -TEST(TimerModule, ScheduleUpdate) { - TimerModule timer; - timer.init(); - - float totalDt = 0.0f; - int callCount = 0; - TimerId id = timer.scheduleUpdate([&](float dt) { - totalDt += dt; - callCount++; - }); - - EXPECT_NE(INVALID_TIMER_ID, id); - - // 模拟多帧 - timer.update(0.016f); - timer.update(0.016f); - timer.update(0.016f); - - EXPECT_EQ(3, callCount); - EXPECT_FLOAT_EQ(0.048f, totalDt); - - // 取消更新定时器 - timer.cancel(id); - EXPECT_EQ(0, timer.getActiveCount()); - - timer.shutdown(); -} - -// ============================================================================ -// 暂停和恢复测试 -// ============================================================================ - -TEST(TimerModule, PauseResume) { - TimerModule timer; - timer.init(); - - int callCount = 0; - TimerId id = timer.scheduleRepeat(0.1f, 0, [&callCount]() { - callCount++; - }); - - // 正常触发一次 - timer.update(0.1f); - EXPECT_EQ(1, callCount); - - // 暂停 - timer.pause(id); - timer.update(0.1f); - EXPECT_EQ(1, callCount); // 不应增加 - - // 恢复 - timer.resume(id); - timer.update(0.1f); - EXPECT_EQ(2, callCount); - - timer.shutdown(); -} - -TEST(TimerModule, PauseInvalidTimer) { - TimerModule timer; - timer.init(); - - // 暂停不存在的定时器不应崩溃 - EXPECT_NO_THROW(timer.pause(99999)); - EXPECT_NO_THROW(timer.resume(99999)); - - timer.shutdown(); -} - -// ============================================================================ -// 时间缩放测试 -// ============================================================================ - -TEST(TimerModule, TimeScaleEffect) { - TimerModule timer; - timer.init(); - - int callCount = 0; - timer.scheduleRepeat(1.0f, 0, [&callCount]() { - callCount++; - }); - - // 设置2倍速 - timer.setTimeScale(2.0f); - - // 实际经过0.5秒,但效果相当于1秒 - timer.update(0.5f); - EXPECT_EQ(1, callCount); - - timer.shutdown(); -} - -TEST(TimerModule, TimeScaleZero) { - TimerModule timer; - timer.init(); - - int callCount = 0; - timer.scheduleRepeat(0.1f, 0, [&callCount]() { - callCount++; - }); - - // 暂停时间 - timer.setTimeScale(0.0f); - - // 无论经过多少时间,都不会触发 - timer.update(1.0f); - timer.update(1.0f); - EXPECT_EQ(0, callCount); - - // 恢复时间 - timer.setTimeScale(1.0f); - timer.update(0.1f); - EXPECT_EQ(1, callCount); - - timer.shutdown(); -} - -// ============================================================================ -// 多定时器测试 -// ============================================================================ - -TEST(TimerModule, MultipleTimers) { - TimerModule timer; - timer.init(); - - int count1 = 0, count2 = 0, count3 = 0; - - TimerId id1 = timer.scheduleOnce(0.1f, [&count1]() { count1++; }); - TimerId id2 = timer.scheduleOnce(0.2f, [&count2]() { count2++; }); - TimerId id3 = timer.scheduleOnce(0.3f, [&count3]() { count3++; }); - - EXPECT_EQ(3, timer.getActiveCount()); - - // 经过0.15秒 - timer.update(0.15f); - EXPECT_EQ(1, count1); - EXPECT_EQ(0, count2); - EXPECT_EQ(0, count3); - EXPECT_EQ(2, timer.getActiveCount()); - - // 再经过0.1秒 - timer.update(0.1f); - EXPECT_EQ(1, count1); - EXPECT_EQ(1, count2); - EXPECT_EQ(0, count3); - EXPECT_EQ(1, timer.getActiveCount()); - - // 再经过0.1秒 - timer.update(0.1f); - EXPECT_EQ(1, count1); - EXPECT_EQ(1, count2); - EXPECT_EQ(1, count3); - EXPECT_EQ(0, timer.getActiveCount()); - - timer.shutdown(); -} - -TEST(TimerModule, CancelAll) { - TimerModule timer; - timer.init(); - - int count = 0; - timer.scheduleOnce(0.1f, [&count]() { count++; }); - timer.scheduleOnce(0.2f, [&count]() { count++; }); - timer.scheduleOnce(0.3f, [&count]() { count++; }); - - EXPECT_EQ(3, timer.getActiveCount()); - - // 取消所有 - timer.cancelAll(); - EXPECT_EQ(0, timer.getActiveCount()); - - // 确认都不会触发 - timer.update(0.5f); - EXPECT_EQ(0, count); - - timer.shutdown(); -} - -// ============================================================================ -// 边界条件测试 -// ============================================================================ - -TEST(TimerModule, SelfCancelInCallback) { - TimerModule timer; - timer.init(); - - TimerId id = INVALID_TIMER_ID; - bool called = false; - - // 在回调中取消自己 - id = timer.scheduleOnce(0.1f, [&]() { - called = true; - timer.cancel(id); - }); - - timer.update(0.1f); - EXPECT_TRUE(called); - - timer.shutdown(); -} - -TEST(TimerModule, ScheduleInCallback) { - TimerModule timer; - timer.init(); - - bool secondCalled = false; - - // 在回调中创建新定时器 - timer.scheduleOnce(0.1f, [&]() { - timer.scheduleOnce(0.1f, [&]() { - secondCalled = true; - }); - }); - - timer.update(0.1f); - EXPECT_FALSE(secondCalled); - - timer.update(0.1f); - EXPECT_TRUE(secondCalled); - - timer.shutdown(); -} diff --git a/tests/xmake.lua b/tests/xmake.lua deleted file mode 100644 index 0825000..0000000 --- a/tests/xmake.lua +++ /dev/null @@ -1,59 +0,0 @@ --- Extra2D 测试套件构建脚本 --- 使用 GoogleTest 标准测试框架 - --- 添加 gtest 包依赖 -add_requires("gtest") - -target("extra2d_tests") - set_kind("binary") - set_languages("c++17") - - -- 添加 gtest 包 - add_packages("gtest") - - -- 添加测试源文件 - add_files("*.cpp") - - -- 添加头文件搜索路径 - add_includedirs(".") - add_includedirs("../include") - - -- 添加引擎源文件(仅核心模块,避免平台依赖) - add_files("../src/context/context.cpp") - add_files("../src/module/module_registry.cpp") - add_files("../src/module/timer_module.cpp") - add_files("../src/plugin/plugin_loader.cpp") - add_files("../src/event/event_bus.cpp") - add_files("../src/utils/random.cpp") - -- 注意:logger.cpp 在 TEST_BUILD 模式下使用条件编译避免 SDL 依赖 - - -- 第三方库 - add_includedirs("../third_party/nlohmann") - add_includedirs("../third_party/stb") - - -- 定义 TEST_BUILD 宏,用于条件编译 - add_defines("TEST_BUILD") - - -- 编译选项 - if is_mode("debug") then - add_defines("DEBUG") - set_symbols("debug") - set_optimize("none") - else - add_defines("NDEBUG") - set_optimize("fastest") - set_strip("all") - end - - -- 警告设置 - set_warnings("all") - - -- 平台特定设置 - if is_plat("windows") then - add_cxflags("/wd4267", "/wd4244", "/wd4996", "/wd4100", "/wd4458") - add_syslinks("kernel32", "user32") - elseif is_plat("mingw") then - add_cxflags("-Wno-unused-parameter", "-Wno-unused-variable") - else - add_cxflags("-Wno-unused-parameter", "-Wno-unused-variable") - end diff --git a/xmake.lua b/xmake.lua index cd1504a..e6ff1d2 100644 --- a/xmake.lua +++ b/xmake.lua @@ -97,10 +97,6 @@ if is_config("examples","true") then includes("examples/resource_loading", {rootdir = "examples/resource_loading"}) end --- 测试套件目标(作为子项目) -if is_config("tests","true") then - includes("tests") -end -- ============================================== -- 项目信息输出