Files
ausboss-ComfyUI-AusBoss/tests/paste_ids.test.mjs
ausboss d0658ea8b2 Workflow Switches and Callout: follow the copies after a paste
Copy and paste give every pasted node and group a new id, and so do
duplicate, Alt + drag and dragging a saved workflow onto the canvas. A
Workflow Switches card remembers its parts by id, so a whole workflow
pasted into a new tab read "empty" on every row and nothing could be
switched on; pasted into another workflow it could switch unrelated nodes
that had the old numbers. A Callout's links to a node or group broke the
same way.

The frontend's paste (LGraphCanvas._deserializeItems) returns which new
node each old id became. js/shared/paste_ids.mjs hands that on after every
paste, and a pasted card or note points at the copies of what it names.
An id the paste did not copy is kept, so a card pasted on its own still
switches the original parts.
2026-10-29 11:05:44 -05:00

59 lines
2.2 KiB
JavaScript

import assert from "node:assert/strict";
import test from "node:test";
import { onPaste, pastedIds } from "../js/shared/paste_ids.mjs";
class Group {
constructor(id) {
this.id = id;
}
}
test("a paste's old ids map to the copies' ids; groups by the order they were made", () => {
const isGroup = (item) => item instanceof Group;
const result = {
nodes: new Map([[41, { id: 151 }], ["105", { id: "152" }]]),
created: [new Group(7), new Group(8), { id: 151 }, { id: "152" }],
};
const ids = pastedIds(result, [3, 4], isGroup);
assert.deepEqual([...ids.nodes], [["41", 151], ["105", "152"]]);
assert.deepEqual([...ids.groups], [["3", 7], ["4", 8]]);
assert.equal(ids.created.length, 4);
// A group the frontend did not make: none is matched rather than a wrong one.
assert.deepEqual([...pastedIds(result, [3], isGroup).groups], []);
assert.deepEqual(pastedIds(undefined), { nodes: new Map(), groups: new Map(), created: [] });
});
test("every paste reaches the handlers, and the frontend gets its own result back", () => {
const calls = [];
class Canvas {
_deserializeItems(items) {
for (const group of items.groups) group.id = -1; // the frontend renumbers what it is handed
return { nodes: new Map([[5, { id: 20 }]]), created: [new Group(30), { id: 20 }] };
}
}
globalThis.LiteGraph = { LGraphCanvas: Canvas, LGraphGroup: Group };
const warn = console.warn;
const warned = [];
console.warn = (...args) => warned.push(args);
try {
onPaste((ids) => calls.push(ids));
onPaste(() => {
throw new Error("one handler failing never breaks the paste");
});
const result = new Canvas()._deserializeItems({ nodes: [{ id: 5 }], groups: [{ id: 2 }] });
assert.deepEqual([...result.nodes.keys()], [5]);
assert.equal(calls.length, 1);
assert.deepEqual([...calls[0].nodes], [["5", 20]]);
assert.deepEqual([...calls[0].groups], [["2", 30]]);
// Wrapped once, however many handlers.
onPaste(() => {});
new Canvas()._deserializeItems({ nodes: [], groups: [] });
assert.equal(calls.length, 2);
assert.equal(warned.length, 2);
} finally {
console.warn = warn;
delete globalThis.LiteGraph;
}
});