Expand editor regression coverage

This commit is contained in:
2026-03-27 12:18:40 +08:00
parent 9a5c187abc
commit 4afe2f88ba
2 changed files with 80 additions and 0 deletions

View File

@@ -304,10 +304,14 @@
- 已新增 `tests/editor/test_action_routing.cpp` - 已新增 `tests/editor/test_action_routing.cpp`
- 已新增 `tests/editor/CMakeLists.txt``editor_tests` target - 已新增 `tests/editor/CMakeLists.txt``editor_tests` target
- 当前 `editor_tests` 已覆盖 7 条 editor 回归用例
- 已覆盖 `Hierarchy Edit route` 的 copy / paste / duplicate / delete / rename request - 已覆盖 `Hierarchy Edit route` 的 copy / paste / duplicate / delete / rename request
- 已覆盖 `Project Edit route` 的 open / back / delete - 已覆盖 `Project Edit route` 的 open / back / delete
- 已覆盖 `scene dirty save + load` 后的 selection / undo reset - 已覆盖 `scene dirty save + load` 后的 selection / undo reset
- 已覆盖 `reparent` 的 parent 切换、cycle 拦截与 world position / scale 保持 - 已覆盖 `reparent` 的 parent 切换、cycle 拦截与 world position / scale 保持
- 已覆盖 `MainMenu` 的 exit / reset-layout 事件请求与 about popup 请求
- 已覆盖 `Hierarchy` rename helper 的 request / commit 语义
- 已覆盖 `Project` 的 create-folder / move-asset / open-folder helper
## 下一阶段建议执行顺序 ## 下一阶段建议执行顺序

View File

@@ -1,6 +1,9 @@
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include "Actions/EditActionRouter.h" #include "Actions/EditActionRouter.h"
#include "Actions/HierarchyActionRouter.h"
#include "Actions/MainMenuActionRouter.h"
#include "Actions/ProjectActionRouter.h"
#include "Commands/EntityCommands.h" #include "Commands/EntityCommands.h"
#include "Commands/SceneCommands.h" #include "Commands/SceneCommands.h"
#include "Core/EditorContext.h" #include "Core/EditorContext.h"
@@ -220,5 +223,78 @@ TEST_F(EditorActionRoutingTest, ReparentPreserveWorldTransformKeepsWorldPose) {
ExpectNear(child->GetTransform()->GetScale(), worldScaleBefore); ExpectNear(child->GetTransform()->GetScale(), worldScaleBefore);
} }
TEST_F(EditorActionRoutingTest, MainMenuRouterRequestsExitResetAndAboutPopup) {
int exitRequestCount = 0;
int resetLayoutCount = 0;
const uint64_t exitSubscription = m_context.GetEventBus().Subscribe<EditorExitRequestedEvent>(
[&](const EditorExitRequestedEvent&) {
++exitRequestCount;
});
const uint64_t resetSubscription = m_context.GetEventBus().Subscribe<DockLayoutResetRequestedEvent>(
[&](const DockLayoutResetRequestedEvent&) {
++resetLayoutCount;
});
UI::DeferredPopupState aboutPopup;
EXPECT_FALSE(aboutPopup.HasPendingOpenRequest());
Actions::RequestAboutPopup(aboutPopup);
Actions::RequestDockLayoutReset(m_context);
Actions::RequestEditorExit(m_context);
EXPECT_TRUE(aboutPopup.HasPendingOpenRequest());
EXPECT_EQ(resetLayoutCount, 1);
EXPECT_EQ(exitRequestCount, 1);
m_context.GetEventBus().Unsubscribe<EditorExitRequestedEvent>(exitSubscription);
m_context.GetEventBus().Unsubscribe<DockLayoutResetRequestedEvent>(resetSubscription);
}
TEST_F(EditorActionRoutingTest, HierarchyRouterRenameHelpersPublishAndCommit) {
auto* entity = Commands::CreateEmptyEntity(m_context, nullptr, "Create Entity", "BeforeRename");
ASSERT_NE(entity, nullptr);
uint64_t renameRequestedId = 0;
const uint64_t renameSubscription = m_context.GetEventBus().Subscribe<EntityRenameRequestedEvent>(
[&](const EntityRenameRequestedEvent& event) {
renameRequestedId = event.entityId;
});
Actions::RequestEntityRename(m_context, entity);
EXPECT_EQ(renameRequestedId, entity->GetID());
EXPECT_TRUE(Actions::CommitEntityRename(m_context, entity->GetID(), "AfterRename"));
ASSERT_NE(m_context.GetSceneManager().GetEntity(entity->GetID()), nullptr);
EXPECT_EQ(m_context.GetSceneManager().GetEntity(entity->GetID())->GetName(), "AfterRename");
EXPECT_TRUE(m_context.GetUndoManager().CanUndo());
EXPECT_FALSE(Actions::CommitEntityRename(m_context, entity->GetID(), ""));
EXPECT_FALSE(Actions::CommitEntityRename(m_context, 0, "Invalid"));
m_context.GetEventBus().Unsubscribe<EntityRenameRequestedEvent>(renameSubscription);
}
TEST_F(EditorActionRoutingTest, ProjectCommandsCreateFolderMoveAssetAndOpenFolderHelper) {
const fs::path assetsDir = m_projectRoot / "Assets";
const fs::path sourceFilePath = assetsDir / "MoveMe.txt";
std::ofstream(sourceFilePath.string()) << "move source";
EXPECT_TRUE(Commands::CreateFolder(m_context.GetProjectManager(), "MovedFolder"));
m_context.GetProjectManager().RefreshCurrentFolder();
const AssetItemPtr folderItem = FindCurrentItemByName("MovedFolder");
ASSERT_NE(folderItem, nullptr);
ASSERT_TRUE(folderItem->isFolder);
EXPECT_TRUE(Commands::MoveAssetToFolder(m_context.GetProjectManager(), sourceFilePath.string(), folderItem));
EXPECT_FALSE(fs::exists(sourceFilePath));
EXPECT_TRUE(fs::exists(assetsDir / "MovedFolder" / "MoveMe.txt"));
EXPECT_TRUE(Actions::OpenProjectAsset(m_context, folderItem));
EXPECT_EQ(m_context.GetProjectManager().GetCurrentPath(), "Assets/MovedFolder");
}
} // namespace } // namespace
} // namespace XCEngine::Editor } // namespace XCEngine::Editor