gabriel / muse public

test_cmd_hooks_install.py file-level

at sha256:d · View file ↗ · Intel ↗

History
1 files
1 commits
0 hotspots
0 🧊 dead
0 💥 blast risk
sha256:7 feat: add chess domain plugin (Episode 22 finale) A chess game as a po… · gabriel · Sep 12, 2026
1 """Tests for `muse hooks install/uninstall/status` — musehub#192 Phase 2.
2
3 Phase 1's `muse hooks list` is covered separately in tests/test_cmd_hooks.py.
4 """
5
6 from __future__ import annotations
7
8 import json
9 import pathlib
10
11 from tests.cli_test_helper import CliRunner
12
13 runner = CliRunner()
14
15
16 def _invoke(path: pathlib.Path, args: list[str]):
17 import os
18 saved = os.getcwd()
19 try:
20 os.chdir(path)
21 return runner.invoke(None, args)
22 finally:
23 os.chdir(saved)
24
25
26 def _init_repo(path: pathlib.Path, domain: str = "code") -> None:
27 r = _invoke(path, ["init", "--domain", domain])
28 assert r.exit_code == 0, r.output
29
30
31 def _write_hooks(path: pathlib.Path, content: str) -> None:
32 (path / ".musehooks.toml").write_text(content, encoding="utf-8")
33
34
35 class TestHooksInstall:
36 def test_install_exits_0_and_marks_installed(self, tmp_path: pathlib.Path) -> None:
37 _init_repo(tmp_path)
38 _write_hooks(tmp_path, '[pre-commit]\ncommands = ["echo hi"]\n')
39 r = _invoke(tmp_path, ["hooks", "install", "--json"])
40 assert r.exit_code == 0, r.output
41 data = json.loads(r.output)
42 assert data["installed"] is True
43
44 status_r = _invoke(tmp_path, ["hooks", "status", "--json"])
45 assert json.loads(status_r.output)["state"] == "installed"
46
47 def test_install_twice_is_still_success(self, tmp_path: pathlib.Path) -> None:
48 _init_repo(tmp_path)
49 _write_hooks(tmp_path, '[pre-commit]\ncommands = ["echo hi"]\n')
50 assert _invoke(tmp_path, ["hooks", "install"]).exit_code == 0
51 assert _invoke(tmp_path, ["hooks", "install"]).exit_code == 0
52
53 def test_install_not_a_repo_exits_2(self, tmp_path: pathlib.Path) -> None:
54 r = _invoke(tmp_path, ["hooks", "install", "--json"])
55 assert r.exit_code == 2
56
57
58 class TestHooksUninstall:
59 def test_uninstall_exits_0_and_clears_state(self, tmp_path: pathlib.Path) -> None:
60 _init_repo(tmp_path)
61 _write_hooks(tmp_path, '[pre-commit]\ncommands = ["echo hi"]\n')
62 _invoke(tmp_path, ["hooks", "install"])
63 r = _invoke(tmp_path, ["hooks", "uninstall", "--json"])
64 assert r.exit_code == 0, r.output
65 data = json.loads(r.output)
66 assert data["installed"] is False
67
68 status_r = _invoke(tmp_path, ["hooks", "status", "--json"])
69 assert json.loads(status_r.output)["state"] == "defined_not_installed"
70
71 def test_uninstall_when_never_installed_is_still_success(self, tmp_path: pathlib.Path) -> None:
72 _init_repo(tmp_path)
73 r = _invoke(tmp_path, ["hooks", "uninstall", "--json"])
74 assert r.exit_code == 0, r.output
75
76
77 class TestHooksStatus:
78 def test_not_defined_state(self, tmp_path: pathlib.Path) -> None:
79 _init_repo(tmp_path)
80 r = _invoke(tmp_path, ["hooks", "status", "--json"])
81 assert r.exit_code == 0, r.output
82 assert json.loads(r.output)["state"] == "not_defined"
83
84 def test_defined_not_installed_state(self, tmp_path: pathlib.Path) -> None:
85 _init_repo(tmp_path)
86 _write_hooks(tmp_path, '[pre-commit]\ncommands = ["echo hi"]\n')
87 r = _invoke(tmp_path, ["hooks", "status", "--json"])
88 assert json.loads(r.output)["state"] == "defined_not_installed"
89
90 def test_text_mode_mentions_install_command_when_not_installed(self, tmp_path: pathlib.Path) -> None:
91 _init_repo(tmp_path)
92 _write_hooks(tmp_path, '[pre-commit]\ncommands = ["echo hi"]\n')
93 r = _invoke(tmp_path, ["hooks", "status"])
94 assert r.exit_code == 0, r.output
95 assert "muse hooks install" in r.output
96
97 def test_malformed_toml_exits_1(self, tmp_path: pathlib.Path) -> None:
98 _init_repo(tmp_path)
99 _write_hooks(tmp_path, "[pre-commit\ncommands = [")
100 r = _invoke(tmp_path, ["hooks", "status", "--json"])
101 assert r.exit_code == 1
102
103 def test_status_not_a_repo_exits_2(self, tmp_path: pathlib.Path) -> None:
104 r = _invoke(tmp_path, ["hooks", "status", "--json"])
105 assert r.exit_code == 2