"""IMP-13 u7 smoke — discovery, source invariants, dry-run, idempotency, manifest schema.""" from __future__ import annotations import json, os, re, sys from pathlib import Path REPO_ROOT = Path(__file__).resolve().parent.parent SCRIPT_PATH = REPO_ROOT / "scripts" / "generate_frame_previews.py" sys.path.insert(0, str(SCRIPT_PATH.parent)) import generate_frame_previews as gfp # noqa: E402 def _fixture(root: Path) -> Path: blocks = root / "blocks" (blocks / "FRAME_A").mkdir(parents=True) (blocks / "FRAME_A" / "index.html").write_text("", encoding="utf-8") (blocks / "FRAME_A" / "preview.png").write_bytes(b"\x89PNG\r\n\x1a\n") (blocks / "FRAME_B").mkdir() (blocks / "ORPHAN").mkdir() (blocks / "ORPHAN" / "preview.png").write_bytes(b"x") return blocks def test_discover_counts(tmp_path: Path) -> None: rows = gfp.discover(_fixture(tmp_path)) assert [r.frame_id for r in rows] == ["FRAME_A", "FRAME_B", "ORPHAN"] assert sum(r.has_index for r in rows) == 1 and sum(r.has_preview for r in rows) == 2 def test_source_invariants() -> None: src = SCRIPT_PATH.read_text(encoding="utf-8") for t in ("anthropic", "openai", "jinja", "phase_z2", "slide_measurer"): assert t not in src, t for lit in ("1280", "720", "1400", "900"): assert not re.search(rf"(? None: rc = gfp.main(["--blocks-dir", str(_fixture(tmp_path)), "--manifest", str(tmp_path / "m.json"), "--dry-run"]) assert rc == 0 and "discovered: total=3 with_index_html=1 with_preview_png=2" in capsys.readouterr().out def test_idempotency_unchanged(tmp_path: Path) -> None: row = gfp.discover(_fixture(tmp_path))[0] mt = row.index_html_path.stat().st_mtime os.utime(row.preview_png_path, (mt + 1, mt + 1)) sha = gfp._sha256_file(row.index_html_path) assert gfp.is_unchanged(row, {"index_sha256": sha}) is True assert gfp.is_unchanged(row, {"index_sha256": "x"}) is False assert gfp.is_unchanged(row, None) is False def test_manifest_schema(tmp_path: Path) -> None: blocks = tmp_path / "blocks"; (blocks / "F").mkdir(parents=True); (blocks / "F" / "preview.png").write_bytes(b"x") mf = tmp_path / "m.json" assert gfp.main(["--blocks-dir", str(blocks), "--manifest", str(mf)]) == 0 data = json.loads(mf.read_text(encoding="utf-8")) assert set(data) >= {"schema", "generated_at", "blocks_dir", "summary", "frames"} and data["schema"] == 1 assert set(data["summary"]) >= {"total", "renderable", "missing_index_html", "orphan", "rendered", "skipped_unchanged", "error"} and data["summary"]["orphan"] == 1 and data["frames"]["F"]["status"] == "orphan"