1
0
Fork 0
arangodb/js/apps/system/aardvark/test/specs/graphViewer/specNodeReducer/modularityJoinerSpec.js

2074 lines
83 KiB
JavaScript

/*jslint indent: 2, nomen: true, maxlen: 100, white: true plusplus: true */
/*global beforeEach, afterEach, jasmine */
/*global runs, waitsFor */
/*global describe, it, expect, spyOn */
/*global window, eb, loadFixtures, document, console*/
/*global $, _, d3*/
/*global helper*/
/*global ModularityJoiner, WebWorkerWrapper*/
////////////////////////////////////////////////////////////////////////////////
/// @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('Modularity Joiner', function () {
beforeEach(function() {
this.addMatchers({
toContainNodes: function(ns) {
var com = this.actual,
check = true;
this.message = function() {
return "Expected " + com + " to contain " + ns;
};
if (com.length !== ns.length) {
return false;
}
_.each(ns, function(n) {
if(!_.contains(com, n)) {
check = false;
}
});
return check;
}
});
});
describe('setup process', function() {
it('should not throw an error if mandatory information is given', function() {
expect(function() {
var s = new ModularityJoiner();
}).not.toThrow();
});
it('should be possible to create it as a worker', function() {
var called, created, error;
runs(function() {
error = "";
created = false;
called = false;
var n = [],
e = [],
cb = function(d) {
var data = d.data;
called = true;
if (data.cmd === "construct") {
created = data.result;
error = data.error;
}
},
w = new WebWorkerWrapper(ModularityJoiner, cb);
});
waitsFor(function() {
return called;
});
runs(function() {
expect(created).toBeTruthy();
expect(error).toBeUndefined();
});
});
});
describe('setup correctly', function() {
var joiner,
nodes,
edges,
testNetFour;
beforeEach(function () {
nodes = [];
edges = [];
joiner = new ModularityJoiner();
testNetFour = function() {
helper.insertSimpleNodes(nodes, ["0", "1", "2", "3"]);
edges.push(helper.createSimpleEdge(nodes, 0, 1));
edges.push(helper.createSimpleEdge(nodes, 0, 3));
edges.push(helper.createSimpleEdge(nodes, 1, 2));
edges.push(helper.createSimpleEdge(nodes, 2, 1));
edges.push(helper.createSimpleEdge(nodes, 2, 3));
edges.push(helper.createSimpleEdge(nodes, 3, 0));
edges.push(helper.createSimpleEdge(nodes, 3, 1));
edges.push(helper.createSimpleEdge(nodes, 3, 2));
joiner.insertEdge("0", "1");
joiner.insertEdge("0", "3");
joiner.insertEdge("1", "2");
joiner.insertEdge("2", "1");
joiner.insertEdge("2", "3");
joiner.insertEdge("3", "0");
joiner.insertEdge("3", "1");
joiner.insertEdge("3", "2");
};
});
describe('getters', function() {
beforeEach(function() {
this.addMatchers({
toBeGetter: function() {
var func = joiner[this.actual];
if (!func) {
this.message = function() {
return "Expected " + this.actual + " to be defined.";
};
return false;
}
if ("function" !== typeof func) {
this.message = function() {
return "Expected " + this.actual + " to be a function.";
};
return false;
}
if (func.length !== 0) {
this.message = function() {
return "Expected " + this.actual + " to be a getter function.";
};
return false;
}
return true;
}
});
});
it('should offer the adjacency matrix', function() {
expect("getAdjacencyMatrix").toBeGetter();
});
it('should offer the heap', function() {
expect("getHeap").toBeGetter();
});
it('should offer the delta qs', function() {
expect("getDQ").toBeGetter();
});
it('should offer the degrees', function() {
expect("getDegrees").toBeGetter();
});
it('should offer the best join', function() {
expect("getBest").toBeGetter();
});
it('should offer the community list', function() {
expect("getCommunities").toBeGetter();
});
});
describe('checking the interface', function() {
it('should offer a function to insert an edge', function() {
expect(joiner.insertEdge).toBeDefined();
expect(joiner.insertEdge).toEqual(jasmine.any(Function));
expect(joiner.insertEdge.length).toEqual(2);
});
it('should offer a function to delete an edge', function() {
expect(joiner.deleteEdge).toBeDefined();
expect(joiner.deleteEdge).toEqual(jasmine.any(Function));
expect(joiner.deleteEdge.length).toEqual(2);
});
it('should offer a setup function', function() {
expect(joiner.setup).toBeDefined();
expect(joiner.setup).toEqual(jasmine.any(Function));
expect(joiner.setup.length).toEqual(0);
});
it('should offer a function to join two communities', function() {
expect(joiner.joinCommunity).toBeDefined();
expect(joiner.joinCommunity).toEqual(jasmine.any(Function));
expect(joiner.joinCommunity.length).toEqual(1);
});
it('should offer a function to identify a far away community', function() {
expect(joiner.getCommunity).toBeDefined();
expect(joiner.getCommunity).toEqual(jasmine.any(Function));
expect(joiner.getCommunity.length).toEqual(2);
});
});
describe('after setup', function() {
beforeEach(function() {
testNetFour();
joiner.setup();
});
describe('the adjacency matrix', function() {
it('should be created', function() {
expect(joiner.getAdjacencyMatrix()).toEqual({
"0": {
"1": 1,
"3": 1
},
"1": {
"2": 1
},
"2": {
"1": 1,
"3": 1
},
"3": {
"0": 1,
"1": 1,
"2": 1
}
});
});
it('should react to insert edge', function() {
joiner.insertEdge("a", "b");
expect(joiner.getAdjacencyMatrix()).toEqual({
"0": {
"1": 1,
"3": 1
},
"1": {
"2": 1
},
"2": {
"1": 1,
"3": 1
},
"3": {
"0": 1,
"1": 1,
"2": 1
},
"a": {
"b": 1
}
});
});
it('should react to delete edge', function() {
joiner.deleteEdge("0", "1");
expect(joiner.getAdjacencyMatrix()).toEqual({
"0": {
"3": 1
},
"1": {
"2": 1
},
"2": {
"1": 1,
"3": 1
},
"3": {
"0": 1,
"1": 1,
"2": 1
}
});
});
it('should remove empty lines on delete', function() {
joiner.deleteEdge("1", "2");
expect(joiner.getAdjacencyMatrix()).toEqual({
"0": {
"1": 1,
"3": 1
},
"2": {
"1": 1,
"3": 1
},
"3": {
"0": 1,
"1": 1,
"2": 1
}
});
});
it('should only remove one of the edges on delete', function() {
joiner.insertEdge("1", "2");
joiner.insertEdge("1", "2");
joiner.deleteEdge("1", "2");
expect(joiner.getAdjacencyMatrix()).toEqual({
"0": {
"1": 1,
"3": 1
},
"1": {
"2": 2
},
"2": {
"1": 1,
"3": 1
},
"3": {
"0": 1,
"1": 1,
"2": 1
}
});
});
});
describe('the degrees', function() {
var m, one, two, three, initDeg;
beforeEach(function() {
m = edges.length;
one = 1 / m;
two = 2 / m;
three = 3 / m;
initDeg = {
"0": {
_in: one,
_out: two
},
"1": {
_in: three,
_out: one
},
"2": {
_in: two,
_out: two
},
"3": {
_in: two,
_out: three
}
};
});
it('should initialy be populated', function() {
expect(joiner.getDegrees()).toEqual(initDeg);
});
it('should be updated after a joining step', function() {
var toJoin = joiner.getBest(),
expected = {};
//Make sure we join the right ones:
expect(toJoin.sID).toEqual("0");
expect(toJoin.lID).toEqual("3");
expected["0"] = {
_in: initDeg["0"]._in + initDeg["3"]._in,
_out: initDeg["0"]._out + initDeg["3"]._out
};
expected["1"] = initDeg["1"];
expected["2"] = initDeg["2"];
joiner.joinCommunity(toJoin);
expect(joiner.getDegrees()).toEqual(expected);
});
});
describe('the deltaQ', function() {
var m, zero, one, two, three, initDQ,
cleanDQ = function(dq) {
_.each(dq, function(list, s) {
_.each(list, function(v, t) {
if (v < 0) {
delete list[t];
}
});
if (_.isEmpty(list)) {
delete dq[s];
}
});
};
beforeEach(function() {
m = edges.length;
zero = {
_in: 1/m,
_out: 2/m
};
one = {
_in: 3/m,
_out: 1/m
};
two = {
_in: 2/m,
_out: 2/m
};
three = {
_in: 2/m,
_out: 3/m
};
initDQ = {
"0": {
"1": 1/m - zero._in * one._out - zero._out * one._in,
"2": - zero._in * two._out - zero._out * two._in,
"3": 2/m - zero._in * three._out - zero._out * three._in
},
"1": {
"2": 2/m - one._in * two._out - one._out * two._in,
"3": 1/m - one._in * three._out - one._out * three._in
},
"2": {
"3": 2/m - two._in * three._out - two._out * three._in
}
};
cleanDQ(initDQ);
});
it('should initialy be populated', function() {
expect(joiner.getDQ()).toEqual(initDQ);
});
it('should be updated after a joining step', function() {
var toJoin = joiner.getBest(),
expected = {};
//Make sure we join the right ones:
expect(toJoin.sID).toEqual("0");
expect(toJoin.lID).toEqual("3");
expected["0"] = {};
if (initDQ["0"]["1"] && initDQ["1"]["3"]) {
expected["0"]["1"] = initDQ["0"]["1"] + initDQ["1"]["3"];
}
if (initDQ["0"]["2"] && initDQ["2"]["3"]) {
expected["0"]["2"] = initDQ["0"]["2"] + initDQ["2"]["3"];
}
expected["1"] = {};
if (initDQ["1"]["2"]) {
expected["1"]["2"] = initDQ["1"]["2"];
}
cleanDQ(expected);
joiner.joinCommunity(toJoin);
expect(joiner.getDQ()).toEqual(expected);
});
it('should be ordered', function() {
this.addMatchers({
toBeOrdered: function() {
var dQ = this.actual,
notFailed = true,
msg = "The pointers: ";
_.each(dQ, function(list, pointer) {
_.each(list, function(val, target) {
if (target < pointer) {
notFailed = false;
msg += pointer + " -> " + target + ", ";
}
});
});
this.message = function() {
return msg + "are not correct";
};
return notFailed;
}
});
var firstID = nodes.length;
helper.insertSimpleNodes(nodes, ["9", "20", "10", "99", "12"]);
edges.push(helper.createSimpleEdge(nodes, 0, firstID));
joiner.insertEdge("0", "9");
edges.push(helper.createSimpleEdge(nodes, firstID, firstID + 1));
joiner.insertEdge("9", "20");
edges.push(helper.createSimpleEdge(nodes, firstID + 1, firstID + 2));
joiner.insertEdge("20", "10");
edges.push(helper.createSimpleEdge(nodes, firstID + 2, firstID + 3));
joiner.insertEdge("10", "99");
edges.push(helper.createSimpleEdge(nodes, firstID + 3, firstID + 4));
joiner.insertEdge("99", "12");
edges.push(helper.createSimpleEdge(nodes, firstID + 4, firstID));
joiner.insertEdge("12", "9");
edges.push(helper.createSimpleEdge(nodes, firstID + 3, firstID));
joiner.insertEdge("99", "9");
joiner.setup();
expect(joiner.getDQ()).toBeOrdered();
});
});
describe('the heap', function() {
var m, zero, one, two, three;
beforeEach(function() {
m = edges.length;
zero = {
_in: 1/m,
_out: 2/m
};
one = {
_in: 3/m,
_out: 1/m
};
two = {
_in: 2/m,
_out: 2/m
};
three = {
_in: 2/m,
_out: 3/m
};
});
it('should initialy by populated', function() {
expect(joiner.getHeap()).toEqual({
"0": "3",
"1": "2",
"2": "3"
});
});
it('should return the largest value', function() {
expect(joiner.getBest()).toEqual({
sID: "0",
lID: "3",
val: 2/m - zero._in * three._out - zero._out * three._in
});
});
it('should be updated after a join step', function() {
var toJoin = joiner.getBest(),
expected = {};
//Make sure we join the right ones:
expect(toJoin.sID).toEqual("0");
expect(toJoin.lID).toEqual("3");
joiner.joinCommunity(toJoin);
expect(joiner.getHeap()).toEqual({
"1": "2"
});
});
it('should return the largest value after a join step', function() {
var toJoin = joiner.getBest(),
expected = {};
//Make sure we join the right ones:
expect(toJoin.sID).toEqual("0");
expect(toJoin.lID).toEqual("3");
joiner.joinCommunity(toJoin);
expect(joiner.getBest()).toEqual({
sID: "1",
lID: "2",
val: 2/m - one._in * two._out - one._out * two._in
});
});
it('should return null for best if the value is 0 or worse', function() {
var toJoin = joiner.getBest();
//Make sure we join the right ones:
expect(toJoin.sID).toEqual("0");
expect(toJoin.lID).toEqual("3");
joiner.joinCommunity(toJoin);
toJoin = joiner.getBest();
//Make sure we join the right ones:
expect(toJoin.sID).toEqual("1");
expect(toJoin.lID).toEqual("2");
joiner.joinCommunity(toJoin);
expect(joiner.getBest()).toBeNull();
});
});
describe('communities', function() {
it('should be able to get the communities', function() {
// No communities yet. Should not return single nodes.
expect(joiner.getCommunities()).toEqual({});
});
it('should be able to join two communities', function() {
var toJoin = joiner.getBest(),
joinVal = toJoin.val,
lowId = toJoin.sID,
highId = toJoin.lID,
expected = {},
m = edges.length,
zero = {
_in: 1/m,
_out: 2/m
},
one = {
_in: 3/m,
_out: 1/m
},
two = {
_in: 2/m,
_out: 2/m
},
three = {
_in: 2/m,
_out: 3/m
};
expected[lowId] = {
nodes: [
lowId,
highId
],
q: joinVal
};
expect(toJoin).toEqual({
sID: "0",
lID: "3",
val: 2/m - zero._in * three._out - zero._out * three._in
});
joiner.joinCommunity(toJoin);
expect(joiner.getCommunities()).toEqual(expected);
});
});
describe('checking multiple executions', function() {
it('should be able to recompute the joining', function() {
var best = joiner.getBest(),
first,
firstStringified,
second,
secondStringified;
best = joiner.getBest();
while (best !== null) {
joiner.joinCommunity(best);
best = joiner.getBest();
}
first = joiner.getCommunities();
firstStringified = JSON.stringify(first);
joiner.setup();
best = joiner.getBest();
while (best !== null) {
joiner.joinCommunity(best);
best = joiner.getBest();
}
second = joiner.getCommunities();
secondStringified = JSON.stringify(second);
expect(JSON.stringify(first)).toEqual(firstStringified);
expect(secondStringified).toEqual(firstStringified);
});
});
describe('checking massively insertion/deletion of edges', function() {
it('should be possible to keep a consistent adj. matrix', function() {
joiner.deleteEdge("0", "1");
joiner.deleteEdge("0", "3");
joiner.deleteEdge("1", "2");
joiner.deleteEdge("2", "1");
joiner.deleteEdge("2", "3");
joiner.deleteEdge("3", "0");
joiner.deleteEdge("3", "1");
joiner.deleteEdge("3", "2");
expect(joiner.getAdjacencyMatrix()).toEqual({});
});
});
});
describe('checking direct community identification', function() {
it('should be able to identify an obvious community', function() {
helper.insertSimpleNodes(nodes, ["0", "1", "2", "3", "4"]);
edges.push(helper.createSimpleEdge(nodes, 0, 1));
edges.push(helper.createSimpleEdge(nodes, 0, 2));
edges.push(helper.createSimpleEdge(nodes, 0, 3));
edges.push(helper.createSimpleEdge(nodes, 3, 4));
_.each(edges, function(e) {
joiner.insertEdge(e.source._id, e.target._id);
});
var com = joiner.getCommunity(3, nodes[4]._id);
expect(com).toContainNodes(["0", "1", "2"]);
});
it('should prefer cliques as a community over an equal sized other group', function() {
helper.insertSimpleNodes(nodes, ["0", "1", "2", "3", "4", "5", "6", "7", "8"]);
helper.insertClique(nodes, edges, [0, 1, 2, 3]);
edges.push(helper.createSimpleEdge(nodes, 4, 3));
edges.push(helper.createSimpleEdge(nodes, 4, 5));
edges.push(helper.createSimpleEdge(nodes, 5, 6));
edges.push(helper.createSimpleEdge(nodes, 5, 7));
edges.push(helper.createSimpleEdge(nodes, 5, 8));
_.each(edges, function(e) {
joiner.insertEdge(e.source._id, e.target._id);
});
var com = joiner.getCommunity(6, nodes[4]._id);
expect(com).toContainNodes(["0", "1", "2", "3"]);
});
it('should not return a close group if there is an alternative', function() {
helper.insertSimpleNodes(nodes, ["0", "1", "2", "3", "4", "5", "6", "7", "8"]);
helper.insertClique(nodes, edges, [0, 1, 2]);
helper.insertClique(nodes, edges, [3, 4, 5]);
helper.insertClique(nodes, edges, [6, 7, 8]);
edges.push(helper.createSimpleEdge(nodes, 3, 2));
edges.push(helper.createSimpleEdge(nodes, 5, 6));
_.each(edges, function(e) {
joiner.insertEdge(e.source._id, e.target._id);
});
var com = joiner.getCommunity(6, nodes[3]._id);
expect(com).toContainNodes(["6", "7", "8"]);
});
/*
it('should also take the best community if no focus is given', function() {
helper.insertSimpleNodes(nodes, ["0", "1", "2", "3", "4", "5", "6", "7"]);
helper.insertClique(nodes, edges, [0, 1, 2]);
edges.push(helper.createSimpleEdge(nodes, 3, 2));
edges.push(helper.createSimpleEdge(nodes, 3, 4));
edges.push(helper.createSimpleEdge(nodes, 4, 5));
edges.push(helper.createSimpleEdge(nodes, 5, 6));
edges.push(helper.createSimpleEdge(nodes, 5, 7));
_.each(edges, function(e) {
joiner.insertEdge(e.source._id, e.target._id);
});
var com = joiner.getCommunity(6);
expect(com).toContainNodes(["0", "1", "2"]);
});
*/
});
describe('checking the zachary karate club', function() {
beforeEach(function() {
// This is the Zachary Karate Club Network
helper.insertSimpleNodes(nodes, [
"0", // Just Temporary node, as the orig is counting from 1 instead of 0
"1","2","3","4","5","6","7","8","9","10",
"11","12","13","14","15","16","17","18","19","20",
"21","22","23","24","25","26","27","28","29","30",
"31","32","33","34"
]);
edges.push(helper.createSimpleEdge(nodes, 2, 1));
edges.push(helper.createSimpleEdge(nodes, 3, 1));
edges.push(helper.createSimpleEdge(nodes, 3, 2));
edges.push(helper.createSimpleEdge(nodes, 4, 1));
edges.push(helper.createSimpleEdge(nodes, 4, 2));
edges.push(helper.createSimpleEdge(nodes, 4, 3));
edges.push(helper.createSimpleEdge(nodes, 5, 1));
edges.push(helper.createSimpleEdge(nodes, 6, 1));
edges.push(helper.createSimpleEdge(nodes, 7, 1));
edges.push(helper.createSimpleEdge(nodes, 7, 5));
edges.push(helper.createSimpleEdge(nodes, 7, 6));
edges.push(helper.createSimpleEdge(nodes, 8, 1));
edges.push(helper.createSimpleEdge(nodes, 8, 2));
edges.push(helper.createSimpleEdge(nodes, 8, 3));
edges.push(helper.createSimpleEdge(nodes, 8, 4));
edges.push(helper.createSimpleEdge(nodes, 9, 1));
edges.push(helper.createSimpleEdge(nodes, 9, 3));
edges.push(helper.createSimpleEdge(nodes, 10, 3));
edges.push(helper.createSimpleEdge(nodes, 11, 1));
edges.push(helper.createSimpleEdge(nodes, 11, 5));
edges.push(helper.createSimpleEdge(nodes, 11, 6));
edges.push(helper.createSimpleEdge(nodes, 12, 1));
edges.push(helper.createSimpleEdge(nodes, 13, 1));
edges.push(helper.createSimpleEdge(nodes, 13, 4));
edges.push(helper.createSimpleEdge(nodes, 14, 1));
edges.push(helper.createSimpleEdge(nodes, 14, 2));
edges.push(helper.createSimpleEdge(nodes, 14, 3));
edges.push(helper.createSimpleEdge(nodes, 14, 4));
edges.push(helper.createSimpleEdge(nodes, 17, 6));
edges.push(helper.createSimpleEdge(nodes, 17, 7));
edges.push(helper.createSimpleEdge(nodes, 18, 1));
edges.push(helper.createSimpleEdge(nodes, 18, 2));
edges.push(helper.createSimpleEdge(nodes, 20, 1));
edges.push(helper.createSimpleEdge(nodes, 20, 2));
edges.push(helper.createSimpleEdge(nodes, 22, 1));
edges.push(helper.createSimpleEdge(nodes, 22, 2));
edges.push(helper.createSimpleEdge(nodes, 26, 24));
edges.push(helper.createSimpleEdge(nodes, 26, 25));
edges.push(helper.createSimpleEdge(nodes, 28, 3));
edges.push(helper.createSimpleEdge(nodes, 28, 24));
edges.push(helper.createSimpleEdge(nodes, 28, 25));
edges.push(helper.createSimpleEdge(nodes, 29, 3));
edges.push(helper.createSimpleEdge(nodes, 30, 24));
edges.push(helper.createSimpleEdge(nodes, 30, 27));
edges.push(helper.createSimpleEdge(nodes, 31, 2));
edges.push(helper.createSimpleEdge(nodes, 31, 9));
edges.push(helper.createSimpleEdge(nodes, 32, 1));
edges.push(helper.createSimpleEdge(nodes, 32, 25));
edges.push(helper.createSimpleEdge(nodes, 32, 26));
edges.push(helper.createSimpleEdge(nodes, 32, 29));
edges.push(helper.createSimpleEdge(nodes, 33, 3));
edges.push(helper.createSimpleEdge(nodes, 33, 9));
edges.push(helper.createSimpleEdge(nodes, 33, 15));
edges.push(helper.createSimpleEdge(nodes, 33, 16));
edges.push(helper.createSimpleEdge(nodes, 33, 19));
edges.push(helper.createSimpleEdge(nodes, 33, 21));
edges.push(helper.createSimpleEdge(nodes, 33, 23));
edges.push(helper.createSimpleEdge(nodes, 33, 24));
edges.push(helper.createSimpleEdge(nodes, 33, 30));
edges.push(helper.createSimpleEdge(nodes, 33, 31));
edges.push(helper.createSimpleEdge(nodes, 33, 32));
edges.push(helper.createSimpleEdge(nodes, 34, 9));
edges.push(helper.createSimpleEdge(nodes, 34, 10));
edges.push(helper.createSimpleEdge(nodes, 34, 14));
edges.push(helper.createSimpleEdge(nodes, 34, 15));
edges.push(helper.createSimpleEdge(nodes, 34, 16));
edges.push(helper.createSimpleEdge(nodes, 34, 19));
edges.push(helper.createSimpleEdge(nodes, 34, 20));
edges.push(helper.createSimpleEdge(nodes, 34, 21));
edges.push(helper.createSimpleEdge(nodes, 34, 23));
edges.push(helper.createSimpleEdge(nodes, 34, 24));
edges.push(helper.createSimpleEdge(nodes, 34, 27));
edges.push(helper.createSimpleEdge(nodes, 34, 28));
edges.push(helper.createSimpleEdge(nodes, 34, 29));
edges.push(helper.createSimpleEdge(nodes, 34, 30));
edges.push(helper.createSimpleEdge(nodes, 34, 31));
edges.push(helper.createSimpleEdge(nodes, 34, 32));
edges.push(helper.createSimpleEdge(nodes, 34, 33));
nodes.shift(1); //Remove the temporary node;
_.each(edges, function(e) {
joiner.insertEdge(e.source._id, e.target._id);
});
joiner.setup();
});
it('should never have duplicates in communities', function() {
this.addMatchers({
toNotContainDuplicates: function() {
var comms = this.actual,
duplicate = [],
found = {},
failed = false;
_.each(comms, function (v) {
_.each(v.nodes, function (i) {
if (found[i]) {
failed = true;
duplicate.push(i);
} else {
found[i] = true;
}
});
});
this.message = function() {
var outComms = comms;
_.each(outComms, function(o) {
o.nodes = _.filter(o.nodes, function(n) {
return _.contains(duplicate, n);
});
});
return "Found duplicate nodes [" + duplicate
+ "] in communities: " + JSON.stringify(outComms);
};
return !failed;
}
});
var best = joiner.getBest();
while (best !== null) {
joiner.joinCommunity(best);
best = joiner.getBest();
expect(joiner.getCommunities()).toNotContainDuplicates();
}
});
it('should be able to find communities', function() {
/////////////////////////////////////////////////////
/// correct acc to: NMCM09 //
/// Red: //
/// 21,23,24,19,27,16,30,33,34,29,15,9,31 //
/// White: //
/// 25, 26, 28, 32 //
/// Green: //
/// 5, 6, 7, 11, 17 //
/// Blue: //
/// 1, 2, 3, 4, 10, 14, 20, 22, 18, 13, 12 //
/////////////////////////////////////////////////////
this.addMatchers({
toContainKarateClubCommunities: function() {
var c1 = [
"10", "15", "16", "19", "21", "23",
"30", "33", "34"
].sort().join(),
c2 = ["1", "12", "13", "14", "18", "2", "20", "22", "3", "4", "8"].sort().join(),
c3 = ["11", "17", "5", "6", "7"].sort().join(),
c4 = ["24", "25", "26", "28", "29", "32"].sort().join(),
swap = ["9", "27", "31"],
comms = this.actual,
failed = false,
msg = "Found incorrect: ";
_.each(comms, function(o) {
var check = o.nodes;
_.each(swap, function (s) {
var index = _.indexOf(check, s);
if (index > -1) {
check = _.without(check, s);
swap = _.without(swap, s);
}
});
check = check.sort().join();
switch (check) {
case c1:
c1 = "";
break;
case c2:
c2 = "";
break;
case c3:
c3 = "";
break;
case c4:
c4 = "";
break;
default:
msg += "[" + check + "] ";
failed = true;
}
return;
});
this.message = function() {
var notFound = "";
if (c1 !== "") {
notFound += "[" + c1 + "] ";
}
if (c2 !== "") {
notFound += "[" + c2 + "] ";
}
if (c3 !== "") {
notFound += "[" + c3 + "] ";
}
if (c4 !== "") {
notFound += "[" + c4 + "] ";
}
if (swap.length > 0) {
notFound += "[" + swap.join() + "] ";
}
return msg + " and did not find: " + notFound;
};
return !failed;
}
});
var best = joiner.getBest();
while (best !== null) {
joiner.joinCommunity(best);
best = joiner.getBest();
}
expect(joiner.getCommunities()).toContainKarateClubCommunities();
});
});
describe('checking consistency after join', function() {
beforeEach(function() {
this.addMatchers({
toBeOrdered: function() {
var dQ = this.actual,
notFailed = true,
msg = "In dQ the pointers: ";
_.each(dQ, function(list, pointer) {
_.each(list, function(val, target) {
if (target < pointer) {
notFailed = false;
msg += pointer + " -> " + target + ", ";
}
});
});
this.message = function() {
return msg + "are not correct";
};
return notFailed;
},
toFulfillHeapConstraint: function(joined) {
var heap = this.actual.getHeap(),
high = joined.lID;
this.message = function() {
return "The heap " + _.keys(heap) + " should not contain " + high;
};
return _.isUndefined(heap[high]);
},
toFulfillDQConstraint: function(joined) {
var dQ = this.actual.getDQ(),
high = joined.lID;
this.message = function() {
return "The delta Q " + _.keys(dQ) + " should not contain " + high;
};
return _.isUndefined(dQ[high]);
},
toBeDefinedInHeapIffInDQ: function(testee) {
var id = this.actual,
dQ = testee.getDQ(),
heap = testee.getHeap();
if (_.isUndefined(dQ[id])) {
this.message = id + " is defined on heap but not on dQ";
return _.isUndefined(heap[id]);
}
this.message = id + " is defined on dQ but not on heap";
return !_.isUndefined(heap[id]);
},
toFulfillCommunityInclusionConstraint: function(joined) {
var comms = this.actual.getCommunities(),
low = joined.sID,
high = joined.lID;
if (_.isUndefined(comms[low])) {
this.message = function() {
return "The lower ID " + low + " is no pointer to a community";
};
return false;
}
this.message = function() {
return "The community " + comms[low].nodes + " should contain " + high;
};
return _.contains(comms[low].nodes, high);
},
toFulfillCommunityPointerConstraint: function() {
var comms = this.actual.getCommunities(),
notFailed = true,
msg = "In communities the pointers: ";
_.each(comms, function(list, pointer) {
var ns = list.nodes;
if (ns[0] !== pointer) {
notFailed = false;
msg += pointer + " -first-> " + ns[0] + ", ";
}
_.each(ns, function(id) {
if (id < pointer) {
notFailed = false;
msg += pointer + " -> " + id + ", ";
}
});
});
this.message = function () {
return msg + "are not correct";
};
return notFailed;
},
toNotContainAnyJoinedNode: function() {
var comms = this.actual.getCommunities(),
dQ = this.actual.getDQ(),
forbidden = [],
msg = "Nodes: ",
notFailed = true;
_.each(comms, function(list) {
var reducedList = list.nodes.slice();
reducedList.shift(1);
forbidden = forbidden.concat(reducedList);
});
_.each(forbidden, function (id) {
if (!_.isUndefined(dQ[id])) {
notFailed = false;
msg += id + ", ";
}
});
this.message = function() {
return msg + "should not be contained in dQ";
};
return notFailed;
},
toBeConsistent: function(joined) {
var testee = this.actual;
expect(testee).toFulfillDQConstraint(joined);
expect(testee).toFulfillHeapConstraint(joined);
expect(joined.sID).toBeDefinedInHeapIffInDQ(testee);
expect(testee).toFulfillCommunityInclusionConstraint(joined);
expect(testee).toNotContainAnyJoinedNode();
expect(testee).toFulfillCommunityPointerConstraint();
return true;
},
toContainALowerAndAHigherID: function() {
var toJoin = this.actual;
this.message = function() {
return toJoin.sID + " shold be lower than " + toJoin.lID;
};
return toJoin.sID < toJoin.lID;
}
});
});
it('for a larger network', function() {
var i, best,
step = 0,
nodeCount = 20;
helper.insertNSimpleNodes(nodes, nodeCount);
helper.insertClique(nodes, edges, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
for (i = 11; i < nodeCount; i++) {
edges.push(helper.createSimpleEdge(nodes, i - 1, i));
edges.push(helper.createSimpleEdge(nodes, i, i - 2));
}
joiner.setup();
best = joiner.getBest();
while (best !== null) {
expect(best).toContainALowerAndAHigherID();
joiner.joinCommunity(best);
expect(joiner).toBeConsistent(best, step);
best = joiner.getBest();
step++;
}
});
});
/*
describe('checking large networks', function() {
it('should be able to handle 1000 nodes', function() {
var start = (new Date()).getTime(),
i,
best,
nodeCount = 1000,
diff;
helper.insertNSimpleNodes(nodes, nodeCount);
helper.insertClique(nodes, edges, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
for (i = 11; i < nodeCount; i++) {
edges.push(helper.createSimpleEdge(nodes, i - 1, i));
edges.push(helper.createSimpleEdge(nodes, i, i - 2));
}
_.each(edges, function(e) {
joiner.insertEdge(e.source._id, e.target._id);
});
diff = (new Date()).getTime() - start;
console.log("Runtime Fill:", diff, "ms");
start = (new Date()).getTime();
joiner.setup();
diff = (new Date()).getTime() - start;
console.log("Runtime Setup:", diff, "ms");
start = (new Date()).getTime();
best = joiner.getBest();
while (best !== null) {
joiner.joinCommunity(best);
best = joiner.getBest();
}
diff = (new Date()).getTime() - start;
console.log("Runtime Compute:", diff, "ms");
});
// This is the max. number of nodes for the admin UI
// However the format is realy unlikely in the adminUI
it('should be able to handle 3000 nodes', function() {
var start = (new Date()).getTime(),
i, best, nodeCount = 3000, diff;
helper.insertNSimpleNodes(nodes, nodeCount);
helper.insertClique(nodes, edges, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
for (i = 11; i < nodeCount; i++) {
edges.push(helper.createSimpleEdge(nodes, i - 1, i));
edges.push(helper.createSimpleEdge(nodes, i, i - 2));
}
_.each(edges, function(e) {
joiner.insertEdge(e.source._id, e.target._id);
});
diff = (new Date()).getTime() - start;
console.log("Runtime Fill:", diff, "ms");
start = (new Date()).getTime();
joiner.setup();
diff = (new Date()).getTime() - start;
console.log("Runtime Setup:", diff, "ms");
start = (new Date()).getTime();
best = joiner.getBest();
while (best !== null) {
joiner.joinCommunity(best);
best = joiner.getBest();
}
diff = (new Date()).getTime() - start;
console.log("Runtime Compute:", diff, "ms");
});
// This is what we expect in the Admin UI
it('should be able to handle few large satelites', function() {
var start = (new Date()).getTime(),
i,
best,
diff,
s0 = helper.insertSatelite(nodes, edges, 0, 500),
s1 = helper.insertSatelite(nodes, edges, 1, 300),
s2 = helper.insertSatelite(nodes, edges, 2, 313),
s3 = helper.insertSatelite(nodes, edges, 3, 461),
s4 = helper.insertSatelite(nodes, edges, 4, 251),
s5 = helper.insertSatelite(nodes, edges, 5, 576),
s6 = helper.insertSatelite(nodes, edges, 6, 126),
s7 = helper.insertSatelite(nodes, edges, 7, 231),
s8 = helper.insertSatelite(nodes, edges, 8, 50),
s9 = helper.insertSatelite(nodes, edges, 9, 70),
s10 = helper.insertSatelite(nodes, edges, 10, 111);
edges.push(helper.createSimpleEdge(nodes, s0, s1));
edges.push(helper.createSimpleEdge(nodes, s0, s2));
edges.push(helper.createSimpleEdge(nodes, s0, s3));
edges.push(helper.createSimpleEdge(nodes, s0, s4));
edges.push(helper.createSimpleEdge(nodes, s1, s0));
edges.push(helper.createSimpleEdge(nodes, s1, s5));
edges.push(helper.createSimpleEdge(nodes, s1, s6));
edges.push(helper.createSimpleEdge(nodes, s2, s1));
edges.push(helper.createSimpleEdge(nodes, s3, s7));
edges.push(helper.createSimpleEdge(nodes, s3, s8));
edges.push(helper.createSimpleEdge(nodes, s4, s0));
edges.push(helper.createSimpleEdge(nodes, s4, s8));
edges.push(helper.createSimpleEdge(nodes, s4, s9));
edges.push(helper.createSimpleEdge(nodes, s5, s2));
edges.push(helper.createSimpleEdge(nodes, s5, s6));
edges.push(helper.createSimpleEdge(nodes, s5, s10));
edges.push(helper.createSimpleEdge(nodes, s6, s5));
edges.push(helper.createSimpleEdge(nodes, s7, s5));
edges.push(helper.createSimpleEdge(nodes, s7, s6));
edges.push(helper.createSimpleEdge(nodes, s8, s0));
edges.push(helper.createSimpleEdge(nodes, s8, s2));
edges.push(helper.createSimpleEdge(nodes, s8, s4));
edges.push(helper.createSimpleEdge(nodes, s8, s6));
edges.push(helper.createSimpleEdge(nodes, s9, s8));
edges.push(helper.createSimpleEdge(nodes, s9, s10));
edges.push(helper.createSimpleEdge(nodes, s10, s1));
edges.push(helper.createSimpleEdge(nodes, s10, s9));
_.each(edges, function(e) {
joiner.insertEdge(e.source._id, e.target._id);
});
diff = (new Date()).getTime() - start;
console.log("Runtime Fill:", diff, "ms");
start = (new Date()).getTime();
joiner.setup();
diff = (new Date()).getTime() - start;
console.log("Runtime Setup:", diff, "ms");
start = (new Date()).getTime();
best = joiner.getBest();
while (best !== null) {
joiner.joinCommunity(best);
best = joiner.getBest();
}
diff = (new Date()).getTime() - start;
console.log("Runtime Compute:", diff, "ms");
});
it('should be able to handle many small satelites', function() {
var start = (new Date()).getTime(),
i,
best,
diff,
// This test network has been randomly generated.
// Each Satelite center has 20-100 children
// And has an edge to 3 - 13 centers
s0 = helper.insertSatelite(nodes, edges, 0, 22),
s1 = helper.insertSatelite(nodes, edges, 1, 72),
s2 = helper.insertSatelite(nodes, edges, 2, 76),
s3 = helper.insertSatelite(nodes, edges, 3, 68),
s4 = helper.insertSatelite(nodes, edges, 4, 64),
s5 = helper.insertSatelite(nodes, edges, 5, 46),
s6 = helper.insertSatelite(nodes, edges, 6, 24),
s7 = helper.insertSatelite(nodes, edges, 7, 98),
s8 = helper.insertSatelite(nodes, edges, 8, 84),
s9 = helper.insertSatelite(nodes, edges, 9, 93),
s10 = helper.insertSatelite(nodes, edges, 10, 79),
s11 = helper.insertSatelite(nodes, edges, 11, 58),
s12 = helper.insertSatelite(nodes, edges, 12, 98),
s13 = helper.insertSatelite(nodes, edges, 13, 64),
s14 = helper.insertSatelite(nodes, edges, 14, 62),
s15 = helper.insertSatelite(nodes, edges, 15, 56),
s16 = helper.insertSatelite(nodes, edges, 16, 63),
s17 = helper.insertSatelite(nodes, edges, 17, 83),
s18 = helper.insertSatelite(nodes, edges, 18, 98),
s19 = helper.insertSatelite(nodes, edges, 19, 29),
s20 = helper.insertSatelite(nodes, edges, 20, 50),
s21 = helper.insertSatelite(nodes, edges, 21, 62),
s22 = helper.insertSatelite(nodes, edges, 22, 20),
s23 = helper.insertSatelite(nodes, edges, 23, 30),
s24 = helper.insertSatelite(nodes, edges, 24, 50),
s25 = helper.insertSatelite(nodes, edges, 25, 55),
s26 = helper.insertSatelite(nodes, edges, 26, 41),
s27 = helper.insertSatelite(nodes, edges, 27, 60),
s28 = helper.insertSatelite(nodes, edges, 28, 62),
s29 = helper.insertSatelite(nodes, edges, 29, 91),
s30 = helper.insertSatelite(nodes, edges, 30, 59),
s31 = helper.insertSatelite(nodes, edges, 31, 48),
s32 = helper.insertSatelite(nodes, edges, 32, 76),
s33 = helper.insertSatelite(nodes, edges, 33, 88),
s34 = helper.insertSatelite(nodes, edges, 34, 92),
s35 = helper.insertSatelite(nodes, edges, 35, 87),
s36 = helper.insertSatelite(nodes, edges, 36, 65),
s37 = helper.insertSatelite(nodes, edges, 37, 80),
s38 = helper.insertSatelite(nodes, edges, 38, 28),
s39 = helper.insertSatelite(nodes, edges, 39, 33),
s40 = helper.insertSatelite(nodes, edges, 40, 86),
s41 = helper.insertSatelite(nodes, edges, 41, 81),
s42 = helper.insertSatelite(nodes, edges, 42, 26),
s43 = helper.insertSatelite(nodes, edges, 43, 57),
s44 = helper.insertSatelite(nodes, edges, 44, 61),
s45 = helper.insertSatelite(nodes, edges, 45, 47),
s46 = helper.insertSatelite(nodes, edges, 46, 47),
s47 = helper.insertSatelite(nodes, edges, 47, 33);
edges.push(helper.createSimpleEdge(nodes, s0, s44));
edges.push(helper.createSimpleEdge(nodes, s0, s47));
edges.push(helper.createSimpleEdge(nodes, s0, s3));
edges.push(helper.createSimpleEdge(nodes, s0, s39));
edges.push(helper.createSimpleEdge(nodes, s0, s8));
edges.push(helper.createSimpleEdge(nodes, s0, s21));
edges.push(helper.createSimpleEdge(nodes, s1, s36));
edges.push(helper.createSimpleEdge(nodes, s1, s43));
edges.push(helper.createSimpleEdge(nodes, s1, s43));
edges.push(helper.createSimpleEdge(nodes, s1, s40));
edges.push(helper.createSimpleEdge(nodes, s1, s39));
edges.push(helper.createSimpleEdge(nodes, s1, s44));
edges.push(helper.createSimpleEdge(nodes, s2, s32));
edges.push(helper.createSimpleEdge(nodes, s2, s10));
edges.push(helper.createSimpleEdge(nodes, s2, s26));
edges.push(helper.createSimpleEdge(nodes, s2, s39));
edges.push(helper.createSimpleEdge(nodes, s2, s43));
edges.push(helper.createSimpleEdge(nodes, s2, s42));
edges.push(helper.createSimpleEdge(nodes, s2, s16));
edges.push(helper.createSimpleEdge(nodes, s2, s7));
edges.push(helper.createSimpleEdge(nodes, s2, s3));
edges.push(helper.createSimpleEdge(nodes, s3, s8));
edges.push(helper.createSimpleEdge(nodes, s3, s33));
edges.push(helper.createSimpleEdge(nodes, s3, s9));
edges.push(helper.createSimpleEdge(nodes, s3, s18));
edges.push(helper.createSimpleEdge(nodes, s3, s18));
edges.push(helper.createSimpleEdge(nodes, s3, s6));
edges.push(helper.createSimpleEdge(nodes, s3, s1));
edges.push(helper.createSimpleEdge(nodes, s4, s47));
edges.push(helper.createSimpleEdge(nodes, s4, s13));
edges.push(helper.createSimpleEdge(nodes, s4, s9));
edges.push(helper.createSimpleEdge(nodes, s4, s17));
edges.push(helper.createSimpleEdge(nodes, s4, s18));
edges.push(helper.createSimpleEdge(nodes, s4, s44));
edges.push(helper.createSimpleEdge(nodes, s4, s7));
edges.push(helper.createSimpleEdge(nodes, s5, s47));
edges.push(helper.createSimpleEdge(nodes, s5, s27));
edges.push(helper.createSimpleEdge(nodes, s5, s12));
edges.push(helper.createSimpleEdge(nodes, s5, s35));
edges.push(helper.createSimpleEdge(nodes, s5, s33));
edges.push(helper.createSimpleEdge(nodes, s5, s2));
edges.push(helper.createSimpleEdge(nodes, s5, s38));
edges.push(helper.createSimpleEdge(nodes, s5, s17));
edges.push(helper.createSimpleEdge(nodes, s5, s18));
edges.push(helper.createSimpleEdge(nodes, s5, s2));
edges.push(helper.createSimpleEdge(nodes, s5, s27));
edges.push(helper.createSimpleEdge(nodes, s5, s0));
edges.push(helper.createSimpleEdge(nodes, s6, s25));
edges.push(helper.createSimpleEdge(nodes, s6, s32));
edges.push(helper.createSimpleEdge(nodes, s6, s12));
edges.push(helper.createSimpleEdge(nodes, s6, s47));
edges.push(helper.createSimpleEdge(nodes, s6, s3));
edges.push(helper.createSimpleEdge(nodes, s7, s11));
edges.push(helper.createSimpleEdge(nodes, s7, s35));
edges.push(helper.createSimpleEdge(nodes, s7, s28));
edges.push(helper.createSimpleEdge(nodes, s7, s46));
edges.push(helper.createSimpleEdge(nodes, s7, s37));
edges.push(helper.createSimpleEdge(nodes, s7, s15));
edges.push(helper.createSimpleEdge(nodes, s7, s31));
edges.push(helper.createSimpleEdge(nodes, s7, s3));
edges.push(helper.createSimpleEdge(nodes, s8, s41));
edges.push(helper.createSimpleEdge(nodes, s8, s30));
edges.push(helper.createSimpleEdge(nodes, s8, s20));
edges.push(helper.createSimpleEdge(nodes, s8, s2));
edges.push(helper.createSimpleEdge(nodes, s8, s40));
edges.push(helper.createSimpleEdge(nodes, s9, s21));
edges.push(helper.createSimpleEdge(nodes, s9, s40));
edges.push(helper.createSimpleEdge(nodes, s9, s42));
edges.push(helper.createSimpleEdge(nodes, s9, s46));
edges.push(helper.createSimpleEdge(nodes, s9, s23));
edges.push(helper.createSimpleEdge(nodes, s9, s8));
edges.push(helper.createSimpleEdge(nodes, s9, s17));
edges.push(helper.createSimpleEdge(nodes, s10, s43));
edges.push(helper.createSimpleEdge(nodes, s10, s18));
edges.push(helper.createSimpleEdge(nodes, s10, s6));
edges.push(helper.createSimpleEdge(nodes, s11, s18));
edges.push(helper.createSimpleEdge(nodes, s11, s31));
edges.push(helper.createSimpleEdge(nodes, s11, s43));
edges.push(helper.createSimpleEdge(nodes, s11, s28));
edges.push(helper.createSimpleEdge(nodes, s11, s5));
edges.push(helper.createSimpleEdge(nodes, s11, s37));
edges.push(helper.createSimpleEdge(nodes, s12, s14));
edges.push(helper.createSimpleEdge(nodes, s12, s6));
edges.push(helper.createSimpleEdge(nodes, s12, s35));
edges.push(helper.createSimpleEdge(nodes, s12, s6));
edges.push(helper.createSimpleEdge(nodes, s12, s8));
edges.push(helper.createSimpleEdge(nodes, s12, s36));
edges.push(helper.createSimpleEdge(nodes, s13, s28));
edges.push(helper.createSimpleEdge(nodes, s13, s38));
edges.push(helper.createSimpleEdge(nodes, s13, s41));
edges.push(helper.createSimpleEdge(nodes, s14, s32));
edges.push(helper.createSimpleEdge(nodes, s14, s19));
edges.push(helper.createSimpleEdge(nodes, s14, s29));
edges.push(helper.createSimpleEdge(nodes, s14, s21));
edges.push(helper.createSimpleEdge(nodes, s14, s17));
edges.push(helper.createSimpleEdge(nodes, s14, s31));
edges.push(helper.createSimpleEdge(nodes, s15, s0));
edges.push(helper.createSimpleEdge(nodes, s15, s28));
edges.push(helper.createSimpleEdge(nodes, s15, s22));
edges.push(helper.createSimpleEdge(nodes, s15, s25));
edges.push(helper.createSimpleEdge(nodes, s15, s11));
edges.push(helper.createSimpleEdge(nodes, s15, s39));
edges.push(helper.createSimpleEdge(nodes, s16, s37));
edges.push(helper.createSimpleEdge(nodes, s16, s41));
edges.push(helper.createSimpleEdge(nodes, s16, s37));
edges.push(helper.createSimpleEdge(nodes, s16, s22));
edges.push(helper.createSimpleEdge(nodes, s16, s11));
edges.push(helper.createSimpleEdge(nodes, s16, s45));
edges.push(helper.createSimpleEdge(nodes, s16, s38));
edges.push(helper.createSimpleEdge(nodes, s17, s28));
edges.push(helper.createSimpleEdge(nodes, s17, s11));
edges.push(helper.createSimpleEdge(nodes, s17, s10));
edges.push(helper.createSimpleEdge(nodes, s17, s13));
edges.push(helper.createSimpleEdge(nodes, s17, s0));
edges.push(helper.createSimpleEdge(nodes, s17, s11));
edges.push(helper.createSimpleEdge(nodes, s17, s1));
edges.push(helper.createSimpleEdge(nodes, s17, s25));
edges.push(helper.createSimpleEdge(nodes, s18, s39));
edges.push(helper.createSimpleEdge(nodes, s18, s24));
edges.push(helper.createSimpleEdge(nodes, s18, s41));
edges.push(helper.createSimpleEdge(nodes, s18, s14));
edges.push(helper.createSimpleEdge(nodes, s18, s31));
edges.push(helper.createSimpleEdge(nodes, s19, s43));
edges.push(helper.createSimpleEdge(nodes, s19, s44));
edges.push(helper.createSimpleEdge(nodes, s19, s23));
edges.push(helper.createSimpleEdge(nodes, s19, s40));
edges.push(helper.createSimpleEdge(nodes, s19, s0));
edges.push(helper.createSimpleEdge(nodes, s19, s5));
edges.push(helper.createSimpleEdge(nodes, s20, s13));
edges.push(helper.createSimpleEdge(nodes, s20, s34));
edges.push(helper.createSimpleEdge(nodes, s20, s46));
edges.push(helper.createSimpleEdge(nodes, s20, s39));
edges.push(helper.createSimpleEdge(nodes, s20, s14));
edges.push(helper.createSimpleEdge(nodes, s20, s12));
edges.push(helper.createSimpleEdge(nodes, s20, s34));
edges.push(helper.createSimpleEdge(nodes, s20, s37));
edges.push(helper.createSimpleEdge(nodes, s20, s39));
edges.push(helper.createSimpleEdge(nodes, s21, s2));
edges.push(helper.createSimpleEdge(nodes, s21, s10));
edges.push(helper.createSimpleEdge(nodes, s21, s28));
edges.push(helper.createSimpleEdge(nodes, s21, s7));
edges.push(helper.createSimpleEdge(nodes, s21, s44));
edges.push(helper.createSimpleEdge(nodes, s21, s13));
edges.push(helper.createSimpleEdge(nodes, s21, s37));
edges.push(helper.createSimpleEdge(nodes, s22, s12));
edges.push(helper.createSimpleEdge(nodes, s22, s12));
edges.push(helper.createSimpleEdge(nodes, s22, s5));
edges.push(helper.createSimpleEdge(nodes, s22, s8));
edges.push(helper.createSimpleEdge(nodes, s22, s42));
edges.push(helper.createSimpleEdge(nodes, s22, s26));
edges.push(helper.createSimpleEdge(nodes, s22, s29));
edges.push(helper.createSimpleEdge(nodes, s22, s1));
edges.push(helper.createSimpleEdge(nodes, s22, s0));
edges.push(helper.createSimpleEdge(nodes, s22, s19));
edges.push(helper.createSimpleEdge(nodes, s23, s47));
edges.push(helper.createSimpleEdge(nodes, s23, s20));
edges.push(helper.createSimpleEdge(nodes, s23, s13));
edges.push(helper.createSimpleEdge(nodes, s23, s36));
edges.push(helper.createSimpleEdge(nodes, s24, s19));
edges.push(helper.createSimpleEdge(nodes, s24, s10));
edges.push(helper.createSimpleEdge(nodes, s24, s32));
edges.push(helper.createSimpleEdge(nodes, s24, s42));
edges.push(helper.createSimpleEdge(nodes, s24, s11));
edges.push(helper.createSimpleEdge(nodes, s24, s32));
edges.push(helper.createSimpleEdge(nodes, s24, s1));
edges.push(helper.createSimpleEdge(nodes, s24, s29));
edges.push(helper.createSimpleEdge(nodes, s24, s34));
edges.push(helper.createSimpleEdge(nodes, s25, s45));
edges.push(helper.createSimpleEdge(nodes, s25, s34));
edges.push(helper.createSimpleEdge(nodes, s25, s9));
edges.push(helper.createSimpleEdge(nodes, s25, s41));
edges.push(helper.createSimpleEdge(nodes, s26, s37));
edges.push(helper.createSimpleEdge(nodes, s26, s28));
edges.push(helper.createSimpleEdge(nodes, s26, s34));
edges.push(helper.createSimpleEdge(nodes, s26, s43));
edges.push(helper.createSimpleEdge(nodes, s26, s13));
edges.push(helper.createSimpleEdge(nodes, s26, s6));
edges.push(helper.createSimpleEdge(nodes, s27, s47));
edges.push(helper.createSimpleEdge(nodes, s27, s29));
edges.push(helper.createSimpleEdge(nodes, s27, s36));
edges.push(helper.createSimpleEdge(nodes, s27, s36));
edges.push(helper.createSimpleEdge(nodes, s27, s45));
edges.push(helper.createSimpleEdge(nodes, s27, s15));
edges.push(helper.createSimpleEdge(nodes, s28, s30));
edges.push(helper.createSimpleEdge(nodes, s28, s5));
edges.push(helper.createSimpleEdge(nodes, s28, s27));
edges.push(helper.createSimpleEdge(nodes, s28, s33));
edges.push(helper.createSimpleEdge(nodes, s28, s4));
edges.push(helper.createSimpleEdge(nodes, s28, s44));
edges.push(helper.createSimpleEdge(nodes, s28, s24));
edges.push(helper.createSimpleEdge(nodes, s28, s25));
edges.push(helper.createSimpleEdge(nodes, s29, s18));
edges.push(helper.createSimpleEdge(nodes, s29, s3));
edges.push(helper.createSimpleEdge(nodes, s29, s10));
edges.push(helper.createSimpleEdge(nodes, s29, s38));
edges.push(helper.createSimpleEdge(nodes, s29, s5));
edges.push(helper.createSimpleEdge(nodes, s29, s0));
edges.push(helper.createSimpleEdge(nodes, s29, s25));
edges.push(helper.createSimpleEdge(nodes, s29, s46));
edges.push(helper.createSimpleEdge(nodes, s30, s46));
edges.push(helper.createSimpleEdge(nodes, s30, s7));
edges.push(helper.createSimpleEdge(nodes, s30, s2));
edges.push(helper.createSimpleEdge(nodes, s30, s22));
edges.push(helper.createSimpleEdge(nodes, s30, s27));
edges.push(helper.createSimpleEdge(nodes, s30, s34));
edges.push(helper.createSimpleEdge(nodes, s30, s39));
edges.push(helper.createSimpleEdge(nodes, s30, s45));
edges.push(helper.createSimpleEdge(nodes, s31, s33));
edges.push(helper.createSimpleEdge(nodes, s31, s46));
edges.push(helper.createSimpleEdge(nodes, s31, s30));
edges.push(helper.createSimpleEdge(nodes, s31, s5));
edges.push(helper.createSimpleEdge(nodes, s31, s2));
edges.push(helper.createSimpleEdge(nodes, s31, s25));
edges.push(helper.createSimpleEdge(nodes, s31, s18));
edges.push(helper.createSimpleEdge(nodes, s31, s27));
edges.push(helper.createSimpleEdge(nodes, s31, s25));
edges.push(helper.createSimpleEdge(nodes, s32, s30));
edges.push(helper.createSimpleEdge(nodes, s32, s26));
edges.push(helper.createSimpleEdge(nodes, s32, s1));
edges.push(helper.createSimpleEdge(nodes, s32, s21));
edges.push(helper.createSimpleEdge(nodes, s32, s38));
edges.push(helper.createSimpleEdge(nodes, s32, s38));
edges.push(helper.createSimpleEdge(nodes, s32, s23));
edges.push(helper.createSimpleEdge(nodes, s33, s36));
edges.push(helper.createSimpleEdge(nodes, s33, s40));
edges.push(helper.createSimpleEdge(nodes, s33, s6));
edges.push(helper.createSimpleEdge(nodes, s34, s19));
edges.push(helper.createSimpleEdge(nodes, s34, s29));
edges.push(helper.createSimpleEdge(nodes, s34, s2));
edges.push(helper.createSimpleEdge(nodes, s34, s0));
edges.push(helper.createSimpleEdge(nodes, s34, s14));
edges.push(helper.createSimpleEdge(nodes, s34, s0));
edges.push(helper.createSimpleEdge(nodes, s34, s1));
edges.push(helper.createSimpleEdge(nodes, s34, s19));
edges.push(helper.createSimpleEdge(nodes, s34, s42));
edges.push(helper.createSimpleEdge(nodes, s34, s39));
edges.push(helper.createSimpleEdge(nodes, s34, s15));
edges.push(helper.createSimpleEdge(nodes, s34, s17));
edges.push(helper.createSimpleEdge(nodes, s35, s13));
edges.push(helper.createSimpleEdge(nodes, s35, s31));
edges.push(helper.createSimpleEdge(nodes, s35, s30));
edges.push(helper.createSimpleEdge(nodes, s35, s22));
edges.push(helper.createSimpleEdge(nodes, s35, s47));
edges.push(helper.createSimpleEdge(nodes, s35, s25));
edges.push(helper.createSimpleEdge(nodes, s36, s44));
edges.push(helper.createSimpleEdge(nodes, s36, s25));
edges.push(helper.createSimpleEdge(nodes, s36, s19));
edges.push(helper.createSimpleEdge(nodes, s36, s9));
edges.push(helper.createSimpleEdge(nodes, s36, s11));
edges.push(helper.createSimpleEdge(nodes, s36, s11));
edges.push(helper.createSimpleEdge(nodes, s36, s6));
edges.push(helper.createSimpleEdge(nodes, s36, s14));
edges.push(helper.createSimpleEdge(nodes, s36, s28));
edges.push(helper.createSimpleEdge(nodes, s36, s31));
edges.push(helper.createSimpleEdge(nodes, s37, s40));
edges.push(helper.createSimpleEdge(nodes, s37, s4));
edges.push(helper.createSimpleEdge(nodes, s37, s45));
edges.push(helper.createSimpleEdge(nodes, s37, s11));
edges.push(helper.createSimpleEdge(nodes, s37, s39));
edges.push(helper.createSimpleEdge(nodes, s37, s30));
edges.push(helper.createSimpleEdge(nodes, s37, s31));
edges.push(helper.createSimpleEdge(nodes, s37, s9));
edges.push(helper.createSimpleEdge(nodes, s37, s35));
edges.push(helper.createSimpleEdge(nodes, s37, s45));
edges.push(helper.createSimpleEdge(nodes, s37, s7));
edges.push(helper.createSimpleEdge(nodes, s37, s32));
edges.push(helper.createSimpleEdge(nodes, s38, s36));
edges.push(helper.createSimpleEdge(nodes, s38, s45));
edges.push(helper.createSimpleEdge(nodes, s38, s5));
edges.push(helper.createSimpleEdge(nodes, s38, s1));
edges.push(helper.createSimpleEdge(nodes, s39, s37));
edges.push(helper.createSimpleEdge(nodes, s39, s32));
edges.push(helper.createSimpleEdge(nodes, s39, s31));
edges.push(helper.createSimpleEdge(nodes, s39, s13));
edges.push(helper.createSimpleEdge(nodes, s39, s20));
edges.push(helper.createSimpleEdge(nodes, s39, s25));
edges.push(helper.createSimpleEdge(nodes, s39, s7));
edges.push(helper.createSimpleEdge(nodes, s39, s20));
edges.push(helper.createSimpleEdge(nodes, s39, s27));
edges.push(helper.createSimpleEdge(nodes, s39, s5));
edges.push(helper.createSimpleEdge(nodes, s39, s17));
edges.push(helper.createSimpleEdge(nodes, s39, s8));
edges.push(helper.createSimpleEdge(nodes, s40, s8));
edges.push(helper.createSimpleEdge(nodes, s40, s12));
edges.push(helper.createSimpleEdge(nodes, s40, s31));
edges.push(helper.createSimpleEdge(nodes, s40, s39));
edges.push(helper.createSimpleEdge(nodes, s40, s31));
edges.push(helper.createSimpleEdge(nodes, s40, s9));
edges.push(helper.createSimpleEdge(nodes, s41, s45));
edges.push(helper.createSimpleEdge(nodes, s41, s6));
edges.push(helper.createSimpleEdge(nodes, s41, s36));
edges.push(helper.createSimpleEdge(nodes, s41, s12));
edges.push(helper.createSimpleEdge(nodes, s41, s26));
edges.push(helper.createSimpleEdge(nodes, s41, s6));
edges.push(helper.createSimpleEdge(nodes, s41, s21));
edges.push(helper.createSimpleEdge(nodes, s41, s33));
edges.push(helper.createSimpleEdge(nodes, s42, s25));
edges.push(helper.createSimpleEdge(nodes, s42, s28));
edges.push(helper.createSimpleEdge(nodes, s42, s46));
edges.push(helper.createSimpleEdge(nodes, s42, s34));
edges.push(helper.createSimpleEdge(nodes, s42, s41));
edges.push(helper.createSimpleEdge(nodes, s42, s32));
edges.push(helper.createSimpleEdge(nodes, s42, s9));
edges.push(helper.createSimpleEdge(nodes, s43, s12));
edges.push(helper.createSimpleEdge(nodes, s43, s29));
edges.push(helper.createSimpleEdge(nodes, s43, s2));
edges.push(helper.createSimpleEdge(nodes, s43, s14));
edges.push(helper.createSimpleEdge(nodes, s43, s1));
edges.push(helper.createSimpleEdge(nodes, s43, s13));
edges.push(helper.createSimpleEdge(nodes, s43, s28));
edges.push(helper.createSimpleEdge(nodes, s43, s47));
edges.push(helper.createSimpleEdge(nodes, s43, s22));
edges.push(helper.createSimpleEdge(nodes, s43, s2));
edges.push(helper.createSimpleEdge(nodes, s43, s5));
edges.push(helper.createSimpleEdge(nodes, s44, s3));
edges.push(helper.createSimpleEdge(nodes, s44, s1));
edges.push(helper.createSimpleEdge(nodes, s44, s18));
edges.push(helper.createSimpleEdge(nodes, s44, s37));
edges.push(helper.createSimpleEdge(nodes, s44, s0));
edges.push(helper.createSimpleEdge(nodes, s44, s4));
edges.push(helper.createSimpleEdge(nodes, s44, s18));
edges.push(helper.createSimpleEdge(nodes, s44, s7));
edges.push(helper.createSimpleEdge(nodes, s44, s9));
edges.push(helper.createSimpleEdge(nodes, s44, s38));
edges.push(helper.createSimpleEdge(nodes, s44, s15));
edges.push(helper.createSimpleEdge(nodes, s45, s35));
edges.push(helper.createSimpleEdge(nodes, s45, s34));
edges.push(helper.createSimpleEdge(nodes, s45, s5));
edges.push(helper.createSimpleEdge(nodes, s46, s7));
edges.push(helper.createSimpleEdge(nodes, s46, s39));
edges.push(helper.createSimpleEdge(nodes, s46, s21));
edges.push(helper.createSimpleEdge(nodes, s46, s47));
edges.push(helper.createSimpleEdge(nodes, s46, s1));
edges.push(helper.createSimpleEdge(nodes, s46, s19));
edges.push(helper.createSimpleEdge(nodes, s46, s11));
edges.push(helper.createSimpleEdge(nodes, s47, s9));
edges.push(helper.createSimpleEdge(nodes, s47, s10));
edges.push(helper.createSimpleEdge(nodes, s47, s46));
edges.push(helper.createSimpleEdge(nodes, s47, s13));
edges.push(helper.createSimpleEdge(nodes, s47, s21));
edges.push(helper.createSimpleEdge(nodes, s47, s19));
edges.push(helper.createSimpleEdge(nodes, s47, s8));
edges.push(helper.createSimpleEdge(nodes, s47, s39));
edges.push(helper.createSimpleEdge(nodes, s47, s15));
edges.push(helper.createSimpleEdge(nodes, s47, s34));
edges.push(helper.createSimpleEdge(nodes, s47, s30));
edges.push(helper.createSimpleEdge(nodes, s47, s45));
_.each(edges, function(e) {
joiner.insertEdge(e.source._id, e.target._id);
});
diff = (new Date()).getTime() - start;
console.log("Runtime Fill:", diff, "ms");
start = (new Date()).getTime();
joiner.setup();
diff = (new Date()).getTime() - start;
console.log("Runtime Setup:", diff, "ms");
start = (new Date()).getTime();
best = joiner.getBest();
while (best !== null) {
joiner.joinCommunity(best);
best = joiner.getBest();
}
diff = (new Date()).getTime() - start;
console.log("Runtime Compute:", diff, "ms");
});
});
*/
/*
it('should be able to handle 10000 nodes', function() {
var start = (new Date()).getTime();
var i, best, nodeCount = 10000;
helper.insertNSimpleNodes(nodes, nodeCount);
helper.insertClique(nodes, edges, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
for (i = 11; i < nodeCount; i++) {
edges.push(helper.createSimpleEdge(nodes, i - 1, i));
edges.push(helper.createSimpleEdge(nodes, i, i - 2));
}
var diff = (new Date()).getTime() - start;
console.log("Runtime Fill:", diff, "ms");
start = (new Date()).getTime();
joiner.setup();
diff = (new Date()).getTime() - start;
console.log("Runtime Setup:", diff, "ms");
start = (new Date()).getTime();
best = joiner.getBest();
var step = 0;
while (best !== null) {
joiner.joinCommunity(best);
best = joiner.getBest();
step++;
}
diff = (new Date()).getTime() - start;
console.log("Runtime Compute:", diff, "ms");
});
*/
});
describe('configured as a worker', function() {
var joiner,
nodes,
edges,
testNetFour,
called,
result,
custom,
error;
beforeEach(function () {
runs(function() {
custom = function() {};
called = false;
result = "";
error = "";
nodes = [];
edges = [];
testNetFour = function() {
helper.insertSimpleNodes(nodes, ["0", "1", "2", "3"]);
edges.push(helper.createSimpleEdge(nodes, 0, 1));
edges.push(helper.createSimpleEdge(nodes, 0, 3));
edges.push(helper.createSimpleEdge(nodes, 1, 2));
edges.push(helper.createSimpleEdge(nodes, 2, 1));
edges.push(helper.createSimpleEdge(nodes, 2, 3));
edges.push(helper.createSimpleEdge(nodes, 3, 0));
edges.push(helper.createSimpleEdge(nodes, 3, 1));
edges.push(helper.createSimpleEdge(nodes, 3, 2));
_.each(edges, function(e) {
joiner.call("insertEdge", e.source._id, e.target._id);
});
};
var callback = function(d) {
custom(d);
if (d.data.cmd === "insertEdge") {
return;
}
called = true;
if (d.data.cmd !== "construct") {
result = d.data.result;
error = d.data.error;
}
};
joiner = new WebWorkerWrapper(ModularityJoiner, callback);
});
waitsFor(function() {
return called;
}, 1000);
runs(function() {
called = false;
});
});
it('should be able to identify an obvious community', function() {
runs(function() {
helper.insertSimpleNodes(nodes, ["0", "1", "2", "3", "4"]);
edges.push(helper.createSimpleEdge(nodes, 0, 1));
edges.push(helper.createSimpleEdge(nodes, 0, 2));
edges.push(helper.createSimpleEdge(nodes, 0, 3));
edges.push(helper.createSimpleEdge(nodes, 3, 4));
_.each(edges, function(e) {
joiner.call("insertEdge", e.source._id, e.target._id);
});
joiner.call("getCommunity", 3, nodes[4]._id);
});
waitsFor(function() {
return called;
});
runs(function() {
expect(result).toContainNodes(["0", "1", "2"]);
expect(error).toBeUndefined();
});
});
it('should prefer cliques as a community over an equal sized other group', function() {
runs(function() {
helper.insertSimpleNodes(nodes, ["0", "1", "2", "3", "4", "5", "6", "7", "8"]);
helper.insertClique(nodes, edges, [0, 1, 2, 3]);
edges.push(helper.createSimpleEdge(nodes, 4, 3));
edges.push(helper.createSimpleEdge(nodes, 4, 5));
edges.push(helper.createSimpleEdge(nodes, 5, 6));
edges.push(helper.createSimpleEdge(nodes, 5, 7));
edges.push(helper.createSimpleEdge(nodes, 5, 8));
_.each(edges, function(e) {
joiner.call("insertEdge", e.source._id, e.target._id);
});
joiner.call("getCommunity", 6, nodes[4]._id);
});
waitsFor(function() {
return called;
});
runs(function() {
expect(result).toContainNodes(["0", "1", "2", "3"]);
expect(error).toBeUndefined();
});
});
it('should not return a close group if there is an alternative', function() {
runs(function() {
helper.insertSimpleNodes(nodes, ["0", "1", "2", "3", "4", "5", "6", "7", "8"]);
helper.insertClique(nodes, edges, [0, 1, 2]);
helper.insertClique(nodes, edges, [3, 4, 5]);
helper.insertClique(nodes, edges, [6, 7, 8]);
edges.push(helper.createSimpleEdge(nodes, 3, 2));
edges.push(helper.createSimpleEdge(nodes, 5, 6));
_.each(edges, function(e) {
joiner.call("insertEdge", e.source._id, e.target._id);
});
joiner.call("getCommunity", 6, nodes[3]._id);
});
waitsFor(function() {
return called;
});
runs(function() {
expect(result).toContainNodes(["6", "7", "8"]);
expect(error).toBeUndefined();
});
});
it('should also take the best community if no focus is given', function() {
runs(function() {
helper.insertSimpleNodes(nodes, ["0", "1", "2", "3", "4", "5", "6", "7"]);
helper.insertClique(nodes, edges, [0, 1, 2]);
edges.push(helper.createSimpleEdge(nodes, 3, 2));
edges.push(helper.createSimpleEdge(nodes, 3, 4));
edges.push(helper.createSimpleEdge(nodes, 4, 5));
edges.push(helper.createSimpleEdge(nodes, 5, 6));
edges.push(helper.createSimpleEdge(nodes, 5, 7));
_.each(edges, function(e) {
joiner.call("insertEdge", e.source._id, e.target._id);
});
joiner.call("getCommunity", 6);
});
waitsFor(function() {
return called;
});
runs(function() {
expect(result).toContainNodes(["0", "1", "2"]);
expect(error).toBeUndefined();
});
});
it('should be possible to send many getCommunity requests without crashing', function() {
var customCounter, s0, s1, s2, s3, s4, ts, comResults, errors;
runs(function() {
customCounter = [];
comResults = [];
errors = [];
s0 = helper.insertSatelite(nodes, edges, 0, 500);
s1 = helper.insertSatelite(nodes, edges, 1, 300);
s2 = helper.insertSatelite(nodes, edges, 2, 313);
s3 = helper.insertSatelite(nodes, edges, 3, 461);
s4 = helper.insertSatelite(nodes, edges, 4, 251);
edges.push(helper.createSimpleEdge(nodes, s0, s1));
edges.push(helper.createSimpleEdge(nodes, s0, s2));
edges.push(helper.createSimpleEdge(nodes, s1, s3));
edges.push(helper.createSimpleEdge(nodes, s1, s4));
edges.push(helper.createSimpleEdge(nodes, s2, s1));
edges.push(helper.createSimpleEdge(nodes, s2, s4));
edges.push(helper.createSimpleEdge(nodes, s3, s0));
edges.push(helper.createSimpleEdge(nodes, s4, s1));
custom = function(d) {
var data = d.data;
customCounter.push(((new Date()).getTime() - ts) + ": " + data.cmd);
if (d.data.cmd === "getCommunity") {
comResults.push(data.result || data.error);
}
if (data.error) {
errors.push(data.cmd + ": " + data.error);
}
};
ts = (new Date()).getTime();
_.each(edges, function(e) {
joiner.call("insertEdge", e.source._id, e.target._id);
});
ts = (new Date()).getTime();
});
waitsFor(function() {
return customCounter.length === 1833;
});
runs(function() {
customCounter = [];
joiner.call("getCommunity", 800);
/*
joiner.call("deleteEdge", s0._id, s1._id);
joiner.call("deleteEdge", s2._id, s1._id);
joiner.call("deleteEdge", s3._id, s0._id);
joiner.call("insertEdge", s3._id, s0._id);
joiner.call("insertEdge", s2._id, s1._id);
joiner.call("insertEdge", s0._id, s1._id);
*/
joiner.call("getCommunity", 800);
});
waitsFor(function() {
return comResults.length === 2;
});
runs(function() {
expect(comResults[0]).toEqual(comResults[1]);
expect(errors).toEqual([]);
});
});
it('should not crash because of insertion/deletion of edges', function() {
var customCounter, s0, s1, s2, s3, s4, ts, comResults, errors, adjResults;
runs(function() {
customCounter = [];
comResults = [];
errors = [];
adjResults = [];
s0 = helper.insertSatelite(nodes, edges, 0, 500);
s1 = helper.insertSatelite(nodes, edges, 1, 300);
s2 = helper.insertSatelite(nodes, edges, 2, 313);
s3 = helper.insertSatelite(nodes, edges, 3, 461);
s4 = helper.insertSatelite(nodes, edges, 4, 251);
edges.push(helper.createSimpleEdge(nodes, s0, s1));
edges.push(helper.createSimpleEdge(nodes, s0, s2));
edges.push(helper.createSimpleEdge(nodes, s1, s3));
edges.push(helper.createSimpleEdge(nodes, s1, s4));
edges.push(helper.createSimpleEdge(nodes, s2, s1));
edges.push(helper.createSimpleEdge(nodes, s2, s4));
edges.push(helper.createSimpleEdge(nodes, s3, s0));
edges.push(helper.createSimpleEdge(nodes, s4, s1));
custom = function(d) {
var data = d.data;
customCounter.push(((new Date()).getTime() - ts) + ": " + data.cmd);
if (data.cmd === "getCommunity") {
comResults.push(data.result || data.error);
}
if (data.error) {
errors.push(data.cmd + ": " + data.error);
}
};
ts = (new Date()).getTime();
_.each(edges, function(e) {
joiner.call("insertEdge", e.source._id, e.target._id);
});
ts = (new Date()).getTime();
});
waitsFor(function() {
return customCounter.length === 1833;
});
runs(function() {
customCounter = [];
joiner.call("getCommunity", 800);
joiner.call("deleteEdge", "0", "1");
joiner.call("deleteEdge", "2", "1");
joiner.call("deleteEdge", "3", "0");
joiner.call("insertEdge", "3", "0");
joiner.call("insertEdge", "2", "1");
joiner.call("insertEdge", "0", "1");
joiner.call("getCommunity", 800);
});
waitsFor(function() {
return comResults.length === 2;
});
runs(function() {
expect(adjResults[0]).toEqual(adjResults[1]);
expect(comResults[0]).toEqual(comResults[1]);
expect(errors).toEqual([]);
});
});
});
});
}());