test_cli_workspace.py python
102 lines 4.2 KB
Raw
sha256:a78e7e5a8740e03315f325d19edeb3aa1b306b3337d04abbaa9a9e0f3bbeb7a1 docs: MuseHub-first before ISR #74 — staging solidify NEXT Human 1 day ago
1 """Integration tests for ok workspace CLI (§MR.10 integration)."""
2
3 from __future__ import annotations
4
5 import json
6 from pathlib import Path
7
8 from tests.fixtures.workspace import build_two_repo_constellation
9 from tests.support import run_cli
10 from tools.workspace.types import EXIT_WORKSPACE_RELAY
11
12
13 def test_workspace_status_json_basenames(tmp_path: Path) -> None:
14 fx = build_two_repo_constellation(tmp_path)
15 code = run_cli(["workspace", "status", "--json"], cwd=fx["scooling"])
16 assert code == 0
17 # run_cli may not capture stdout — use main with capsys style via subprocess helper
18 from tests.support import run_shim
19
20 result = run_shim("ok", ["workspace", "status", "--json"], cwd=fx["scooling"])
21 assert result.exit_code == 0
22 payload = json.loads(result.stdout)
23 assert payload["authoritative_handover"]
24 bases = {m["id"]: m["handover_basename"] for m in payload["members"]}
25 assert bases["scooling"] == "SCOOLING-OVERSEER-HANDOVER.md"
26 assert bases["knowtation"] == "KNOWTATION-OVERSEER-HANDOVER.md"
27 assert bases["scooling"] != bases["knowtation"]
28
29
30 def test_check_next_exit_codes(tmp_path: Path) -> None:
31 from tests.support import run_shim
32
33 good = build_two_repo_constellation(tmp_path / "g")
34 bad = build_two_repo_constellation(tmp_path / "b", stale_relay=True)
35 assert run_shim("ok", ["workspace", "check-next"], cwd=good["scooling"]).exit_code == 0
36 assert (
37 run_shim("ok", ["workspace", "check-next"], cwd=bad["scooling"]).exit_code
38 == EXIT_WORKSPACE_RELAY
39 )
40
41
42 def test_status_workspace_does_not_imply_ok_on_green_single_repo(tmp_path: Path) -> None:
43 """S9: single-repo status green must not imply workspace.ok when relay stale."""
44 from tests.support import run_shim, seed_git_repo
45 from cli.version_lock import write_version_lock
46 from cli.footprint import resolve_footprint
47 from adapters.config import load_config
48
49 fx = build_two_repo_constellation(tmp_path, stale_relay=True)
50 seed_git_repo(fx["scooling"])
51 # Minimal lock so status can run without config error
52 cfg = load_config(fx["scooling"] / ".overseer" / "config.yaml")
53 # status without --workspace should not force workspace failure into overall claim
54 plain = run_shim("ok", ["status", "--json"], cwd=fx["scooling"])
55 assert plain.exit_code == 0
56 plain_payload = json.loads(plain.stdout)
57 assert "workspace" not in plain_payload or plain_payload.get("workspace") is None
58
59 ws = run_shim("ok", ["status", "--workspace", "--json"], cwd=fx["scooling"])
60 ws_payload = json.loads(ws.stdout)
61 assert ws_payload["workspace"]["ok"] is False
62 # Without --exit-code, process exit stays 0 even when workspace.ok false
63 assert ws.exit_code == 0
64
65 ws_exit = run_shim(
66 "ok", ["status", "--workspace", "--exit-code", "--json"], cwd=fx["scooling"]
67 )
68 payload = json.loads(ws_exit.stdout)
69 assert payload["workspace"]["ok"] is False
70 # Precedence 2 > 6 > 35 > 3 > 0 — lock/substrate may win over 35 on bare fixtures
71 assert ws_exit.exit_code in {2, 6, 35}
72
73
74 def test_doctor_board_name_violation(tmp_path: Path) -> None:
75 from tests.support import run_shim
76
77 fx = build_two_repo_constellation(tmp_path, bare_names_on_relay=True)
78 result = run_shim("ok", ["workspace", "doctor", "--json"], cwd=fx["scooling"])
79 assert result.exit_code == 0
80 payload = json.loads(result.stdout)
81 codes = [f["code"] for f in payload["findings"]]
82 assert "board_name_violation" in codes
83
84
85 def test_muse_only_member_skips_git(tmp_path: Path) -> None:
86 from tools.workspace.doctor import run_doctor
87 from adapters.config import load_config
88
89 fx = build_two_repo_constellation(tmp_path, with_musehub=True)
90 cfg = load_config(fx["scooling"] / ".overseer" / "config.yaml")
91 report = run_doctor(cfg, fx["scooling"], invoke_git=True)
92 codes = [f.code for f in report.findings]
93 assert "muse_only_skip_git" in codes
94
95
96 def test_check_next_not_configured_is_config_exit(tmp_path: Path) -> None:
97 from tests.support import run_cli, write_config
98
99 write_config(tmp_path, "config-git-only.yaml")
100 (tmp_path / "docs").mkdir(exist_ok=True)
101 code = run_cli(["workspace", "check-next"], cwd=tmp_path)
102 assert code == 2
File History 1 commit
sha256:a78e7e5a8740e03315f325d19edeb3aa1b306b3337d04abbaa9a9e0f3bbeb7a1 docs: MuseHub-first before ISR #74 — staging solidify NEXT Human 1 day ago