Files
chemenu/tools/chemenu/tests/test_install_doc.py
T
torben c77bda2004
CI / verify (push) Successful in 5m20s
CI / pwsh (push) Successful in 1m53s
Release / release (push) Successful in 37s
feat: INSTALL.md held to the installation instructions - prerequisites lists generated from the manifest, setup questions checked by docs verify (#154)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SnAJ7Z3CpVD3PRbN73QtU2

Files changed:
- CHANGES.md
- INSTALL.md
- VERSION
- instructions/dev/doc-pull-through.md
- instructions/dev/stack-close/SKILL.md
- instructions/setup-instance.md
- tools/CONTRACT.md
- tools/README.md
- tools/chemenu/cli_contract.py
- tools/chemenu/commands/docs_verify.py
- tools/chemenu/install_doc.py
- tools/chemenu/tests/test_install_doc.py
2026-10-02 07:47:39 +02:00

174 lines
6.4 KiB
Python

from typer.testing import CliRunner
from chemenu import config, install_doc, prerequisites
from chemenu.cli import app
runner = CliRunner()
MANIFEST = prerequisites.Manifest(
limits={},
tools=(
prerequisites.Tool("python", "3.11", "all", "Python", "why"),
prerequisites.Tool("git", None, "all", "Git", "why"),
prerequisites.Tool("pwsh", "7", "windows", "PowerShell 7 (pwsh)", "why"),
),
)
CURRENT = """# Installation
Vorher:
<!-- wikitool:prerequisites -->
- **Python** ≥ 3.11
- **Git**
<!-- /wikitool:prerequisites -->
Unter Windows zusätzlich:
<!-- wikitool:prerequisites-windows -->
- **PowerShell 7 (pwsh)** ≥ 7
<!-- /wikitool:prerequisites-windows -->
## Was der Agent dich fragt
- <!-- setup-question: identity --> **Autor-Identität** - Name und E-Mail.
"""
SETUP = """# Set up
2. <!-- setup-question: identity --> **Decision point - identity.** Ask the user.
"""
def _tree(tmp_path, monkeypatch, install=CURRENT, setup=SETUP, manifest=MANIFEST):
monkeypatch.setattr(config, "ROOT", tmp_path)
monkeypatch.setattr(prerequisites, "load_manifest", lambda path=None: manifest)
(tmp_path / "instructions").mkdir()
(tmp_path / "INSTALL.md").write_text(install, encoding="utf-8")
(tmp_path / "instructions" / "setup-instance.md").write_text(setup, encoding="utf-8")
return tmp_path
def test_this_repos_install_doc_matches_the_manifest():
assert install_doc.check_prerequisite_regions() == []
def test_this_repos_install_doc_names_every_setup_question():
assert install_doc.check_setup_questions() == []
def test_this_repos_setup_instruction_marks_its_questions():
"""The check compares two sets; an instruction that lost every marker would
compare empty against empty and pass. Guard the real file's own count."""
text = install_doc.setup_instruction_path().read_text(encoding="utf-8")
assert install_doc.question_keys(text) >= {
"identity", "remote", "kb-language", "domain",
"personalization", "environment", "telemetry", "task-tracker",
}
def test_render_lines_are_label_and_minimum_only():
assert install_doc.render_lines(MANIFEST.tools) == [
"- **Python** ≥ 3.11",
"- **Git**",
"- **PowerShell 7 (pwsh)** ≥ 7",
]
def test_a_current_install_doc_passes(tmp_path, monkeypatch):
_tree(tmp_path, monkeypatch)
assert install_doc.check_prerequisite_regions() == []
assert install_doc.check_setup_questions() == []
def test_a_manifest_tool_missing_from_install_doc_fails(tmp_path, monkeypatch):
"""Acceptance criterion: a tool in the manifest that INSTALL.md lacks fails `docs verify`."""
_tree(tmp_path, monkeypatch, install=CURRENT.replace("- **Git**\n", ""))
issues = install_doc.check_prerequisite_regions()
assert any("no longer matches tools/prerequisites.txt" in issue for issue in issues)
def test_a_new_platform_without_a_region_fails(tmp_path, monkeypatch):
manifest = prerequisites.Manifest(
limits={},
tools=MANIFEST.tools + (prerequisites.Tool("brew", None, "macos", "Homebrew", "why"),),
)
_tree(tmp_path, monkeypatch, manifest=manifest)
issues = install_doc.check_prerequisite_regions()
assert any("<!-- wikitool:prerequisites-macos -->" in issue for issue in issues)
def test_a_region_for_a_platform_no_tool_has_fails(tmp_path, monkeypatch):
manifest = prerequisites.Manifest(limits={}, tools=MANIFEST.tools[:2])
_tree(tmp_path, monkeypatch, manifest=manifest)
issues = install_doc.check_prerequisite_regions()
assert any("prerequisites-windows" in issue and "no tool" in issue for issue in issues)
def test_a_missing_install_doc_is_reported(tmp_path, monkeypatch):
_tree(tmp_path, monkeypatch)
(tmp_path / "INSTALL.md").unlink()
assert any("missing" in issue for issue in install_doc.check_prerequisite_regions())
assert install_doc.check_setup_questions() == []
def test_refresh_touches_nothing_outside_the_regions(tmp_path):
stale = CURRENT.replace("≥ 3.11", "≥ 3.9")
refreshed, missing = install_doc.refresh(stale, MANIFEST)
assert missing == []
assert refreshed == CURRENT
def test_refresh_is_idempotent():
once, _ = install_doc.refresh(CURRENT, MANIFEST)
twice, _ = install_doc.refresh(once, MANIFEST)
assert once == twice == CURRENT
def test_a_question_the_install_doc_does_not_name_fails(tmp_path, monkeypatch):
"""Acceptance criterion: a new question in setup-instance.md that INSTALL.md
does not name fails `docs verify`."""
setup = SETUP + "\n3. <!-- setup-question: remote --> **Decision point - remote.**\n"
_tree(tmp_path, monkeypatch, setup=setup)
issues = install_doc.check_setup_questions()
assert len(issues) == 1
assert "`remote`" in issues[0] and "does not name it" in issues[0]
def test_a_question_no_longer_asked_fails(tmp_path, monkeypatch):
install = CURRENT + "- <!-- setup-question: telemetry --> **Telemetrie**\n"
_tree(tmp_path, monkeypatch, install=install)
issues = install_doc.check_setup_questions()
assert len(issues) == 1
assert "`telemetry`" in issues[0] and "no longer asks" in issues[0]
def test_docs_prerequisites_is_a_dry_run_by_default(tmp_path, monkeypatch):
stale = CURRENT.replace("≥ 3.11", "≥ 3.9")
root = _tree(tmp_path, monkeypatch, install=stale)
result = runner.invoke(app, ["docs", "prerequisites"])
assert result.exit_code == 0, result.output
assert "would change" in result.output
assert (root / "INSTALL.md").read_text(encoding="utf-8") == stale
def test_docs_prerequisites_apply_rewrites_the_regions(tmp_path, monkeypatch):
root = _tree(tmp_path, monkeypatch, install=CURRENT.replace("≥ 3.11", "≥ 3.9"))
result = runner.invoke(app, ["docs", "prerequisites", "--apply"])
assert result.exit_code == 0, result.output
assert (root / "INSTALL.md").read_text(encoding="utf-8") == CURRENT
assert install_doc.check_prerequisite_regions() == []
def test_docs_prerequisites_never_places_a_missing_region(tmp_path, monkeypatch):
without_windows = CURRENT.replace(
"<!-- wikitool:prerequisites-windows -->\n- **PowerShell 7 (pwsh)** ≥ 7\n"
"<!-- /wikitool:prerequisites-windows -->\n",
"",
)
root = _tree(tmp_path, monkeypatch, install=without_windows)
result = runner.invoke(app, ["docs", "prerequisites", "--apply"])
assert result.exit_code == 1
assert "prerequisites-windows" in result.output
assert (root / "INSTALL.md").read_text(encoding="utf-8") == without_windows