"""Tests for CLI routing and parser behavior.""" import pytest from coinhunter.cli import ALIASES, MODULE_MAP, build_parser, run_python_module class TestAliases: def test_all_aliases_resolve_to_canonical(self): for alias, canonical in ALIASES.items(): assert canonical in MODULE_MAP, f"alias {alias!r} points to missing canonical {canonical!r}" def test_no_alias_is_itself_an_alias_loop(self): for alias in ALIASES: assert alias not in ALIASES.values() or alias in MODULE_MAP class TestModuleMap: def test_all_modules_exist(self): import importlib for command, module_name in MODULE_MAP.items(): full = f"coinhunter.{module_name}" mod = importlib.import_module(full) assert hasattr(mod, "main"), f"{full} missing main()" class TestBuildParser: def test_help_includes_commands(self): parser = build_parser() help_text = parser.format_help() assert "coinhunter diag" in help_text assert "coinhunter exec" in help_text def test_parses_command_and_args(self): parser = build_parser() ns = parser.parse_args(["exec", "bal"]) assert ns.command == "exec" assert "bal" in ns.args def test_version_action_exits(self): parser = build_parser() with pytest.raises(SystemExit) as exc: parser.parse_args(["--version"]) assert exc.value.code == 0 class TestRunPythonModule: def test_runs_module_main_and_returns_int(self): result = run_python_module("commands.paths", [], "coinhunter paths") assert result == 0 def test_mutates_sys_argv(self): import sys original = sys.argv[:] run_python_module("commands.paths", ["--help"], "coinhunter paths") assert sys.argv == original