from __future__ import annotations import argparse import json import re from pathlib import Path import yaml ROOT = Path(__file__).resolve().parents[1] REGISTRY = ROOT / "spec" / "13_formula_registry.yaml" GOLDEN = ROOT / "spec" / "formula_golden_cases_v2.yaml" GOLDEN_FALLBACK = ROOT / "Temp" / "formula_golden_cases.yaml" def _registry_ids() -> set[str]: if not REGISTRY.exists(): return set() payload = yaml.safe_load(REGISTRY.read_text(encoding="utf-8")) text = json.dumps(payload, ensure_ascii=False) ids = set(re.findall(r'\b([A-Z][A-Z0-9_]+_V[0-9]+)\b', text)) return ids def main() -> int: ap = argparse.ArgumentParser() ap.parse_args() golden_path = GOLDEN if GOLDEN.exists() else GOLDEN_FALLBACK if not golden_path.exists(): print("FORMULA_GOLDEN_CASES_FAIL") print("- missing file: spec/formula_golden_cases_v2.yaml") return 1 payload = yaml.safe_load(golden_path.read_text(encoding="utf-8")) rows = payload.get("golden_cases_v2") if isinstance(payload, dict) else None if rows is None and isinstance(payload, dict): rows = payload.get("golden_cases") if not isinstance(rows, list): print("FORMULA_GOLDEN_CASES_FAIL") print("- golden_cases must be list") return 1 reg = _registry_ids() errors: list[str] = [] warnings: list[str] = [] covered = 0 for i, r in enumerate(rows): if not isinstance(r, dict): errors.append(f"golden_cases[{i}] must be object") continue fid = str(r.get("formula_id") or "") if not fid: errors.append(f"golden_cases[{i}] missing formula_id") continue if reg and fid not in reg: warnings.append(f"golden_cases[{i}] formula_id not in registry: {fid}") if not isinstance(r.get("cases"), list) or len(r["cases"]) == 0: errors.append(f"golden_cases[{i}] must include non-empty cases") else: covered += 1 if errors: print("FORMULA_GOLDEN_CASES_FAIL") for e in errors: print(f"- {e}") return 1 if warnings: print("FORMULA_GOLDEN_CASES_WARN") for w in warnings: print(f"- {w}") else: print("FORMULA_GOLDEN_CASES_OK") print(f"rows={len(rows)} covered={covered} warnings={len(warnings)} source={golden_path.name}") return 0 if __name__ == "__main__": raise SystemExit(main())