1
0
Fork 0
arangodb/js/common/tests/shell-graph-algorithms.js

634 lines
21 KiB
JavaScript

/*jshint globalstrict:false, strict:false, unused: false */
/*global assertEqual */
////////////////////////////////////////////////////////////////////////////////
/// @brief test the graph class
///
/// @file
///
/// DISCLAIMER
///
/// Copyright 2010-2012 triagens GmbH, Cologne, Germany
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
/// Copyright holder is triAGENS GmbH, Cologne, Germany
///
/// @author Dr. Frank Celler, Lucas Dohmen
/// @author Copyright 2012, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////
var jsunity = require("jsunity");
var console = require("console");
// -----------------------------------------------------------------------------
// --SECTION-- collection methods
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief test suite: Get Neighbor Function
////////////////////////////////////////////////////////////////////////////////
function neighborSuite() {
'use strict';
var Graph = require("org/arangodb/graph").Graph,
graph_name = "UnitTestsCollectionGraph",
vertex = "UnitTestsCollectionVertex",
edge = "UnitTestsCollectionEdge",
graph = null;
return {
////////////////////////////////////////////////////////////////////////////////
/// @brief set up
////////////////////////////////////////////////////////////////////////////////
setUp : function () {
try {
try {
// Drop the graph if it exsits
graph = new Graph(graph_name);
require("internal").print("FOUND: ");
require("internal").printObject(graph);
graph.drop();
} catch (err1) {
}
graph = new Graph(graph_name, vertex, edge);
} catch (err2) {
console.error("[FAILED] setup failed:" + err2);
}
},
////////////////////////////////////////////////////////////////////////////////
/// @brief tear down
////////////////////////////////////////////////////////////////////////////////
tearDown : function () {
try {
if (graph !== null) {
graph.drop();
}
} catch (err) {
console.error("[FAILED] tear-down failed:" + err);
}
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test the get neighbors function
////////////////////////////////////////////////////////////////////////////////
testGetAllNeighbors : function () {
var v1 = graph.addVertex("1"),
v2 = graph.addVertex("2"),
v3 = graph.addVertex("3"),
result_array = [];
graph.addEdge(v1, v2);
graph.addEdge(v3, v1);
result_array = v1.getNeighbors({ direction: 'both' });
assertEqual(result_array.length, "2");
assertEqual(result_array[0].id, "2");
assertEqual(result_array[1].id, "3");
},
testGetOutboundNeighbors : function () {
var v1 = graph.addVertex("1"),
v2 = graph.addVertex("2"),
v3 = graph.addVertex("3"),
result_array = [];
graph.addEdge(v1, v2);
graph.addEdge(v3, v1);
result_array = v1.getNeighbors({ direction: 'outbound' });
assertEqual(result_array.length, "1");
assertEqual(result_array[0].id, "2");
},
testGetInboundNeighbors : function () {
var v1 = graph.addVertex("1"),
v2 = graph.addVertex("2"),
v3 = graph.addVertex("3"),
result_array = [];
graph.addEdge(v1, v2);
graph.addEdge(v3, v1);
result_array = v1.getNeighbors({ direction: 'inbound' });
assertEqual(result_array.length, "1");
assertEqual(result_array[0].id, "3");
},
testGetNeighborsWithPathLabel : function () {
var v1 = graph.addVertex("1"),
v2 = graph.addVertex("2"),
v3 = graph.addVertex("3"),
result_array = [];
graph.addEdge(v1, v2, 8, 'a');
graph.addEdge(v1, v3, 9, 'b');
result_array = v1.getNeighbors({ direction: 'both', labels: ['a', 'c'] });
assertEqual(result_array.length, "1");
assertEqual(result_array[0].id, "2");
}
};
}
////////////////////////////////////////////////////////////////////////////////
/// @brief test suite: Dijkstra
////////////////////////////////////////////////////////////////////////////////
function dijkstraSuite() {
'use strict';
var Graph = require("org/arangodb/graph").Graph,
graph_name = "UnitTestsCollectionGraph",
vertex = "UnitTestsCollectionVertex",
edge = "UnitTestsCollectionEdge",
graph = null;
return {
////////////////////////////////////////////////////////////////////////////////
/// @brief set up
////////////////////////////////////////////////////////////////////////////////
setUp : function () {
try {
try {
// Drop the graph if it exsits
graph = new Graph(graph_name);
graph.drop();
} catch (err1) {
}
graph = new Graph(graph_name, vertex, edge);
} catch (err2) {
console.error("[FAILED] setup failed:" + err2);
}
},
////////////////////////////////////////////////////////////////////////////////
/// @brief tear down
////////////////////////////////////////////////////////////////////////////////
tearDown : function () {
try {
if (graph !== null) {
graph.drop();
}
} catch (err) {
console.error("[FAILED] tear-down failed:" + err);
}
},
////////////////////////////////////////////////////////////////////////////////
/// @brief get a short, distinct path
////////////////////////////////////////////////////////////////////////////////
testPathesForTree : function () {
var v1 = graph.addVertex(1),
v2 = graph.addVertex(2),
v3 = graph.addVertex(3),
v4 = graph.addVertex(4),
v5 = graph.addVertex(5),
tree = {},
pathes;
tree[v1.getId()] = [v2.getId(), v3.getId()];
tree[v2.getId()] = [v4.getId(), v5.getId()];
pathes = v1.pathesForTree(tree);
assertEqual(pathes.length, 3);
assertEqual(pathes[0].length, 3);
assertEqual(pathes[1].length, 3);
assertEqual(pathes[2].length, 2);
},
////////////////////////////////////////////////////////////////////////////////
/// @brief get a short, distinct path
////////////////////////////////////////////////////////////////////////////////
testGetAShortDistinctPath : function () {
var v1, v2, e1, path;
v1 = graph.addVertex(1);
v2 = graph.addVertex(2);
e1 = graph.addEdge(v1, v2);
path = v1.pathTo(v2)[0];
assertEqual(path.length, 2);
assertEqual(path[0].toString(), v1.getId());
assertEqual(path[1].toString(), v2.getId());
},
////////////////////////////////////////////////////////////////////////////////
/// @brief get a longer, distinct path
////////////////////////////////////////////////////////////////////////////////
testGetALongerDistinctPath : function () {
var v1, v2, v3, e1, e2, path;
v1 = graph.addVertex(1);
v2 = graph.addVertex(2);
v3 = graph.addVertex(3);
e1 = graph.addEdge(v1, v2);
e2 = graph.addEdge(v2, v3);
path = v1.pathTo(v3)[0];
assertEqual(path.length, 3);
assertEqual(path[0].toString(), v1.getId());
assertEqual(path[1].toString(), v2.getId());
assertEqual(path[2].toString(), v3.getId());
},
////////////////////////////////////////////////////////////////////////////////
/// @brief get a short, distinct path on a directed graph
////////////////////////////////////////////////////////////////////////////////
testGetADirectedDistinctPath : function () {
var v1 = graph.addVertex(1),
v2 = graph.addVertex(2),
v3 = graph.addVertex(3),
v4 = graph.addVertex(4),
e1 = graph.addEdge(v1, v2),
e2 = graph.addEdge(v2, v3),
e3 = graph.addEdge(v3, v4),
e4 = graph.addEdge(v4, v1),
pathes = v1.pathTo(v3, {direction: "outbound"});
assertEqual(pathes.length, 1);
assertEqual(pathes[0][0].toString(), v1.getId());
assertEqual(pathes[0][1].toString(), v2.getId());
assertEqual(pathes[0][2].toString(), v3.getId());
},
testGetCorrectCachedResults : function () {
var v1 = graph.addVertex(1),
v2 = graph.addVertex(2),
v3 = graph.addVertex(3),
e1 = graph.addEdge(v1, v2),
e2 = graph.addEdge(v2, v3),
e3,
pathes = v1.pathTo(v3, {cached: true});
e3 = graph.addEdge(v1, v3);
pathes = v1.pathTo(v3, {cached: true});
assertEqual(pathes.length, 1);
assertEqual(pathes[0][0].toString(), v1.getId());
assertEqual(pathes[0][1].toString(), v3.getId());
},
////////////////////////////////////////////////////////////////////////////////
/// @brief get a short, distinct path on a directed graph
////////////////////////////////////////////////////////////////////////////////
testGetADirectedLabeledPath : function () {
var v1 = graph.addVertex(1),
v2 = graph.addVertex(2),
v3 = graph.addVertex(3),
v4 = graph.addVertex(4),
e1 = graph.addEdge(v1, v2, 5, "no"),
e2 = graph.addEdge(v1, v3, 6, "yes"),
e3 = graph.addEdge(v3, v4, 7, "yeah"),
e4 = graph.addEdge(v4, v2, 8, "yes"),
pathes = v1.pathTo(v2, { labels: ["yes", "yeah"] });
assertEqual(pathes.length, 1);
assertEqual(pathes[0][0].toString(), v1.getId());
assertEqual(pathes[0][1].toString(), v3.getId());
assertEqual(pathes[0][2].toString(), v4.getId());
assertEqual(pathes[0][3].toString(), v2.getId());
},
////////////////////////////////////////////////////////////////////////////////
/// @brief get a short, distinct path on a weighted graph
////////////////////////////////////////////////////////////////////////////////
testGetADirectedWeightedPath : function () {
var v1 = graph.addVertex(1),
v2 = graph.addVertex(2),
v3 = graph.addVertex(3),
v4 = graph.addVertex(4),
e1 = graph.addEdge(v1, v2, 5, "5", { my_weight: 5 }),
e2 = graph.addEdge(v1, v3, 6, "6", { my_weight: 1 }),
e3 = graph.addEdge(v3, v4, 7, "7", { my_weight: 1 }),
e4 = graph.addEdge(v4, v2, 8, "8", { my_weight: 1 }),
pathes = v1.pathTo(v2, { weight: "my_weight" });
assertEqual(pathes.length, 1);
assertEqual(pathes[0][0].toString(), v1.getId());
assertEqual(pathes[0][1].toString(), v3.getId());
assertEqual(pathes[0][2].toString(), v4.getId());
assertEqual(pathes[0][3].toString(), v2.getId());
},
////////////////////////////////////////////////////////////////////////////////
/// @brief get a short, distinct path on a weighted graph
////////////////////////////////////////////////////////////////////////////////
testGetADirectedWeightedPathWithUndefinedWeights : function () {
var v1 = graph.addVertex(1),
v2 = graph.addVertex(2),
v3 = graph.addVertex(3),
v4 = graph.addVertex(4),
e1 = graph.addEdge(v1, v2, 5, "5"),
e2 = graph.addEdge(v1, v3, 6, "6", { my_weight: 1 }),
e3 = graph.addEdge(v3, v4, 7, "7", { my_weight: 1 }),
e4 = graph.addEdge(v4, v2, 8, "8", { my_weight: 1 }),
pathes = v1.pathTo(v2, { weight: "my_weight" });
assertEqual(pathes.length, 1);
assertEqual(pathes[0][0].toString(), v1.getId());
assertEqual(pathes[0][1].toString(), v3.getId());
assertEqual(pathes[0][2].toString(), v4.getId());
assertEqual(pathes[0][3].toString(), v2.getId());
},
////////////////////////////////////////////////////////////////////////////////
/// @brief get a short, distinct path on a weighted graph
////////////////////////////////////////////////////////////////////////////////
testGetADirectedWeightedPathWithDefaultWeight : function () {
var v1 = graph.addVertex(1),
v2 = graph.addVertex(2),
v3 = graph.addVertex(3),
v4 = graph.addVertex(4),
e1 = graph.addEdge(v1, v2, 5, "5"),
e2 = graph.addEdge(v1, v3, 6, "6", { my_weight: 1 }),
e3 = graph.addEdge(v3, v4, 7, "7", { my_weight: 1 }),
e4 = graph.addEdge(v4, v2, 8, "8", { my_weight: 1 }),
pathes = v1.pathTo(v2, { weight: "my_weight", default_weight: 1 });
assertEqual(pathes.length, 1);
assertEqual(pathes[0][0].toString(), v1.getId());
assertEqual(pathes[0][1].toString(), v2.getId());
},
////////////////////////////////////////////////////////////////////////////////
/// @brief get a short, distinct path on a weighted graph with a custom function
////////////////////////////////////////////////////////////////////////////////
testGetAPathWithACustomWeightFunction : function () {
var v1 = graph.addVertex(1),
v2 = graph.addVertex(2),
v3 = graph.addVertex(3),
v4 = graph.addVertex(4),
e1 = graph.addEdge(v1, v2, 5, "5", { my_weight: 5 }),
e2 = graph.addEdge(v1, v3, 6, "6", { my_weight: 1 }),
e3 = graph.addEdge(v3, v4, 7, "7", { my_weight: 1 }),
e4 = graph.addEdge(v4, v2, 8, "8", { my_weight: 1 }),
pathes;
pathes = v1.pathTo(v2, {
weight_function: function (edge) {
return edge.getProperty("my_weight");
}
});
assertEqual(pathes.length, 1);
assertEqual(pathes[0][0].toString(), v1.getId());
assertEqual(pathes[0][1].toString(), v3.getId());
assertEqual(pathes[0][2].toString(), v4.getId());
assertEqual(pathes[0][3].toString(), v2.getId());
},
////////////////////////////////////////////////////////////////////////////////
/// @brief get a short, distinct path while excluding certain edges
////////////////////////////////////////////////////////////////////////////////
testGetAPathWithEdgeExclusion: function () {
var v1 = graph.addVertex(1),
v2 = graph.addVertex(2),
v3 = graph.addVertex(3),
v4 = graph.addVertex(4),
e1 = graph.addEdge(v1, v2, 5, "5", { rating: 3 }),
e2 = graph.addEdge(v1, v3, 6, "6", { rating: 5 }),
e3 = graph.addEdge(v3, v4, 7, "7", { rating: 4 }),
e4 = graph.addEdge(v4, v2, 8, "8", { rating: 6 }),
pathes;
pathes = v1.pathTo(v2, {
only: function (edge) {
return (edge.getProperty("rating") > 3);
}
});
assertEqual(pathes.length, 1);
assertEqual(pathes[0][0].toString(), v1.getId());
assertEqual(pathes[0][1].toString(), v3.getId());
assertEqual(pathes[0][2].toString(), v4.getId());
assertEqual(pathes[0][3].toString(), v2.getId());
}
};
}
////////////////////////////////////////////////////////////////////////////////
/// @brief test suite: Common Neighbors and Attributes
////////////////////////////////////////////////////////////////////////////////
function commonSuite() {
'use strict';
var Graph = require("org/arangodb/graph").Graph,
graph_name = "UnitTestsCollectionGraph",
vertex = "UnitTestsCollectionVertex",
edge = "UnitTestsCollectionEdge",
graph = null;
return {
////////////////////////////////////////////////////////////////////////////////
/// @brief set up
////////////////////////////////////////////////////////////////////////////////
setUp : function () {
try {
try {
// Drop the graph if it exsits
graph = new Graph(graph_name);
require("internal").print("FOUND: ");
require("internal").printObject(graph);
graph.drop();
} catch (err1) {
}
graph = new Graph(graph_name, vertex, edge);
} catch (err2) {
console.error("[FAILED] setup failed:" + err2);
}
},
////////////////////////////////////////////////////////////////////////////////
/// @brief tear down
////////////////////////////////////////////////////////////////////////////////
tearDown : function () {
try {
if (graph !== null) {
graph.drop();
}
} catch (err) {
console.error("[FAILED] tear-down failed:" + err);
}
},
////////////////////////////////////////////////////////////////////////////////
/// @brief Test CommonNeighborsWith
////////////////////////////////////////////////////////////////////////////////
testCommonNeighborsWith: function () {
var v1 = graph.addVertex(1),
v2 = graph.addVertex(2),
v3 = graph.addVertex(3),
v4 = graph.addVertex(4),
v5 = graph.addVertex(5),
e1 = graph.addEdge(v1, v3),
e2 = graph.addEdge(v1, v4),
e3 = graph.addEdge(v2, v4),
e4 = graph.addEdge(v2, v5),
commonNeighbors;
commonNeighbors = v1.commonNeighborsWith(v2);
assertEqual(commonNeighbors, 1);
},
////////////////////////////////////////////////////////////////////////////////
/// @brief Test normalized CommonNeighborsWith
////////////////////////////////////////////////////////////////////////////////
testNormalizedCommonNeighborsWith: function () {
var v1 = graph.addVertex(1),
v2 = graph.addVertex(2),
v3 = graph.addVertex(3),
v4 = graph.addVertex(4),
v5 = graph.addVertex(5),
e1 = graph.addEdge(v1, v3),
e2 = graph.addEdge(v1, v4),
e3 = graph.addEdge(v2, v4),
e4 = graph.addEdge(v2, v5),
commonNeighbors;
commonNeighbors = v1.commonNeighborsWith(v2, { normalized: true});
assertEqual(commonNeighbors, (1 / 3));
},
////////////////////////////////////////////////////////////////////////////////
/// @brief Test listed CommonNeighborsWith
////////////////////////////////////////////////////////////////////////////////
testListedCommonNeighborsWith: function () {
var v1 = graph.addVertex(1),
v2 = graph.addVertex(2),
v3 = graph.addVertex(3),
v4 = graph.addVertex(4),
v5 = graph.addVertex(5),
e1 = graph.addEdge(v1, v3),
e2 = graph.addEdge(v1, v4),
e3 = graph.addEdge(v2, v4),
e4 = graph.addEdge(v2, v5),
commonNeighbors;
commonNeighbors = v1.commonNeighborsWith(v2, { listed: true});
assertEqual(commonNeighbors.length, 1);
assertEqual(commonNeighbors[0], v4.getId());
},
////////////////////////////////////////////////////////////////////////////////
/// @brief Test CommonPropertiesWith
////////////////////////////////////////////////////////////////////////////////
testCommonPropertiesWith: function () {
var v1 = graph.addVertex(1),
v2 = graph.addVertex(2),
commonProperties;
v1.setProperty("a", 1);
v2.setProperty("a", 2);
v1.setProperty("b", 1);
v2.setProperty("b", 1);
v2.setProperty("c", 0);
commonProperties = v1.commonPropertiesWith(v2);
assertEqual(commonProperties, 1);
},
////////////////////////////////////////////////////////////////////////////////
/// @brief Test Normalized CommonPropertiesWith
////////////////////////////////////////////////////////////////////////////////
testNormalizedCommonPropertiesWith: function () {
var v1 = graph.addVertex(1),
v2 = graph.addVertex(2),
commonProperties;
v1.setProperty("a", 1);
v2.setProperty("a", 2);
v1.setProperty("b", 1);
v2.setProperty("b", 1);
v2.setProperty("c", 0);
commonProperties = v1.commonPropertiesWith(v2, { normalized: true });
assertEqual(commonProperties, (1 / 3));
},
////////////////////////////////////////////////////////////////////////////////
/// @brief Test Listed CommonPropertiesWith
////////////////////////////////////////////////////////////////////////////////
testListedCommonPropertiesWith: function () {
var v1 = graph.addVertex(1),
v2 = graph.addVertex(2),
commonProperties;
v1.setProperty("a", 1);
v2.setProperty("a", 2);
v1.setProperty("b", 1);
v2.setProperty("b", 1);
v2.setProperty("c", 0);
commonProperties = v1.commonPropertiesWith(v2, { listed: true });
assertEqual(commonProperties.length, 1);
assertEqual(commonProperties[0], "b");
}
};
}
////////////////////////////////////////////////////////////////////////////////
/// @brief executes the test suites
////////////////////////////////////////////////////////////////////////////////
jsunity.run(neighborSuite);
jsunity.run(dijkstraSuite);
jsunity.run(commonSuite);
return jsunity.done();