Files
2026-08-03 22:40:29 +01:00

110 lines
4.4 KiB
Python

"""Compatibility-ledger validation tests."""
import json
import tempfile
from pathlib import Path
from support import ArchitectureFixture
class CompatibilityLedgerTest(ArchitectureFixture):
def test_malformed_and_duplicate_entries_fail(self) -> None:
entry = self.valid_ledger_entry()
entry.pop("owner")
self.write_ledger([entry])
self.track_all()
malformed = self.run_cli("--all")
self.assertEqual(malformed.returncode, 1)
self.assertIn("owner", malformed.stdout)
entry = self.valid_ledger_entry()
self.write_ledger([entry, entry])
duplicate = self.run_cli("--all")
self.assertEqual(duplicate.returncode, 1)
self.assertIn("duplicate compatibility id", duplicate.stdout)
def test_invalid_and_expired_dates_fail(self) -> None:
entry = self.valid_ledger_entry()
entry["introduced_on"] = "2026-99-99"
self.write_ledger([entry])
self.track_all()
invalid = self.run_cli("--all")
self.assertEqual(invalid.returncode, 1)
self.assertIn("invalid introduced_on date", invalid.stdout)
entry = self.valid_ledger_entry()
entry["target_removal_date"] = "2000-01-01"
self.write_ledger([entry])
expired = self.run_cli("--all")
self.assertEqual(expired.returncode, 1)
self.assertIn("expired on 2000-01-01", expired.stdout)
def test_missing_path_or_marker_fails(self) -> None:
self.write_ledger([self.valid_ledger_entry()])
self.track_all()
missing_path = self.run_cli("--all")
self.assertEqual(missing_path.returncode, 1)
self.assertIn("referenced path is not tracked", missing_path.stdout)
self.write("apps/backend/internal/example/compat.go", "package example\n// different\n")
self.track_all()
missing_marker = self.run_cli("--all")
self.assertEqual(missing_marker.returncode, 1)
self.assertIn("marker no longer exists", missing_marker.stdout)
def test_valid_registered_entry_passes(self) -> None:
marker = "// compat: old-name"
self.write("apps/backend/internal/example/compat.go", f"package example\n{marker}\n")
self.write_ledger([self.valid_ledger_entry(marker=marker)])
self.track_all()
result = self.run_cli("--all")
self.assertEqual(result.returncode, 0, result.stdout + result.stderr)
def test_semver_accepts_prerelease_and_build_metadata(self) -> None:
marker = "// compat: semver"
self.write("apps/backend/internal/example/compat.go", f"package example\n{marker}\n")
entry = self.valid_ledger_entry(marker=marker)
entry.pop("introduced_on")
entry["introduced_version"] = "1.2.3-alpha+build.7"
entry.pop("target_removal_date")
entry["target_removal_version"] = "2.0.0"
self.write_ledger([entry])
self.track_all()
result = self.run_cli("--all")
self.assertEqual(result.returncode, 0, result.stdout + result.stderr)
def test_semver_rejects_leading_zero_and_empty_identifiers(self) -> None:
marker = "// compat: semver"
self.write("apps/backend/internal/example/compat.go", f"package example\n{marker}\n")
for invalid in ("01.2.3", "1.2.3-..", "1.2.3-alpha..1"):
with self.subTest(invalid=invalid):
entry = self.valid_ledger_entry(marker=marker)
entry.pop("introduced_on")
entry["introduced_version"] = invalid
self.write_ledger([entry])
self.track_all()
result = self.run_cli("--all")
self.assertEqual(result.returncode, 1)
self.assertIn("invalid introduced_version", result.stdout)
def test_ledger_outside_repository_uses_absolute_label(self) -> None:
marker = "// compat: external-ledger"
self.write("apps/backend/internal/example/compat.go", f"package example\n{marker}\n")
self.track_all()
with tempfile.TemporaryDirectory() as tempdir:
ledger_path = Path(tempdir) / "compatibility-ledger.json"
ledger_path.write_text(
json.dumps({"version": 1, "entries": [self.valid_ledger_entry(marker=marker)]}) + "\n",
encoding="utf-8",
)
result = self.run_cli("--all", "--ledger", str(ledger_path))
self.assertEqual(result.returncode, 0, result.stdout + result.stderr)