import assert from "node:assert/strict"; import test from "node:test"; import { createVectorCropSiblingNode, croppedSvgViewBox, vectorCropRasterSize, vectorCropSiblingSize } from "../src/ui/pages/CanvasWorkspace/canvas/cadCrop.ts"; import { cropSelectionFromScreenDrag, cropSelectionScreenBounds, visibleCropSelectionForBounds } from "../src/ui/pages/CanvasWorkspace/canvas/cropViewport.ts"; const source = { id: "cad-source", type: "image", title: "plan (DWG).svg", x: 100, y: 80, width: 1200, height: 840, content: "/canvas-assets/plan.svg", tone: "transparent-image", status: "success", layerRole: "cad-vector", semanticContext: "full drawing context" }; test("creates a CAD crop beside the immutable source", () => { const before = structuredClone(source); const crop = createVectorCropSiblingNode(source, { id: "cad-crop", title: "plan crop", publicUrl: "/canvas-assets/plan-crop.webp", cropWidth: 180, cropHeight: 120, semanticContext: "cropped room context" }); assert.deepEqual(source, before); assert.equal(crop.x, source.x + source.width + 40); assert.equal(crop.y, source.y); assert.equal(crop.layerRole, "cad-crop"); assert.equal(crop.semanticContext, "cropped room context"); assert.equal(crop.content, "/canvas-assets/plan-crop.webp"); }); test("keeps cropped sibling dimensions readable and bounded", () => { assert.deepEqual(vectorCropSiblingSize(120, 60), { width: 220, height: 110 }); assert.deepEqual(vectorCropSiblingSize(1280, 640), { width: 640, height: 320 }); }); test("renders small vector selections at model-readable resolution", () => { assert.deepEqual(vectorCropRasterSize(60, 30), { width: 2048, height: 1024 }); assert.deepEqual(vectorCropRasterSize(100, 400), { width: 512, height: 2048 }); }); test("maps a normalized crop into a non-zero SVG viewBox without changing its aspect", () => { const crop = croppedSvgViewBox( { minX: -240, minY: 80, width: 1800, height: 1200 }, { x: 0.25, y: 0.1, width: 0.5, height: 0.3 } ); assert.deepEqual(crop, { minX: 210, minY: 200, width: 900, height: 360 }); assert.deepEqual(vectorCropRasterSize(crop.width, crop.height), { width: 2048, height: 819 }); assert.ok(Math.abs(crop.width / crop.height - 2.5) < Number.EPSILON); }); test("initializes an oversized image crop inside the visible stage", () => { const imageBounds = { left: -400, top: -300, width: 1800, height: 1400 }; const selection = visibleCropSelectionForBounds(imageBounds, { width: 1200, height: 800 }); const visibleBounds = cropSelectionScreenBounds(imageBounds, selection); assert.deepEqual(visibleBounds, { left: 24, top: 24, width: 1152, height: 704 }); assert.ok(selection.x > 0 && selection.y > 0); assert.ok(selection.width < 1 && selection.height < 1); }); test("keeps the full crop when the image already fits the safe viewport", () => { const imageBounds = { left: 100, top: 80, width: 640, height: 420 }; assert.deepEqual(visibleCropSelectionForBounds(imageBounds, { width: 1200, height: 800 }), { x: 0, y: 0, width: 1, height: 1 }); }); test("clamps a manually drawn crop to the currently visible image region", () => { const imageBounds = { left: -200, top: -100, width: 1000, height: 800 }; const visibleSelection = { x: 0.2, y: 0.125, width: 0.6, height: 0.75 }; assert.deepEqual( cropSelectionFromScreenDrag(imageBounds, visibleSelection, { x: 0, y: 0 }, { x: 900, y: 700 }), visibleSelection ); assert.deepEqual( cropSelectionFromScreenDrag(imageBounds, visibleSelection, { x: 100, y: 140 }, { x: 500, y: 460 }), { x: 0.3, y: 0.3, width: 0.4, height: 0.4 } ); });