mirror of
https://github.com/nejimakibird/model-weave.git
synced 2026-07-22 06:51:24 +00:00
156 lines
5.2 KiB
JavaScript
156 lines
5.2 KiB
JavaScript
import assert from "node:assert/strict";
|
|
import { test } from "node:test";
|
|
import { build } from "esbuild";
|
|
|
|
const outputFile = "dist/test-mermaid-node-interactions.mjs";
|
|
|
|
await build({
|
|
stdin: {
|
|
contents: 'export { getGraphInteractionNativeTooltipText, resolveGraphHoverParent, resolveGraphHoverLinkTargetElement } from "./src/views/mermaid-node-interactions";',
|
|
resolveDir: ".",
|
|
sourcefile: "test-mermaid-node-interactions-entry.ts",
|
|
loader: "ts"
|
|
},
|
|
bundle: true,
|
|
format: "esm",
|
|
platform: "browser",
|
|
plugins: [
|
|
{
|
|
name: "stub-obsidian",
|
|
setup(buildApi) {
|
|
buildApi.onResolve({ filter: /^obsidian$/ }, () => ({
|
|
path: "obsidian",
|
|
namespace: "stub"
|
|
}));
|
|
buildApi.onLoad({ filter: /^obsidian$/, namespace: "stub" }, () => ({
|
|
contents: "export class App {};",
|
|
loader: "js"
|
|
}));
|
|
}
|
|
}
|
|
],
|
|
outfile: outputFile,
|
|
logLevel: "silent"
|
|
});
|
|
|
|
const {
|
|
getGraphInteractionNativeTooltipText,
|
|
resolveGraphHoverParent,
|
|
resolveGraphHoverLinkTargetElement
|
|
} = await import(`../${outputFile}?t=${Date.now()}`);
|
|
|
|
class TestElement {
|
|
constructor(className = "", parent = null) {
|
|
this.className = className;
|
|
this.parentElement = parent;
|
|
}
|
|
|
|
closest(selector) {
|
|
const selectors = selector.split(",").map((entry) => entry.trim());
|
|
let current = this;
|
|
while (current) {
|
|
if (selectors.some((entry) => current.matches(entry))) {
|
|
return current;
|
|
}
|
|
current = current.parentElement;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
matches(selector) {
|
|
if (!selector.startsWith(".")) {
|
|
return false;
|
|
}
|
|
const expected = selector.slice(1);
|
|
return this.className.split(/\s+/).includes(expected);
|
|
}
|
|
}
|
|
|
|
test("resolveGraphHoverParent prefers View Only stage", () => {
|
|
const fallback = new TestElement("fallback");
|
|
const viewerRoot = new TestElement("model-weave-viewer-root", fallback);
|
|
const viewOnlyStage = new TestElement("model-weave-view-only-stage", viewerRoot);
|
|
const shell = new TestElement("model-weave-mermaid-shell", viewOnlyStage);
|
|
const target = new TestElement("node", shell);
|
|
|
|
assert.equal(resolveGraphHoverParent(target, fallback), viewOnlyStage);
|
|
});
|
|
|
|
test("resolveGraphHoverParent prefers viewer root before graph shell in Focus mode", () => {
|
|
const fallback = new TestElement("fallback");
|
|
const viewerRoot = new TestElement("model-weave-viewer-root model-weave-viewer-focus-mode", fallback);
|
|
const shell = new TestElement("model-weave-mermaid-shell", viewerRoot);
|
|
const diagram = new TestElement("mdspec-diagram mdspec-diagram--dfd", shell);
|
|
const target = new TestElement("node", diagram);
|
|
|
|
assert.equal(resolveGraphHoverParent(target, fallback), viewerRoot);
|
|
});
|
|
|
|
test("resolveGraphHoverParent falls back to workspace leaf content", () => {
|
|
const fallback = new TestElement("fallback");
|
|
const leaf = new TestElement("workspace-leaf-content", fallback);
|
|
const shell = new TestElement("model-weave-mermaid-shell", leaf);
|
|
const target = new TestElement("node", shell);
|
|
|
|
assert.equal(resolveGraphHoverParent(target, fallback), leaf);
|
|
});
|
|
|
|
test("resolveGraphHoverParent keeps explicit hover parent override", () => {
|
|
const fallback = new TestElement("fallback");
|
|
const explicit = new TestElement("explicit");
|
|
const viewerRoot = new TestElement("model-weave-viewer-root", fallback);
|
|
const target = new TestElement("node", viewerRoot);
|
|
|
|
assert.equal(resolveGraphHoverParent(target, fallback, explicit), explicit);
|
|
assert.equal(
|
|
resolveGraphHoverParent(target, fallback, () => explicit),
|
|
explicit
|
|
);
|
|
});
|
|
|
|
|
|
test("resolveGraphHoverLinkTargetElement prefers graph canvas", () => {
|
|
const viewerRoot = new TestElement("model-weave-viewer-root");
|
|
const viewport = new TestElement("model-weave-graph-viewport", viewerRoot);
|
|
const canvas = new TestElement("model-weave-graph-canvas", viewport);
|
|
const svgNode = new TestElement("node", canvas);
|
|
|
|
assert.equal(resolveGraphHoverLinkTargetElement(svgNode, viewerRoot), canvas);
|
|
});
|
|
|
|
test("resolveGraphHoverLinkTargetElement falls back through viewport and viewer root", () => {
|
|
const viewerRoot = new TestElement("model-weave-viewer-root");
|
|
const viewport = new TestElement("model-weave-graph-viewport", viewerRoot);
|
|
const svgNode = new TestElement("node", viewport);
|
|
const detached = new TestElement("node");
|
|
|
|
assert.equal(resolveGraphHoverLinkTargetElement(svgNode, viewerRoot), viewport);
|
|
assert.equal(resolveGraphHoverLinkTargetElement(detached, viewerRoot), viewerRoot);
|
|
});
|
|
|
|
|
|
test("getGraphInteractionNativeTooltipText keeps normal tooltip fallback without rich metadata", () => {
|
|
assert.equal(
|
|
getGraphInteractionNativeTooltipText({
|
|
mermaidId: "node",
|
|
linktext: "MODEL.md",
|
|
sourcePath: "SOURCE.md",
|
|
label: "Model Node"
|
|
}),
|
|
"Model Node"
|
|
);
|
|
});
|
|
|
|
test("getGraphInteractionNativeTooltipText prefers explicit safe tooltip for rich hover metadata", () => {
|
|
assert.equal(
|
|
getGraphInteractionNativeTooltipText({
|
|
mermaidId: "node",
|
|
linktext: "SOURCE.md",
|
|
sourcePath: "SOURCE.md",
|
|
label: "[[MISSING]]",
|
|
hoverRows: [{ label: "ref", value: "[[MISSING]]" }],
|
|
nativeTooltip: "Flow Object: NODE\nref: [[MISSING]]"
|
|
}),
|
|
"Flow Object: NODE\nref: [[MISSING]]"
|
|
);
|
|
});
|