105 lines
2.9 KiB
JavaScript
105 lines
2.9 KiB
JavaScript
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);
|
|
});
|
|
}); |