"""Tests for workspace directory management.""" import pytest from pathlib import Path from gsd_openclaw.workspace import Workspace, WorkspaceManager class TestWorkspacePaths: """Test Workspace dataclass path properties.""" def test_workspace_creates_correct_paths_for_all_directories(self, tmp_workspaces_root: Path): """Workspace creates correct paths for all directories.""" root = tmp_workspaces_root / "test-project" workspace = Workspace("test-project", root) assert workspace.root == root assert workspace.gsd_dir == root / ".gsd" assert workspace.state_path == root / ".gsd" / "state.json" assert workspace.state_backup_path == root / ".gsd" / "state.json.bak" assert workspace.session_dump_dir == root / ".gsd" / "session-dump" assert workspace.code_dir == root / "code" assert workspace.io_logs_dir == root / "io-logs" def test_workspace_paths_are_consistent_same_root(self, tmp_workspaces_root: Path): """Workspace paths are consistent (same root).""" root = tmp_workspaces_root / "my-project" workspace = Workspace("my-project", root) # All paths should start with the same root assert str(workspace.gsd_dir).startswith(str(workspace.root)) assert str(workspace.state_path).startswith(str(workspace.root)) assert str(workspace.code_dir).startswith(str(workspace.root)) assert str(workspace.io_logs_dir).startswith(str(workspace.root)) def test_workspace_handles_project_names_with_special_characters_safely(self, tmp_workspaces_root: Path): """Workspace handles project names with special characters safely.""" # Test with project name that has spaces and hyphens root = tmp_workspaces_root / "my-project-2024" workspace = Workspace("my-project-2024", root) assert workspace.root == root assert workspace.project_name == "my-project-2024" def test_workspace_io_log_path_with_session_id(self, tmp_workspaces_root: Path): """Workspace io_log_path returns correct path for session ID.""" root = tmp_workspaces_root / "test-project" workspace = Workspace("test-project", root) log_path = workspace.io_log_path("session-123") assert log_path == root / "io-logs" / "session-123.log" class TestWorkspaceManagerCreate: """Test WorkspaceManager create operations.""" def test_create_creates_all_required_directories(self, workspace_manager: WorkspaceManager): """create() creates all required directories.""" workspace = workspace_manager.create() assert workspace.root.exists() assert workspace.gsd_dir.exists() assert workspace.session_dump_dir.exists() assert workspace.code_dir.exists() assert workspace.io_logs_dir.exists() def test_create_is_idempotent(self, workspace_manager: WorkspaceManager): """create() is idempotent (calling twice doesn't fail).""" workspace1 = workspace_manager.create() workspace2 = workspace_manager.create() # Should not raise assert workspace1.root.exists() assert workspace2.root.exists() class TestWorkspaceManagerDestroy: """Test WorkspaceManager destroy operations.""" def test_destroy_removes_entire_workspace_directory(self, tmp_workspaces_root: Path): """destroy() removes entire workspace directory.""" manager = WorkspaceManager("test-project", tmp_workspaces_root) manager.create() assert manager.workspace.root.exists() manager.destroy() assert not manager.workspace.root.exists() def test_exists_returns_true_after_create_false_after_destroy(self, tmp_workspaces_root: Path): """exists() returns True after create, False after destroy.""" manager = WorkspaceManager("test-project", tmp_workspaces_root) assert not manager.exists() manager.create() assert manager.exists() manager.destroy() assert not manager.exists() class TestWorkspaceIsolation: """Test workspace isolation between projects.""" def test_two_projects_have_isolated_workspaces(self, tmp_workspaces_root: Path): """Two projects have isolated workspaces (different roots).""" manager1 = WorkspaceManager("project-alpha", tmp_workspaces_root) manager2 = WorkspaceManager("project-beta", tmp_workspaces_root) workspace1 = manager1.create() workspace2 = manager2.create() # Different roots assert workspace1.root != workspace2.root # Both exist independently assert workspace1.root.exists() assert workspace2.root.exists() # Destroying one doesn't affect the other manager1.destroy() assert not workspace1.root.exists() assert workspace2.root.exists()