Refactor new editor boundaries and test ownership

This commit is contained in:
2026-04-19 15:52:28 +08:00
parent dc13b56cf3
commit 93f06e84ed
279 changed files with 6349 additions and 3238 deletions

View File

@@ -1,4 +1,5 @@
#include "Features/Project/ProjectPanel.h"
#include "Ports/SystemInteractionPort.h"
#include "Rendering/Assets/BuiltInIcons.h"
#include "Composition/EditorPanelIds.h"
@@ -13,6 +14,32 @@
namespace XCEngine::UI::Editor::App {
namespace {
class FakeSystemInteractionHost final : public Ports::SystemInteractionPort {
public:
bool CopyTextToClipboard(std::string_view text) override {
lastClipboardText = std::string(text);
++clipboardCallCount;
return clipboardResult;
}
bool RevealPathInFileBrowser(
const std::filesystem::path& path,
bool selectTarget) override {
lastRevealPath = path;
lastRevealSelectTarget = selectTarget;
++revealCallCount;
return revealResult;
}
bool clipboardResult = true;
bool revealResult = true;
int clipboardCallCount = 0;
int revealCallCount = 0;
bool lastRevealSelectTarget = false;
std::string lastClipboardText = {};
std::filesystem::path lastRevealPath = {};
};
class TemporaryRepo final {
public:
TemporaryRepo() {
@@ -83,6 +110,13 @@ UIEditorPanelContentHostFrame MakeProjectHostFrame() {
return event;
}
PanelInputContext MakeFocusedPanelInputContext() {
PanelInputContext inputContext = {};
inputContext.allowInteraction = true;
inputContext.hasInputFocus = true;
return inputContext;
}
TEST(ProjectPanelTests, CreateFolderCommandCreatesDirectoryAndQueuesRename) {
TemporaryRepo repo = {};
@@ -141,13 +175,11 @@ TEST(ProjectPanelTests, BackgroundContextMenuCreateFolderUsesCurrentFolder) {
panel.Update(
hostFrame,
{ MakePointerButtonDown(520.0f, 180.0f, ::XCEngine::UI::UIPointerButton::Right) },
true,
true);
MakeFocusedPanelInputContext());
panel.Update(
hostFrame,
{ MakePointerButtonDown(520.0f, 194.0f, ::XCEngine::UI::UIPointerButton::Left) },
true,
true);
MakeFocusedPanelInputContext());
EXPECT_TRUE(std::filesystem::exists(repo.Root() / "project/Assets/New Folder"));
const UIEditorHostCommandEvaluationResult renameEvaluation =
@@ -172,13 +204,11 @@ TEST(ProjectPanelTests, FolderContextMenuCreateFolderUsesFolderTarget) {
panel.Update(
hostFrame,
{ MakePointerButtonDown(300.0f, 80.0f, ::XCEngine::UI::UIPointerButton::Right) },
true,
true);
MakeFocusedPanelInputContext());
panel.Update(
hostFrame,
{ MakePointerButtonDown(320.0f, 120.0f, ::XCEngine::UI::UIPointerButton::Left) },
true,
true);
MakeFocusedPanelInputContext());
EXPECT_TRUE(std::filesystem::exists(repo.Root() / "project/Assets/FolderA/New Folder"));
}
@@ -241,5 +271,56 @@ TEST(ProjectPanelTests, BuiltInIconsCanBeConfiguredBeforeRuntimeInitialization)
EXPECT_TRUE(evaluation.executable);
}
TEST(ProjectPanelTests, CopyPathCommandUsesInjectedSystemHost) {
TemporaryRepo repo = {};
ASSERT_TRUE(repo.CreateDirectory("project/Assets/Scripts"));
ASSERT_TRUE(repo.WriteFile("project/Assets/Scripts/Player.cs"));
EditorProjectRuntime runtime = {};
ASSERT_TRUE(runtime.Initialize(repo.Root()));
ASSERT_TRUE(runtime.NavigateToFolder("Assets/Scripts"));
ASSERT_TRUE(runtime.SetSelection("Assets/Scripts/Player.cs"));
ProjectPanel panel = {};
FakeSystemInteractionHost systemHost = {};
panel.SetProjectRuntime(&runtime);
panel.SetSystemInteractionHost(&systemHost);
const UIEditorHostCommandEvaluationResult evaluation =
panel.EvaluateAssetCommand("assets.copy_path");
EXPECT_TRUE(evaluation.executable);
const UIEditorHostCommandDispatchResult dispatch =
panel.DispatchAssetCommand("assets.copy_path");
EXPECT_TRUE(dispatch.commandExecuted);
EXPECT_EQ(systemHost.clipboardCallCount, 1);
EXPECT_EQ(systemHost.lastClipboardText, "Assets/Scripts/Player.cs");
}
TEST(ProjectPanelTests, ShowInExplorerCommandUsesInjectedSystemHost) {
TemporaryRepo repo = {};
ASSERT_TRUE(repo.CreateDirectory("project/Assets/Scripts"));
ASSERT_TRUE(repo.WriteFile("project/Assets/Scripts/Player.cs"));
EditorProjectRuntime runtime = {};
ASSERT_TRUE(runtime.Initialize(repo.Root()));
ASSERT_TRUE(runtime.NavigateToFolder("Assets/Scripts"));
ASSERT_TRUE(runtime.SetSelection("Assets/Scripts/Player.cs"));
ProjectPanel panel = {};
FakeSystemInteractionHost systemHost = {};
panel.SetProjectRuntime(&runtime);
panel.SetSystemInteractionHost(&systemHost);
const UIEditorHostCommandDispatchResult dispatch =
panel.DispatchAssetCommand("assets.show_in_explorer");
EXPECT_TRUE(dispatch.commandExecuted);
EXPECT_EQ(systemHost.revealCallCount, 1);
EXPECT_EQ(
systemHost.lastRevealPath.lexically_normal(),
(repo.Root() / "project/Assets/Scripts/Player.cs").lexically_normal());
EXPECT_TRUE(systemHost.lastRevealSelectTarget);
}
} // namespace
} // namespace XCEngine::UI::Editor::App