UNPKG

dist-javascript-algorithms-and-data-structures

Version:

Algorithms and data-structures implemented on JavaScript

204 lines (189 loc) 7.69 kB
"use strict"; var _Graph = _interopRequireDefault(require("../../../../data-structures/graph/Graph")); var _GraphVertex = _interopRequireDefault(require("../../../../data-structures/graph/GraphVertex")); var _GraphEdge = _interopRequireDefault(require("../../../../data-structures/graph/GraphEdge")); var _breadthFirstSearch = _interopRequireDefault(require("../breadthFirstSearch")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } describe('breadthFirstSearch', () => { it('should perform BFS operation on graph', () => { const graph = new _Graph.default(true); const vertexA = new _GraphVertex.default('A'); const vertexB = new _GraphVertex.default('B'); const vertexC = new _GraphVertex.default('C'); const vertexD = new _GraphVertex.default('D'); const vertexE = new _GraphVertex.default('E'); const vertexF = new _GraphVertex.default('F'); const vertexG = new _GraphVertex.default('G'); const vertexH = new _GraphVertex.default('H'); const edgeAB = new _GraphEdge.default(vertexA, vertexB); const edgeBC = new _GraphEdge.default(vertexB, vertexC); const edgeCG = new _GraphEdge.default(vertexC, vertexG); const edgeAD = new _GraphEdge.default(vertexA, vertexD); const edgeAE = new _GraphEdge.default(vertexA, vertexE); const edgeEF = new _GraphEdge.default(vertexE, vertexF); const edgeFD = new _GraphEdge.default(vertexF, vertexD); const edgeDH = new _GraphEdge.default(vertexD, vertexH); const edgeGH = new _GraphEdge.default(vertexG, vertexH); graph.addEdge(edgeAB).addEdge(edgeBC).addEdge(edgeCG).addEdge(edgeAD).addEdge(edgeAE).addEdge(edgeEF).addEdge(edgeFD).addEdge(edgeDH).addEdge(edgeGH); expect(graph.toString()).toBe('A,B,C,G,D,E,F,H'); const enterVertexCallback = jest.fn(); const leaveVertexCallback = jest.fn(); // Traverse graphs without callbacks first. (0, _breadthFirstSearch.default)(graph, vertexA); // Traverse graph with enterVertex and leaveVertex callbacks. (0, _breadthFirstSearch.default)(graph, vertexA, { enterVertex: enterVertexCallback, leaveVertex: leaveVertexCallback }); expect(enterVertexCallback).toHaveBeenCalledTimes(8); expect(leaveVertexCallback).toHaveBeenCalledTimes(8); const enterVertexParamsMap = [{ currentVertex: vertexA, previousVertex: null }, { currentVertex: vertexB, previousVertex: vertexA }, { currentVertex: vertexD, previousVertex: vertexB }, { currentVertex: vertexE, previousVertex: vertexD }, { currentVertex: vertexC, previousVertex: vertexE }, { currentVertex: vertexH, previousVertex: vertexC }, { currentVertex: vertexF, previousVertex: vertexH }, { currentVertex: vertexG, previousVertex: vertexF }]; for (let callIndex = 0; callIndex < graph.getAllVertices().length; callIndex += 1) { const params = enterVertexCallback.mock.calls[callIndex][0]; expect(params.currentVertex).toEqual(enterVertexParamsMap[callIndex].currentVertex); expect(params.previousVertex).toEqual(enterVertexParamsMap[callIndex].previousVertex); } const leaveVertexParamsMap = [{ currentVertex: vertexA, previousVertex: null }, { currentVertex: vertexB, previousVertex: vertexA }, { currentVertex: vertexD, previousVertex: vertexB }, { currentVertex: vertexE, previousVertex: vertexD }, { currentVertex: vertexC, previousVertex: vertexE }, { currentVertex: vertexH, previousVertex: vertexC }, { currentVertex: vertexF, previousVertex: vertexH }, { currentVertex: vertexG, previousVertex: vertexF }]; for (let callIndex = 0; callIndex < graph.getAllVertices().length; callIndex += 1) { const params = leaveVertexCallback.mock.calls[callIndex][0]; expect(params.currentVertex).toEqual(leaveVertexParamsMap[callIndex].currentVertex); expect(params.previousVertex).toEqual(leaveVertexParamsMap[callIndex].previousVertex); } }); it('should allow to create custom vertex visiting logic', () => { const graph = new _Graph.default(true); const vertexA = new _GraphVertex.default('A'); const vertexB = new _GraphVertex.default('B'); const vertexC = new _GraphVertex.default('C'); const vertexD = new _GraphVertex.default('D'); const vertexE = new _GraphVertex.default('E'); const vertexF = new _GraphVertex.default('F'); const vertexG = new _GraphVertex.default('G'); const vertexH = new _GraphVertex.default('H'); const edgeAB = new _GraphEdge.default(vertexA, vertexB); const edgeBC = new _GraphEdge.default(vertexB, vertexC); const edgeCG = new _GraphEdge.default(vertexC, vertexG); const edgeAD = new _GraphEdge.default(vertexA, vertexD); const edgeAE = new _GraphEdge.default(vertexA, vertexE); const edgeEF = new _GraphEdge.default(vertexE, vertexF); const edgeFD = new _GraphEdge.default(vertexF, vertexD); const edgeDH = new _GraphEdge.default(vertexD, vertexH); const edgeGH = new _GraphEdge.default(vertexG, vertexH); graph.addEdge(edgeAB).addEdge(edgeBC).addEdge(edgeCG).addEdge(edgeAD).addEdge(edgeAE).addEdge(edgeEF).addEdge(edgeFD).addEdge(edgeDH).addEdge(edgeGH); expect(graph.toString()).toBe('A,B,C,G,D,E,F,H'); const enterVertexCallback = jest.fn(); const leaveVertexCallback = jest.fn(); // Traverse graph with enterVertex and leaveVertex callbacks. (0, _breadthFirstSearch.default)(graph, vertexA, { enterVertex: enterVertexCallback, leaveVertex: leaveVertexCallback, allowTraversal: ({ currentVertex, nextVertex }) => { return !(currentVertex === vertexA && nextVertex === vertexB); } }); expect(enterVertexCallback).toHaveBeenCalledTimes(7); expect(leaveVertexCallback).toHaveBeenCalledTimes(7); const enterVertexParamsMap = [{ currentVertex: vertexA, previousVertex: null }, { currentVertex: vertexD, previousVertex: vertexA }, { currentVertex: vertexE, previousVertex: vertexD }, { currentVertex: vertexH, previousVertex: vertexE }, { currentVertex: vertexF, previousVertex: vertexH }, { currentVertex: vertexD, previousVertex: vertexF }, { currentVertex: vertexH, previousVertex: vertexD }]; for (let callIndex = 0; callIndex < 7; callIndex += 1) { const params = enterVertexCallback.mock.calls[callIndex][0]; expect(params.currentVertex).toEqual(enterVertexParamsMap[callIndex].currentVertex); expect(params.previousVertex).toEqual(enterVertexParamsMap[callIndex].previousVertex); } const leaveVertexParamsMap = [{ currentVertex: vertexA, previousVertex: null }, { currentVertex: vertexD, previousVertex: vertexA }, { currentVertex: vertexE, previousVertex: vertexD }, { currentVertex: vertexH, previousVertex: vertexE }, { currentVertex: vertexF, previousVertex: vertexH }, { currentVertex: vertexD, previousVertex: vertexF }, { currentVertex: vertexH, previousVertex: vertexD }]; for (let callIndex = 0; callIndex < 7; callIndex += 1) { const params = leaveVertexCallback.mock.calls[callIndex][0]; expect(params.currentVertex).toEqual(leaveVertexParamsMap[callIndex].currentVertex); expect(params.previousVertex).toEqual(leaveVertexParamsMap[callIndex].previousVertex); } }); });