"""The manual page, which is generated from the settings table.""" import shutil import subprocess import sys from pathlib import Path import pytest from bandsaunter import settings as st GENERATOR = Path(__file__).resolve().parent.parent / "packaging" / "make-man.py" @pytest.fixture(scope="module") def page(tmp_path_factory): out = tmp_path_factory.mktemp("man") / "bandsaunter.1" subprocess.run([sys.executable, str(GENERATOR), str(out)], check=True, capture_output=True) return out.read_text() def test_every_setting_is_documented(page): """A setting the manual does not mention is one nobody can look up.""" missing = [s.key for s in st.SETTINGS if s.key not in page] assert not missing, f"settings missing from the manual: {missing}" def test_every_flag_is_documented(page): missing = [f for s in st.SETTINGS for f in s.flags + s.off_flags if f.replace("-", "\\-") not in page and f not in page] assert not missing, f"flags missing from the manual: {missing}" def test_every_setting_explains_itself_in_plain_words(page): """The guidance is the point of the manual: what it is, when to change it.""" for s in st.SETTINGS: assert s.guidance, f"{s.key} has no plain-language guidance" assert len(s.guidance) > 80, f"{s.key}'s guidance says too little" # The first sentence has to stand on its own for someone skimming. assert s.guidance.rstrip().endswith("."), s.key def test_the_commands_and_the_keys_are_documented(page): for word in ("scan", "bands", "config", "transcribe", "devices", "profiles", "analyze"): assert f".B {word}\n" in page, f"command {word} undocumented" for section in ("SYNOPSIS", "DESCRIPTION", "COMMANDS", "OPTIONS", "SETTINGS", "FILES", "ENVIRONMENT", "EXAMPLES"): assert f".SH {section}" in page @pytest.mark.skipif(not shutil.which("groff"), reason="groff not installed") def test_it_renders_without_complaint(page, tmp_path): """Troff is unforgiving: an unescaped leading dot silently eats a line.""" src = tmp_path / "bandsaunter.1" src.write_text(page) proc = subprocess.run(["groff", "-man", "-Tutf8", "-ww", "-z", str(src)], capture_output=True, text=True) assert proc.returncode == 0, proc.stderr assert not proc.stderr.strip(), proc.stderr @pytest.mark.skipif(not shutil.which("groff"), reason="groff not installed") def test_the_guidance_survives_into_the_rendered_page(page, tmp_path): src = tmp_path / "bandsaunter.1" src.write_text(page) rendered = subprocess.run(["groff", "-man", "-Tutf8", str(src)], capture_output=True, text=True).stdout flat = " ".join(rendered.replace("\b", "").split()) # A sentence from one setting's guidance, chosen because it is the one a # newcomer most needs: what the squelch actually is. assert "This is the squelch knob." in flat