116 lines
4.2 KiB
TypeScript
116 lines
4.2 KiB
TypeScript
import { describe, it } from "node:test";
|
|
import assert from "node:assert/strict";
|
|
|
|
import { resolveGraphRelationFocus } from "../src/render/relation-focus";
|
|
|
|
describe("graph relation focus", () => {
|
|
it("classifies focus, first-degree, second-degree, and unrelated nodes", () => {
|
|
const focus = resolveGraphRelationFocus({
|
|
activeNodeId: "A",
|
|
nodes: [
|
|
{ id: "A" },
|
|
{ id: "B" },
|
|
{ id: "C" },
|
|
{ id: "D" },
|
|
{ id: "E" },
|
|
{ id: "F" }
|
|
],
|
|
edges: [
|
|
{ id: "A-B", source: "A", target: "B" },
|
|
{ id: "A-C", source: "A", target: "C" },
|
|
{ id: "B-D", source: "B", target: "D" },
|
|
{ id: "C-E", source: "C", target: "E" },
|
|
{ id: "D-F", source: "D", target: "F" }
|
|
]
|
|
});
|
|
|
|
assert.equal(focus.activeNodeId, "A");
|
|
assert.equal(focus.nodeDepthById.get("A"), "focus");
|
|
assert.equal(focus.nodeDepthById.get("B"), "first");
|
|
assert.equal(focus.nodeDepthById.get("C"), "first");
|
|
assert.equal(focus.nodeDepthById.get("D"), "second");
|
|
assert.equal(focus.nodeDepthById.get("E"), "second");
|
|
assert.equal(focus.nodeDepthById.get("F"), "unrelated");
|
|
assert.equal(focus.edgeDepthById.get("A-B"), "first");
|
|
assert.equal(focus.edgeDepthById.get("A-C"), "first");
|
|
assert.equal(focus.edgeDepthById.get("B-D"), "second");
|
|
assert.equal(focus.edgeDepthById.get("C-E"), "second");
|
|
assert.equal(focus.edgeDepthById.get("D-F"), "unrelated");
|
|
});
|
|
|
|
it("keeps first-neighbor cross links as faint second-degree context", () => {
|
|
const focus = resolveGraphRelationFocus({
|
|
activeNodeId: "A",
|
|
nodes: [{ id: "A" }, { id: "B" }, { id: "C" }],
|
|
edges: [
|
|
{ id: "A-B", source: "A", target: "B" },
|
|
{ id: "A-C", source: "A", target: "C" },
|
|
{ id: "B-C", source: "B", target: "C" }
|
|
]
|
|
});
|
|
|
|
assert.equal(focus.edgeDepthById.get("A-B"), "first");
|
|
assert.equal(focus.edgeDepthById.get("A-C"), "first");
|
|
assert.equal(focus.edgeDepthById.get("B-C"), "second");
|
|
});
|
|
|
|
it("handles an isolated active node without inventing relations", () => {
|
|
const focus = resolveGraphRelationFocus({
|
|
activeNodeId: "A",
|
|
nodes: [{ id: "A" }, { id: "B" }, { id: "C" }],
|
|
edges: []
|
|
});
|
|
|
|
assert.equal(focus.activeNodeId, "A");
|
|
assert.equal(focus.nodeDepthById.get("A"), "focus");
|
|
assert.equal(focus.nodeDepthById.get("B"), "unrelated");
|
|
assert.equal(focus.nodeDepthById.get("C"), "unrelated");
|
|
assert.deepEqual([...focus.edgeDepthById.values()], []);
|
|
});
|
|
|
|
it("returns none states when there is no active node or the node is missing", () => {
|
|
const graph = {
|
|
nodes: [{ id: "A" }, { id: "B" }],
|
|
edges: [{ id: "A-B", source: "A", target: "B" }]
|
|
};
|
|
|
|
const inactive = resolveGraphRelationFocus({ ...graph, activeNodeId: null });
|
|
const missing = resolveGraphRelationFocus({ ...graph, activeNodeId: "missing" });
|
|
|
|
assert.equal(inactive.activeNodeId, null);
|
|
assert.deepEqual([...inactive.nodeDepthById.values()], ["none", "none"]);
|
|
assert.deepEqual([...inactive.edgeDepthById.values()], ["none"]);
|
|
assert.equal(missing.activeNodeId, null);
|
|
assert.deepEqual([...missing.nodeDepthById.values()], ["none", "none"]);
|
|
assert.deepEqual([...missing.edgeDepthById.values()], ["none"]);
|
|
});
|
|
|
|
it("treats a self-loop on the active node as a direct first-degree edge", () => {
|
|
const focus = resolveGraphRelationFocus({
|
|
activeNodeId: "A",
|
|
nodes: [{ id: "A" }, { id: "B" }],
|
|
edges: [{ id: "A-A", source: "A", target: "A" }]
|
|
});
|
|
|
|
assert.equal(focus.activeNodeId, "A");
|
|
assert.equal(focus.nodeDepthById.get("A"), "focus");
|
|
assert.equal(focus.nodeDepthById.get("B"), "unrelated");
|
|
assert.equal(focus.edgeDepthById.get("A-A"), "first");
|
|
});
|
|
|
|
it("treats parallel edges between the same pair as first-degree", () => {
|
|
const focus = resolveGraphRelationFocus({
|
|
activeNodeId: "A",
|
|
nodes: [{ id: "A" }, { id: "B" }],
|
|
edges: [
|
|
{ id: "A-B-1", source: "A", target: "B" },
|
|
{ id: "B-A-2", source: "B", target: "A" }
|
|
]
|
|
});
|
|
|
|
assert.equal(focus.nodeDepthById.get("B"), "first");
|
|
assert.equal(focus.edgeDepthById.get("A-B-1"), "first");
|
|
assert.equal(focus.edgeDepthById.get("B-A-2"), "first");
|
|
});
|
|
});
|