Enforce single source of truth for editor project folder state
This commit is contained in:
@@ -202,7 +202,7 @@ TEST(EditorProjectRuntimeTests, BoundStorePreservesPersistedCurrentFolderDuringI
|
||||
ASSERT_TRUE(runtime.Initialize(repo.Root() / "project"));
|
||||
|
||||
EXPECT_EQ(store.GetState().session.currentProjectFolderId, "Assets/Scenes");
|
||||
EXPECT_EQ(runtime.GetBrowserModel().GetCurrentFolderId(), "Assets/Scenes");
|
||||
EXPECT_EQ(runtime.GetCurrentFolderId(), "Assets/Scenes");
|
||||
}
|
||||
|
||||
TEST(EditorProjectRuntimeTests, BoundStoreCanonicalizesInvalidPersistedCurrentFolderDuringInitialize) {
|
||||
@@ -219,7 +219,7 @@ TEST(EditorProjectRuntimeTests, BoundStoreCanonicalizesInvalidPersistedCurrentFo
|
||||
ASSERT_TRUE(runtime.Initialize(repo.Root() / "project"));
|
||||
|
||||
EXPECT_EQ(store.GetState().session.currentProjectFolderId, "Assets");
|
||||
EXPECT_EQ(runtime.GetBrowserModel().GetCurrentFolderId(), "Assets");
|
||||
EXPECT_EQ(runtime.GetCurrentFolderId(), "Assets");
|
||||
}
|
||||
|
||||
TEST(EditorProjectRuntimeTests, BoundStoreRemainsTheAuthoritativeCurrentFolderSourceAtRuntime) {
|
||||
@@ -236,13 +236,13 @@ TEST(EditorProjectRuntimeTests, BoundStoreRemainsTheAuthoritativeCurrentFolderSo
|
||||
|
||||
ASSERT_TRUE(runtime.NavigateToFolder("Assets/Scenes"));
|
||||
EXPECT_EQ(store.GetState().session.currentProjectFolderId, "Assets/Scenes");
|
||||
EXPECT_EQ(runtime.GetBrowserModel().GetCurrentFolderId(), "Assets/Scenes");
|
||||
EXPECT_EQ(runtime.GetCurrentFolderId(), "Assets/Scenes");
|
||||
|
||||
const Product::EditorStore::DispatchResult dispatchResult =
|
||||
store.Dispatch(Product::EditorCommand::SetCurrentProjectFolder("Assets/Scripts"));
|
||||
ASSERT_TRUE(dispatchResult.handled);
|
||||
ASSERT_TRUE(dispatchResult.stateChanged);
|
||||
EXPECT_EQ(runtime.GetBrowserModel().GetCurrentFolderId(), "Assets/Scripts");
|
||||
EXPECT_EQ(runtime.GetCurrentFolderId(), "Assets/Scripts");
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -58,7 +58,7 @@ private:
|
||||
std::filesystem::path m_root = {};
|
||||
};
|
||||
|
||||
TEST(ProjectBrowserModelTests, ReparentFolderMovesFolderMetaAndRemapsCurrentFolder) {
|
||||
TEST(ProjectBrowserModelTests, ReparentFolderMovesFolderMetaAndRemapsExplicitCurrentFolder) {
|
||||
TemporaryRepo repo = {};
|
||||
ASSERT_TRUE(repo.CreateDirectory("project/Assets/A/Child"));
|
||||
ASSERT_TRUE(repo.CreateDirectory("project/Assets/B"));
|
||||
@@ -69,20 +69,19 @@ TEST(ProjectBrowserModelTests, ReparentFolderMovesFolderMetaAndRemapsCurrentFold
|
||||
ProjectBrowserModel model = {};
|
||||
model.Initialize(repo.Root() / "project");
|
||||
|
||||
ASSERT_TRUE(model.NavigateToFolder("Assets/A/Child"));
|
||||
|
||||
std::string currentFolderId = "Assets/A/Child";
|
||||
std::string movedFolderId = {};
|
||||
ASSERT_TRUE(model.ReparentFolder("Assets/A", "Assets/B", &movedFolderId));
|
||||
ASSERT_TRUE(model.ReparentFolder("Assets/A", "Assets/B", &movedFolderId, ¤tFolderId));
|
||||
|
||||
EXPECT_EQ(movedFolderId, "Assets/B/A");
|
||||
EXPECT_EQ(model.GetCurrentFolderId(), "Assets/B/A/Child");
|
||||
EXPECT_EQ(currentFolderId, "Assets/B/A/Child");
|
||||
EXPECT_TRUE(std::filesystem::exists(repo.Root() / "project/Assets/B/A"));
|
||||
EXPECT_TRUE(std::filesystem::exists(repo.Root() / "project/Assets/B/A.meta"));
|
||||
EXPECT_FALSE(std::filesystem::exists(repo.Root() / "project/Assets/A"));
|
||||
EXPECT_FALSE(std::filesystem::exists(repo.Root() / "project/Assets/A.meta"));
|
||||
}
|
||||
|
||||
TEST(ProjectBrowserModelTests, MoveFolderToRootMovesFolderMetaAndRemapsCurrentFolder) {
|
||||
TEST(ProjectBrowserModelTests, MoveFolderToRootMovesFolderMetaAndRemapsExplicitCurrentFolder) {
|
||||
TemporaryRepo repo = {};
|
||||
ASSERT_TRUE(repo.CreateDirectory("project/Assets/Parent/Nested"));
|
||||
ASSERT_TRUE(repo.WriteFile("project/Assets/Parent.meta"));
|
||||
@@ -91,13 +90,12 @@ TEST(ProjectBrowserModelTests, MoveFolderToRootMovesFolderMetaAndRemapsCurrentFo
|
||||
ProjectBrowserModel model = {};
|
||||
model.Initialize(repo.Root() / "project");
|
||||
|
||||
ASSERT_TRUE(model.NavigateToFolder("Assets/Parent/Nested"));
|
||||
|
||||
std::string currentFolderId = "Assets/Parent/Nested";
|
||||
std::string movedFolderId = {};
|
||||
ASSERT_TRUE(model.MoveFolderToRoot("Assets/Parent/Nested", &movedFolderId));
|
||||
ASSERT_TRUE(model.MoveFolderToRoot("Assets/Parent/Nested", &movedFolderId, ¤tFolderId));
|
||||
|
||||
EXPECT_EQ(movedFolderId, "Assets/Nested");
|
||||
EXPECT_EQ(model.GetCurrentFolderId(), "Assets/Nested");
|
||||
EXPECT_EQ(currentFolderId, "Assets/Nested");
|
||||
EXPECT_TRUE(std::filesystem::exists(repo.Root() / "project/Assets/Nested"));
|
||||
EXPECT_TRUE(std::filesystem::exists(repo.Root() / "project/Assets/Nested.meta"));
|
||||
EXPECT_FALSE(std::filesystem::exists(repo.Root() / "project/Assets/Parent/Nested"));
|
||||
@@ -136,10 +134,12 @@ TEST(ProjectBrowserModelTests, CreateMaterialCreatesUniqueMaterialFileAndExposes
|
||||
model.BuildProjectRelativePath(createdItemId),
|
||||
"Assets/Materials/New Material 1.mat");
|
||||
|
||||
ASSERT_TRUE(model.NavigateToFolder("Assets/Materials"));
|
||||
const ProjectBrowserModel::FolderViewState viewState =
|
||||
model.Refresh("Assets/Materials");
|
||||
const ProjectBrowserModel::AssetEntry* createdEntry =
|
||||
model.FindAssetEntry(createdItemId);
|
||||
ASSERT_NE(createdEntry, nullptr);
|
||||
EXPECT_EQ(viewState.currentFolderId, "Assets/Materials");
|
||||
EXPECT_EQ(createdEntry->kind, ProjectBrowserModel::ItemKind::Material);
|
||||
EXPECT_EQ(createdEntry->displayName, "New Material 1");
|
||||
EXPECT_EQ(createdEntry->nameWithExtension, "New Material 1.mat");
|
||||
@@ -157,7 +157,7 @@ TEST(ProjectBrowserModelTests, CanMoveItemToFolderRejectsDescendantFolderTargets
|
||||
EXPECT_TRUE(model.CanMoveItemToFolder("Assets/FolderA", "Assets/FolderB"));
|
||||
}
|
||||
|
||||
TEST(ProjectBrowserModelTests, MoveItemToFolderMovesFileMetaAndRefreshesCurrentListing) {
|
||||
TEST(ProjectBrowserModelTests, MoveItemToFolderMovesFileMetaAndPreservesExplicitCurrentFolder) {
|
||||
TemporaryRepo repo = {};
|
||||
ASSERT_TRUE(repo.CreateDirectory("project/Assets/Scripts"));
|
||||
ASSERT_TRUE(repo.CreateDirectory("project/Assets/Archive"));
|
||||
@@ -166,44 +166,53 @@ TEST(ProjectBrowserModelTests, MoveItemToFolderMovesFileMetaAndRefreshesCurrentL
|
||||
|
||||
ProjectBrowserModel model = {};
|
||||
model.Initialize(repo.Root() / "project");
|
||||
ASSERT_TRUE(model.NavigateToFolder("Assets/Scripts"));
|
||||
|
||||
std::string currentFolderId = "Assets/Scripts";
|
||||
std::string movedItemId = {};
|
||||
ASSERT_TRUE(model.MoveItemToFolder(
|
||||
"Assets/Scripts/Player.cs",
|
||||
"Assets/Archive",
|
||||
&movedItemId));
|
||||
&movedItemId,
|
||||
¤tFolderId));
|
||||
|
||||
EXPECT_EQ(movedItemId, "Assets/Archive/Player.cs");
|
||||
EXPECT_EQ(model.GetCurrentFolderId(), "Assets/Scripts");
|
||||
EXPECT_EQ(currentFolderId, "Assets/Scripts");
|
||||
EXPECT_FALSE(std::filesystem::exists(repo.Root() / "project/Assets/Scripts/Player.cs"));
|
||||
EXPECT_FALSE(std::filesystem::exists(repo.Root() / "project/Assets/Scripts/Player.cs.meta"));
|
||||
EXPECT_TRUE(std::filesystem::exists(repo.Root() / "project/Assets/Archive/Player.cs"));
|
||||
EXPECT_TRUE(std::filesystem::exists(repo.Root() / "project/Assets/Archive/Player.cs.meta"));
|
||||
|
||||
model.Refresh("Assets/Scripts");
|
||||
EXPECT_EQ(model.FindAssetEntry("Assets/Scripts/Player.cs"), nullptr);
|
||||
|
||||
ASSERT_TRUE(model.NavigateToFolder("Assets/Archive"));
|
||||
model.Refresh("Assets/Archive");
|
||||
EXPECT_NE(model.FindAssetEntry("Assets/Archive/Player.cs"), nullptr);
|
||||
}
|
||||
|
||||
TEST(ProjectBrowserModelTests, RenameFilePreservesExtensionAndUpdatesCurrentListing) {
|
||||
TEST(ProjectBrowserModelTests, RenameFilePreservesExtensionAndUpdatesExplicitCurrentFolderListing) {
|
||||
TemporaryRepo repo = {};
|
||||
ASSERT_TRUE(repo.WriteFile("project/Assets/Scenes/Main.xc"));
|
||||
ASSERT_TRUE(repo.WriteFile("project/Assets/Scenes/Main.xc.meta"));
|
||||
|
||||
ProjectBrowserModel model = {};
|
||||
model.Initialize(repo.Root() / "project");
|
||||
ASSERT_TRUE(model.NavigateToFolder("Assets/Scenes"));
|
||||
|
||||
std::string currentFolderId = "Assets/Scenes";
|
||||
std::string renamedItemId = {};
|
||||
ASSERT_TRUE(model.RenameItem("Assets/Scenes/Main.xc", "Gameplay", &renamedItemId));
|
||||
ASSERT_TRUE(model.RenameItem(
|
||||
"Assets/Scenes/Main.xc",
|
||||
"Gameplay",
|
||||
&renamedItemId,
|
||||
¤tFolderId));
|
||||
|
||||
EXPECT_EQ(renamedItemId, "Assets/Scenes/Gameplay.xc");
|
||||
EXPECT_EQ(currentFolderId, "Assets/Scenes");
|
||||
EXPECT_TRUE(std::filesystem::exists(repo.Root() / "project/Assets/Scenes/Gameplay.xc"));
|
||||
EXPECT_TRUE(std::filesystem::exists(repo.Root() / "project/Assets/Scenes/Gameplay.xc.meta"));
|
||||
EXPECT_FALSE(std::filesystem::exists(repo.Root() / "project/Assets/Scenes/Main.xc"));
|
||||
EXPECT_FALSE(std::filesystem::exists(repo.Root() / "project/Assets/Scenes/Main.xc.meta"));
|
||||
|
||||
model.Refresh(currentFolderId);
|
||||
const ProjectBrowserModel::AssetEntry* renamedEntry =
|
||||
model.FindAssetEntry("Assets/Scenes/Gameplay.xc");
|
||||
ASSERT_NE(renamedEntry, nullptr);
|
||||
@@ -211,7 +220,7 @@ TEST(ProjectBrowserModelTests, RenameFilePreservesExtensionAndUpdatesCurrentList
|
||||
EXPECT_EQ(renamedEntry->nameWithExtension, "Gameplay.xc");
|
||||
}
|
||||
|
||||
TEST(ProjectBrowserModelTests, DeleteFolderRemovesMetaAndFallsBackCurrentFolder) {
|
||||
TEST(ProjectBrowserModelTests, DeleteFolderRemapsExplicitCurrentFolderToParent) {
|
||||
TemporaryRepo repo = {};
|
||||
ASSERT_TRUE(repo.CreateDirectory("project/Assets/Parent/Nested"));
|
||||
ASSERT_TRUE(repo.WriteFile("project/Assets/Parent.meta"));
|
||||
@@ -219,16 +228,16 @@ TEST(ProjectBrowserModelTests, DeleteFolderRemovesMetaAndFallsBackCurrentFolder)
|
||||
|
||||
ProjectBrowserModel model = {};
|
||||
model.Initialize(repo.Root() / "project");
|
||||
ASSERT_TRUE(model.NavigateToFolder("Assets/Parent/Nested"));
|
||||
|
||||
ASSERT_TRUE(model.DeleteItem("Assets/Parent"));
|
||||
std::string currentFolderId = "Assets/Parent/Nested";
|
||||
ASSERT_TRUE(model.DeleteItem("Assets/Parent", ¤tFolderId));
|
||||
|
||||
EXPECT_EQ(model.GetCurrentFolderId(), "Assets");
|
||||
EXPECT_EQ(currentFolderId, "Assets");
|
||||
EXPECT_FALSE(std::filesystem::exists(repo.Root() / "project/Assets/Parent"));
|
||||
EXPECT_FALSE(std::filesystem::exists(repo.Root() / "project/Assets/Parent.meta"));
|
||||
}
|
||||
|
||||
TEST(ProjectBrowserModelTests, AssetEntriesExposeKindAndOpenCapability) {
|
||||
TEST(ProjectBrowserModelTests, AssetEntriesExposeKindAndOpenCapabilityForExplicitView) {
|
||||
TemporaryRepo repo = {};
|
||||
ASSERT_TRUE(repo.CreateDirectory("project/Assets/Scenes"));
|
||||
ASSERT_TRUE(repo.WriteFile("project/Assets/Scenes/Main.xc"));
|
||||
@@ -238,11 +247,14 @@ TEST(ProjectBrowserModelTests, AssetEntriesExposeKindAndOpenCapability) {
|
||||
ProjectBrowserModel model = {};
|
||||
model.Initialize(repo.Root() / "project");
|
||||
|
||||
const ProjectBrowserModel::AssetEntry* sceneEntry =
|
||||
const ProjectBrowserModel::FolderViewState rootView = model.Refresh("Assets");
|
||||
ASSERT_EQ(rootView.currentFolderId, "Assets");
|
||||
|
||||
const ProjectBrowserModel::AssetEntry* modelEntry =
|
||||
model.FindAssetEntry("Assets/mesh.fbx");
|
||||
ASSERT_NE(sceneEntry, nullptr);
|
||||
EXPECT_EQ(sceneEntry->kind, ProjectBrowserModel::ItemKind::Model);
|
||||
EXPECT_FALSE(sceneEntry->canOpen);
|
||||
ASSERT_NE(modelEntry, nullptr);
|
||||
EXPECT_EQ(modelEntry->kind, ProjectBrowserModel::ItemKind::Model);
|
||||
EXPECT_FALSE(modelEntry->canOpen);
|
||||
|
||||
const ProjectBrowserModel::AssetEntry* fileEntry =
|
||||
model.FindAssetEntry("Assets/readme.txt");
|
||||
@@ -250,7 +262,9 @@ TEST(ProjectBrowserModelTests, AssetEntriesExposeKindAndOpenCapability) {
|
||||
EXPECT_EQ(fileEntry->kind, ProjectBrowserModel::ItemKind::File);
|
||||
EXPECT_FALSE(fileEntry->canOpen);
|
||||
|
||||
ASSERT_TRUE(model.NavigateToFolder("Assets/Scenes"));
|
||||
const ProjectBrowserModel::FolderViewState sceneView =
|
||||
model.Refresh("Assets/Scenes");
|
||||
ASSERT_EQ(sceneView.currentFolderId, "Assets/Scenes");
|
||||
const ProjectBrowserModel::AssetEntry* openedSceneEntry =
|
||||
model.FindAssetEntry("Assets/Scenes/Main.xc");
|
||||
ASSERT_NE(openedSceneEntry, nullptr);
|
||||
|
||||
Reference in New Issue
Block a user