@@ -0,0 +1,52 @@
|
||||
import { PDFDocument } from "pdf-lib";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { createPdf } from "../../src/labels/pdf";
|
||||
import { renderLabelPages } from "../../src/labels/render";
|
||||
import { STOCKS } from "../../src/labels/stocks";
|
||||
import type { RenderOptions } from "../../src/labels/types";
|
||||
|
||||
describe("vector PDF export", () => {
|
||||
it("keeps the physical page geometry and emits vector page operators", async () => {
|
||||
const stock = STOCKS[0]!;
|
||||
const options: RenderOptions = {
|
||||
stock,
|
||||
calibration: { offsetXmm: 0, offsetYmm: 0, scaleX: 1, scaleY: 1 },
|
||||
layout: "address",
|
||||
mapping: {
|
||||
title: "name",
|
||||
subtitle: "subtitle",
|
||||
body: "body",
|
||||
barcode: "code",
|
||||
image: "image",
|
||||
},
|
||||
barcodeFormat: "qrcode",
|
||||
includeBarcodeText: false,
|
||||
fontFamily: "Arial, Helvetica, sans-serif",
|
||||
records: [
|
||||
{
|
||||
name: "Vector label",
|
||||
subtitle: "Local",
|
||||
body: "Physical units",
|
||||
code: "SAFE-1",
|
||||
},
|
||||
],
|
||||
images: [],
|
||||
defaultImage: "",
|
||||
cutMarks: true,
|
||||
registrationMarks: true,
|
||||
startPosition: 0,
|
||||
};
|
||||
const blob = await createPdf(renderLabelPages(options), stock);
|
||||
expect(blob.type).toBe("application/pdf");
|
||||
const document = await PDFDocument.load(await blob.arrayBuffer());
|
||||
expect(document.getPageCount()).toBe(1);
|
||||
expect(document.getPage(0).getWidth()).toBeCloseTo(
|
||||
(stock.pageWidthMm * 72) / 25.4,
|
||||
4,
|
||||
);
|
||||
expect(document.getPage(0).getHeight()).toBeCloseTo(
|
||||
(stock.pageHeightMm * 72) / 25.4,
|
||||
4,
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -6,6 +6,7 @@ import {
|
||||
toMillimetres,
|
||||
} from "../../src/labels/stocks";
|
||||
import type { RenderOptions } from "../../src/labels/types";
|
||||
import { defaultTemplate } from "../../src/labels/template";
|
||||
|
||||
function options(): RenderOptions {
|
||||
return {
|
||||
@@ -67,4 +68,17 @@ describe("label SVG renderer", () => {
|
||||
expect(fromMillimetres(25.4, "pt")).toBeCloseTo(72);
|
||||
expect(toMillimetres(fromMillimetres(42, "in"), "in")).toBeCloseTo(42);
|
||||
});
|
||||
|
||||
it("renders merged designer elements and preserves barcode quiet space", () => {
|
||||
const input = options();
|
||||
input.layout = "designer";
|
||||
input.template = defaultTemplate(
|
||||
input.stock.labelWidthMm,
|
||||
input.stock.labelHeightMm,
|
||||
);
|
||||
const page = renderLabelPages(input).pages[0]!;
|
||||
expect(page).toContain("<script>aler");
|
||||
expect(page).toContain("designer-0-");
|
||||
expect(page).not.toContain("<script>");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import {
|
||||
defaultTemplate,
|
||||
exportTemplate,
|
||||
importTemplate,
|
||||
mergeContent,
|
||||
validateTemplate,
|
||||
} from "../../src/labels/template";
|
||||
|
||||
describe("label template model", () => {
|
||||
it("round-trips a bounded reusable template", () => {
|
||||
const template = defaultTemplate(63.5, 33.9);
|
||||
expect(importTemplate(exportTemplate(template))).toEqual(template);
|
||||
expect(mergeContent("{{name}} / {{missing}}", { name: "Ada" })).toBe(
|
||||
"Ada / ",
|
||||
);
|
||||
});
|
||||
|
||||
it("reports quiet zones and rejects out-of-bounds elements", () => {
|
||||
const template = defaultTemplate(40, 20);
|
||||
const barcode = template.elements.find(
|
||||
(element) => element.kind === "barcode",
|
||||
)!;
|
||||
if (barcode.kind !== "barcode") throw new Error("fixture mismatch");
|
||||
barcode.quietZoneMm = 0;
|
||||
barcode.xMm = 100;
|
||||
const issues = validateTemplate(template);
|
||||
expect(issues.some((issue) => issue.severity === "warning")).toBe(true);
|
||||
expect(issues.some((issue) => issue.severity === "error")).toBe(true);
|
||||
});
|
||||
|
||||
it("rejects malformed imported element collections without iterating them", () => {
|
||||
const malformed = JSON.stringify({
|
||||
...defaultTemplate(40, 20),
|
||||
elements: { unexpected: true },
|
||||
});
|
||||
expect(() => importTemplate(malformed)).toThrow(/at most 100 elements/iu);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user