"""Tests for myagents.commands.switch (version / agent subcommands).""" 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)) workspace = tmp_path / "ws" workspace.mkdir() monkeypatch.setattr(sw_mod, "get_workspace_root", lambda create=False: workspace) # sync_workspace is imported locally in switch_version import myagents.commands.sync_workspace as sync_mod monkeypatch.setattr( sync_mod, "sync_workspace", lambda _ws: {"added": [], "updated": [], "skipped": [], "removed": []}, ) # _install_tools is imported locally inside switch_version from upgrade import myagents.commands.upgrade as ug_mod monkeypatch.setattr(ug_mod, "_install_tools", lambda _rt: []) 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 TestSwitchVersion: def test_switches_current_and_reinstalls( self, fake_home: Path, monkeypatch: pytest.MonkeyPatch ) -> None: _make_versions(fake_home, ("v1", "v2"), "v2") installed: list[str] = [] import myagents.commands.upgrade as ug_mod monkeypatch.setattr( ug_mod, "_install_tools", lambda _rt: (installed.append(_rt.name), [])[1] or [], ) result = CliRunner().invoke(sw_mod.switch_version, ["v1", "--yes"]) assert result.exit_code == 0, result.output assert "Switched:" 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_version, ["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_version, ["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_version, [], input="v2\ny\n") assert result.exit_code == 0, result.output assert "v2" in result.output and "(current)" in result.output def test_cancelled_keeps_current(self, fake_home: Path) -> None: _make_versions(fake_home, ("v1", "v2"), "v2") result = CliRunner().invoke(sw_mod.switch_version, ["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_version, ["v1", "--yes"]) assert result.exit_code != 0 assert "No installed runtime" in result.output class TestSwitchAgent: def test_bare_invocation_lists_agents(self) -> None: result = CliRunner().invoke( sw_mod.switch_agent, [], input="claude\n" ) assert result.exit_code == 0, result.output assert "Available agents" in result.output assert "claude" in result.output assert "kimi" in result.output def test_switch_to_kimi(self) -> None: result = CliRunner().invoke(sw_mod.switch_agent, ["kimi"]) assert result.exit_code == 0, result.output assert "Switched" in result.output def test_already_current_noop(self) -> None: from myagents.settings import get_setting current = get_setting("default_agent", "claude") result = CliRunner().invoke(sw_mod.switch_agent, [current]) assert result.exit_code == 0 assert "Already on" in result.output def test_unknown_agent_errors(self) -> None: result = CliRunner().invoke(sw_mod.switch_agent, ["unknown-ai"]) assert result.exit_code != 0 assert "Unknown agent" in result.output class TestSwitchGroup: def test_bare_invocation_shows_options(self) -> None: result = CliRunner().invoke(sw_mod.switch_cmd, []) assert result.exit_code == 0 assert "switch version" in result.output assert "switch agent" in result.output assert "switch provider" in result.output def test_help_lists_subcommands(self) -> None: result = CliRunner().invoke(sw_mod.switch_cmd, ["--help"]) assert result.exit_code == 0 assert "version" in result.output assert "agent" in result.output assert "provider" in result.output