176 lines
4.1 KiB
JavaScript
176 lines
4.1 KiB
JavaScript
"use strict";
|
|
|
|
const test = require("node:test");
|
|
const assert = require("node:assert/strict");
|
|
|
|
function fakeElement() {
|
|
return {
|
|
className: "rw-cmap-item",
|
|
style: {},
|
|
dataset: {},
|
|
querySelector: () => null,
|
|
querySelectorAll: () => [],
|
|
remove() {},
|
|
addEventListener() {},
|
|
classList: { add() {}, remove() {}, toggle() {} },
|
|
setAttribute() {},
|
|
removeAttribute() {}
|
|
};
|
|
}
|
|
|
|
function fakeNode(attributes) {
|
|
const state = { ...attributes };
|
|
return {
|
|
attr(value) {
|
|
if (typeof value === "string") return state[value];
|
|
Object.assign(state, value);
|
|
return this;
|
|
},
|
|
onRendered() {},
|
|
onMove() {},
|
|
onMoveEnd() {},
|
|
visible() {},
|
|
redraw() {},
|
|
toFront() {},
|
|
remove() {},
|
|
element: () => null
|
|
};
|
|
}
|
|
|
|
function fakeLink(attributes) {
|
|
const state = { ...attributes };
|
|
let source = null;
|
|
let target = null;
|
|
let connectionChangeHandler = null;
|
|
return {
|
|
attr(value) {
|
|
if (typeof value === "string") return state[value];
|
|
Object.assign(state, value);
|
|
return this;
|
|
},
|
|
sourceNode(value) {
|
|
if (arguments.length === 0) return source;
|
|
source = value;
|
|
return this;
|
|
},
|
|
targetNode(value) {
|
|
if (arguments.length === 0) return target;
|
|
target = value;
|
|
return this;
|
|
},
|
|
onConnectionChange(handler) { connectionChangeHandler = handler; },
|
|
triggerConnectionChange(type, node) {
|
|
if (type === "source") source = node;
|
|
if (type === "target") target = node;
|
|
connectionChangeHandler(this, type, node);
|
|
},
|
|
onRendered() {},
|
|
visible() {},
|
|
straighten() {},
|
|
draggable() {},
|
|
redraw() {},
|
|
remove() {},
|
|
element: () => null
|
|
};
|
|
}
|
|
|
|
async function loadEditorFactory() {
|
|
global.Element = class Element {};
|
|
global.document = {
|
|
currentScript: null,
|
|
styleSheets: [],
|
|
body: { append() {} },
|
|
createElement: () => fakeElement()
|
|
};
|
|
global.window = {
|
|
Cmap: null,
|
|
setTimeout,
|
|
clearTimeout,
|
|
requestAnimationFrame: (callback) => callback()
|
|
};
|
|
await import("../static/cmap/cmap-racket-wiki.js");
|
|
return global.window.RacketWikiCmap;
|
|
}
|
|
|
|
test("a dragged connector endpoint survives collapsing and expanding its submap", async () => {
|
|
const factory = await loadEditorFactory();
|
|
const links = [];
|
|
const map = {
|
|
onSelection() {},
|
|
onActivation() {},
|
|
node: (attributes) => fakeNode(attributes),
|
|
link(attributes) {
|
|
const link = fakeLink(attributes);
|
|
links.push(link);
|
|
return link;
|
|
}
|
|
};
|
|
const canvas = {
|
|
addEventListener() {},
|
|
querySelector: () => null,
|
|
clientWidth: 1200,
|
|
clientHeight: 800,
|
|
scrollLeft: 0,
|
|
scrollTop: 0,
|
|
isConnected: true
|
|
};
|
|
const editor = factory.createEditor(canvas, { Cmap: () => map });
|
|
const submap = editor.addItem({
|
|
id: 1,
|
|
kind: "submap",
|
|
label: "Problemen en Symptomen LTS Model",
|
|
x: 300,
|
|
y: 200,
|
|
width: 320,
|
|
height: 70
|
|
});
|
|
submap.expanded = true;
|
|
submap.submapInitialized = true;
|
|
const problems = editor.addItem({
|
|
id: 2,
|
|
kind: "phrase",
|
|
label: "problemen",
|
|
parentSubmap: submap,
|
|
submapDepth: 1,
|
|
x: 400,
|
|
y: 300
|
|
});
|
|
const symptoms = editor.addItem({
|
|
id: 3,
|
|
kind: "phrase",
|
|
label: "Symptomen",
|
|
parentSubmap: submap,
|
|
submapDepth: 1,
|
|
x: 400,
|
|
y: 500
|
|
});
|
|
const concept = editor.addItem({
|
|
id: 4,
|
|
kind: "concept",
|
|
label: "Rob maakt veel fouten",
|
|
parentSubmap: submap,
|
|
submapDepth: 1,
|
|
x: 800,
|
|
y: 400
|
|
});
|
|
const connector = editor.addConnector(problems, concept, true, { id: 1 });
|
|
|
|
links[0].triggerConnectionChange("source", symptoms.node);
|
|
assert.equal(connector.source, symptoms,
|
|
"the editor model follows the endpoint dragged by the drawing library");
|
|
|
|
editor.toggleSubmap(submap, false);
|
|
editor.toggleSubmap(submap, true);
|
|
|
|
assert.equal(connector.source, symptoms);
|
|
assert.equal(connector.link.sourceNode(), symptoms.node);
|
|
assert.deepEqual(editor.toDocument().connectors, [{
|
|
id: 1,
|
|
sourceId: symptoms.id,
|
|
targetId: concept.id,
|
|
hasArrow: true,
|
|
lineColor: "#333",
|
|
lineWidth: 2
|
|
}]);
|
|
});
|