Vorlagen testen
Mit @formfeed/testing prüft Ihre eigene Vitest- oder Jest-Suite Vorlagen: dass sie mit bestimmten Daten kompilieren und rendern, dass sie nur Variablen lesen, die die Daten haben, welchen Text sie enthalten und, über die API, wie viele Seiten sie drucken. Das Paket braucht Node.js 22 oder neuer und, wenn Sie Vitest nutzen, Vitest 3.2 oder neuer. Installieren Sie die Helfer:
npm install -D @formfeed/testing
import { loadTemplate } from '@formfeed/testing';
import invoice from '../templates/invoice-de/data/default.json';
const tpl = await loadTemplate('templates/invoice-de');
test('kompiliert und nutzt nur bekannte Variablen', async () => {
await expect(tpl).toRenderWithoutErrors(invoice);
await expect(tpl).toUseOnlyKnownVariables(invoice);
});
test('HTML-Snapshot', async () => {
const html = await tpl.render(invoice);
expect(html).toMatchSnapshot();
});
test('zwei Seiten bei vierzig Positionen', async () => {
await expect(tpl).toHavePageCount(2, invoice); // echtes Rendering über die API; ohne Schlüssel übersprungen
});
Die Matcher brauchen die Setup-Datei Ihres Test-Runners.
loadTemplate
loadTemplate(folder) liest einen Vorlagenordner und liefert ein Handle. Der Pfad wird vom aktuellen Arbeitsverzeichnis aus aufgelöst (dort, wo der Test-Runner startet), nicht von der Testdatei aus. Eine formfeed.json oberhalb des Ordners wird verwendet, wenn es eine gibt; sonst gilt der übergeordnete Ordner als Vorlagenordner, und partials/ neben diesem liefert die Includes.
| Element | Was es ist |
|---|---|
tpl.render(data?) | Das zusammengesetzte Dokument als HTML, so wie die API es drucken würde. Kopf- und Fußzeile gehören nicht dazu. |
tpl.analyze(data?) | Die Diagnosen des Editors: Syntaxfehler, unbekannte Filter, Variablen, die in den Daten fehlen |
tpl.data(name?) | Ein Datensatz aus data/<name>.json; ohne Namen default, sonst die erste Datei. Ein unbekannter Name wirft einen Fehler. |
tpl.slug, tpl.dir | Name und absoluter Pfad des Ordners |
tpl.files, tpl.project | Die Dateien der Vorlage und das Projekt, so wie das Devkit sie liest |
data ist überall optional: Ohne Angabe wird der Standard-Datensatz der Vorlage verwendet.
Die Helfer rendern HTML-Vorlagen. loadTemplate liest auch einen Ordner mit einem Word- oder PowerPoint-Dokument, und tpl.analyze(data) listet dessen Funde nach Teil und Absatz, aber tpl.render wirft dafür einen Fehler, sodass die Matcher fehlschlagen. Testen Sie solche Vorlagen mit formfeed test.
Matcher
| Matcher | Schicht | Besteht, wenn |
|---|---|---|
toRenderWithoutErrors(data?) | offline | Die Vorlage keine Fehler-Diagnosen hat und ohne Engine-Fehler rendert |
toUseOnlyKnownVariables(data?) | offline | Kein Variablenpfad, den die Vorlage liest, in den Daten fehlt (die Warnung unknown-variable, die validate durchgehen lässt) |
toContainText(text, data?) | offline | Der Text des gerenderten Dokuments, ohne Tags, <style> und <script>, text enthält |
toHavePageCount(n, data?) | API | Das echte Rendering über die API genau n Seiten hat |
toHavePageCount rendert das Dokument lokal, sendet es mit den Einstellungen der Vorlage als HTML an die API und liest die Seitenzahl des PDFs. Es ist ein echtes Rendering: kostenlos mit einem Test-Schlüssel, mit einem Live-Schlüssel zählt es gegen Ihren Plan. Seinen Schlüssel liest es nur aus FORMFEED_API_KEY, nicht aus der gespeicherten Anmeldung der CLI. Ohne diese Variable besteht es und gibt eine Warnung aus (toHavePageCount skipped …); setzen Sie in der CI FORMFEED_REQUIRE_API=1, damit es stattdessen fehlschlägt.
Noch nicht verfügbar: Pixel-Snapshots des echten Renderings (toMatchRenderSnapshot).
Einrichtung
Vitest:
import { defineConfig } from 'vitest/config';
export default defineConfig({
test: { setupFiles: ['@formfeed/testing/vitest'] },
});
Jest: Fügen Sie @formfeed/testing/jest zu setupFilesAfterEnv hinzu. Beide Setup-Dateien rufen expect.extend mit den Matchern auf und ergänzen ihre Typen bei expect, sodass TypeScript toRenderWithoutErrors und die anderen kennt. Für einen anderen Runner rufen Sie expect.extend(matchers) selbst auf, mit matchers aus @formfeed/testing; createMatchers({ env, client, warn }) baut sie mit Ihrer eigenen Umgebung, Ihrem eigenen API-Client (etwa einer Attrappe in Tests) oder Ihrer eigenen Warnfunktion.
FORMFEED_API_KEY (und optional FORMFEED_REGION, Standard eu, und FORMFEED_BASE_URL) schalten den API-gestützten Matcher frei.
Ohne Test-Runner
formfeed test prüft jede Vorlage des Projekts oder eine (formfeed test invoice-de) mit jedem Datensatz in data/*.json (--data <name> für einen): Es kompiliert und analysiert die Vorlage, rendert sie und vergleicht das Ergebnis mit dem genehmigten Snapshot in tests/__snapshots__/. Ein Datensatz mit einer Fehler-Diagnose oder einem abweichenden Snapshot lässt den Lauf mit Exit-Code 1 scheitern; ein Datensatz ohne Snapshot erscheint als without snapshot und lässt nichts scheitern. --update-snapshots (-u) schreibt die aktuelle Ausgabe als genehmigten Snapshot; committen Sie die Snapshots mit den Vorlagen.
Bei einer HTML-Vorlage ist der Snapshot das zusammengesetzte Dokument (<Datensatz>.html), gefolgt von der gerenderten Kopf- und Fußzeile unter den Zeilen <!-- formfeed:header --> und <!-- formfeed:footer -->: Chromium druckt sie aus eigenen Templates, außerhalb des Dokuments, und eine geänderte Fußzeile muss den Test scheitern lassen wie jede andere Änderung. Eine Word- oder PowerPoint-Vorlage wird mit jedem Datensatz gefüllt, und ihr Snapshot ist das XML der gefüllten Teile (<Datensatz>.xml), formatiert und gefüllt, ohne Bilder zu laden oder zu zeichnen, damit der Vergleich offline läuft und jedes Mal dasselbe Ergebnis liefert. Das PDF einer solchen Vorlage kommt vom Konverter; seine Seiten prüfen Sie mit formfeed render --output pdf oder ci preview.