#!/usr/bin/env python3 """Adversarial tests for the label geometry verifier (verify-geometry.py).""" from __future__ import annotations import importlib.util import sys import tempfile from pathlib import Path ROOT = Path(__file__).resolve().parent.parent VERIFIER = ROOT / "scripts/verify-geometry.py" ASSET_DIR = ROOT / "skills/diagram-design/assets" ARCHITECTURE = ASSET_DIR / "example-architecture.html" SWIMLANE = ASSET_DIR / "example-swimlane.html" ZONED = ASSET_DIR / "example-dp-integration.html" SEQUENCE_OAUTH = ASSET_DIR / "example-sequence-oauth.html" def load_verifier(): spec = importlib.util.spec_from_file_location("verify_geometry", VERIFIER) assert spec is not None and spec.loader is not None module = importlib.util.module_from_spec(spec) spec.loader.exec_module(module) return module SVG_HEAD = ( '' "TT." ) def document(body: str) -> str: return f"{SVG_HEAD}{body}" def main() -> int: module = load_verifier() failures: list[str] = [] def check(label: str, source: str, expect_findings: int) -> None: with tempfile.TemporaryDirectory() as scratch: candidate = Path(scratch) / "candidate.html" candidate.write_text(source, encoding="utf-8") findings = module.check(candidate) if len(findings) != expect_findings: failures.append( f"{label}: expected {expect_findings} finding(s), got " f"{len(findings)}: {findings}" ) else: print(f"OK: {label}") def check_file(label: str, path: Path, expect_findings: int) -> None: findings = module.check(path) if len(findings) != expect_findings: failures.append( f"{label}: expected {expect_findings} finding(s), got " f"{len(findings)}: {findings}" ) else: print(f"OK: {label}") node = '' badge = '' zone = '' # A label mask straddling a node declared later is the defect being caught. check( "mask clipped by a later node", document('' + node), 1, ) # Same geometry, but the node is painted first, so the label stays on top. check( "mask over an earlier node is legal", document(node + ''), 0, ) # A badge chip fully inside its own node is legal regardless of order. check("badge chip inside a node", document(badge + node), 0) # A zone eyebrow overlaps the zone container, which is painted first. check( "zone eyebrow on a zone container", document(zone + ''), 0, ) # A mask entirely in open canvas is legal. check( "mask clear of every node", document('' + node), 0, ) # Touching within the 1px tolerance is not a finding. check( "mask abutting a node edge", document('' + node), 0, ) # A long mono plate (128px, as shipped in example-sequence-oauth.html) or a # wide CJK label plate must be recognized as a mask and checked like any other. check( "wide mono mask clipped by a later node", document('' + node), 1, ) check( "wide mono mask over an earlier node is legal", document(node + ''), 0, ) # Wide-but-tall rects are container header bars or row stripes, not masks — # the height cap stays at 14 so they are never reported. check( "container header bar is not a mask", document('' + node), 0, ) check_file("shipped architecture example", ARCHITECTURE, 0) check_file("shipped swimlane example", SWIMLANE, 0) check_file("shipped zoned example", ZONED, 0) check_file("shipped sequence-oauth example", SEQUENCE_OAUTH, 0) if failures: print("\nFAILURES:") for failure in failures: print(f" - {failure}") return 1 print("All label geometry tests passed.") return 0 if __name__ == "__main__": sys.exit(main())