from __future__ import annotations import csv import subprocess import sys from pathlib import Path REPOSITORY_ROOT = next( parent for parent in Path(__file__).resolve().parents if (parent / "seed" / "generate_seed.py").is_file() ) SEED_DIRECTORY = REPOSITORY_ROOT / "seed" def _rows_by_ref(path: Path) -> dict[str, dict[str, str]]: with path.open(newline="", encoding="utf-8") as handle: rows = list(csv.DictReader(handle)) assert all(None not in row for row in rows), f"malformed CSV row in {path.name}" return {row["public_ref"]: row for row in rows} def test_generator_reproduces_committed_seed_snapshot_byte_for_byte(tmp_path: Path): subprocess.run( [ sys.executable, str(SEED_DIRECTORY / "generate_seed.py"), "--anchor", "2026-08-01", "--seed", "20260801", "--out", str(tmp_path), ], cwd=REPOSITORY_ROOT, check=True, capture_output=True, text=True, ) committed_files = sorted(SEED_DIRECTORY.glob("*.csv")) generated_files = sorted(tmp_path.glob("*.csv")) assert [path.name for path in generated_files] == [path.name for path in committed_files] for committed in committed_files: generated = tmp_path / committed.name assert generated.read_bytes() == committed.read_bytes(), ( f"{committed.name} differs from the deterministic generated snapshot" ) bookings = _rows_by_ref(tmp_path / "bookings.csv") inspections = _rows_by_ref(tmp_path / "inspections.csv") issues = _rows_by_ref(tmp_path / "data_quality_issues.csv") assert int(bookings["BK-H-0007"]["end_odometer_km"]) < int( bookings["BK-H-0057"]["end_odometer_km"] ) assert int(bookings["BK-H-0010"]["end_odometer_km"]) < int( bookings["BK-H-0060"]["end_odometer_km"] ) assert inspections["INSP-0007"]["odometer_km"] == bookings["BK-H-0007"]["end_odometer_km"] assert inspections["INSP-0010"]["odometer_km"] == bookings["BK-H-0010"]["end_odometer_km"] assert inspections["INSP-0001"]["completed_at"] == bookings["BK-H-0001"]["ends_at"] expected_issue_refs = {f"DQ-{index:04d}" for index in range(5, 22)} assert expected_issue_refs <= issues.keys() assert all( issues[public_ref]["evidence"] != "Synthetic deterministic seed issue" for public_ref in expected_issue_refs ) assert "INSP-0007" in issues["DQ-0007"]["evidence"] assert "INSP-0057" in issues["DQ-0007"]["evidence"] assert "INSP-0010" in issues["DQ-0010"]["evidence"] assert "INSP-0060" in issues["DQ-0010"]["evidence"]