Files
Endoleap/tests/canvas-media.test.mjs

39 lines
2.5 KiB
JavaScript

import { test } from "node:test";
import assert from "node:assert/strict";
import { canvasReducer, decodeCanvas, emptyCanvas, makeCanvasNode } from "../src/lib/canvas.ts";
import { CanvasElement, CardElement, PlainImageElement } from "../src/lib/canvas-elements.ts";
import { resizeFromPointer } from "../src/lib/canvas-geometry.ts";
import { iconCatalog, iconsById, searchIcons } from "../src/components/canvas/icon-catalog.ts";
test("plain images inherit transforms without card connections and preserve source/name on restore", () => {
const image = new PlainImageElement({ x: 0, y: 0 }, "", "data:image/png;base64,YQ==");
assert(image instanceof CanvasElement); assert.equal(image instanceof CardElement, false);
const node = image.toNode();
assert.equal(node.type, "plainImage"); assert.equal(PlainImageElement.capabilities.connectable, false);
const resized = resizeFromPointer(node, "bottom-right", { x: 320, y: 240 });
assert.equal(resized.width, 640); assert.equal(resized.height, 480);
const renamed = canvasReducer({ past: [], present: { ...emptyCanvas(), nodes: [node] }, future: [] }, { type: "rename-node", id: node.id, title: "参考照片" });
const restored = decodeCanvas(JSON.stringify(renamed.present));
assert.equal(restored.nodes[0].data.title, "参考照片"); assert.equal(restored.nodes[0].data.src, node.data.src);
assert.equal(canvasReducer(renamed, { type: "undo" }).present.nodes[0].data.title, "图片");
});
test("plain image sources are required and pure images cannot acquire card connections", () => {
const image = makeCanvasNode("plain-image", { x: 0, y: 0 }, "data:image/png;base64,YQ==");
const card = makeCanvasNode("text", { x: 300, y: 0 });
const document = { ...emptyCanvas(), nodes: [image, card], edges: [{ id: "edge", source: card.id, target: image.id }] };
assert.throws(() => decodeCanvas(JSON.stringify(document)));
image.data.src = "javascript:bad"; document.edges = [];
assert.throws(() => decodeCanvas(JSON.stringify(document)));
});
test("the complete Lucide catalog has unique backend-compatible identifiers and searchable names", () => {
assert(iconCatalog.length > 2000);
assert.equal(iconsById.size, iconCatalog.length);
for (const icon of iconCatalog) assert.match(icon.name, /^[A-Z][A-Za-z0-9]{0,63}$/);
assert(searchIcons("箭头").length > 45);
assert(searchIcons("arrow left").some((icon) => icon.name === "ArrowLeft"));
assert.equal(iconsById.get("Star").slug, "star");
assert.equal(iconsById.get("WandSparkles").slug, "wand-sparkles");
});