dist-javascript-algorithms-and-data-structures
Version:
Algorithms and data-structures implemented on JavaScript
204 lines (189 loc) • 7.69 kB
JavaScript
"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);
}
});
});