Replace the prior release tree with the current plugin, frontend, tests, and documentation. Document retired node IDs and the public Gitea update source.
91 lines
4.6 KiB
JavaScript
91 lines
4.6 KiB
JavaScript
import assert from "node:assert/strict";
|
|
import fs from "node:fs";
|
|
import vm from "node:vm";
|
|
|
|
|
|
const sourcePath = new URL("../web/js/o1keyReferenceImageEditor.js", import.meta.url);
|
|
const source = fs.readFileSync(sourcePath, "utf8");
|
|
const executableSource = source.replace(/^export /gm, "");
|
|
const context = vm.createContext({ console });
|
|
vm.runInContext(executableSource, context, { filename: sourcePath.pathname });
|
|
|
|
const fitCropToRatio = vm.runInContext("fitCropToRatio", context);
|
|
const constrainCropRect = vm.runInContext("constrainCropRect", context);
|
|
const editedReferenceFilename = vm.runInContext("editedReferenceFilename", context);
|
|
const fitStickerTransform = vm.runInContext("fitStickerTransform", context);
|
|
const stickerControlGeometry = vm.runInContext("stickerControlGeometry", context);
|
|
const hitTestSticker = vm.runInContext("hitTestSticker", context);
|
|
const arrowHeadGeometry = vm.runInContext("arrowHeadGeometry", context);
|
|
const ratios = vm.runInContext("REFERENCE_EDITOR_RATIOS", context);
|
|
|
|
assert.deepEqual(
|
|
JSON.parse(JSON.stringify(fitCropToRatio(1600, 900, 1))),
|
|
{ x: 350, y: 0, width: 900, height: 900 },
|
|
);
|
|
assert.deepEqual(
|
|
JSON.parse(JSON.stringify(fitStickerTransform(1000, 500, 800, 600))),
|
|
{ x: 400, y: 300, width: 400, height: 200, rotation: 0, opacity: 1 },
|
|
);
|
|
const rotatedSticker = { x: 100, y: 100, width: 40, height: 20, rotation: Math.PI / 2 };
|
|
const rotatedGeometry = JSON.parse(JSON.stringify(stickerControlGeometry(rotatedSticker, 30)));
|
|
assert.ok(Math.abs(rotatedGeometry.corners[0].x - 110) < 1e-9);
|
|
assert.ok(Math.abs(rotatedGeometry.corners[0].y - 80) < 1e-9);
|
|
assert.equal(hitTestSticker({ ...rotatedSticker, rotation: 0 }, { x: 100, y: 100 }), "move");
|
|
assert.equal(hitTestSticker({ ...rotatedSticker, rotation: 0 }, { x: 80, y: 90 }), "scale");
|
|
assert.equal(hitTestSticker({ ...rotatedSticker, rotation: 0 }, { x: 100, y: 60 }, 8, 30), "rotate");
|
|
assert.equal(hitTestSticker({ ...rotatedSticker, rotation: 0 }, { x: 10, y: 10 }), null);
|
|
const arrowHead = JSON.parse(JSON.stringify(arrowHeadGeometry({ x: 0, y: 0 }, { x: 100, y: 0 }, 4)));
|
|
assert.deepEqual(arrowHead.tip, { x: 100, y: 0 });
|
|
assert.ok(Math.abs(arrowHead.left.x - arrowHead.right.x) < 1e-9);
|
|
assert.ok(Math.abs(arrowHead.left.y + arrowHead.right.y) < 1e-9);
|
|
assert.ok(arrowHead.left.x < arrowHead.tip.x);
|
|
assert.deepEqual(
|
|
JSON.parse(JSON.stringify(fitCropToRatio(1600, 900, 4 / 3))),
|
|
{ x: 200, y: 0, width: 1200, height: 900 },
|
|
);
|
|
assert.deepEqual(
|
|
JSON.parse(JSON.stringify(fitCropToRatio(600, 900, "original"))),
|
|
{ x: 0, y: 0, width: 600, height: 900 },
|
|
);
|
|
assert.deepEqual(
|
|
JSON.parse(JSON.stringify(constrainCropRect({ x: -20, y: 880, width: 300, height: 100 }, 1000, 900))),
|
|
{ x: 0, y: 800, width: 300, height: 100 },
|
|
);
|
|
assert.deepEqual(
|
|
JSON.parse(JSON.stringify(constrainCropRect({ x: 950, y: 850, width: 5000, height: 5000 }, 1000, 900))),
|
|
{ x: 0, y: 0, width: 1000, height: 900 },
|
|
);
|
|
assert.equal(editedReferenceFilename("products/look.v2.jpg"), "look.v2_edited.png");
|
|
assert.equal(editedReferenceFilename("bad:name?.webp"), "bad_name__edited.png");
|
|
assert.deepEqual(
|
|
JSON.parse(JSON.stringify(ratios.map((item) => item.key))),
|
|
["free", "original", "1:1", "4:3", "3:4", "3:2", "2:3", "16:9", "9:16"],
|
|
);
|
|
|
|
assert.match(source, /\["crop", "裁剪"/);
|
|
assert.match(source, /\["mask", "遮罩"/);
|
|
assert.match(source, /\["brush", "画笔"/);
|
|
assert.match(source, /\["sticker", "贴图"/);
|
|
assert.match(source, /\["arrow", "箭头"/);
|
|
assert.match(source, /不会创建 MASK 数据/);
|
|
assert.match(source, /#\$\{EDITOR_ID\} \[hidden\]\{display:none!important;\}/);
|
|
assert.match(source, /overflow-x:hidden;overflow-y:auto/);
|
|
assert.match(source, /historyRow\.append\(undo, redo\)/);
|
|
assert.match(source, /sidebarActions\.append\(historyRow, clearMarks, reset\)/);
|
|
assert.match(source, /clearMarks\.hidden = state\.mode !== "mask" && state\.mode !== "brush" && state\.mode !== "arrow"/);
|
|
assert.match(source, /state\.mode === "sticker" \? "重置贴图"/);
|
|
assert.match(source, /white-space:nowrap/);
|
|
assert.match(source, /cursor:not-allowed/);
|
|
assert.doesNotMatch(source, /cursor:wait/);
|
|
assert.match(source, /outputContext\.drawImage\(/);
|
|
assert.match(source, /URL\.createObjectURL\(file\)/);
|
|
assert.match(source, /URL\.revokeObjectURL\(objectUrl\)/);
|
|
assert.match(source, /drawSticker\(outputContext, state\.sticker/);
|
|
assert.match(source, /state\.activeStroke\.tool === "arrow"/);
|
|
assert.match(source, /松开位置就是箭头尖端/);
|
|
assert.match(source, /await onConfirm\(\{/);
|
|
assert.match(source, /canvas\.toBlob/);
|
|
assert.doesNotMatch(source, /api\.fetchApi|authorization|base64/iu);
|
|
|
|
console.log("o1key reference image editor tests passed");
|