"""The public Python CLI exposes exactly the approved workflow surface.""" from __future__ import annotations import json from pathlib import Path from typer.main import get_command from typer.testing import CliRunner from tht.cli import app _FIXTURE = Path(__file__).parent / "fixtures" / "approved_cli_surface.json" def _leaf_paths(command, prefix: tuple[str, ...] = ()) -> set[str]: """Return the terminal paths offered by the real Typer/Click command tree.""" children = getattr(command, "commands", {}) if not children: return {" ".join(prefix)} if prefix else set() paths: set[str] = set() for name, child in children.items(): paths.update(_leaf_paths(child, prefix + (name,))) return paths def _approved_surface() -> dict[str, list[str]]: return json.loads(_FIXTURE.read_text(encoding="utf-8")) def test_typer_tree_matches_the_approved_command_surface(): """Catches a missing live command or an accidentally re-registered erased command.""" approved = _approved_surface() expected = set(approved["maintained"]) | set(approved["enhanced"]) assert len(approved["maintained"]) == 57 assert len(approved["enhanced"]) == 8 assert len(approved["erased"]) == 14 assert not (expected & set(approved["erased"])) assert _leaf_paths(get_command(app)) == expected def test_erased_commands_are_rejected_with_the_standard_typer_error(): """Catches a regression that restores a retired command under an existing group.""" runner = CliRunner() for path in _approved_surface()["erased"]: result = runner.invoke(app, [*path.split(), "--help"]) assert result.exit_code != 0, path assert "no such command" in result.output.casefold(), path