from __future__ import annotations
import importlib.util
import sys
from pathlib import Path
_spec = importlib.util.spec_from_file_location(
"adr_governance", Path(__file__).with_name("adr-governance.py")
)
assert _spec and _spec.loader
adr = importlib.util.module_from_spec(_spec)
_spec.loader.exec_module(adr)
_MISTITLED = """\
- Status: Accepted (2026-06-11)
## Context
Some context.
## Decision
The decision body.
## Consequences
The consequences.
## Acceptance criteria
- criterion one
- criterion two
"""
_REPAIRED = _MISTITLED.replace("## Acceptance criteria", "## Validation")
def check(name: str, cond: bool) -> bool:
print(f"{'ok' if cond else 'FAIL'} - {name}")
return cond
def main() -> int:
results = [
check(
"heading-only rename restoring a required section is a repair",
adr.is_template_repair(_MISTITLED, _REPAIRED),
),
check(
"no-op edit on an already-compliant ADR is not a repair",
not adr.is_template_repair(_REPAIRED, _REPAIRED),
),
check(
"editing decision body is not a repair",
not adr.is_template_repair(
_MISTITLED,
_REPAIRED.replace("The decision body.", "A reworded decision."),
),
),
check(
"adding a new section with new content is not a repair",
not adr.is_template_repair(
_MISTITLED.replace("## Acceptance criteria\n- criterion one\n- criterion two\n", ""),
_MISTITLED.replace("## Acceptance criteria", "## Validation"),
),
),
check(
"rename that does not restore a required section is not a repair",
not adr.is_template_repair(
_MISTITLED, _MISTITLED.replace("## Acceptance criteria", "## Notes")
),
),
check("has_section detects present heading", adr.has_section(_REPAIRED, "Validation")),
check("has_section rejects absent heading", not adr.has_section(_MISTITLED, "Validation")),
]
failed = results.count(False)
print(f"\n{len(results) - failed}/{len(results)} passed")
return 1 if failed else 0
if __name__ == "__main__":
raise SystemExit(main())