diff --git a/html/admin/js/graphViewer/graph/abstractAdapter.js b/html/admin/js/graphViewer/graph/abstractAdapter.js
index c382d44a03..20ec6e0889 100644
--- a/html/admin/js/graphViewer/graph/abstractAdapter.js
+++ b/html/admin/js/graphViewer/graph/abstractAdapter.js
@@ -124,10 +124,10 @@ function AbstractAdapter(nodes, edges) {
source = findNode(data._from);
target = findNode(data._to);
if (!source) {
- throw "Unable to insert Edge, source node not existing " + edge._from;
+ throw "Unable to insert Edge, source node not existing " + data._from;
}
if (!target) {
- throw "Unable to insert Edge, target node not existing " + edge._to;
+ throw "Unable to insert Edge, target node not existing " + data._to;
}
edge.source = source;
edge.target = target;
@@ -323,9 +323,8 @@ function AbstractAdapter(nodes, edges) {
},
checkSizeOfInserted = function (inserted) {
- var buckets;
if (_.size(inserted) > childLimit) {
- buckets = reducer.bucketNodes(_.values(inserted), childLimit);
+ var buckets = reducer.bucketNodes(_.values(inserted), childLimit);
_.each(buckets, function(b) {
if (b.length > 1) {
var ids = _.map(b, function(n) {
diff --git a/html/admin/js/graphViewer/graph/arangoAdapter.js b/html/admin/js/graphViewer/graph/arangoAdapter.js
index 0f0338e741..a6b42e5084 100644
--- a/html/admin/js/graphViewer/graph/arangoAdapter.js
+++ b/html/admin/js/graphViewer/graph/arangoAdapter.js
@@ -367,7 +367,7 @@ function ArangoAdapter(nodes, edges, config) {
processData: false,
success: function() {
absAdapter.removeEdgesForNode(nodeToRemove);
- permanentlyRemoveEdgesOfNode(nodeToRemove._id);
+ permanentlyRemoveEdgesOfNode(nodeToRemove._id);
absAdapter.removeNode(nodeToRemove);
if (callback !== undefined && _.isFunction(callback)) {
callback();
diff --git a/html/admin/js/graphViewer/jasmine_test/specAdapter/abstractAdapterSpec.js b/html/admin/js/graphViewer/jasmine_test/specAdapter/abstractAdapterSpec.js
new file mode 100644
index 0000000000..de4cd85294
--- /dev/null
+++ b/html/admin/js/graphViewer/jasmine_test/specAdapter/abstractAdapterSpec.js
@@ -0,0 +1,725 @@
+/*jslint indent: 2, nomen: true, maxlen: 100, white: true plusplus: true */
+/*global beforeEach, afterEach */
+/*global describe, it, expect, jasmine */
+/*global runs, spyOn, waitsFor, waits */
+/*global window, eb, loadFixtures, document */
+/*global $, _, d3*/
+/*global describeInterface*/
+/*global AbstractAdapter*/
+
+////////////////////////////////////////////////////////////////////////////////
+/// @brief Graph functionality
+///
+/// @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 Michael Hackstein
+/// @author Copyright 2011-2013, triAGENS GmbH, Cologne, Germany
+////////////////////////////////////////////////////////////////////////////////
+
+
+(function () {
+ "use strict";
+
+ describe('Abstract Adapter', function () {
+
+ var nodes, edges,
+
+ getCommunityNodes = function() {
+ return _.filter(nodes, function(n) {
+ return String(n._id).match(/^\*community/);
+ });
+ },
+
+ getCommunityNodesIds = function() {
+ return _.pluck(getCommunityNodes(), "_id");
+ },
+
+ nodeWithID = function(id) {
+ return $.grep(nodes, function(e){
+ return e._id === id;
+ })[0];
+ },
+ edgeWithSourceAndTargetId = function(sourceId, targetId) {
+ return $.grep(edges, function(e){
+ return e.source._id === sourceId
+ && e.target._id === targetId;
+ })[0];
+ },
+ existNode = function(id) {
+ var node = nodeWithID(id);
+ expect(node).toBeDefined();
+ expect(node._id).toEqual(id);
+ },
+
+ notExistNode = function(id) {
+ var node = nodeWithID(id);
+ expect(node).toBeUndefined();
+ },
+
+ existEdge = function(source, target) {
+ var edge = edgeWithSourceAndTargetId(source, target);
+ expect(edge).toBeDefined();
+ expect(edge.source._id).toEqual(source);
+ expect(edge.target._id).toEqual(target);
+ },
+
+ notExistEdge = function(source, target) {
+ var edge = edgeWithSourceAndTargetId(source, target);
+ expect(edge).toBeUndefined();
+ },
+
+ existNodes = function(ids) {
+ _.each(ids, existNode);
+ },
+
+ notExistNodes = function(ids) {
+ _.each(ids, notExistNode);
+ };
+
+
+ beforeEach(function() {
+ nodes = [];
+ edges = [];
+ });
+
+ describe('setup process', function() {
+
+ it('should throw an error if nodes are not given', function() {
+ expect(
+ function() {
+ var t = new AbstractAdapter();
+ }
+ ).toThrow("The nodes have to be given.");
+ });
+
+ it('should throw an error if edges are not given', function() {
+ expect(
+ function() {
+ var t = new AbstractAdapter([]);
+ }
+ ).toThrow("The edges have to be given.");
+ });
+
+ it('should not throw an error if setup correctly', function() {
+ expect(
+ function() {
+ var t = new AbstractAdapter([], []);
+ }
+ ).not.toThrow();
+ });
+
+ });
+
+
+ describe('checking the interface', function() {
+ var testee;
+
+ beforeEach(function() {
+ testee = new AbstractAdapter([], []);
+ this.addMatchers({
+ toHaveFunction: function(func, argCounter) {
+ var obj = this.actual;
+ this.message = function(){
+ return testee.constructor.name
+ + " should react to function "
+ + func
+ + " with at least "
+ + argCounter
+ + " arguments.";
+ };
+ if (typeof(obj[func]) !== "function") {
+ return false;
+ }
+ if (obj[func].length < argCounter) {
+ return false;
+ }
+ return true;
+ }
+ });
+ });
+
+ it('should offer a function to set the width', function() {
+ expect(testee).toHaveFunction("setWidth", 1);
+ });
+
+ it('should offer a function to set the height', function() {
+ expect(testee).toHaveFunction("setHeight", 1);
+ });
+
+ it('should offer a function to insert a node', function() {
+ expect(testee).toHaveFunction("insertNode", 1);
+ });
+
+ it('should offer a function to insert an edge', function() {
+ expect(testee).toHaveFunction("insertEdge", 1);
+ });
+
+ it('should offer a function to remove a node', function() {
+ expect(testee).toHaveFunction("removeNode", 1);
+ });
+
+ it('should offer a function to remove an edge', function() {
+ expect(testee).toHaveFunction("removeEdge", 1);
+ });
+
+ it('should offer a function to remove edges for a given node', function() {
+ expect(testee).toHaveFunction("removeEdgesForNode", 1);
+ });
+
+ it('should offer a function to expand a community', function() {
+ expect(testee).toHaveFunction("expandCommunity", 1);
+ });
+
+ it('should offer a function to set the node limit', function() {
+ expect(testee).toHaveFunction("setNodeLimit", 1);
+ });
+
+ it('should offer a function to set the child limit', function() {
+ expect(testee).toHaveFunction("setChildLimit", 1);
+ });
+
+ it('should offer a function to check the amount of freshly inserted nodes', function() {
+ expect(testee).toHaveFunction("checkSizeOfInserted", 1);
+ });
+
+ it('should offer a function to check the overall amount of nodes', function() {
+ expect(testee).toHaveFunction("checkNodeLimit", 1);
+ });
+ });
+
+ describe('checking nodes', function() {
+
+ var adapter;
+
+ beforeEach(function() {
+ adapter = new AbstractAdapter(nodes, []);
+ });
+
+ it('should be possible to insert a node', function() {
+ var newNode = {_id: 1};
+ adapter.insertNode(newNode);
+ existNode(1);
+ expect(nodes.length).toEqual(1);
+ });
+
+ it('should not add the same node twice', function() {
+ var newNode = {_id: 1};
+ adapter.insertNode(newNode);
+ adapter.insertNode(newNode);
+ existNode(1);
+ expect(nodes.length).toEqual(1);
+ });
+
+ it('should add x and y coordinates', function() {
+ var newNode = {_id: 1};
+ adapter.insertNode(newNode);
+ this.addMatchers({
+ toHaveCorrectCoordinates: function() {
+ var list = this.actual,
+ evil;
+ _.each(list, function(n) {
+ if (isNaN(n.x) || isNaN(n.y)) {
+ evil = n;
+ }
+ });
+ this.message = function() {
+ return "Expected " + JSON.stringify(evil) + " to contain Numbers as X and Y.";
+ };
+ return evil === undefined;
+ }
+ });
+ expect(nodes).toHaveCorrectCoordinates();
+ });
+
+ it('should set in- and outbound counters', function() {
+ var newNode = adapter.insertNode({_id: 1});
+ expect(newNode._outboundCounter).toEqual(0);
+ expect(newNode._inboundCounter).toEqual(0);
+ });
+
+ it('should set the x coordinate close to the center', function() {
+ var width = 200,
+ newNode;
+ adapter.setWidth(width);
+ newNode = adapter.insertNode({_id: 1});
+ expect(newNode.x).toBeGreaterThan(width / 4);
+ expect(newNode.x).toBeLessThan(3 * width / 4);
+ });
+
+ it('should set the y coordinate close to the center', function() {
+ var height = 200,
+ newNode;
+ adapter.setHeight(height);
+ newNode = adapter.insertNode({_id: 1});
+ expect(newNode.y).toBeGreaterThan(height / 4);
+ expect(newNode.y).toBeLessThan(3 * height / 4);
+ });
+
+ it('should be able to delete a node', function() {
+ var toDelete = {_id: 1},
+ nodeToDelete = adapter.insertNode(toDelete);
+ adapter.removeNode(nodeToDelete);
+
+ notExistNode(1);
+ expect(nodes.length).toEqual(0);
+ });
+
+ });
+
+ describe('checking edges', function() {
+
+ var adapter,
+ source,
+ target,
+ sourceid,
+ targetid;
+
+ beforeEach(function() {
+ adapter = new AbstractAdapter(nodes, edges);
+ source = adapter.insertNode({_id: 1});
+ target = adapter.insertNode({_id: 2});
+ sourceid = source._id;
+ targetid = target._id;
+ });
+
+ it('should be able to insert an edge', function() {
+ adapter.insertEdge({
+ _id: "1-2",
+ _from: sourceid,
+ _to: targetid
+ });
+ existEdge(sourceid, targetid);
+ expect(edges.length).toEqual(1);
+ });
+
+ it('should not insert the same edge twice', function() {
+ var toInsert = {
+ _id: "1-2",
+ _from: sourceid,
+ _to: targetid
+ };
+ adapter.insertEdge(toInsert);
+ adapter.insertEdge(toInsert);
+ existEdge(sourceid, targetid);
+ expect(edges.length).toEqual(1);
+ });
+
+ it('should throw an error if an edge is inserted with illeagal source', function() {
+ expect(
+ function() {
+ adapter.insertEdge({
+ _id: "1-3",
+ _from: 3,
+ _to: targetid
+ });
+ }
+ ).toThrow("Unable to insert Edge, source node not existing 3");
+
+ notExistEdge(3, targetid);
+ expect(edges.length).toEqual(0);
+ });
+
+ it('should throw an error if an edge is inserted with illeagal target', function() {
+ expect(
+ function() {
+ adapter.insertEdge({
+ _id: "1-3",
+ _from: sourceid,
+ _to: 3
+ });
+ }
+ ).toThrow("Unable to insert Edge, target node not existing 3");
+ notExistEdge(sourceid, 3);
+ expect(edges.length).toEqual(0);
+ });
+
+ it('should change the in- and outbound counters accordingly', function() {
+ var toInsert = {
+ _id: "1-2",
+ _from: sourceid,
+ _to: targetid
+ };
+ adapter.insertEdge(toInsert);
+ expect(source._outboundCounter).toEqual(1);
+ expect(source._inboundCounter).toEqual(0);
+ expect(target._outboundCounter).toEqual(0);
+ expect(target._inboundCounter).toEqual(1);
+ });
+
+ it('should be able to delete an edge', function() {
+ var toDelete = {
+ _id: "1-2",
+ _from: sourceid,
+ _to: targetid
+ },
+ edgeToDel = adapter.insertEdge(toDelete);
+ adapter.removeEdge(edgeToDel);
+
+ notExistEdge(sourceid, targetid);
+ expect(edges.length).toEqual(0);
+ });
+
+ it('should be able to remove all edges of a node', function() {
+ adapter.insertNode({_id: 3});
+ adapter.insertEdge({
+ _id: "3-1",
+ _from: 3,
+ _to: sourceid // This is nodes[0]
+ });
+ var edgeToKeep = adapter.insertEdge({
+ _id: "2-3",
+ _from: targetid, // This is nodes[1]
+ _to: 3
+ });
+
+ adapter.removeEdgesForNode(source);
+
+ existEdge(2, 3);
+ notExistEdge(1, 2);
+ notExistEdge(3, 1);
+ expect(edges.length).toEqual(1);
+ expect(edges[0]).toEqual(edgeToKeep);
+ });
+
+ it('should maintain in- and outboundcounter '
+ + 'when removing all edges of a node', function() {
+ var thirdNode = adapter.insertNode({_id: 3});
+ adapter.insertEdge({
+ _id: "3-1",
+ _from: 3,
+ _to: sourceid // This is nodes[0]
+ });
+ adapter.insertEdge({
+ _id: "2-3",
+ _from: targetid, // This is nodes[1]
+ _to: 3
+ });
+
+ adapter.removeEdgesForNode(source);
+ expect(nodes.length).toEqual(3);
+ existNode(1);
+ existNode(2);
+ existNode(3);
+ expect(source._inboundCounter).toEqual(0);
+ expect(source._outboundCounter).toEqual(0);
+ expect(target._inboundCounter).toEqual(0);
+ expect(target._outboundCounter).toEqual(1);
+ expect(thirdNode._inboundCounter).toEqual(1);
+ expect(thirdNode._outboundCounter).toEqual(0);
+ });
+
+ });
+
+ describe('checking communities', function() {
+
+ var adapter, mockReducer;
+
+ beforeEach(function() {
+ mockReducer = {};
+ mockReducer.getCommunity = function() {};
+ mockReducer.bucketNodes = function() {};
+ spyOn(window, "NodeReducer").andCallFake(function(v, e) {
+ return {
+ getCommunity: function(limit, focus) {
+ if (focus !== undefined) {
+ return mockReducer.getCommunity(limit, focus);
+ }
+ return mockReducer.getCommunity(limit);
+ },
+ bucketNodes: function(toSort, numBuckets) {
+ return mockReducer.bucketNodes(toSort, numBuckets);
+ }
+ };
+ });
+ adapter = new AbstractAdapter(nodes, edges);
+ });
+
+ it('should not take any action if no limit is set', function() {
+ spyOn(mockReducer, "getCommunity");
+ adapter.insertNode({_id: 1});
+ adapter.insertNode({_id: 2});
+ adapter.insertNode({_id: 3});
+ adapter.insertNode({_id: 4});
+ adapter.insertNode({_id: 5});
+ adapter.checkNodeLimit();
+ expect(mockReducer.getCommunity).wasNotCalled();
+ });
+
+ it('should take a given focus into account', function() {
+ var n1, limit;
+ spyOn(mockReducer, "getCommunity").andCallFake(function() {
+ return [2, 4];
+ });
+ limit = 2;
+ adapter.setNodeLimit(limit);
+ n1 = adapter.insertNode({_id: 1});
+ adapter.insertNode({_id: 2});
+ adapter.insertNode({_id: 3});
+ adapter.insertNode({_id: 4});
+ adapter.insertNode({_id: 5});
+ adapter.checkNodeLimit(n1);
+ expect(mockReducer.getCommunity).toHaveBeenCalledWith(limit, n1);
+ });
+
+ it('should create a community if too many nodes are added', function() {
+ var n1, n2, commId;
+ spyOn(mockReducer, "getCommunity").andCallFake(function() {
+ return [1, 2];
+ });
+ adapter.setNodeLimit(2);
+ n1 = adapter.insertNode({_id: 1});
+ n2 = adapter.insertNode({_id: 2});
+ adapter.insertNode({_id: 3});
+ adapter.checkNodeLimit();
+ expect(mockReducer.getCommunity).wasCalledWith(2);
+ expect(getCommunityNodesIds().length).toEqual(1);
+ notExistNode([1, 2]);
+ existNode(3);
+ });
+
+ it('should create a community if limit is set to small', function() {
+ var n1, n2, commId;
+ spyOn(mockReducer, "getCommunity").andCallFake(function() {
+ return [1, 2];
+ });
+ n1 = adapter.insertNode({_id: 1});
+ n2 = adapter.insertNode({_id: 2});
+ adapter.insertNode({_id: 3});
+ adapter.setNodeLimit(2);
+ expect(mockReducer.getCommunity).wasCalledWith(2);
+ expect(getCommunityNodesIds().length).toEqual(1);
+ notExistNode([1, 2]);
+ existNode(3);
+ });
+
+ it('should connect edges to communities', function() {
+ var n1, n2, comm, e1, e2, e3;
+ spyOn(mockReducer, "getCommunity").andCallFake(function() {
+ return [1, 2];
+ });
+ n1 = adapter.insertNode({_id: 1});
+ n2 = adapter.insertNode({_id: 2});
+ adapter.insertNode({_id: 3});
+ e1 = adapter.insertEdge({
+ _id: "1-2",
+ _from: 1,
+ _to: 2
+ });
+ e2 = adapter.insertEdge({
+ _id: "2-3",
+ _from: 2,
+ _to: 3
+ });
+ e3 = adapter.insertEdge({
+ _id: "3-1",
+ _from: 3,
+ _to: 1
+ });
+ adapter.setNodeLimit(2);
+
+ comm = getCommunityNodes()[0];
+ notExistEdge(1, 2);
+ expect(e2.source).toEqual(comm);
+ expect(e3.target).toEqual(comm);
+ });
+
+ describe('if a community allready exists', function() {
+
+ var n1, n2, n3, n4,
+ e1, e2, e3, comm;
+
+ beforeEach(function() {
+ mockReducer.getCommunity = function() {
+ return [1, 2];
+ };
+ n1 = adapter.insertNode({_id: 1});
+ n2 = adapter.insertNode({_id: 2});
+ n3 = adapter.insertNode({_id: 3});
+ n4 = adapter.insertNode({_id: 4});
+ e1 = adapter.insertEdge({
+ _id: "1-2",
+ _from: 1,
+ _to: 2
+ });
+ e2 = adapter.insertEdge({
+ _id: "2-3",
+ _from: 2,
+ _to: 3
+ });
+ e3 = adapter.insertEdge({
+ _id: "3-1",
+ _from: 3,
+ _to: 1
+ });
+
+ adapter.setNodeLimit(3);
+ comm = getCommunityNodes()[0];
+ });
+
+ it('should be able to expand the community', function() {
+ adapter.setNodeLimit(10);
+ adapter.expandCommunity(comm);
+
+ expect(getCommunityNodes().length).toEqual(0);
+ expect(nodes.length).toEqual(4);
+ expect(edges.length).toEqual(3);
+ existEdge(1, 2);
+ existEdge(2, 3);
+ existEdge(3, 1);
+ existNodes([1,2,3,4]);
+ });
+
+ it('should collapse another community if limit is to small', function() {
+ spyOn(mockReducer, "getCommunity").andCallFake(function() {
+ return [3, 4];
+ });
+ adapter.expandCommunity(comm);
+ expect(getCommunityNodes().length).toEqual(1);
+ var comm2 = getCommunityNodes()[0];
+ expect(comm).not.toEqual(comm2);
+ expect(mockReducer.getCommunity).wasCalled();
+ expect(nodes.length).toEqual(3);
+ existNodes([1, 2]);
+ notExistNodes([3, 4]);
+ });
+
+ it('should collapse another community if limit is further reduced', function() {
+ spyOn(mockReducer, "getCommunity").andCallFake(function() {
+ return [3, 4];
+ });
+ adapter.setNodeLimit(2);
+ expect(getCommunityNodes().length).toEqual(2);
+ var comm2 = getCommunityNodes()[1];
+ expect(comm).not.toEqual(comm2);
+ expect(mockReducer.getCommunity).wasCalled();
+ expect(nodes.length).toEqual(2);
+ notExistNodes([1, 2, 3, 4]);
+ });
+
+ });
+
+ });
+
+ describe('checking many child nodes', function() {
+
+ var adapter, mockReducer;
+
+ beforeEach(function() {
+ mockReducer = {};
+ mockReducer.getCommunity = function() {};
+ mockReducer.bucketNodes = function() {};
+ spyOn(window, "NodeReducer").andCallFake(function(v, e) {
+ return {
+ getCommunity: function(limit, focus) {
+ if (focus !== undefined) {
+ return mockReducer.getCommunity(limit, focus);
+ }
+ return mockReducer.getCommunity(limit);
+ },
+ bucketNodes: function(toSort, numBuckets) {
+ return mockReducer.bucketNodes(toSort, numBuckets);
+ }
+ };
+ });
+ adapter = new AbstractAdapter(nodes, edges);
+ });
+
+ it('should not take any action if the limit is high enough', function() {
+ adapter.setChildLimit(5);
+ spyOn(mockReducer, "bucketNodes");
+
+
+ var n1, n2, n3, n4, n5,
+ inserted = {};
+ n1 = adapter.insertNode({_id: 1 });
+ n2 = adapter.insertNode({_id: 2 });
+ n3 = adapter.insertNode({_id: 3 });
+ n4 = adapter.insertNode({_id: 4 });
+ n5 = adapter.insertNode({_id: 5 });
+ _.each(nodes, function(n) {
+ inserted[n._id] = n;
+ });
+ adapter.checkSizeOfInserted(inserted);
+ expect(mockReducer.bucketNodes).wasNotCalled();
+ });
+
+ it('should bucket nodes if limit is to small', function() {
+ var n1, n2, n3, n4, n5,
+ inserted = [],
+ limit = 2;
+ spyOn(mockReducer, "bucketNodes").andCallFake(function() {
+ return [
+ [n1, n2],
+ [n3, n4, n5]
+ ];
+ });
+ adapter.setChildLimit(limit);
+ n1 = adapter.insertNode({_id: 1 });
+ n2 = adapter.insertNode({_id: 2 });
+ n3 = adapter.insertNode({_id: 3 });
+ n4 = adapter.insertNode({_id: 4 });
+ n5 = adapter.insertNode({_id: 5 });
+ _.each(nodes, function(n) {
+ inserted.push(n);
+ });
+ adapter.checkSizeOfInserted(inserted);
+
+ expect(mockReducer.bucketNodes).wasCalledWith(inserted, limit);
+
+ expect(nodes.length).toEqual(2);
+ expect(getCommunityNodes().length).toEqual(2);
+ notExistNodes([1, 2, 3, 4, 5]);
+ });
+
+ it('should not display single nodes as buckets', function() {
+ var n1, n2, n3, n4, n5,
+ inserted = [],
+ limit = 3;
+ spyOn(mockReducer, "bucketNodes").andCallFake(function() {
+ return [
+ [n1],
+ [n3, n4, n5],
+ [n2]
+ ];
+ });
+ adapter.setChildLimit(limit);
+ n1 = adapter.insertNode({_id: 1 });
+ n2 = adapter.insertNode({_id: 2 });
+ n3 = adapter.insertNode({_id: 3 });
+ n4 = adapter.insertNode({_id: 4 });
+ n5 = adapter.insertNode({_id: 5 });
+ _.each(nodes, function(n) {
+ inserted.push(n);
+ });
+ adapter.checkSizeOfInserted(inserted);
+
+ expect(mockReducer.bucketNodes).wasCalledWith(inserted, limit);
+
+ expect(nodes.length).toEqual(3);
+ expect(getCommunityNodes().length).toEqual(1);
+ notExistNodes([3, 4, 5]);
+ existNodes([1, 2]);
+ });
+
+ });
+
+ });
+}());
diff --git a/html/admin/js/graphViewer/jasmine_test/specAdapter/foxxAdapterSpec.js b/html/admin/js/graphViewer/jasmine_test/specAdapter/foxxAdapterSpec.js
index 7b84161502..0878471864 100644
--- a/html/admin/js/graphViewer/jasmine_test/specAdapter/foxxAdapterSpec.js
+++ b/html/admin/js/graphViewer/jasmine_test/specAdapter/foxxAdapterSpec.js
@@ -5,7 +5,7 @@
/*global window, eb, loadFixtures, document */
/*global $, _, d3*/
/*global describeInterface*/
-/*global ArangoAdapter*/
+/*global FoxxAdapter*/
////////////////////////////////////////////////////////////////////////////////
/// @brief Graph functionality
@@ -40,19 +40,16 @@
describe('Foxx Adapter', function () {
- describeInterface(new FoxxAdapter([], [], {
- nodeCollection: "",
- edgeCollection: ""
- }));
+ describeInterface(new FoxxAdapter([], [], "foxx/route"));
+
+ describeIntegeration(new FoxxAdapter([], [], "foxx/route"));
var adapter,
nodes,
edges,
arangodb = "http://localhost:8529",
nodesCollection,
- altNodesCollection,
edgesCollection,
- altEdgesCollection,
mockCollection,
callbackCheck,
checkCallbackFunction = function() {
@@ -163,11 +160,6 @@
beforeEach(function() {
nodes = [];
edges = [];
- mockCollection = {};
- nodesCollection = "TestNodes321";
- edgesCollection = "TestEdges321";
- altNodesCollection = "TestNodes654";
- altEdgesCollection = "TestEdges654";
this.addMatchers({
toHaveCorrectCoordinates: function() {
@@ -193,7 +185,7 @@
it('should throw an error if no nodes are given', function() {
expect(
function() {
- var t = new ArangoAdapter();
+ var t = new FoxxAdapter();
}
).toThrow("The nodes have to be given.");
});
@@ -201,90 +193,61 @@
it('should throw an error if no edges are given', function() {
expect(
function() {
- var t = new ArangoAdapter([]);
+ var t = new FoxxAdapter([]);
}
).toThrow("The edges have to be given.");
});
- it('should throw an error if no nodeCollection is given', function() {
+ it('should throw an error if no route is given', function() {
expect(
function() {
- var t = new ArangoAdapter([], [], {
+ var t = new FoxxAdapter([], [], {
edgeCollection: ""
});
}
- ).toThrow("The nodeCollection has to be given.");
+ ).toThrow("The route has to be given.");
});
-
- it('should throw an error if no edgeCollection is given', function() {
- expect(
- function() {
- var t = new ArangoAdapter([], [], {
- nodeCollection: ""
- });
- }
- ).toThrow("The edgeCollection has to be given.");
- });
-
- it('should not throw an error if everything is given', function() {
- expect(
- function() {
- var t = new ArangoAdapter([], [], {
- nodeCollection: "",
- edgeCollection: ""
- });
- }
- ).not.toThrow();
- });
-
- it('should automatically determine the host of not given', function() {
- var adapter = new ArangoAdapter(
+
+ it('should automatically determine the host of relative route is given', function() {
+ var route = "foxx/route"
+ adapter = new FoxxAdapter(
nodes,
edges,
- {
- nodeCollection: nodesCollection,
- edgeCollection: edgesCollection,
- width: 100,
- height: 40
- }
+ route
),
args,
host;
spyOn($, "ajax");
adapter.createNode({}, function() {});
args = $.ajax.mostRecentCall.args[0];
- host = window.location.protocol + "//" + window.location.host;
+ host = window.location.protocol + "//" + window.location.host + "/" + route;
expect(args.url).toContain(host);
});
it('should create a nodeReducer instance', function() {
spyOn(window, "NodeReducer");
- var adapter = new ArangoAdapter(
+ var adapter = new FoxxAdapter(
nodes,
edges,
- {
- nodeCollection: nodesCollection,
- edgeCollection: edgesCollection,
- width: 100,
- height: 40
- }
+ "foxx/route"
);
expect(window.NodeReducer).wasCalledWith(nodes, edges);
});
describe('setup correctly', function() {
- var traversalQuery,
- filterQuery,
- childrenQuery,
+ var edgeRoute,
+ nodeRoute,
+ queryRoute,
loadGraph,
requests;
beforeEach(function() {
var self = this,
- host = window.location.protocol + "//" + window.location.host,
- apibase = host + "/_api/",
- apiCursor = apibase + 'cursor';
+ route = "foxx/route"
+ host = window.location.protocol + "//"
+ + window.location.host + "/"
+ + route;
self.fakeReducerRequest = function() {};
self.fakeReducerBucketRequest = function() {};
spyOn(window, "NodeReducer").andCallFake(function(v, e) {
@@ -300,73 +263,23 @@
}
};
});
- adapter = new ArangoAdapter(
+ adapter = new FoxxAdapter(
nodes,
edges,
- {
- nodeCollection: nodesCollection,
- edgeCollection: edgesCollection,
- width: 100,
- height: 40
- }
+ route
);
- traversalQuery = function(id, nods, edgs, undirected) {
- var dir;
- if (undirected === true) {
- dir = "any";
- } else {
- dir = "outbound";
- }
- return JSON.stringify({
- query: "RETURN TRAVERSAL(@@nodes, @@edges, @id, @dir,"
- + " {strategy: \"depthfirst\",maxDepth: 1,paths: true})",
- bindVars: {
- id: id,
- "@nodes": nods,
- dir: dir,
- "@edges": edgs
- }
- });
- };
- filterQuery = function(v, nods, edgs, undirected) {
- var dir;
- if (undirected === true) {
- dir = "any";
- } else {
- dir = "outbound";
- }
- return JSON.stringify({
- query: "FOR n IN @@nodes FILTER n.id == @value"
- + " RETURN TRAVERSAL(@@nodes, @@edges, n._id, @dir,"
- + " {strategy: \"depthfirst\",maxDepth: 1,paths: true})",
- bindVars: {
- value: v,
- "@nodes": nods,
- dir: dir,
- "@edges": edgs
- }
- });
- };
- childrenQuery = function(id, nods, edgs) {
- return JSON.stringify({
- query: "FOR u IN @@nodes FILTER u._id == @id"
- + " LET g = ( FOR l in @@edges FILTER l._from == u._id RETURN 1 )"
- + " RETURN length(g)",
- bindVars: {
- id: id,
- "@nodes": nods,
- "@edges": edgs
- }
- });
- };
- loadGraph = function(vars) {
- var nid = vars.id,
- ncol = vars["@nodes"],
- ecol = vars["@edges"],
- res = [],
- inner = [],
- first = {},
- node1 = readNode(ncol, nid);
+ edgeRoute = host + "/edges";
+ nodeRoute = host + "/nodes";
+ queryRoute = host + "/query";
+
+ loadGraph = function(data) {
+ var res = [],
+ nid,
+ ncol = nodesCollection,
+ ecol = edgesCollection,
+ inner = [],
+ first = {},
+ node1 = readNode(ncol, nid);
res.push(inner);
first.vertex = node1;
first.path = {
@@ -386,10 +299,10 @@
requests = {};
- requests.cursor = function(data) {
+ requests.query = function(data) {
return {
type: 'POST',
- url: apiCursor,
+ url: queryRoute,
data: data,
contentType: 'application/json',
dataType: 'json',
@@ -398,98 +311,62 @@
processData: false
};
};
- requests.node = function(col) {
- var read = apibase + "document?collection=" + col,
- write = apibase + "document/",
- base = {
- cache: false,
- dataType: "json",
- contentType: "application/json",
- processData: false,
- success: jasmine.any(Function),
- error: jasmine.any(Function)
- };
+ requests.node = function() {
+ var base = {
+ cache: false,
+ dataType: "json",
+ contentType: "application/json",
+ processData: false,
+ success: jasmine.any(Function),
+ error: jasmine.any(Function)
+ };
return {
create: function(data) {
- return $.extend(base, {url: read, type: "POST", data: JSON.stringify(data)});
+ return $.extend(base, {url: nodeRoute, type: "POST", data: JSON.stringify(data)});
},
patch: function(id, data) {
- return $.extend(base, {url: write + id, type: "PUT", data: JSON.stringify(data)});
+ return $.extend(base, {url: nodeRoute + "/" + id, type: "PUT", data: JSON.stringify(data)});
},
del: function(id) {
- return $.extend(base, {url: write + id, type: "DELETE"});
+ return $.extend(base, {url: nodeRoute + "/" + id, type: "DELETE"});
}
};
};
requests.edge = function(col) {
- var create = apibase + "edge?collection=" + col,
- base = {
- cache: false,
- dataType: "json",
- contentType: "application/json",
- processData: false,
- success: jasmine.any(Function),
- error: jasmine.any(Function)
- };
+ var base = {
+ cache: false,
+ dataType: "json",
+ contentType: "application/json",
+ processData: false,
+ success: jasmine.any(Function),
+ error: jasmine.any(Function)
+ };
return {
create: function(from, to, data) {
+ data = $.extend(data, {_from: from, _to: to});
return $.extend(base, {
- url: create + "&from=" + from + "&to=" + to,
+ url: edgeRoute,
type: "POST",
data: JSON.stringify(data)
});
+ },
+ patch: function(id, data) {
+ return $.extend(base, {url: edgeRoute + "/" + id, type: "PUT", data: JSON.stringify(data)});
+ },
+ del: function(id) {
+ return $.extend(base, {url: edgeRoute + "/" + id, type: "DELETE"});
}
};
};
});
- it('should offer lists of available collections', function() {
- var collections = [],
- sys1 = {id: "1", name: "_sys1", status: 3, type: 2},
- sys2 = {id: "2", name: "_sys2", status: 2, type: 2},
- doc1 = {id: "3", name: "doc1", status: 3, type: 2},
- doc2 = {id: "4", name: "doc2", status: 2, type: 2},
- doc3 = {id: "5", name: "doc3", status: 3, type: 2},
- edge1 = {id: "6", name: "edge1", status: 3, type: 3},
- edge2 = {id: "7", name: "edge2", status: 2, type: 3};
-
- collections.push(sys1);
- collections.push(sys2);
- collections.push(doc1);
- collections.push(doc2);
- collections.push(doc3);
- collections.push(edge1);
- collections.push(edge2);
-
- spyOn($, "ajax").andCallFake(function(request) {
- request.success({collections: collections});
- });
-
- adapter.getCollections(function(docs, edge) {
- expect(docs).toContain("doc1");
- expect(docs).toContain("doc2");
- expect(docs).toContain("doc3");
-
- expect(docs.length).toEqual(3);
-
- expect(edge).toContain("edge1");
- expect(edge).toContain("edge2");
-
- expect(edge.length).toEqual(2);
- });
- });
-
- it('should be able to load a tree node from '
- + 'ArangoDB by internal _id attribute', function() {
+ it('should be able to load by internal _id attribute', function() {
var c0, c1, c2, c3, c4;
runs(function() {
spyOn($, "ajax").andCallFake(function(request) {
- var vars = JSON.parse(request.data).bindVars;
- if (vars !== undefined) {
- request.success({result: loadGraph(vars)});
- }
+ request.success({result: loadGraph(JSON.parse(request.data))});
});
c0 = insertNode(nodesCollection, 0);
@@ -504,7 +381,7 @@
insertEdge(edgesCollection, c0, c4);
callbackCheck = false;
- adapter.loadNodeFromTreeById(c0, checkCallbackFunction);
+ adapter.loadNode(c0, checkCallbackFunction);
});
waitsFor(function() {
diff --git a/html/admin/js/graphViewer/jasmine_test/specAdapter/interfaceSpec.js b/html/admin/js/graphViewer/jasmine_test/specAdapter/interfaceSpec.js
index 299302a30f..1b41efa18d 100644
--- a/html/admin/js/graphViewer/jasmine_test/specAdapter/interfaceSpec.js
+++ b/html/admin/js/graphViewer/jasmine_test/specAdapter/interfaceSpec.js
@@ -1,5 +1,5 @@
/*jslint indent: 2, nomen: true, maxlen: 100, white: true plusplus: true */
-/*global it, expect */
+/*global it, expect, describe*/
////////////////////////////////////////////////////////////////////////////////
@@ -33,6 +33,7 @@
var describeInterface = function (testee) {
"use strict";
+ describe('checking the interface', function() {
it('should comply to the Adapter Interface', function() {
this.addMatchers({
toHaveFunction: function(func, argCounter) {
@@ -69,7 +70,13 @@ var describeInterface = function (testee) {
expect(testee).toHaveFunction("setNodeLimit", 2);
expect(testee).toHaveFunction("setChildLimit", 1);
expect(testee).toHaveFunction("expandCommunity", 2);
-
});
+ });
+
};
+
+var describeIntegeration = function(testee) {
+ "use strict";
+
+};