Files
tono/frontend/tests/nodeClipboard.test.mjs

180 lines
4.7 KiB
JavaScript

import test from 'node:test';
import assert from 'node:assert/strict';
import {
buildNodeClipboardPayload,
instantiateNodeClipboardPayload,
NODE_CLIPBOARD_KIND,
parseNodeClipboardPayload,
} from '../src/nodeClipboard.js';
test('buildNodeClipboardPayload keeps only selected nodes and internal edges', () => {
const nodes = [
{
id: '1',
selected: true,
type: 'custom',
position: { x: 10, y: 20 },
data: {
label: 'Image',
className: 'Image',
widgetValues: { filename: 'scan.ibw' },
runtimeValues: { layerIndex: 2 },
},
},
{
id: '2',
selected: true,
position: { x: 100, y: 200 },
data: {
label: 'Preview',
className: 'Preview',
widgetValues: { mode: 'auto' },
},
},
{
id: '3',
selected: false,
position: { x: 500, y: 600 },
data: {
label: 'Save',
className: 'Save',
},
},
];
const edges = [
{
id: 'e1-2',
source: '1',
sourceHandle: 'output::0::DATA_FIELD',
target: '2',
targetHandle: 'input::field::DATA_FIELD',
style: { stroke: '#fff', strokeWidth: 2 },
},
{
id: 'e2-3',
source: '2',
sourceHandle: 'output::0::IMAGE',
target: '3',
targetHandle: 'input::value::SAVE_VALUE',
},
];
const payload = buildNodeClipboardPayload(nodes, edges);
assert.equal(payload.kind, NODE_CLIPBOARD_KIND);
assert.equal(payload.nodes.length, 2);
assert.deepEqual(payload.nodes.map((node) => node.id), ['1', '2']);
assert.equal(payload.edges.length, 1);
assert.deepEqual(payload.edges[0], {
source: '1',
sourceHandle: 'output::0::DATA_FIELD',
target: '2',
targetHandle: 'input::field::DATA_FIELD',
style: { stroke: '#fff', strokeWidth: 2 },
});
const reparsed = parseNodeClipboardPayload(JSON.stringify(payload));
assert.deepEqual(reparsed, payload);
});
test('instantiateNodeClipboardPayload remaps ids, offsets positions, and hydrates node shells', () => {
const payload = {
kind: NODE_CLIPBOARD_KIND,
version: 1,
nodes: [
{
id: '1',
position: { x: 10, y: 20 },
data: {
label: 'Image',
className: 'Image',
widgetValues: { filename: 'scan.ibw', colormap: 'viridis' },
runtimeValues: { layerIndex: 1 },
},
},
{
id: '2',
position: { x: 100, y: 200 },
data: {
label: 'Preview',
className: 'Preview',
widgetValues: { colormap: 'gray' },
},
},
],
edges: [
{
source: '1',
sourceHandle: 'output::0::DATA_FIELD',
target: '2',
targetHandle: 'input::field::DATA_FIELD',
style: { stroke: '#abc', strokeWidth: 2 },
},
],
};
const defs = {
Image: { output: ['DATA_FIELD'], output_name: ['field'] },
Preview: { output: ['IMAGE'], output_name: ['preview'] },
};
const instantiated = instantiateNodeClipboardPayload(payload, defs, 12, { x: 32, y: 48 });
assert.equal(instantiated.nextNodeId, 14);
assert.deepEqual(instantiated.nodes.map((node) => node.id), ['12', '13']);
assert.deepEqual(instantiated.nodes.map((node) => node.position), [
{ x: 42, y: 68 },
{ x: 132, y: 248 },
]);
assert.equal(instantiated.nodes[0].selected, true);
assert.deepEqual(instantiated.nodes[0].data.widgetValues, { filename: 'scan.ibw', colormap: 'viridis' });
assert.deepEqual(instantiated.nodes[0].data.runtimeValues, { layerIndex: 1 });
assert.equal(instantiated.nodes[0].data.previewImage, null);
assert.deepEqual(instantiated.nodes[0].data.definition, defs.Image);
assert.deepEqual(instantiated.edges, [
{
id: 'e12-13-0',
source: '12',
sourceHandle: 'output::0::DATA_FIELD',
target: '13',
targetHandle: 'input::field::DATA_FIELD',
selected: false,
style: { stroke: '#abc', strokeWidth: 2 },
},
]);
});
test('clipboard payload deep-copies local widget and runtime fields', () => {
const nodes = [
{
id: '9',
selected: true,
position: { x: 0, y: 0 },
data: {
label: 'Markup',
className: 'Markup',
widgetValues: {
stroke_width: 3,
markup_shapes: [
{ kind: 'line', points: [0.1, 0.2, 0.3, 0.4] },
],
},
runtimeValues: {
camera: { azimuth: 15, polar: 60 },
},
},
},
];
const payload = buildNodeClipboardPayload(nodes, []);
nodes[0].data.widgetValues.markup_shapes[0].points[0] = 0.9;
nodes[0].data.runtimeValues.camera.azimuth = 90;
assert.equal(payload.nodes[0].data.widgetValues.markup_shapes[0].points[0], 0.1);
assert.equal(payload.nodes[0].data.runtimeValues.camera.azimuth, 15);
});