TableGuard, BottomSpacer, FirstPageHeader and PageChrome implement the verified pagination rules; renderCore returns bytes, a normalised layout tree, audit issues and a layout fingerprint. auditLayout detects overlaps, ink overflow, truncation, header-only pages and split blocks. Quirk tests pin the react-pdf behaviours the design depends on, and a child-process test pins the page-level absolute Svg hang.
56 lines
2.1 KiB
TypeScript
56 lines
2.1 KiB
TypeScript
// Child-process scenarios for src/pdf/hang.test.ts. Bundled with esbuild and run with node, because
|
|
// react-pdf's paginate() is a synchronous loop: an in-process timer never fires while it spins.
|
|
import { createElement as h } from "react";
|
|
import { Document, Page, Path, Svg, Text, View } from "@react-pdf/renderer";
|
|
import path from "node:path";
|
|
import { FirstPageHeader } from "../../src/pdf/blocks/FirstPageHeader";
|
|
import { find } from "../../src/pdf/testing/docs";
|
|
import { registerBundledFonts, stack } from "../../src/pdf/fonts/register";
|
|
import { renderCore } from "../../src/pdf/render/core";
|
|
|
|
registerBundledFonts(path.resolve(process.cwd(), "public/fonts"));
|
|
|
|
const [scenario, rowsArg] = process.argv.slice(2);
|
|
const rows = Number(rowsArg);
|
|
const W = 595.28;
|
|
const H = 841.89;
|
|
const PAD = 40;
|
|
const text = { fontFamily: stack("IBM Plex Sans"), fontSize: 10, lineHeight: "12pt" };
|
|
|
|
const flow = Array.from({ length: rows }, (_, i) =>
|
|
h(View, { key: i, style: { height: 18 } }, h(Text, { style: text }, `Row ${i + 1}`)),
|
|
);
|
|
|
|
const svg = (extra: Record<string, unknown>) =>
|
|
h(
|
|
Svg,
|
|
{ viewBox: "0 0 100 40", style: { width: W, height: 40, ...extra } },
|
|
h(Path, { d: "M0 0 L100 0 L100 40 L0 40 Z", fill: "#cccccc" }),
|
|
);
|
|
|
|
function pageWith(children: unknown[]) {
|
|
return h(Document, null, h(Page, { size: { width: W, height: H }, style: { padding: PAD } }, ...(children as never[])));
|
|
}
|
|
|
|
const element =
|
|
scenario === "page-level-svg"
|
|
? // Non-fixed, absolute, full width, straddling the bottom margin line (H - PAD = 801.89).
|
|
pageWith([...flow, svg({ position: "absolute", left: 0, top: H - PAD - 20 })])
|
|
: pageWith([
|
|
h(
|
|
FirstPageHeader,
|
|
{
|
|
key: "head",
|
|
pad: { top: PAD, right: PAD, bottom: PAD, left: PAD },
|
|
decor: [{ x: 0, y: 10, width: W, height: 40, children: svg({}) }],
|
|
style: { height: 60 },
|
|
},
|
|
h(Text, { style: text }, "Header"),
|
|
),
|
|
...flow,
|
|
]);
|
|
|
|
const r = await renderCore(element);
|
|
const svgPages = r.layout.map((p) => find(p, (n) => n.type === "svg").length);
|
|
console.log(JSON.stringify({ pages: r.pages, svgPages }));
|