Skip to content

Commit

Permalink
Create a function that runs the common tests of all shortest paths al…
Browse files Browse the repository at this point in the history
…gorithms.
  • Loading branch information
mstou committed Apr 29, 2020
1 parent 9fe70eb commit fcce9e6
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 150 deletions.
84 changes: 5 additions & 79 deletions test/alg/bellman-ford-tests.js
Original file line number Diff line number Diff line change
@@ -1,84 +1,10 @@
var expect = require("../chai").expect;

var Graph = require("../..").Graph,
bellmanFord = require("../..").alg.bellmanFord;
var expect = require("../chai").expect,
Graph = require("../..").Graph,
bellmanFord = require("../..").alg.bellmanFord,
shortestPathsTests = require("./shortest-paths-tests.js");

describe("alg.bellmanFord", function(){
it("Assigns distance 0 for the source node", function() {
var g = new Graph();
g.setNode("source");
expect(bellmanFord(g, "source")).to.eql({ source: { distance: 0 } });
});

it("Returns Number.POSITIVE_INFINITY for unconnected nodes", function() {
var g = new Graph();
g.setNode("a");
g.setNode("b");
expect(bellmanFord(g, "a")).to.eql({
a: { distance: 0 },
b: { distance: Number.POSITIVE_INFINITY }
});
});

it("Returns the distance and predecessor for all nodes", function() {
var g = new Graph();
g.setPath(["a", "b", "c"]);
g.setEdge("b", "d");
expect(bellmanFord(g, "a")).to.eql({
a: { distance: 0 },
b: { distance: 1, predecessor: "a" },
c: { distance: 2, predecessor: "b" },
d: { distance: 2, predecessor: "b" }
});
});

it("Works for undirected graphs", function() {
var g = new Graph({ directed: false });
g.setPath(["a", "b", "c"]);
g.setEdge("b", "d");
expect(bellmanFord(g, "a")).to.eql({
a: { distance: 0 },
b: { distance: 1, predecessor: "a" },
c: { distance: 2, predecessor: "b" },
d: { distance: 2, predecessor: "b" }
});
});

it("Works with an optionally supplied weight function", function() {
var g = new Graph();
g.setEdge("a", "b", 1);
g.setEdge("a", "c", 2);
g.setEdge("b", "d", 3);
g.setEdge("c", "d", 3);

expect(bellmanFord(g, "a", weightFn(g))).to.eql({
a: { distance: 0 },
b: { distance: 1, predecessor: "a" },
c: { distance: 2, predecessor: "a" },
d: { distance: 4, predecessor: "b" }
});
});

it("Uses an optionally supplied edge function", function() {
var g = new Graph();
g.setPath(["a", "c", "d"]);
g.setEdge("b", "c");

function edgeFn(v){
switch (v) {
case "d": return [{ v: "d", w: "c" }];
case "c": return [{ v: "c", w: "b" }, { v: "c", w: "a" }];
default: return [];
}
}

expect(bellmanFord(g, "d", undefined, edgeFn)).to.eql({
a: { distance: 2, predecessor: "c" },
b: { distance: 2, predecessor: "c" },
c: { distance: 1, predecessor: "d" },
d: { distance: 0 }
});
});
shortestPathsTests(bellmanFord);

it("Works with negative weight edges on the graph", function() {
var g = new Graph();
Expand Down
76 changes: 5 additions & 71 deletions test/alg/dijkstra-test.js
Original file line number Diff line number Diff line change
@@ -1,76 +1,10 @@
var expect = require("../chai").expect;

var Graph = require("../..").Graph;
var dijkstra = require("../..").alg.dijkstra;
var expect = require("../chai").expect,
Graph = require("../..").Graph,
dijkstra = require("../..").alg.dijkstra,
shortestPathsTests = require("./shortest-paths-tests.js");

describe("alg.dijkstra", function() {
it("assigns distance 0 for the source node", function() {
var g = new Graph();
g.setNode("source");
expect(dijkstra(g, "source")).to.eql({ source: { distance: 0 } });
});

it("returns Number.POSITIVE_INFINITY for unconnected nodes", function() {
var g = new Graph();
g.setNode("a");
g.setNode("b");
expect(dijkstra(g, "a")).to.eql({
a: { distance: 0 },
b: { distance: Number.POSITIVE_INFINITY }
});
});

it("returns the distance and path from the source node to other nodes", function() {
var g = new Graph();
g.setPath(["a", "b", "c"]);
g.setEdge("b", "d");
expect(dijkstra(g, "a")).to.eql({
a: { distance: 0 },
b: { distance: 1, predecessor: "a" },
c: { distance: 2, predecessor: "b" },
d: { distance: 2, predecessor: "b" }
});
});

it("works for undirected graphs", function() {
var g = new Graph({ directed: false });
g.setPath(["a", "b", "c"]);
g.setEdge("b", "d");
expect(dijkstra(g, "a")).to.eql({
a: { distance: 0 },
b: { distance: 1, predecessor: "a" },
c: { distance: 2, predecessor: "b" },
d: { distance: 2, predecessor: "b" }
});
});

it("uses an optionally supplied weight function", function() {
var g = new Graph();
g.setEdge("a", "b", 1);
g.setEdge("a", "c", 2);
g.setEdge("b", "d", 3);
g.setEdge("c", "d", 3);

expect(dijkstra(g, "a", weightFn(g))).to.eql({
a: { distance: 0 },
b: { distance: 1, predecessor: "a" },
c: { distance: 2, predecessor: "a" },
d: { distance: 4, predecessor: "b" }
});
});

it("uses an optionally supplied edge function", function() {
var g = new Graph();
g.setPath(["a", "c", "d"]);
g.setEdge("b", "c");

expect(dijkstra(g, "d", undefined, function(e) { return g.inEdges(e); })).to.eql({
a: { distance: 2, predecessor: "c" },
b: { distance: 2, predecessor: "c" },
c: { distance: 1, predecessor: "d" },
d: { distance: 0 }
});
});
shortestPathsTests(dijkstra);

it("throws an Error if it encounters a negative edge weight", function() {
var g = new Graph();
Expand Down
82 changes: 82 additions & 0 deletions test/alg/shortest-paths-tests.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
var expect = require("../chai").expect,
Graph = require("../..").Graph;

module.exports = tests;

function tests(algorithm) {
describe( "Shortest Path Algorithms", function() {
it("assigns distance 0 for the source node", function() {
var g = new Graph();
g.setNode("source");
expect(algorithm(g, "source")).to.eql({ source: { distance: 0 } });
});

it("returns Number.POSITIVE_INFINITY for unconnected nodes", function() {
var g = new Graph();
g.setNode("a");
g.setNode("b");
expect(algorithm(g, "a")).to.eql({
a: { distance: 0 },
b: { distance: Number.POSITIVE_INFINITY }
});
});

it("returns the distance and path from the source node to other nodes", function() {
var g = new Graph();
g.setPath(["a", "b", "c"]);
g.setEdge("b", "d");
expect(algorithm(g, "a")).to.eql({
a: { distance: 0 },
b: { distance: 1, predecessor: "a" },
c: { distance: 2, predecessor: "b" },
d: { distance: 2, predecessor: "b" }
});
});

it("works for undirected graphs", function() {
var g = new Graph({ directed: false });
g.setPath(["a", "b", "c"]);
g.setEdge("b", "d");
expect(algorithm(g, "a")).to.eql({
a: { distance: 0 },
b: { distance: 1, predecessor: "a" },
c: { distance: 2, predecessor: "b" },
d: { distance: 2, predecessor: "b" }
});
});

it("uses an optionally supplied weight function", function() {
var g = new Graph();
g.setEdge("a", "b", 1);
g.setEdge("a", "c", 2);
g.setEdge("b", "d", 3);
g.setEdge("c", "d", 3);

expect(algorithm(g, "a", weightFn(g))).to.eql({
a: { distance: 0 },
b: { distance: 1, predecessor: "a" },
c: { distance: 2, predecessor: "a" },
d: { distance: 4, predecessor: "b" }
});
});

it("uses an optionally supplied edge function", function() {
var g = new Graph();
g.setPath(["a", "c", "d"]);
g.setEdge("b", "c");

expect(algorithm(g, "d", undefined, function(e) { return g.inEdges(e); })).to.eql({
a: { distance: 2, predecessor: "c" },
b: { distance: 2, predecessor: "c" },
c: { distance: 1, predecessor: "d" },
d: { distance: 0 }
});
});
});
}

function weightFn(g) {
return function(e) {
return g.edge(e);
};
}

0 comments on commit fcce9e6

Please sign in to comment.