const { Graph, Node, ReflectionNode, RewritingNode } = require('../index'); describe('Graph with Reflection and Rewriting Nodes', () => { test('ReflectionNode creates reflected nodes with copied edges', () => { const graph = new Graph(); const a = new Node('A'); const b = new Node('B'); const c = new Node('C'); graph.addNode(a); graph.addNode(b); graph.addNode(c); graph.addEdge('A', 'B'); graph.addEdge('B', 'C'); const r = new ReflectionNode('R'); graph.addNode(r); graph.addEdge('R', 'B'); r.reflect(graph); const bRef = graph.getNode('B_ref'); expect(bRef).toBeDefined(); expect(bRef.type).toBe('generic'); const edges = graph.edges.get('B_ref'); expect(edges).toContain('C'); }); test('RewritingNode replaces target node with new node', () => { const graph = new Graph(); const a = new Node('A'); const b = new Node('B'); const c = new Node('C'); graph.addNode(a); graph.addNode(b); graph.addNode(c); graph.addEdge('A', 'B'); graph.addEdge('B', 'C'); const w = new RewritingNode('W'); graph.addNode(w); graph.addEdge('W', 'C'); const d = new Node('D'); w.rewrite(graph, 'C', d); expect(graph.getNode('C')).toBeUndefined(); expect(graph.getNode('D')).toBeDefined(); const edges = graph.edges.get('B'); expect(edges).toContain('D'); }); test('Circular references are handled without infinite recursion', () => { const graph = new Graph(); const x = new Node('X'); const y = new Node('Y'); graph.addNode(x); graph.addNode(y); graph.addEdge('X', 'Y'); graph.addEdge('Y', 'X'); const r = new ReflectionNode('R'); graph.addNode(r); graph.addEdge('R', 'X'); expect(() => r.reflect(graph)).not.toThrow(); const xRef = graph.getNode('X_ref'); expect(xRef).toBeDefined(); const edges = graph.edges.get('X_ref'); expect(edges).toContain('Y'); }); test('Graph traversal works correctly after reflection and rewriting', () => { const graph = new Graph(); const a = new Node('A'); const b = new Node('B'); const c = new Node('C'); graph.addNode(a); graph.addNode(b); graph.addNode(c); graph.addEdge('A', 'B'); graph.addEdge('B', 'C'); const r = new ReflectionNode('R'); graph.addNode(r); graph.addEdge('R', 'B'); r.reflect(graph); const w = new RewritingNode('W'); graph.addNode(w); graph.addEdge('W', 'C'); const d = new Node('D'); w.rewrite(graph, 'C', d); const traversal = graph.traverse('A'); // Should visit A, B, D, and B_ref (which points to D) expect(traversal).toContain('A'); expect(traversal).toContain('B'); expect(traversal).toContain('D'); expect(traversal).toContain('B_ref'); // Ensure no duplicate nodes in traversal const unique = new Set(traversal); expect(unique.size).toBe(traversal.length); }); });