#!/usr/bin/env python3 """Validate the diagram-only fixture contract.""" from __future__ import annotations import json import xml.etree.ElementTree as ET from pathlib import Path ROOT = Path(__file__).resolve().parent SVG_NS = {"svg": "http://www.w3.org/2000/svg"} FORBIDDEN_EFFECTS = ( " None: directories = sorted(p for p in ROOT.iterdir() if p.is_dir() and len(p.name) > 3 and p.name[:2].isdigit() and p.name[2] == "-") if not directories: raise SystemExit("no numbered fixture directories found") for directory in directories: svgs = list(directory.glob("*.svg")) if len(svgs) != 1: raise SystemExit(f"{directory.name}: expected one SVG, found {len(svgs)}") svg_path = svgs[0] source = svg_path.read_text(encoding="utf-8") root = ET.fromstring(source) if root.find("svg:title", SVG_NS) is None or root.find("svg:desc", SVG_NS) is None: raise SystemExit(f"{svg_path}: missing SVG title/desc") for token in FORBIDDEN_EFFECTS: if token in source: raise SystemExit(f"{svg_path}: forbidden visual effect {token}") for phrase in FORBIDDEN_VISIBLE_PHRASES: if phrase in source: raise SystemExit(f"{svg_path}: forbidden poster chrome {phrase}") composition_path = directory / "composition.json" composition = json.loads(composition_path.read_text(encoding="utf-8")) if composition.get("diagram_only") is not True: raise SystemExit(f"{composition_path}: diagram_only must be true") required = {"global title", "footer", "takeaway band", "gradient", "drop shadow", "glow"} actual = set(composition.get("forbidden_visible_elements", [])) missing = required - actual if missing: raise SystemExit(f"{composition_path}: missing forbidden items {sorted(missing)}") print(f"PASS {len(directories)} diagram-only fixtures") if __name__ == "__main__": main()