"""Integration tests for the real CLI wiring into domain_command_registry — muse#74 Phase 2 (SCR_04-07). Unlike test_domain_command_registry.py (pure unit tests of the registry contract using arbitrary fixture data), these tests invoke the real CLI via CliRunner and assert on what the actual argparse tree — `muse code`, `muse mist`, `muse social` — populates. `main()` must build the full parser tree to parse argv regardless of which command actually runs, so any invocation (even an unrelated one) populates the registry. Assertions use membership + a count floor, never an exact list — an exact list here would just be a second hardcoded array, the exact failure mode this issue exists to eliminate. """ from tests.cli_test_helper import CliRunner from muse.cli.domain_command_registry import get_supported_commands runner = CliRunner() def _touch_cli() -> None: """Invoke the CLI once so main() builds the full parser tree. Any command works — --version is the cheapest one that always succeeds regardless of CWD or repo state. """ result = runner.invoke(None, ["--version"]) assert result.exit_code == 0, result.output class TestCodeNamespaceWiring: def test_contains_stable_known_anchors(self) -> None: _touch_cli() commands = get_supported_commands("code") for anchor in ("grep", "impact", "symbols", "gravity", "hotspots"): assert anchor in commands, f"{anchor!r} missing from muse code's registered commands" def test_has_more_than_30_entries(self) -> None: _touch_cli() commands = get_supported_commands("code") assert len(commands) > 30, ( f"only {len(commands)} code commands registered — " "expected 30+ real muse code subcommands, not a short hardcoded stand-in" ) def test_does_not_contain_universal_muse_commands(self) -> None: # "commit"/"diff"/"merge" are top-level `muse ` commands, not # `muse code ` subcommands — they must not leak into this # namespace's registered list. _touch_cli() commands = get_supported_commands("code") assert "commit" not in commands assert "merge" not in commands class TestMistNamespaceWiring: def test_contains_mist_specific_commands(self) -> None: _touch_cli() commands = get_supported_commands("mist") for anchor in ("create", "fork", "embed", "delete", "update"): assert anchor in commands, f"{anchor!r} missing from muse mist's registered commands" def test_does_not_contain_universal_muse_commands(self) -> None: # Proves the registry captures the dedicated `muse mist ` # namespace specifically, not every command muse has. _touch_cli() commands = get_supported_commands("mist") assert "commit" not in commands assert "diff" not in commands assert "merge" not in commands assert "log" not in commands assert "status" not in commands class TestSocialNamespaceWiring: def test_contains_social_specific_commands(self) -> None: _touch_cli() commands = get_supported_commands("social") for anchor in ("post", "follow", "timeline", "profile"): assert anchor in commands, f"{anchor!r} missing from muse social's registered commands" def test_does_not_contain_universal_muse_commands(self) -> None: _touch_cli() commands = get_supported_commands("social") assert "commit" not in commands assert "diff" not in commands class TestUndeclaredNamespacesReturnEmpty: def test_identity_has_no_dedicated_namespace(self) -> None: _touch_cli() assert get_supported_commands("identity") == [] def test_scaffold_has_no_dedicated_namespace(self) -> None: _touch_cli() assert get_supported_commands("scaffold") == [] def test_completely_unknown_name_returns_empty(self) -> None: _touch_cli() assert get_supported_commands("this-domain-does-not-exist") == []