#!/usr/bin/env python3 from __future__ import annotations import json import os import subprocess import sys from pathlib import Path ROOT = Path(__file__).resolve().parents[1] SCHEMAS = ROOT / "schemas" TEMPLATES = ROOT / "templates" EXAMPLE_CARD = ROOT / "examples" / "card" EXAMPLE_SERIES = ROOT / "examples" / "series" / "series.json" def load_json(path: Path) -> dict: with path.open(encoding="utf-8") as stream: value = json.load(stream) if not isinstance(value, dict): raise AssertionError(f"{path}: korzeń JSON musi być obiektem") return value def check_json_files() -> None: for path in sorted(SCHEMAS.glob("*.json")): schema = load_json(path) assert schema.get("$schema", "").endswith("2020-12/schema"), path for path in sorted(TEMPLATES.glob("*.json")): template = load_json(path) assert template.get("schema") == "esc-card-template.v1", path assert template.get("emitters", {}).get("latex"), path assert template.get("emitters", {}).get("html"), path card = load_json(EXAMPLE_CARD / "json" / "card_source.json") assert card.get("schema") == "esc-card-source.v1" assert card.get("sections") assert card.get("educational_requirements") series = load_json(EXAMPLE_SERIES) assert series.get("version") == 1 assert series.get("cards") def check_optional_json_schema() -> None: try: import jsonschema except ModuleNotFoundError: if os.environ.get("CARD_LAYOUTS_REQUIRE_JSONSCHEMA") == "1": raise AssertionError("brak pakietu jsonschema wymaganego przez pełną kontrolę") print("INFO: jsonschema nie jest zainstalowany; wykonuję walidację generatora.") return pairs = [ (SCHEMAS / "card-source.schema.json", EXAMPLE_CARD / "json" / "card_source.json"), (SCHEMAS / "series.schema.json", EXAMPLE_SERIES), ] pairs.extend( (SCHEMAS / "card-template.schema.json", path) for path in sorted(TEMPLATES.glob("*.json")) ) for schema_path, document_path in pairs: jsonschema.Draft202012Validator(load_json(schema_path)).validate(load_json(document_path)) def check_render() -> None: subprocess.run( [sys.executable, str(ROOT / "tools" / "render_card.py"), str(EXAMPLE_CARD)], cwd=ROOT, check=True, ) tex_path = EXAMPLE_CARD / "build" / "tex" / "main.tex" html_path = EXAMPLE_CARD / "build" / "html" / "index.html" css_path = EXAMPLE_CARD / "build" / "html" / "style.css" for path in (tex_path, html_path, css_path): if not path.is_file() or path.stat().st_size == 0: raise AssertionError(f"brak wygenerowanego pliku: {path}") tex = tex_path.read_text(encoding="utf-8") html = html_path.read_text(encoding="utf-8") for marker in ("DEMO-01", "IP WO", "INF04", "KARTA PRACY"): if marker not in tex: raise AssertionError(f"TeX nie zawiera znacznika {marker!r}") if marker not in html: raise AssertionError(f"HTML nie zawiera znacznika {marker!r}") if r"\qrcode[height=" not in tex: raise AssertionError("TeX nie zawiera kodu QR z tabliczki") for marker in ('class="title-qr"', 'class="code-subblock"'): if marker not in html: raise AssertionError(f"HTML nie zawiera znacznika {marker!r}") def main() -> int: check_json_files() check_optional_json_schema() check_render() print("PASS: schematy, layouty, przykład serii oraz render TeX/HTML są spójne.") return 0 if __name__ == "__main__": raise SystemExit(main())