import { describe, expect, it } from "vitest"; import { comparePdfSnapshotsBasic, createPdfDocumentSnapshot, type PdfDocumentSnapshot, } from "../src/index.js"; import { createMinimalPdf } from "./pdf-fixture.js"; async function snapshot( label: string, text = "Visual diff fixture", width = 595, height = 842, ): Promise { return createPdfDocumentSnapshot(createMinimalPdf(text, width, height), { source: { kind: "custom", label }, includeRaster: false, }); } describe("PDF 基础视觉门禁", () => { it("通过纸张和正文一致的文档", async () => { const baseline = await snapshot("baseline"); const candidate = await snapshot("candidate"); const result = comparePdfSnapshotsBasic(baseline, candidate); expect(result.status).toBe("passed"); expect(result.contentSimilarity).toBe(1); expect(result.issues).toEqual([]); }); it("拒绝纸张尺寸和正文内容偏差", async () => { const baseline = await snapshot("baseline"); const candidate = await snapshot("candidate", "Different content", 612); const result = comparePdfSnapshotsBasic(baseline, candidate); expect(result.status).toBe("failed"); expect(result.issues.map((issue) => issue.code)).toEqual( expect.arrayContaining(["PAGE_SIZE_MISMATCH", "CONTENT_MISMATCH"]), ); }); it("内容完整性比较不受重新换行影响", async () => { const baseline = await snapshot("baseline", "same content"); const candidate = await snapshot("candidate", "samecontent"); const result = comparePdfSnapshotsBasic(baseline, candidate); expect(result.contentSimilarity).toBe(1); expect(result.status).toBe("passed"); }); it("页数不一致时仍保留溢出页配对记录", async () => { const baseline = await snapshot("baseline"); const candidatePage = (await snapshot("candidate")).pages[0]; if (!candidatePage) { throw new Error("测试快照缺少页面"); } const candidate: PdfDocumentSnapshot = { ...(await snapshot("candidate")), pageCount: 2, pages: [ candidatePage, { ...candidatePage, pageNumber: 2, contentText: "", items: [], lines: [], }, ], }; const result = comparePdfSnapshotsBasic(baseline, candidate); expect(result.pagePairs[1]).toEqual({ candidatePageNumber: 2, status: "candidate-only", }); expect(result.issues.map((issue) => issue.code)).toContain( "UNPAIRED_CANDIDATE_PAGE", ); }); });