"""Unit tests for the repository testing contract helpers.""" from __future__ import annotations from pathlib import Path import textwrap from testing.quality_contract import load_contract from testing.quality_coverage import run_check as run_coverage_check from testing.quality_docs import run_check as run_docs_check from testing.quality_hygiene import run_check as run_hygiene_check def test_bundled_contract_exposes_local_and_jenkins_profiles(): contract = load_contract() assert "local" in contract["profiles"] assert "jenkins" in contract["profiles"] assert contract["pytest_suites"]["unit"]["paths"] def test_handoff_modules_are_exactly_managed_linted_and_covered(): """The canonical contract must not silently drop a handoff module.""" contract = load_contract() expected = { path.as_posix() for path in Path("scripts/ops").glob("hermes_handoff_*.py") } assert len(expected) == 16 assert expected <= set(contract["managed_modules"]) assert expected <= set(contract["lint_paths"]) assert expected <= set(contract["coverage"]["tracked_files"]) assert expected <= set(contract["coverage"]["branch_tracked_files"]) assert "scripts/ops" in contract["pytest_suites"]["unit"]["coverage_sources"] assert "scripts/ops/hermes_handoff_*.py" in contract["hygiene"]["line_limit_globs"] def test_hux_replacement_modules_are_quality_managed(): """The deleted prototype helpers are replaced by the production foundation and hook modules.""" contract = load_contract() expected = { "dockerfiles/hermes-hux-foundation/hux/__init__.py", "dockerfiles/hermes-hux-foundation/hux/artifacts.py", "dockerfiles/hermes-hux-foundation/hux/audit.py", "dockerfiles/hermes-hux-foundation/hux/budgets.py", "dockerfiles/hermes-hux-foundation/hux/contracts.py", "dockerfiles/hermes-hux-foundation/hux/diffs.py", "dockerfiles/hermes-hux-foundation/hux/errors.py", "dockerfiles/hermes-hux-foundation/hux/events.py", "dockerfiles/hermes-hux-foundation/hux/flags.py", "dockerfiles/hermes-hux-foundation/hux/foundation.py", "dockerfiles/hermes-hux-foundation/hux/http.py", "dockerfiles/hermes-hux-foundation/hux/identity.py", "dockerfiles/hermes-hux-foundation/hux/memory.py", "dockerfiles/hermes-hux-foundation/hux/organization.py", "dockerfiles/hermes-hux-foundation/hux/policy.py", "dockerfiles/hermes-hux-foundation/hux/privacy.py", "dockerfiles/hermes-hux-foundation/hux/redaction.py", "dockerfiles/hermes-hux-foundation/hux/research.py", "dockerfiles/hermes-hux-foundation/hux/rules.py", "dockerfiles/hermes-hux-foundation/hux/server.py", "dockerfiles/hermes-hux-foundation/hux/store.py", "dockerfiles/hermes-worker-hux/hux_hook/__init__.py", "dockerfiles/hermes-worker-hux/hux_hook/client.py", "dockerfiles/hermes-worker-hux/hux_hook/hooks.py", } for paths in ( contract["managed_modules"], contract["lint_paths"], contract["coverage"]["tracked_files"], contract["coverage"]["branch_tracked_files"], ): assert expected <= set(paths) assert "services/hermes/scripts/hux_contracts.py" not in paths assert "services/hermes/scripts/hux_policy.py" not in paths assert "dockerfiles/hermes-hux-foundation/hux/*.py" in contract["hygiene"]["line_limit_globs"] assert "dockerfiles/hermes-worker-hux/hux_hook/*.py" in contract["hygiene"]["line_limit_globs"] def test_docs_check_reports_missing_docstring_and_missing_path(tmp_path: Path): module_path = tmp_path / "managed.py" module_path.write_text("value = 1\n", encoding="utf-8") (tmp_path / "README.md").write_text("repo docs\n", encoding="utf-8") contract = { "required_docs": [{"path": "README.md", "description": "Docs"}], "managed_modules": ["managed.py"], "lint_paths": ["missing-dir"], "pytest_suites": {"unit": {"description": "Unit", "paths": ["missing-tests"]}}, "manual_scripts": [{"path": "missing-script.py", "description": "Manual"}], } issues = run_docs_check(contract, tmp_path) assert "module docstring missing: managed.py" in issues assert "contract path missing: missing-dir" in issues assert "contract path missing: missing-tests" in issues assert "contract path missing: missing-script.py" in issues def test_docs_check_reports_missing_required_doc_metadata(tmp_path: Path): (tmp_path / "README.md").write_text("", encoding="utf-8") contract = { "required_docs": [ {"path": "README.md", "description": ""}, {"path": "missing.md", "description": "Missing"}, ], "managed_modules": [], "lint_paths": [], "pytest_suites": {"unit": {"description": "", "paths": []}}, "manual_scripts": [{"path": "manual.py", "description": ""}], } issues = run_docs_check(contract, tmp_path) assert "required doc empty: README.md" in issues assert "required doc missing description: README.md" in issues assert "required doc missing: missing.md" in issues assert "pytest suite missing description: unit" in issues assert "manual script missing description: manual.py" in issues def test_hygiene_check_enforces_line_limit_and_name_rules(tmp_path: Path): tests_dir = tmp_path / "tests" tests_dir.mkdir() (tests_dir / "conftest.py").write_text("value = 1\n", encoding="utf-8") bad_name = tests_dir / "bad-name.py" bad_name.write_text("x = 1\n", encoding="utf-8") long_file = tests_dir / "test_too_long.py" long_file.write_text("line\n" * 4, encoding="utf-8") contract = { "hygiene": { "max_lines": 3, "line_limit_globs": ["tests/*.py"], "naming_rules": [ { "glob": "tests/*.py", "pattern": r"^test_[a-z0-9_]+\.py$", "description": "pytest files use test_*.py names.", } ], } } issues = run_hygiene_check(contract, tmp_path) assert any("file exceeds 3 LOC" in issue for issue in issues) assert any( "naming rule failed" in issue and "bad-name.py" in issue for issue in issues ) def test_coverage_check_enforces_per_file_floor(tmp_path: Path): build_dir = tmp_path / "build" build_dir.mkdir() coverage_xml = build_dir / "coverage.xml" coverage_xml.write_text( textwrap.dedent( """\ """ ), encoding="utf-8", ) contract = { "coverage": { "minimum_percent": 95.0, "tracked_files": ["ok.py", "low.py", "weak_branches.py", "missing.py"], } } issues = run_coverage_check(contract, tmp_path, coverage_xml) assert "line coverage below 95.0%: low.py (90.0%)" in issues assert "branch coverage below 95.0%: weak_branches.py (90.0%)" in issues assert "coverage missing for tracked file: missing.py" in issues def test_coverage_check_handles_missing_xml_and_source_root_mapping(tmp_path: Path): missing_xml = tmp_path / "missing.xml" assert run_coverage_check( {"coverage": {"tracked_files": []}}, tmp_path, missing_xml ) == ["coverage xml missing: missing.xml"] source_dir = tmp_path / "pkg" source_dir.mkdir() (source_dir / "mapped.py").write_text("value = 1\n", encoding="utf-8") coverage_xml = tmp_path / "coverage.xml" coverage_xml.write_text( textwrap.dedent( f"""\ {source_dir} """ ), encoding="utf-8", ) (tmp_path / "absolute.py").write_text("value = 2\n", encoding="utf-8") issues = run_coverage_check( { "coverage": { "minimum_percent": 95.0, "tracked_files": ["pkg/mapped.py", "absolute.py"], } }, tmp_path, coverage_xml, ) assert issues == []