From 6b2268a76b096889a5c18beb5f3a457931d807e2 Mon Sep 17 00:00:00 2001 From: Ivan <8611739+IRBorisov@users.noreply.github.com> Date: Wed, 15 Oct 2025 11:54:21 +0300 Subject: [PATCH] B: Fix cst graph visualization --- .../src/features/rsform/models/graph-api.ts | 4 +- .../rsform-page/editor-term-graph/tg-flow.tsx | 2 +- rsconcept/frontend/src/models/graph.test.ts | 39 +++++++++++++++++++ 3 files changed, 42 insertions(+), 3 deletions(-) diff --git a/rsconcept/frontend/src/features/rsform/models/graph-api.ts b/rsconcept/frontend/src/features/rsform/models/graph-api.ts index 5c1697d1..683a1902 100644 --- a/rsconcept/frontend/src/features/rsform/models/graph-api.ts +++ b/rsconcept/frontend/src/features/rsform/models/graph-api.ts @@ -57,11 +57,11 @@ export function applyLayout(nodes: Node[], edges: Edge[], subLabels }); } -export function inferEdgeType(schema: IRSForm, source: number, target: number): GraphType | null { +export function inferEdgeType(schema: IRSForm, source: number, target: number): GraphType { const isDefinition = schema.graph.hasEdge(source, target); const isAttribution = schema.attribution_graph.hasEdge(source, target); if (!isDefinition && !isAttribution) { - return null; + return 'definition'; } else if (isDefinition && isAttribution) { return 'full'; } else if (isDefinition) { diff --git a/rsconcept/frontend/src/features/rsform/pages/rsform-page/editor-term-graph/tg-flow.tsx b/rsconcept/frontend/src/features/rsform/pages/rsform-page/editor-term-graph/tg-flow.tsx index badc2397..c1375a7b 100644 --- a/rsconcept/frontend/src/features/rsform/pages/rsform-page/editor-term-graph/tg-flow.tsx +++ b/rsconcept/frontend/src/features/rsform/pages/rsform-page/editor-term-graph/tg-flow.tsx @@ -88,7 +88,7 @@ export function TGFlow() { filteredGraph.nodes.forEach(source => { source.outputs.forEach(target => { const edgeType = inferEdgeType(schema, source.id, target); - if (edgeType && newNodes.find(node => node.id === String(target))) { + if (newNodes.find(node => node.id === String(target))) { const color = filter.graphType === 'full' ? colorGraphEdge(edgeType) : colorGraphEdge(filter.graphType); newEdges.push({ id: String(edgeID), diff --git a/rsconcept/frontend/src/models/graph.test.ts b/rsconcept/frontend/src/models/graph.test.ts index 0ff1648b..c05cbd31 100644 --- a/rsconcept/frontend/src/models/graph.test.ts +++ b/rsconcept/frontend/src/models/graph.test.ts @@ -61,6 +61,45 @@ describe('Testing Graph editing', () => { expect(graph.hasEdge(2, 5)).toBeTruthy(); }); + test('folding a non-existent node should not change the graph', () => { + const graph = new Graph([ + [1, 2], + [2, 3] + ]); + const clone = graph.clone(); + graph.foldNode(99); // Node 99 does not exist + expect(graph.nodes.size).toBe(clone.nodes.size); + expect([...graph.nodes.keys()]).toEqual([...clone.nodes.keys()]); + expect(graph.hasEdge(1, 2)).toBeTruthy(); + expect(graph.hasEdge(2, 3)).toBeTruthy(); + }); + + test('folding a node with no inputs', () => { + const graph = new Graph([ + [1, 2], + [1, 3] + ]); + graph.foldNode(1); + expect(graph.hasNode(1)).toBeFalsy(); + expect(graph.nodes.size).toBe(2); // Nodes 2 and 3 remain + expect(graph.hasNode(2)).toBeTruthy(); + expect(graph.hasNode(3)).toBeTruthy(); + }); + + test('folding a node with no outputs', () => { + const graph = new Graph([ + [1, 3], + [2, 3] + ]); + graph.foldNode(3); + expect(graph.hasNode(3)).toBeFalsy(); + expect(graph.nodes.size).toBe(2); // Nodes 1 and 2 remain + expect(graph.hasNode(1)).toBeTruthy(); + expect(graph.hasNode(2)).toBeTruthy(); + expect(graph.nodes.get(1)!.outputs.length).toBe(0); + expect(graph.nodes.get(2)!.outputs.length).toBe(0); + }); + test('removing isolated nodes', () => { const graph = new Graph([[9, 1], [9, 2], [2, 1], [4, 3], [5, 9], [7], [8]]); graph.removeIsolated();