from __future__ import annotations import json import subprocess import sys import tempfile import unittest from pathlib import Path from tools.build_api_registry import build as build_api_registry from tools.build_architecture_inventory import ( build as build_architecture_inventory, source_metrics, ) from tools.verify_baseline import python_test_command ROOT = Path(__file__).resolve().parents[1] class MaintenanceToolTests(unittest.TestCase): def test_generated_registries_are_current(self) -> None: expected_api = json.loads( (ROOT / "config" / "api.config.json").read_text(encoding="utf-8") ) expected_architecture = json.loads( (ROOT / "config" / "architecture-inventory.json").read_text( encoding="utf-8" ) ) self.assertEqual(expected_api, build_api_registry()) self.assertEqual(expected_architecture, build_architecture_inventory()) def test_baseline_verifier_uses_the_application_frontend(self) -> None: source = (ROOT / "tools" / "verify_baseline.py").read_text(encoding="utf-8") self.assertIn('FRONTEND_ROOT = ROOT / "frontend"', source) self.assertIn('path.suffix in {".js", ".mjs"}', source) self.assertIn("start_e2e_server()", source) self.assertIn("stop_e2e_server(server)", source) self.assertNotIn('"static/app.js"', source) def test_runtime_artifacts_have_one_ignored_root(self) -> None: gitignore = (ROOT / ".gitignore").read_text(encoding="utf-8") dockerignore = (ROOT / ".dockerignore").read_text(encoding="utf-8") playwright = (ROOT / "playwright.config.js").read_text(encoding="utf-8") launcher = (ROOT / "tools" / "start_local.ps1").read_text(encoding="utf-8") self.assertIn("runtime/*", gitignore) self.assertIn("runtime/", dockerignore) self.assertIn('outputDir: "./runtime/test-results"', playwright) self.assertIn('Join-Path $runtime "logs"', launcher) self.assertEqual(list(ROOT.glob("*.log")), []) def test_verifier_runs_the_complete_standalone_suite(self) -> None: command = python_test_command() self.assertIn("discover", command) self.assertIn("tests", command) def test_architecture_metrics_are_independent_of_checkout_line_endings(self) -> None: with tempfile.TemporaryDirectory() as directory: root = Path(directory) lf = root / "lf.js" crlf = root / "crlf.js" lf.write_bytes(b"const a = 1;\nconst b = 2;\n") crlf.write_bytes(b"const a = 1;\r\nconst b = 2;\r\n") self.assertEqual(source_metrics(lf), source_metrics(crlf)) def test_every_tool_has_a_non_mutating_help_path(self) -> None: for path in sorted((ROOT / "tools").glob("*.py")): if path.name.startswith("_"): continue with self.subTest(tool=path.name): result = subprocess.run( [sys.executable, str(path), "--help"], cwd=ROOT, capture_output=True, text=True, timeout=15, check=False, ) self.assertEqual(result.returncode, 0, result.stderr) def test_migration_only_tools_are_retired(self) -> None: for name in ( "build_preservation_manifest.py", "compare_preservation_apis.py", "compare_preservation_databases.py", "move_class_methods.py", "run_preservation_runtime.py", ): with self.subTest(name=name): self.assertFalse((ROOT / "tools" / name).exists()) if __name__ == "__main__": unittest.main()