mirror of https://gitee.com/bigwinds/arangodb
GraphViewer: Added a further abstraction layer for the adapters, makes it much easier to write adapters for different sources like FOXX
This commit is contained in:
parent
fb33638b91
commit
f719a32251
|
@ -124,10 +124,10 @@ function AbstractAdapter(nodes, edges) {
|
||||||
source = findNode(data._from);
|
source = findNode(data._from);
|
||||||
target = findNode(data._to);
|
target = findNode(data._to);
|
||||||
if (!source) {
|
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) {
|
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.source = source;
|
||||||
edge.target = target;
|
edge.target = target;
|
||||||
|
@ -323,9 +323,8 @@ function AbstractAdapter(nodes, edges) {
|
||||||
},
|
},
|
||||||
|
|
||||||
checkSizeOfInserted = function (inserted) {
|
checkSizeOfInserted = function (inserted) {
|
||||||
var buckets;
|
|
||||||
if (_.size(inserted) > childLimit) {
|
if (_.size(inserted) > childLimit) {
|
||||||
buckets = reducer.bucketNodes(_.values(inserted), childLimit);
|
var buckets = reducer.bucketNodes(_.values(inserted), childLimit);
|
||||||
_.each(buckets, function(b) {
|
_.each(buckets, function(b) {
|
||||||
if (b.length > 1) {
|
if (b.length > 1) {
|
||||||
var ids = _.map(b, function(n) {
|
var ids = _.map(b, function(n) {
|
||||||
|
|
|
@ -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]);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
}());
|
|
@ -5,7 +5,7 @@
|
||||||
/*global window, eb, loadFixtures, document */
|
/*global window, eb, loadFixtures, document */
|
||||||
/*global $, _, d3*/
|
/*global $, _, d3*/
|
||||||
/*global describeInterface*/
|
/*global describeInterface*/
|
||||||
/*global ArangoAdapter*/
|
/*global FoxxAdapter*/
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief Graph functionality
|
/// @brief Graph functionality
|
||||||
|
@ -40,19 +40,16 @@
|
||||||
|
|
||||||
describe('Foxx Adapter', function () {
|
describe('Foxx Adapter', function () {
|
||||||
|
|
||||||
describeInterface(new FoxxAdapter([], [], {
|
describeInterface(new FoxxAdapter([], [], "foxx/route"));
|
||||||
nodeCollection: "",
|
|
||||||
edgeCollection: ""
|
describeIntegeration(new FoxxAdapter([], [], "foxx/route"));
|
||||||
}));
|
|
||||||
|
|
||||||
var adapter,
|
var adapter,
|
||||||
nodes,
|
nodes,
|
||||||
edges,
|
edges,
|
||||||
arangodb = "http://localhost:8529",
|
arangodb = "http://localhost:8529",
|
||||||
nodesCollection,
|
nodesCollection,
|
||||||
altNodesCollection,
|
|
||||||
edgesCollection,
|
edgesCollection,
|
||||||
altEdgesCollection,
|
|
||||||
mockCollection,
|
mockCollection,
|
||||||
callbackCheck,
|
callbackCheck,
|
||||||
checkCallbackFunction = function() {
|
checkCallbackFunction = function() {
|
||||||
|
@ -163,11 +160,6 @@
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
nodes = [];
|
nodes = [];
|
||||||
edges = [];
|
edges = [];
|
||||||
mockCollection = {};
|
|
||||||
nodesCollection = "TestNodes321";
|
|
||||||
edgesCollection = "TestEdges321";
|
|
||||||
altNodesCollection = "TestNodes654";
|
|
||||||
altEdgesCollection = "TestEdges654";
|
|
||||||
|
|
||||||
this.addMatchers({
|
this.addMatchers({
|
||||||
toHaveCorrectCoordinates: function() {
|
toHaveCorrectCoordinates: function() {
|
||||||
|
@ -193,7 +185,7 @@
|
||||||
it('should throw an error if no nodes are given', function() {
|
it('should throw an error if no nodes are given', function() {
|
||||||
expect(
|
expect(
|
||||||
function() {
|
function() {
|
||||||
var t = new ArangoAdapter();
|
var t = new FoxxAdapter();
|
||||||
}
|
}
|
||||||
).toThrow("The nodes have to be given.");
|
).toThrow("The nodes have to be given.");
|
||||||
});
|
});
|
||||||
|
@ -201,90 +193,61 @@
|
||||||
it('should throw an error if no edges are given', function() {
|
it('should throw an error if no edges are given', function() {
|
||||||
expect(
|
expect(
|
||||||
function() {
|
function() {
|
||||||
var t = new ArangoAdapter([]);
|
var t = new FoxxAdapter([]);
|
||||||
}
|
}
|
||||||
).toThrow("The edges have to be given.");
|
).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(
|
expect(
|
||||||
function() {
|
function() {
|
||||||
var t = new ArangoAdapter([], [], {
|
var t = new FoxxAdapter([], [], {
|
||||||
edgeCollection: ""
|
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() {
|
it('should automatically determine the host of relative route is given', function() {
|
||||||
expect(
|
var route = "foxx/route"
|
||||||
function() {
|
adapter = new FoxxAdapter(
|
||||||
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(
|
|
||||||
nodes,
|
nodes,
|
||||||
edges,
|
edges,
|
||||||
{
|
route
|
||||||
nodeCollection: nodesCollection,
|
|
||||||
edgeCollection: edgesCollection,
|
|
||||||
width: 100,
|
|
||||||
height: 40
|
|
||||||
}
|
|
||||||
),
|
),
|
||||||
args,
|
args,
|
||||||
host;
|
host;
|
||||||
spyOn($, "ajax");
|
spyOn($, "ajax");
|
||||||
adapter.createNode({}, function() {});
|
adapter.createNode({}, function() {});
|
||||||
args = $.ajax.mostRecentCall.args[0];
|
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);
|
expect(args.url).toContain(host);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should create a nodeReducer instance', function() {
|
it('should create a nodeReducer instance', function() {
|
||||||
spyOn(window, "NodeReducer");
|
spyOn(window, "NodeReducer");
|
||||||
var adapter = new ArangoAdapter(
|
var adapter = new FoxxAdapter(
|
||||||
nodes,
|
nodes,
|
||||||
edges,
|
edges,
|
||||||
{
|
"foxx/route"
|
||||||
nodeCollection: nodesCollection,
|
|
||||||
edgeCollection: edgesCollection,
|
|
||||||
width: 100,
|
|
||||||
height: 40
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
expect(window.NodeReducer).wasCalledWith(nodes, edges);
|
expect(window.NodeReducer).wasCalledWith(nodes, edges);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('setup correctly', function() {
|
describe('setup correctly', function() {
|
||||||
|
|
||||||
var traversalQuery,
|
var edgeRoute,
|
||||||
filterQuery,
|
nodeRoute,
|
||||||
childrenQuery,
|
queryRoute,
|
||||||
loadGraph,
|
loadGraph,
|
||||||
requests;
|
requests;
|
||||||
|
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
var self = this,
|
var self = this,
|
||||||
host = window.location.protocol + "//" + window.location.host,
|
route = "foxx/route"
|
||||||
apibase = host + "/_api/",
|
host = window.location.protocol + "//"
|
||||||
apiCursor = apibase + 'cursor';
|
+ window.location.host + "/"
|
||||||
|
+ route;
|
||||||
self.fakeReducerRequest = function() {};
|
self.fakeReducerRequest = function() {};
|
||||||
self.fakeReducerBucketRequest = function() {};
|
self.fakeReducerBucketRequest = function() {};
|
||||||
spyOn(window, "NodeReducer").andCallFake(function(v, e) {
|
spyOn(window, "NodeReducer").andCallFake(function(v, e) {
|
||||||
|
@ -300,73 +263,23 @@
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
adapter = new ArangoAdapter(
|
adapter = new FoxxAdapter(
|
||||||
nodes,
|
nodes,
|
||||||
edges,
|
edges,
|
||||||
{
|
route
|
||||||
nodeCollection: nodesCollection,
|
|
||||||
edgeCollection: edgesCollection,
|
|
||||||
width: 100,
|
|
||||||
height: 40
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
traversalQuery = function(id, nods, edgs, undirected) {
|
edgeRoute = host + "/edges";
|
||||||
var dir;
|
nodeRoute = host + "/nodes";
|
||||||
if (undirected === true) {
|
queryRoute = host + "/query";
|
||||||
dir = "any";
|
|
||||||
} else {
|
loadGraph = function(data) {
|
||||||
dir = "outbound";
|
var res = [],
|
||||||
}
|
nid,
|
||||||
return JSON.stringify({
|
ncol = nodesCollection,
|
||||||
query: "RETURN TRAVERSAL(@@nodes, @@edges, @id, @dir,"
|
ecol = edgesCollection,
|
||||||
+ " {strategy: \"depthfirst\",maxDepth: 1,paths: true})",
|
inner = [],
|
||||||
bindVars: {
|
first = {},
|
||||||
id: id,
|
node1 = readNode(ncol, nid);
|
||||||
"@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);
|
|
||||||
res.push(inner);
|
res.push(inner);
|
||||||
first.vertex = node1;
|
first.vertex = node1;
|
||||||
first.path = {
|
first.path = {
|
||||||
|
@ -386,10 +299,10 @@
|
||||||
|
|
||||||
|
|
||||||
requests = {};
|
requests = {};
|
||||||
requests.cursor = function(data) {
|
requests.query = function(data) {
|
||||||
return {
|
return {
|
||||||
type: 'POST',
|
type: 'POST',
|
||||||
url: apiCursor,
|
url: queryRoute,
|
||||||
data: data,
|
data: data,
|
||||||
contentType: 'application/json',
|
contentType: 'application/json',
|
||||||
dataType: 'json',
|
dataType: 'json',
|
||||||
|
@ -398,98 +311,62 @@
|
||||||
processData: false
|
processData: false
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
requests.node = function(col) {
|
requests.node = function() {
|
||||||
var read = apibase + "document?collection=" + col,
|
var base = {
|
||||||
write = apibase + "document/",
|
cache: false,
|
||||||
base = {
|
dataType: "json",
|
||||||
cache: false,
|
contentType: "application/json",
|
||||||
dataType: "json",
|
processData: false,
|
||||||
contentType: "application/json",
|
success: jasmine.any(Function),
|
||||||
processData: false,
|
error: jasmine.any(Function)
|
||||||
success: jasmine.any(Function),
|
};
|
||||||
error: jasmine.any(Function)
|
|
||||||
};
|
|
||||||
return {
|
return {
|
||||||
create: function(data) {
|
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) {
|
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) {
|
del: function(id) {
|
||||||
return $.extend(base, {url: write + id, type: "DELETE"});
|
return $.extend(base, {url: nodeRoute + "/" + id, type: "DELETE"});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
requests.edge = function(col) {
|
requests.edge = function(col) {
|
||||||
var create = apibase + "edge?collection=" + col,
|
var base = {
|
||||||
base = {
|
cache: false,
|
||||||
cache: false,
|
dataType: "json",
|
||||||
dataType: "json",
|
contentType: "application/json",
|
||||||
contentType: "application/json",
|
processData: false,
|
||||||
processData: false,
|
success: jasmine.any(Function),
|
||||||
success: jasmine.any(Function),
|
error: jasmine.any(Function)
|
||||||
error: jasmine.any(Function)
|
};
|
||||||
};
|
|
||||||
return {
|
return {
|
||||||
create: function(from, to, data) {
|
create: function(from, to, data) {
|
||||||
|
data = $.extend(data, {_from: from, _to: to});
|
||||||
return $.extend(base, {
|
return $.extend(base, {
|
||||||
url: create + "&from=" + from + "&to=" + to,
|
url: edgeRoute,
|
||||||
type: "POST",
|
type: "POST",
|
||||||
data: JSON.stringify(data)
|
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() {
|
it('should be able to load by internal _id attribute', 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() {
|
|
||||||
|
|
||||||
var c0, c1, c2, c3, c4;
|
var c0, c1, c2, c3, c4;
|
||||||
|
|
||||||
runs(function() {
|
runs(function() {
|
||||||
spyOn($, "ajax").andCallFake(function(request) {
|
spyOn($, "ajax").andCallFake(function(request) {
|
||||||
var vars = JSON.parse(request.data).bindVars;
|
request.success({result: loadGraph(JSON.parse(request.data))});
|
||||||
if (vars !== undefined) {
|
|
||||||
request.success({result: loadGraph(vars)});
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
c0 = insertNode(nodesCollection, 0);
|
c0 = insertNode(nodesCollection, 0);
|
||||||
|
@ -504,7 +381,7 @@
|
||||||
insertEdge(edgesCollection, c0, c4);
|
insertEdge(edgesCollection, c0, c4);
|
||||||
|
|
||||||
callbackCheck = false;
|
callbackCheck = false;
|
||||||
adapter.loadNodeFromTreeById(c0, checkCallbackFunction);
|
adapter.loadNode(c0, checkCallbackFunction);
|
||||||
});
|
});
|
||||||
|
|
||||||
waitsFor(function() {
|
waitsFor(function() {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*jslint indent: 2, nomen: true, maxlen: 100, white: true plusplus: true */
|
/*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) {
|
var describeInterface = function (testee) {
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
|
describe('checking the interface', function() {
|
||||||
it('should comply to the Adapter Interface', function() {
|
it('should comply to the Adapter Interface', function() {
|
||||||
this.addMatchers({
|
this.addMatchers({
|
||||||
toHaveFunction: function(func, argCounter) {
|
toHaveFunction: function(func, argCounter) {
|
||||||
|
@ -69,7 +70,13 @@ var describeInterface = function (testee) {
|
||||||
expect(testee).toHaveFunction("setNodeLimit", 2);
|
expect(testee).toHaveFunction("setNodeLimit", 2);
|
||||||
expect(testee).toHaveFunction("setChildLimit", 1);
|
expect(testee).toHaveFunction("setChildLimit", 1);
|
||||||
expect(testee).toHaveFunction("expandCommunity", 2);
|
expect(testee).toHaveFunction("expandCommunity", 2);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
var describeIntegeration = function(testee) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue