Document editor architecture finish state

This commit is contained in:
2026-03-27 12:35:05 +08:00
parent 4afe2f88ba
commit fd0b19fd11
3 changed files with 543 additions and 289 deletions

View File

@@ -196,6 +196,38 @@ TEST_F(EditorActionRoutingTest, LoadSceneResetsSelectionAndUndoAfterFallbackSave
EXPECT_EQ(m_context.GetSceneManager().GetRootEntities()[0]->GetName(), "SavedEntity");
}
TEST_F(EditorActionRoutingTest, NewSceneResetsSelectionAndUndoForCleanScene) {
auto* entity = Commands::CreateEmptyEntity(m_context, nullptr, "Create Entity", "BeforeNewScene");
ASSERT_NE(entity, nullptr);
ASSERT_TRUE(m_context.GetSelectionManager().HasSelection());
ASSERT_TRUE(m_context.GetUndoManager().CanUndo());
const fs::path savedScenePath = m_projectRoot / "Assets" / "Scenes" / "BeforeNewScene.xc";
ASSERT_TRUE(m_context.GetSceneManager().SaveSceneAs(savedScenePath.string()));
ASSERT_FALSE(m_context.GetSceneManager().IsSceneDirty());
EXPECT_TRUE(Commands::NewScene(m_context, "Fresh Scene"));
EXPECT_TRUE(m_context.GetSceneManager().HasActiveScene());
EXPECT_TRUE(m_context.GetSceneManager().IsSceneDirty());
EXPECT_EQ(m_context.GetSceneManager().GetCurrentSceneName(), "Fresh Scene");
EXPECT_TRUE(m_context.GetSceneManager().GetCurrentScenePath().empty());
EXPECT_TRUE(m_context.GetSceneManager().GetRootEntities().empty());
EXPECT_FALSE(m_context.GetSelectionManager().HasSelection());
EXPECT_FALSE(m_context.GetUndoManager().CanUndo());
}
TEST_F(EditorActionRoutingTest, SaveDirtySceneWithFallbackDoesNothingWhenSceneIsAlreadyClean) {
const fs::path savedScenePath = m_projectRoot / "Assets" / "Scenes" / "CleanScene.xc";
ASSERT_TRUE(m_context.GetSceneManager().SaveSceneAs(savedScenePath.string()));
ASSERT_FALSE(m_context.GetSceneManager().IsSceneDirty());
const fs::path unusedFallbackPath = m_projectRoot / "Assets" / "Scenes" / "UnusedFallback.xc";
EXPECT_TRUE(Commands::SaveDirtySceneWithFallback(m_context, unusedFallbackPath.string()));
EXPECT_TRUE(fs::exists(savedScenePath));
EXPECT_FALSE(fs::exists(unusedFallbackPath));
EXPECT_EQ(fs::path(m_context.GetSceneManager().GetCurrentScenePath()), savedScenePath);
}
TEST_F(EditorActionRoutingTest, ReparentPreserveWorldTransformKeepsWorldPose) {
auto* parentA = Commands::CreateEmptyEntity(m_context, nullptr, "Create Parent A", "ParentA");
auto* child = Commands::CreateEmptyEntity(m_context, parentA, "Create Child", "Child");
@@ -296,5 +328,30 @@ TEST_F(EditorActionRoutingTest, ProjectCommandsCreateFolderMoveAssetAndOpenFolde
EXPECT_EQ(m_context.GetProjectManager().GetCurrentPath(), "Assets/MovedFolder");
}
TEST_F(EditorActionRoutingTest, ProjectCommandsRejectInvalidMoveTargets) {
const fs::path assetsDir = m_projectRoot / "Assets";
const fs::path sourceFilePath = assetsDir / "MoveSource.txt";
const fs::path targetFolderPath = assetsDir / "TargetFolder";
const fs::path plainFilePath = assetsDir / "PlainFile.txt";
std::ofstream(sourceFilePath.string()) << "move source";
std::ofstream(plainFilePath.string()) << "not a folder";
fs::create_directories(targetFolderPath);
m_context.GetProjectManager().RefreshCurrentFolder();
const AssetItemPtr targetFolder = FindCurrentItemByName("TargetFolder");
const AssetItemPtr plainFile = FindCurrentItemByName("PlainFile.txt");
ASSERT_NE(targetFolder, nullptr);
ASSERT_TRUE(targetFolder->isFolder);
ASSERT_NE(plainFile, nullptr);
ASSERT_FALSE(plainFile->isFolder);
EXPECT_FALSE(Commands::MoveAssetToFolder(m_context.GetProjectManager(), "", targetFolder));
EXPECT_FALSE(Commands::MoveAssetToFolder(m_context.GetProjectManager(), sourceFilePath.string(), nullptr));
EXPECT_FALSE(Commands::MoveAssetToFolder(m_context.GetProjectManager(), sourceFilePath.string(), plainFile));
EXPECT_FALSE(Commands::MoveAssetToFolder(m_context.GetProjectManager(), targetFolder->fullPath, targetFolder));
EXPECT_TRUE(fs::exists(sourceFilePath));
}
} // namespace
} // namespace XCEngine::Editor