test(golden): freeze .tex render output with golden-file regression suite#28
Merged
Conversation
…uite Add deterministic golden-file tests over the .tex render layer so future refactors cannot silently change the rendered output. Representative samples cover one document per Markdown variant (plain, report, protocol-asta, protocol-stupa) — exercising headings, lists, callouts, citations, tables, the font-independent Unicode set (€ → ↔ ≤ ≥ ·) and code spans — plus a .tex.py node-tree document. Each sample is rendered to a LaTeX string in memory (no tectonic, no PDF, no subprocess) and compared byte-for-byte against a checked-in golden under tests/golden/expected/. Output is deterministic: verified identical across PYTHONHASHSEED values, with no timestamps/paths/randomness leaking in (the samples avoid relative image/logo paths; _normalise strips the worktree path as defence in depth). Goldens are intentionally regenerated with PYTEX_UPDATE_GOLDEN=1 pytest tests/golden. PDF output is not hashed (non-deterministic + needs tectonic); an opt-in PYTEX_TEST_PODMAN=1 smoke only asserts a sample compiles to a %PDF- blob. A scoped .gitignore negation keeps the goldens tracked despite the global *.tex ignore. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
Freeze the deterministic
.texrender output so the upcoming cleanup (and any future refactor) cannot silently change what PyTeX emits. A diff in rendered LaTeX now fails CI instead of slipping through.What
New
tests/golden/suite. Each sample is rendered to a LaTeX string in memory — no tectonic, no PDF, no subprocess — and compared byte-for-byte against a checked-in golden undertests/golden/expected/.Samples / variants covered (
tests/golden/inputs/):plain.mdplainreport.mdreportprotocol-asta.mdprotocol-asta{{time}}/{{count}}/{{vote}}shortcodes,[!beschluss]/[!abstimmung]/[!aufgabe]/[!frist]/[!info]boxes, signaturesprotocol-stupa.mdprotocol-stupanodetree.tex.py.py)All four Markdown variants carry the font-independent Unicode set
€ → ↔ ≤ ≥ ·and a code span.Determinism
PYTHONHASHSEEDvalues (0/1/12345) — packages are topologically sorted by name, no set-iteration leaks.logos/*.pdf; samples avoid relative image paths)._normalisestrips the worktree path as defence in depth.set[PackageOption]render order.Regenerating goldens
Intended output changes are applied deliberately:
Review the resulting diff before committing — an intended change shows up there; an accidental one is the regression this suite catches.
PDF
Not hashed (non-deterministic + needs tectonic). An opt-in
PYTEX_TEST_PODMAN=1smoke (test_golden_pdf_smoke.py) only asserts a sample compiles to a%PDF-blob — skipped in CI.Notes
.gitignorenegation (!tests/golden/expected/*.tex) keeps the goldens tracked despite the global*.texignore.Checks
ruff format --check src tests+ruff check src tests✅basedpyright tests/golden→ 0 errors, 0 warnings ✅🤖 Generated with Claude Code