import assert from 'node:assert/strict'; import { readFile } from 'node:fs/promises'; import test from 'node:test'; import ts from 'typescript'; async function loadCanvasDocumentModule() { const source = await readFile(new URL('../src/lib/canvasDocument.ts', import.meta.url), 'utf8'); const compiled = ts.transpileModule(source, { compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2020, }, }).outputText; const module = { exports: {} }; new Function('exports', 'module', compiled)(module.exports, module); return module.exports; } const documentWithTwoLayers = { width: 400, height: 240, background: '#ffffff', layers: [ { id: 'layer-bottom', name: '底层', visible: true, locked: false }, { id: 'layer-top', name: '顶层', visible: true, locked: false }, ], layerFolders: [], elements: [ { id: 'top-first', type: 'rect', layerId: 'layer-top', x: 0, y: 0, width: 10, height: 10, rotation: 0, opacity: 1, fill: '#f00', stroke: '#f00', strokeWidth: 0 }, { id: 'bottom-first', type: 'rect', layerId: 'layer-bottom', x: 0, y: 0, width: 10, height: 10, rotation: 0, opacity: 1, fill: '#0f0', stroke: '#0f0', strokeWidth: 0 }, { id: 'top-second', type: 'rect', layerId: 'layer-top', x: 0, y: 0, width: 10, height: 10, rotation: 0, opacity: 1, fill: '#00f', stroke: '#00f', strokeWidth: 0 }, ], }; test('canvas paint order keeps every element above the background and honors layer order', async () => { const { orderCanvasElementsByLayer } = await loadCanvasDocumentModule(); assert.deepEqual( orderCanvasElementsByLayer(documentWithTwoLayers).map(element => element.id), ['bottom-first', 'top-first', 'top-second'], ); }); test('moving an element only changes its order inside its own canvas layer', async () => { const { moveCanvasElementWithinLayer } = await loadCanvasDocumentModule(); const moved = moveCanvasElementWithinLayer(documentWithTwoLayers, 'top-first', 1); assert.deepEqual( moved.elements.map(element => element.id), ['top-second', 'bottom-first', 'top-first'], ); }); test('canvas elements remain visible when they extend beyond the document surface', async () => { const styles = await readFile(new URL('../src/styles.css', import.meta.url), 'utf8'); const stageRule = /\.studio-stage\s*\{([\s\S]*?)\n\}/.exec(styles)?.[1] ?? ''; assert.match(stageRule, /overflow:\s*visible/); });