import fs from 'node:fs/promises'; import path from 'node:path'; import assert from 'node:assert/strict'; import { NativeCanvas } from '../src/native-bridge.mjs'; import { atomic } from '../src/store.mjs'; const config = JSON.parse(await fs.readFile(process.argv[2], 'utf8')); const canvas = await NativeCanvas.connect(config.canvas); const cmd = (command, params = {}) => canvas.call('engine.execute', { command, params }); const flatten = layers => layers.flatMap(layer => { const { children, selected, ...row } = layer; return [row, ...flatten(children || [])]; }); try { const current = await canvas.call('jiansun.state'); if (current.busy || current.queued) throw Error('先等待模型阶段结束,不中断原任务'); const edited = await cmd('document.inspect'); assert.equal(flatten(edited.layers).find(l => l.id === 16).text.text, '温润质感'); await cmd('edit.undo'); const unmoved = await cmd('document.inspect'); assert.equal(flatten(unmoved.layers).find(l => l.id === 16).text.text, '温润质感'); await cmd('edit.undo'); const original = await cmd('document.inspect'); const oldTitle = flatten(original.layers).find(l => l.id === 16), newTitle = flatten(edited.layers).find(l => l.id === 16); assert.equal(oldTitle.text.text, '实木电脑桌'); assert.equal(newTitle.text.font, oldTitle.text.font); assert.equal(newTitle.text.sizePt, oldTitle.text.sizePt); assert.deepEqual(flatten(original.layers).filter(l => l.id !== 16), flatten(edited.layers).filter(l => l.id !== 16)); await cmd('edit.redo'); await cmd('edit.redo'); const redone = await cmd('document.inspect'); assert.deepEqual(flatten(redone.layers), flatten(edited.layers)); await canvas.call('ui.screenshot', { path: path.join(config.output, 'pi-undo-redo.png'), focus: false }); await canvas.call('app.save', { path: path.join(path.dirname(config.output), 'canvas/pi-1440-local.pcraft') }); const result = { passed: true, width: edited.width, height: edited.height, target: 16, originalText: oldTitle.text.text, changedText: newTitle.text.text, font: newTitle.text.font, fontSizePt: newTitle.text.sizePt, otherLayersUnchanged: true, undoAndRedoExact: true, history: edited.history }; await atomic(path.join(config.output, 'real-model-undo-redo.json'), result); console.log(JSON.stringify(result, null, 2)); } finally { canvas.close(); }