Files
EvoScientist-Multi/tests/test_paths.py
T
Xi Zhang 210e8864f6 feat(memory): migrate MEMORY.md to global path & enhance ask-user prompts (#161)
* feat(prompt): enhance user interaction with multiple-choice and free-text questions

* refactor(paths): rename MEMORY_DIR to MEMORIES_DIR for consistency

* style(tests): format code for better readability in test cases

* feat(prompt): add validation for 'other' option in user prompt

* feat(prompt): refactor validation logic for user prompts and add skip option

* feat(style): refactor to use shared _PICKER_STYLE from interactive module
2026-04-16 15:33:45 +01:00

123 lines
4.4 KiB
Python

"""Tests for EvoScientist.paths — set_workspace_root and ensure_dirs."""
import os
from unittest import mock
import pytest
from EvoScientist import paths
@pytest.fixture(autouse=True)
def _restore_paths():
"""Snapshot module-level path globals and restore after each test."""
orig = {
"WORKSPACE_ROOT": paths.WORKSPACE_ROOT,
"RUNS_DIR": paths.RUNS_DIR,
"MEMORIES_DIR": paths.MEMORIES_DIR,
"MEMORY_DIR": paths.MEMORY_DIR,
"USER_SKILLS_DIR": paths.USER_SKILLS_DIR,
"_active_workspace": paths._active_workspace,
}
yield
paths.WORKSPACE_ROOT = orig["WORKSPACE_ROOT"]
paths.RUNS_DIR = orig["RUNS_DIR"]
paths.MEMORIES_DIR = orig["MEMORIES_DIR"]
paths.MEMORY_DIR = orig["MEMORY_DIR"]
paths.USER_SKILLS_DIR = orig["USER_SKILLS_DIR"]
paths._active_workspace = orig["_active_workspace"]
class TestSetWorkspaceRoot:
"""Tests for set_workspace_root()."""
def test_updates_derived_dirs(self, tmp_path, monkeypatch):
"""set_workspace_root should update WORKSPACE_ROOT and all derived dirs."""
monkeypatch.delenv("EVOSCIENTIST_MEMORIES_DIR", raising=False)
monkeypatch.delenv("EVOSCIENTIST_MEMORY_DIR", raising=False)
monkeypatch.delenv("EVOSCIENTIST_RUNS_DIR", raising=False)
monkeypatch.delenv("EVOSCIENTIST_SKILLS_DIR", raising=False)
new_root = tmp_path / "my_workspace"
new_root.mkdir()
paths.set_workspace_root(new_root)
assert paths.WORKSPACE_ROOT == new_root.resolve()
assert paths.RUNS_DIR == new_root.resolve() / "runs"
# MEMORIES_DIR is global — not derived from workspace root
assert paths.MEMORIES_DIR == paths.GLOBAL_MEMORIES_DIR
assert paths.USER_SKILLS_DIR == new_root.resolve() / "skills"
def test_resets_active_workspace(self, tmp_path):
"""set_workspace_root should reset _active_workspace to new root."""
new_root = tmp_path / "ws"
new_root.mkdir()
# Set active workspace to something different first
paths._active_workspace = tmp_path / "other"
paths.set_workspace_root(new_root)
assert paths._active_workspace == new_root.resolve()
def test_preserves_env_overrides(self, tmp_path):
"""Dirs set via env vars should NOT be overwritten by set_workspace_root."""
custom_mem = tmp_path / "custom_memory"
custom_skills = tmp_path / "custom_skills"
custom_runs = tmp_path / "custom_runs"
env = {
"EVOSCIENTIST_MEMORIES_DIR": str(custom_mem),
"EVOSCIENTIST_SKILLS_DIR": str(custom_skills),
"EVOSCIENTIST_RUNS_DIR": str(custom_runs),
}
new_root = tmp_path / "ws"
new_root.mkdir()
with mock.patch.dict(os.environ, env):
paths.set_workspace_root(new_root)
# WORKSPACE_ROOT and _active_workspace should still update
assert paths.WORKSPACE_ROOT == new_root.resolve()
assert paths._active_workspace == new_root.resolve()
# MEMORIES_DIR respects env override
assert paths.MEMORIES_DIR == custom_mem.expanduser()
assert paths.USER_SKILLS_DIR == custom_skills.expanduser()
assert paths.RUNS_DIR == custom_runs.expanduser()
def test_accepts_string_path(self, tmp_path):
"""set_workspace_root should accept str as well as Path."""
new_root = tmp_path / "str_ws"
new_root.mkdir()
paths.set_workspace_root(str(new_root))
assert paths.WORKSPACE_ROOT == new_root.resolve()
class TestEnsureDirsUsesUpdatedPaths:
"""ensure_dirs should create dirs at the currently set paths."""
def test_ensure_dirs_uses_updated_paths(self, tmp_path):
"""ensure_dirs creates the global memories dir (not workspace-local)."""
new_root = tmp_path / "workspace"
new_root.mkdir()
custom_mem = tmp_path / "memories"
with mock.patch.dict(
os.environ, {"EVOSCIENTIST_MEMORIES_DIR": str(custom_mem)}
):
paths.set_workspace_root(new_root)
paths.ensure_dirs()
assert custom_mem.is_dir()
assert not (new_root / "memory").exists() # no longer workspace-local
assert not (new_root / "memories").exists()
assert not (
new_root / "skills"
).exists() # skills created on demand by install_skill()