#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(); }