import Graph from '../Graph'; import GraphVertex from '../GraphVertex'; import GraphEdge from '../GraphEdge'; describe('Graph', () => { it('should add vertices to graph', () => { const graph = new Graph(); const vertexA = new GraphVertex('A'); const vertexB = new GraphVertex('B'); graph .addVertex(vertexA) .addVertex(vertexB); expect(graph.toString()).toBe('A,B'); expect(graph.getVertexByKey(vertexA.getKey())).toEqual(vertexA); expect(graph.getVertexByKey(vertexB.getKey())).toEqual(vertexB); }); it('should add edges to undirected graph', () => { const graph = new Graph(); const vertexA = new GraphVertex('A'); const vertexB = new GraphVertex('B'); const edgeAB = new GraphEdge(vertexA, vertexB); graph.addEdge(edgeAB); expect(graph.getAllVertices().length).toBe(2); expect(graph.getAllVertices()[0]).toEqual(vertexA); expect(graph.getAllVertices()[1]).toEqual(vertexB); const graphVertexA = graph.getVertexByKey(vertexA.getKey()); const graphVertexB = graph.getVertexByKey(vertexB.getKey()); expect(graph.toString()).toBe('A,B'); expect(graphVertexA).toBeDefined(); expect(graphVertexB).toBeDefined(); expect(graph.getVertexByKey('not existing')).toBeUndefined(); expect(graphVertexA.getNeighbors().length).toBe(1); expect(graphVertexA.getNeighbors()[0]).toEqual(vertexB); expect(graphVertexA.getNeighbors()[0]).toEqual(graphVertexB); expect(graphVertexB.getNeighbors().length).toBe(1); expect(graphVertexB.getNeighbors()[0]).toEqual(vertexA); expect(graphVertexB.getNeighbors()[0]).toEqual(graphVertexA); }); it('should add edges to directed graph', () => { const graph = new Graph(true); const vertexA = new GraphVertex('A'); const vertexB = new GraphVertex('B'); const edgeAB = new GraphEdge(vertexA, vertexB); graph.addEdge(edgeAB); const graphVertexA = graph.getVertexByKey(vertexA.getKey()); const graphVertexB = graph.getVertexByKey(vertexB.getKey()); expect(graph.toString()).toBe('A,B'); expect(graphVertexA).toBeDefined(); expect(graphVertexB).toBeDefined(); expect(graphVertexA.getNeighbors().length).toBe(1); expect(graphVertexA.getNeighbors()[0]).toEqual(vertexB); expect(graphVertexA.getNeighbors()[0]).toEqual(graphVertexB); expect(graphVertexB.getNeighbors().length).toBe(0); }); it('should find edge by vertices in undirected graph', () => { const graph = new Graph(); const vertexA = new GraphVertex('A'); const vertexB = new GraphVertex('B'); const vertexC = new GraphVertex('C'); const edgeAB = new GraphEdge(vertexA, vertexB, 10); graph.addEdge(edgeAB); const graphEdgeAB = graph.findEdge(vertexA, vertexB); const graphEdgeBA = graph.findEdge(vertexB, vertexA); const graphEdgeAC = graph.findEdge(vertexA, vertexC); const graphEdgeCA = graph.findEdge(vertexC, vertexA); expect(graphEdgeAC).toBeNull(); expect(graphEdgeCA).toBeNull(); expect(graphEdgeAB).toEqual(edgeAB); expect(graphEdgeBA).toEqual(edgeAB); expect(graphEdgeAB.weight).toBe(10); }); it('should find edge by vertices in directed graph', () => { const graph = new Graph(true); const vertexA = new GraphVertex('A'); const vertexB = new GraphVertex('B'); const vertexC = new GraphVertex('C'); const edgeAB = new GraphEdge(vertexA, vertexB, 10); graph.addEdge(edgeAB); const graphEdgeAB = graph.findEdge(vertexA, vertexB); const graphEdgeBA = graph.findEdge(vertexB, vertexA); const graphEdgeAC = graph.findEdge(vertexA, vertexC); const graphEdgeCA = graph.findEdge(vertexC, vertexA); expect(graphEdgeAC).toBeNull(); expect(graphEdgeCA).toBeNull(); expect(graphEdgeBA).toBeNull(); expect(graphEdgeAB).toEqual(edgeAB); expect(graphEdgeAB.weight).toBe(10); }); it('should return vertex neighbors', () => { const graph = new Graph(true); const vertexA = new GraphVertex('A'); const vertexB = new GraphVertex('B'); const vertexC = new GraphVertex('C'); const edgeAB = new GraphEdge(vertexA, vertexB); const edgeAC = new GraphEdge(vertexA, vertexC); graph .addEdge(edgeAB) .addEdge(edgeAC); const neighbors = graph.getNeighbors(vertexA); expect(neighbors.length).toBe(2); expect(neighbors[0]).toEqual(vertexB); expect(neighbors[1]).toEqual(vertexC); }); it('should throw an error when trying to add edge twice', () => { function addSameEdgeTwice() { const graph = new Graph(true); const vertexA = new GraphVertex('A'); const vertexB = new GraphVertex('B'); const edgeAB = new GraphEdge(vertexA, vertexB); graph .addEdge(edgeAB) .addEdge(edgeAB); } expect(addSameEdgeTwice).toThrow(); }); it('should return the list of all added edges', () => { const graph = new Graph(true); const vertexA = new GraphVertex('A'); const vertexB = new GraphVertex('B'); const vertexC = new GraphVertex('C'); const edgeAB = new GraphEdge(vertexA, vertexB); const edgeBC = new GraphEdge(vertexB, vertexC); graph .addEdge(edgeAB) .addEdge(edgeBC); const edges = graph.getAllEdges(); expect(edges.length).toBe(2); expect(edges[0]).toEqual(edgeAB); expect(edges[1]).toEqual(edgeBC); }); it('should calculate total graph weight for default graph', () => { const graph = new Graph(); const vertexA = new GraphVertex('A'); const vertexB = new GraphVertex('B'); const vertexC = new GraphVertex('C'); const vertexD = new GraphVertex('D'); const edgeAB = new GraphEdge(vertexA, vertexB); const edgeBC = new GraphEdge(vertexB, vertexC); const edgeCD = new GraphEdge(vertexC, vertexD); const edgeAD = new GraphEdge(vertexA, vertexD); graph .addEdge(edgeAB) .addEdge(edgeBC) .addEdge(edgeCD) .addEdge(edgeAD); expect(graph.getWeight()).toBe(0); }); it('should calculate total graph weight for weighted graph', () => { const graph = new Graph(); const vertexA = new GraphVertex('A'); const vertexB = new GraphVertex('B'); const vertexC = new GraphVertex('C'); const vertexD = new GraphVertex('D'); const edgeAB = new GraphEdge(vertexA, vertexB, 1); const edgeBC = new GraphEdge(vertexB, vertexC, 2); const edgeCD = new GraphEdge(vertexC, vertexD, 3); const edgeAD = new GraphEdge(vertexA, vertexD, 4); graph .addEdge(edgeAB) .addEdge(edgeBC) .addEdge(edgeCD) .addEdge(edgeAD); expect(graph.getWeight()).toBe(10); }); it('should be possible to delete edges from graph', () => { const graph = new Graph(); const vertexA = new GraphVertex('A'); const vertexB = new GraphVertex('B'); const vertexC = new GraphVertex('C'); const edgeAB = new GraphEdge(vertexA, vertexB); const edgeBC = new GraphEdge(vertexB, vertexC); const edgeAC = new GraphEdge(vertexA, vertexC); graph .addEdge(edgeAB) .addEdge(edgeBC) .addEdge(edgeAC); expect(graph.getAllEdges().length).toBe(3); graph.deleteEdge(edgeAB); expect(graph.getAllEdges().length).toBe(2); expect(graph.getAllEdges()[0].getKey()).toBe(edgeBC.getKey()); expect(graph.getAllEdges()[1].getKey()).toBe(edgeAC.getKey()); }); it('should should throw an error when trying to delete not existing edge', () => { function deleteNotExistingEdge() { const graph = new Graph(); const vertexA = new GraphVertex('A'); const vertexB = new GraphVertex('B'); const vertexC = new GraphVertex('C'); const edgeAB = new GraphEdge(vertexA, vertexB); const edgeBC = new GraphEdge(vertexB, vertexC); graph.addEdge(edgeAB); graph.deleteEdge(edgeBC); } expect(deleteNotExistingEdge).toThrowError(); }); it('should be possible to reverse graph', () => { const vertexA = new GraphVertex('A'); const vertexB = new GraphVertex('B'); const vertexC = new GraphVertex('C'); const vertexD = new GraphVertex('D'); const edgeAB = new GraphEdge(vertexA, vertexB); const edgeAC = new GraphEdge(vertexA, vertexC); const edgeCD = new GraphEdge(vertexC, vertexD); const graph = new Graph(true); graph .addEdge(edgeAB) .addEdge(edgeAC) .addEdge(edgeCD); expect(graph.toString()).toBe('A,B,C,D'); expect(graph.getAllEdges().length).toBe(3); expect(graph.getNeighbors(vertexA).length).toBe(2); expect(graph.getNeighbors(vertexA)[0].getKey()).toBe(vertexB.getKey()); expect(graph.getNeighbors(vertexA)[1].getKey()).toBe(vertexC.getKey()); expect(graph.getNeighbors(vertexB).length).toBe(0); expect(graph.getNeighbors(vertexC).length).toBe(1); expect(graph.getNeighbors(vertexC)[0].getKey()).toBe(vertexD.getKey()); expect(graph.getNeighbors(vertexD).length).toBe(0); graph.reverse(); expect(graph.toString()).toBe('A,B,C,D'); expect(graph.getAllEdges().length).toBe(3); expect(graph.getNeighbors(vertexA).length).toBe(0); expect(graph.getNeighbors(vertexB).length).toBe(1); expect(graph.getNeighbors(vertexB)[0].getKey()).toBe(vertexA.getKey()); expect(graph.getNeighbors(vertexC).length).toBe(1); expect(graph.getNeighbors(vertexC)[0].getKey()).toBe(vertexA.getKey()); expect(graph.getNeighbors(vertexD).length).toBe(1); expect(graph.getNeighbors(vertexD)[0].getKey()).toBe(vertexC.getKey()); }); it('should return vertices indices', () => { const vertexA = new GraphVertex('A'); const vertexB = new GraphVertex('B'); const vertexC = new GraphVertex('C'); const vertexD = new GraphVertex('D'); const edgeAB = new GraphEdge(vertexA, vertexB); const edgeBC = new GraphEdge(vertexB, vertexC); const edgeCD = new GraphEdge(vertexC, vertexD); const edgeBD = new GraphEdge(vertexB, vertexD); const graph = new Graph(); graph .addEdge(edgeAB) .addEdge(edgeBC) .addEdge(edgeCD) .addEdge(edgeBD); const verticesIndices = graph.getVerticesIndices(); expect(verticesIndices).toEqual({ A: 0, B: 1, C: 2, D: 3, }); }); it('should generate adjacency matrix for undirected graph', () => { const vertexA = new GraphVertex('A'); const vertexB = new GraphVertex('B'); const vertexC = new GraphVertex('C'); const vertexD = new GraphVertex('D'); const edgeAB = new GraphEdge(vertexA, vertexB); const edgeBC = new GraphEdge(vertexB, vertexC); const edgeCD = new GraphEdge(vertexC, vertexD); const edgeBD = new GraphEdge(vertexB, vertexD); const graph = new Graph(); graph .addEdge(edgeAB) .addEdge(edgeBC) .addEdge(edgeCD) .addEdge(edgeBD); const adjacencyMatrix = graph.getAdjacencyMatrix(); expect(adjacencyMatrix).toEqual([ [Infinity, 0, Infinity, Infinity], [0, Infinity, 0, 0], [Infinity, 0, Infinity, 0], [Infinity, 0, 0, Infinity], ]); }); it('should generate adjacency matrix for directed graph', () => { const vertexA = new GraphVertex('A'); const vertexB = new GraphVertex('B'); const vertexC = new GraphVertex('C'); const vertexD = new GraphVertex('D'); const edgeAB = new GraphEdge(vertexA, vertexB, 2); const edgeBC = new GraphEdge(vertexB, vertexC, 1); const edgeCD = new GraphEdge(vertexC, vertexD, 5); const edgeBD = new GraphEdge(vertexB, vertexD, 7); const graph = new Graph(true); graph .addEdge(edgeAB) .addEdge(edgeBC) .addEdge(edgeCD) .addEdge(edgeBD); const adjacencyMatrix = graph.getAdjacencyMatrix(); expect(adjacencyMatrix).toEqual([ [Infinity, 2, Infinity, Infinity], [Infinity, Infinity, 1, 7], [Infinity, Infinity, Infinity, 5], [Infinity, Infinity, Infinity, Infinity], ]); }); });