gabriel / muse public
test_plumbing_domain_info.py python
128 lines 5.1 KB
86000da9 fix: replace typer CliRunner with argparse-compatible test helper Gabriel Cardona <gabriel@tellurstori.com> 1d ago
1 """Tests for ``muse plumbing domain-info``.
2
3 Verifies that the command correctly reports the active domain, plugin class,
4 capability flags, structural schema, and registered domain enumeration.
5 """
6
7 from __future__ import annotations
8
9 import json
10 import pathlib
11
12 from tests.cli_test_helper import CliRunner
13
14 cli = None # argparse migration — CliRunner ignores this arg
15 from muse.core.errors import ExitCode
16
17 runner = CliRunner()
18
19
20 # ---------------------------------------------------------------------------
21 # Helpers
22 # ---------------------------------------------------------------------------
23
24
25 def _init_repo(path: pathlib.Path, domain: str = "midi") -> pathlib.Path:
26 muse = path / ".muse"
27 muse.mkdir(parents=True, exist_ok=True)
28 (muse / "commits").mkdir(exist_ok=True)
29 (muse / "snapshots").mkdir(exist_ok=True)
30 (muse / "objects").mkdir(exist_ok=True)
31 (muse / "refs" / "heads").mkdir(parents=True, exist_ok=True)
32 (muse / "HEAD").write_text("ref: refs/heads/main", encoding="utf-8")
33 (muse / "repo.json").write_text(
34 json.dumps({"repo_id": "test-repo", "domain": domain}), encoding="utf-8"
35 )
36 return path
37
38
39 def _env(repo: pathlib.Path) -> dict[str, str]:
40 return {"MUSE_REPO_ROOT": str(repo)}
41
42
43 # ---------------------------------------------------------------------------
44 # Tests
45 # ---------------------------------------------------------------------------
46
47
48 class TestDomainInfo:
49 def test_reports_domain_and_plugin_class(self, tmp_path: pathlib.Path) -> None:
50 repo = _init_repo(tmp_path, domain="midi")
51 result = runner.invoke(cli, ["plumbing", "domain-info"], env=_env(repo))
52 assert result.exit_code == 0, result.output
53 data = json.loads(result.stdout)
54 assert data["domain"] == "midi"
55 assert "Plugin" in data["plugin_class"]
56
57 def test_capabilities_dict_has_three_keys(self, tmp_path: pathlib.Path) -> None:
58 repo = _init_repo(tmp_path, domain="midi")
59 result = runner.invoke(cli, ["plumbing", "domain-info"], env=_env(repo))
60 assert result.exit_code == 0, result.output
61 caps = json.loads(result.stdout)["capabilities"]
62 assert "structured_merge" in caps
63 assert "crdt" in caps
64 assert "rerere" in caps
65 assert all(isinstance(v, bool) for v in caps.values())
66
67 def test_schema_has_required_fields(self, tmp_path: pathlib.Path) -> None:
68 repo = _init_repo(tmp_path, domain="midi")
69 result = runner.invoke(cli, ["plumbing", "domain-info"], env=_env(repo))
70 assert result.exit_code == 0, result.output
71 schema = json.loads(result.stdout)["schema"]
72 assert "domain" in schema
73 assert "merge_mode" in schema
74 assert schema["merge_mode"] in ("three_way", "crdt")
75 assert "dimensions" in schema
76
77 def test_registered_domains_list_present(self, tmp_path: pathlib.Path) -> None:
78 repo = _init_repo(tmp_path, domain="midi")
79 result = runner.invoke(cli, ["plumbing", "domain-info"], env=_env(repo))
80 assert result.exit_code == 0, result.output
81 data = json.loads(result.stdout)
82 assert "registered_domains" in data
83 assert "midi" in data["registered_domains"]
84
85 def test_code_domain_reports_correctly(self, tmp_path: pathlib.Path) -> None:
86 repo = _init_repo(tmp_path, domain="code")
87 result = runner.invoke(cli, ["plumbing", "domain-info"], env=_env(repo))
88 assert result.exit_code == 0, result.output
89 assert json.loads(result.stdout)["domain"] == "code"
90
91 def test_text_format_output(self, tmp_path: pathlib.Path) -> None:
92 repo = _init_repo(tmp_path, domain="midi")
93 result = runner.invoke(
94 cli, ["plumbing", "domain-info", "--format", "text"], env=_env(repo)
95 )
96 assert result.exit_code == 0, result.output
97 assert "Domain:" in result.stdout
98 assert "midi" in result.stdout
99 assert "Plugin:" in result.stdout
100 assert "Merge mode:" in result.stdout
101
102 def test_all_domains_flag_json(self, tmp_path: pathlib.Path) -> None:
103 repo = _init_repo(tmp_path, domain="midi")
104 result = runner.invoke(
105 cli, ["plumbing", "domain-info", "--all-domains"], env=_env(repo)
106 )
107 assert result.exit_code == 0, result.output
108 data = json.loads(result.stdout)
109 assert "registered_domains" in data
110 assert isinstance(data["registered_domains"], list)
111 assert len(data["registered_domains"]) >= 1
112
113 def test_all_domains_flag_text(self, tmp_path: pathlib.Path) -> None:
114 repo = _init_repo(tmp_path, domain="midi")
115 result = runner.invoke(
116 cli,
117 ["plumbing", "domain-info", "--all-domains", "--format", "text"],
118 env=_env(repo),
119 )
120 assert result.exit_code == 0, result.output
121 assert "midi" in result.stdout
122
123 def test_bad_format_exits_user_error(self, tmp_path: pathlib.Path) -> None:
124 repo = _init_repo(tmp_path, domain="midi")
125 result = runner.invoke(
126 cli, ["plumbing", "domain-info", "--format", "toml"], env=_env(repo)
127 )
128 assert result.exit_code == ExitCode.USER_ERROR