feat: 完成 DOCX 视觉门禁与字体兼容映射
This commit is contained in:
@@ -0,0 +1,100 @@
|
||||
import { createHash } from "node:crypto";
|
||||
|
||||
import { createCanvas } from "@napi-rs/canvas";
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import {
|
||||
createPdfVisualDiffReport,
|
||||
renderPdfVisualDiffHtml,
|
||||
serializePdfVisualDiffJson,
|
||||
type PdfDocumentSnapshot,
|
||||
type PdfPageRaster,
|
||||
} from "../src/index.js";
|
||||
|
||||
function raster(color: string): PdfPageRaster {
|
||||
const canvas = createCanvas(40, 50);
|
||||
const context = canvas.getContext("2d");
|
||||
context.fillStyle = "#ffffff";
|
||||
context.fillRect(0, 0, 40, 50);
|
||||
context.fillStyle = color;
|
||||
context.fillRect(10, 10, 20, 20);
|
||||
const png = Uint8Array.from(canvas.toBuffer("image/png"));
|
||||
return {
|
||||
widthPx: 40,
|
||||
heightPx: 50,
|
||||
dpi: 144,
|
||||
sha256: createHash("sha256").update(png).digest("hex"),
|
||||
png,
|
||||
};
|
||||
}
|
||||
|
||||
function snapshot(label: string, pageRaster: PdfPageRaster): PdfDocumentSnapshot {
|
||||
return {
|
||||
schemaVersion: 1,
|
||||
source: { kind: "custom", label },
|
||||
sha256: "a".repeat(64),
|
||||
pageCount: 1,
|
||||
contentText: "相同正文",
|
||||
pages: [
|
||||
{
|
||||
pageNumber: 1,
|
||||
widthPt: 20,
|
||||
heightPt: 25,
|
||||
rotation: 0,
|
||||
items: [],
|
||||
lines: [],
|
||||
contentText: "相同正文",
|
||||
raster: pageRaster,
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
describe("PDF 视觉差异报告", () => {
|
||||
it("汇总栅格门禁并生成内嵌图片的安全 HTML", async () => {
|
||||
const report = await createPdfVisualDiffReport(
|
||||
snapshot("<基线>", raster("#111111")),
|
||||
snapshot("候选", raster("#cc0000")),
|
||||
{ generatedAt: "2026-07-31T00:00:00.000Z" },
|
||||
);
|
||||
const html = renderPdfVisualDiffHtml(report);
|
||||
expect(report.status).toBe("failed");
|
||||
expect(html).toContain("<基线>");
|
||||
expect(html).toContain("data:image/png;base64,");
|
||||
expect(html).toContain("差异热力图");
|
||||
expect(html).not.toContain("<基线>");
|
||||
});
|
||||
|
||||
it("JSON 只保留图片字节数和稳定摘要", async () => {
|
||||
const page = raster("#111111");
|
||||
const report = await createPdfVisualDiffReport(
|
||||
snapshot("基线", page),
|
||||
snapshot("候选", page),
|
||||
);
|
||||
const json = serializePdfVisualDiffJson(report);
|
||||
expect(json).toContain('"overlaySha256"');
|
||||
expect(json).toContain('"byteLength"');
|
||||
expect(json).not.toContain('"0": 137');
|
||||
});
|
||||
|
||||
it("在报告中展示未配对的溢出页面", async () => {
|
||||
const baseline = snapshot("基线", raster("#111111"));
|
||||
const candidatePage = snapshot("候选", raster("#111111"));
|
||||
const candidate: PdfDocumentSnapshot = {
|
||||
...candidatePage,
|
||||
pageCount: 2,
|
||||
pages: [
|
||||
candidatePage.pages[0]!,
|
||||
{
|
||||
...candidatePage.pages[0]!,
|
||||
pageNumber: 2,
|
||||
},
|
||||
],
|
||||
};
|
||||
const report = await createPdfVisualDiffReport(baseline, candidate);
|
||||
const overflow = report.pages[1];
|
||||
expect(overflow?.pair.status).toBe("candidate-only");
|
||||
expect(overflow?.unpairedPng?.byteLength).toBeGreaterThan(0);
|
||||
expect(renderPdfVisualDiffHtml(report)).toContain("未配对页面");
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user