Skip to content

test(golden): freeze .tex render output with golden-file regression suite#28

Merged
frederikbeimgraben merged 1 commit into
mainfrom
test/golden-snapshots
Jun 4, 2026
Merged

test(golden): freeze .tex render output with golden-file regression suite#28
frederikbeimgraben merged 1 commit into
mainfrom
test/golden-snapshots

Conversation

@frederikbeimgraben
Copy link
Copy Markdown
Owner

Why

Freeze the deterministic .tex render 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 under tests/golden/expected/.

Samples / variants covered (tests/golden/inputs/):

Sample Variant Exercises
plain.md plain headings, ordered/unordered+nested lists, callouts, citations, GFM table, Unicode, code span + fenced block
report.md report HSRT title page, abstract/keywords/datalines, inline-BibTeX bibliography + citations, callouts, table, Unicode, code
protocol-asta.md protocol-asta AStA protocol: header, {{time}}/{{count}}/{{vote}} shortcodes, [!beschluss]/[!abstimmung]/[!aufgabe]/[!frist]/[!info] boxes, signatures
protocol-stupa.md protocol-stupa StuPa protocol, same feature spread
nodetree.tex.py — (.py) direct node-tree API: sectioning, bold/emph, itemize/enumerate/description, footnote, label/ref, inline + display math

All four Markdown variants carry the font-independent Unicode set € → ↔ ≤ ≥ · and a code span.

Determinism

  • Output verified identical across PYTHONHASHSEED values (0/1/12345) — packages are topologically sorted by name, no set-iteration leaks.
  • No timestamps, randomness, or absolute paths in the goldens (logos render as build-dir-relative logos/*.pdf; samples avoid relative image paths). _normalise strips the worktree path as defence in depth.
  • Single class option per sample to sidestep the unordered set[PackageOption] render order.

Regenerating goldens

Intended output changes are applied deliberately:

PYTEX_UPDATE_GOLDEN=1 pytest tests/golden

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=1 smoke (test_golden_pdf_smoke.py) only asserts a sample compiles to a %PDF- blob — skipped in CI.

Notes

  • A scoped .gitignore negation (!tests/golden/expected/*.tex) keeps the goldens tracked despite the global *.tex ignore.

Checks

  • ruff format --check src tests + ruff check src tests
  • basedpyright tests/golden → 0 errors, 0 warnings ✅
  • Full suite: 923 passed, 3 skipped (incl. the new opt-in PDF smoke) ✅

🤖 Generated with Claude Code

…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>
@frederikbeimgraben frederikbeimgraben merged commit 426df93 into main Jun 4, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant