# file: tests/test_text_hygiene.py # version: 1 """Exercise the governed text hygiene audit's real file and CLI contracts.""" from __future__ import annotations import pathlib import subprocess import sys import tempfile import unittest _SCRIPT = pathlib.Path(__file__).resolve().parents[1] / "scripts/audit_text_hygiene.py" class TextHygieneAuditTests(unittest.TestCase): def setUp(self) -> None: temporary = tempfile.TemporaryDirectory(prefix="pgr-text-hygiene-") self.addCleanup(temporary.cleanup) self.root = pathlib.Path(temporary.name) def source(self, name: str, contents: bytes) -> pathlib.Path: path = self.root / name path.parent.mkdir(parents=True, exist_ok=True) path.write_bytes(contents) return path def run_audit(self, *paths: str) -> subprocess.CompletedProcess[str]: return subprocess.run( [sys.executable, "-B", str(_SCRIPT), *paths], cwd=self.root, capture_output=True, text=True, check=False, ) def test_exactly_one_final_lf_is_clean(self) -> None: self.source("README.md", b"line one\nline two\n") result = self.run_audit("README.md") self.assertEqual(result.returncode, 0, result.stderr) self.assertIn("clean (1 file(s))", result.stdout) def test_extra_blank_line_at_eof_is_rejected(self) -> None: self.source("docs/page.md", b"content\n\n") result = self.run_audit("docs/page.md") self.assertEqual(result.returncode, 1) self.assertIn("extra blank line", result.stderr) def test_missing_final_lf_is_rejected(self) -> None: self.source("VERSION", b"1.2.3") result = self.run_audit("VERSION") self.assertEqual(result.returncode, 1) self.assertIn("missing final LF", result.stderr) def test_crlf_is_rejected(self) -> None: self.source("config.toml", b"value = true\r\n") result = self.run_audit("config.toml") self.assertEqual(result.returncode, 1) self.assertIn("CR byte found", result.stderr) def test_trailing_space_and_tab_are_rejected(self) -> None: self.source("docs/page.md", b"first \nsecond\t\n") result = self.run_audit("docs/page.md") self.assertEqual(result.returncode, 1) self.assertIn("docs/page.md:1: trailing whitespace", result.stderr) self.assertIn("docs/page.md:2: trailing whitespace", result.stderr) def test_generated_directory_is_skipped(self) -> None: self.source("docs/visible.md", b"clean\n") self.source("docs/target/generated.md", b"bad\n\n") result = self.run_audit("docs") self.assertEqual(result.returncode, 0, result.stderr) self.assertIn("clean (1 file(s))", result.stdout) def test_missing_path_is_a_selection_error(self) -> None: result = self.run_audit("missing.md") self.assertEqual(result.returncode, 2) self.assertIn("unsupported or missing path", result.stderr) if __name__ == "__main__": unittest.main()