81 lines
3.2 KiB
Python
81 lines
3.2 KiB
Python
"""Tests for myagents.commands.switch."""
|
|
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
from click.testing import CliRunner
|
|
|
|
from myagents.commands import switch as sw_mod
|
|
|
|
|
|
@pytest.fixture()
|
|
def fake_home(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> Path:
|
|
home = tmp_path / "home"
|
|
home.mkdir()
|
|
monkeypatch.setattr(Path, "home", staticmethod(lambda: home))
|
|
monkeypatch.setattr(sw_mod, "_install_tools", lambda runtime: [])
|
|
workspace = tmp_path / "ws"
|
|
workspace.mkdir()
|
|
monkeypatch.setattr(sw_mod, "get_workspace_root", lambda create=False: workspace)
|
|
monkeypatch.setattr(
|
|
sw_mod,
|
|
"sync_workspace",
|
|
lambda ws: {"added": [], "updated": [], "skipped": [], "removed": []},
|
|
)
|
|
return home
|
|
|
|
|
|
def _make_versions(home: Path, versions: tuple[str, ...], current: str) -> None:
|
|
root = home / ".xiaohe" / "runtime"
|
|
for name in versions:
|
|
(root / name).mkdir(parents=True)
|
|
(root / "current").symlink_to(root / current)
|
|
|
|
|
|
class TestSwitch:
|
|
def test_switches_current_and_reinstalls(
|
|
self, fake_home: Path, monkeypatch: pytest.MonkeyPatch
|
|
) -> None:
|
|
_make_versions(fake_home, ("v1", "v2"), "v2")
|
|
installed: list[str] = []
|
|
monkeypatch.setattr(
|
|
sw_mod, "_install_tools", lambda rt: installed.append(rt.name) or []
|
|
)
|
|
result = CliRunner().invoke(sw_mod.switch_cmd, ["v1", "--yes"])
|
|
assert result.exit_code == 0, result.output
|
|
assert "Switched: v2 -> v1" in result.output
|
|
current = fake_home / ".xiaohe" / "runtime" / "current"
|
|
assert current.resolve().name == "v1"
|
|
assert installed == ["v1"]
|
|
|
|
def test_unknown_version_errors(self, fake_home: Path) -> None:
|
|
_make_versions(fake_home, ("v1", "v2"), "v2")
|
|
result = CliRunner().invoke(sw_mod.switch_cmd, ["v9", "--yes"])
|
|
assert result.exit_code != 0
|
|
assert "not installed" in result.output
|
|
|
|
def test_already_current_is_noop(self, fake_home: Path) -> None:
|
|
_make_versions(fake_home, ("v1", "v2"), "v2")
|
|
result = CliRunner().invoke(sw_mod.switch_cmd, ["v2", "--yes"])
|
|
assert result.exit_code == 0
|
|
assert "Already on v2" in result.output
|
|
|
|
def test_interactive_list_and_prompt(self, fake_home: Path) -> None:
|
|
_make_versions(fake_home, ("v1", "v2"), "v2")
|
|
result = CliRunner().invoke(sw_mod.switch_cmd, [], input="v1\ny\n")
|
|
assert result.exit_code == 0, result.output
|
|
assert "v2" in result.output and "(current)" in result.output
|
|
assert (fake_home / ".xiaohe" / "runtime" / "current").resolve().name == "v1"
|
|
|
|
def test_cancelled_keeps_current(self, fake_home: Path) -> None:
|
|
_make_versions(fake_home, ("v1", "v2"), "v2")
|
|
result = CliRunner().invoke(sw_mod.switch_cmd, ["v1"], input="n\n")
|
|
assert result.exit_code == 0
|
|
assert "Cancelled" in result.output
|
|
assert (fake_home / ".xiaohe" / "runtime" / "current").resolve().name == "v2"
|
|
|
|
def test_no_versions_errors(self, fake_home: Path) -> None:
|
|
result = CliRunner().invoke(sw_mod.switch_cmd, ["v1", "--yes"])
|
|
assert result.exit_code != 0
|
|
assert "No installed runtime" in result.output
|