Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

graphology

Package Overview
Dependencies
Maintainers
1
Versions
64
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

graphology - npm Package Compare versions

Comparing version 0.1.1 to 0.2.0

9

CHANGELOG.md
# Changelog
## 0.2.0
* Adding `#.hasNodeAttribute` & `#.hasEdgeAttribute`.
* Adding `#.removeNodeAttribute` & `#.removeEdgeAttribute`.
* Adding `#.mergeNode`.
* Adding `#.mergeEdge`, `#.mergeEdgeWithKey` and friends.
* Renaming `#.relatedNode` to `#.opposite`.
* Dropping the `onDuplicateNode` & `onDuplicateEdge` options.
## 0.1.1

@@ -4,0 +13,0 @@

@@ -118,2 +118,53 @@ 'use strict';

/**
* Attach an attribute checker method onto the provided class.
*
* @param {function} Class - Target class.
* @param {string} method - Method name.
* @param {string} key - Key of the element's storage on instance.
* @param {string} elementName - Name of target element for messages.
* @param {string} checker - Name of the checker method to use.
* @param {string} [finder] - Name of the finder method to use.
*/
function attachAttributeChecker(Class, method, key, elementName, checker, finder) {
/**
* Checks whether the desired attribute is set for the given element (node or edge).
*
* Arity 2:
* @param {any} element - Target element.
* @param {string} name - Attribute's name.
*
* Arity 3 (only for edges):
* @param {any} source - Source element.
* @param {any} target - Target element.
* @param {string} name - Attribute's name.
*
* @return {boolean}
*
* @throws {Error} - Will throw if too many arguments are provided.
* @throws {Error} - Will throw if any of the elements is not found.
*/
Class.prototype[method] = function (element, name) {
if (arguments.length > 2) {
if (!finder) throw new _errors.InvalidArgumentsGraphError('Graph.' + method + ': too many arguments provided.');
var source = element,
target = name;
name = arguments[2];
if (!this[checker](source, target)) throw new _errors.NotFoundGraphError('Graph.' + method + ': could not find an edge for the given path ("' + source + '" - "' + target + '").');
element = this[finder](source, target);
}
if (!this[checker](element)) throw new _errors.NotFoundGraphError('Graph.' + method + ': could not find the "' + element + '" ' + elementName + ' in the graph.');
var data = this[key].get(element);
return data.attributes.hasOwnProperty(name);
};
}
/**
* Attach an attribute setter method onto the provided class.

@@ -401,2 +452,7 @@ *

name: function name(element) {
return 'has' + element + 'Attribute';
},
attacher: attachAttributeChecker
}, {
name: function name(element) {
return 'set' + element + 'Attribute';

@@ -403,0 +459,0 @@ },

250

dist/graph.js

@@ -37,9 +37,2 @@ 'use strict';

// TODO: finish #.selfLoops (bunch iteration only)
// TODO: solve the #.merge conundrum
// TODO: add the option adding nodes when creating edges if non-existent
// TODO: abstract set storing first element (override add)
// TODO: refactor edge adding methods using a descriptor?
// TODO: discuss .removeNodeAttribute & .hasNodeAttribute
/**

@@ -52,2 +45,35 @@ * Enums.

var EDGE_ADD_METHODS = [{
name: function name(verb) {
return verb + 'Edge';
},
generateKey: true
}, {
name: function name(verb) {
return verb + 'DirectedEdge';
},
generateKey: true,
type: 'directed'
}, {
name: function name(verb) {
return verb + 'UndirectedEdge';
},
generateKey: true,
type: 'undirected'
}, {
name: function name(verb) {
return verb + 'EdgeWithKey';
}
}, {
name: function name(verb) {
return verb + 'DirectedEdgeWithKey';
},
type: 'directed'
}, {
name: function name(verb) {
return verb + 'UndirectedEdgeWithKey';
},
type: 'undirected'
}];
/**

@@ -62,4 +88,2 @@ * Default options.

multi: false,
onDuplicateEdge: null,
onDuplicateNode: null,
type: 'mixed'

@@ -130,2 +154,3 @@ };

* @param {string} name - Name of the child method for errors.
* @param {boolean} merge - Are we merging?
* @param {boolean} mustGenerateId - Should the graph generate an id?

@@ -144,3 +169,3 @@ * @param {boolean} undirected - Whether the edge is undirected.

*/
function _addEdge(graph, name, mustGenerateId, undirected, edge, source, target, attributes) {
function addEdge(graph, name, merge, mustGenerateId, undirected, edge, source, target, attributes) {

@@ -158,6 +183,13 @@ // Checking validity of operation

if (!graph.hasNode(source)) throw new _errors.NotFoundGraphError('Graph.' + name + ': source node "' + source + '" not found.');
var mustAddSource = false,
mustAddTarget = false;
if (!graph.hasNode(target)) throw new _errors.NotFoundGraphError('Graph.' + name + ': target node "' + target + '" not found.');
if (!graph.hasNode(source)) {
if (!merge) throw new _errors.NotFoundGraphError('Graph.' + name + ': source node "' + source + '" not found.');else mustAddSource = true;
}
if (!graph.hasNode(target)) {
if (!merge) throw new _errors.NotFoundGraphError('Graph.' + name + ': target node "' + target + '" not found.');else mustAddTarget = true;
}
if (!graph.allowSelfLoops && source === target) throw new _errors.UsageGraphError('Graph.' + name + ': source & target are the same, thus creating a loop explicitly forbidden by this graph \'allowSelfLoops\' option set to false.');

@@ -176,11 +208,18 @@

// Do we need to handle duplicate?
var canHandleDuplicate = typeof graph._options.onDuplicateEdge === 'function';
var mustHandleDuplicate = false;
var alreadyExistingEdge = null;
// Here, we have a key collision
if (graph.hasEdge(edge)) {
if (!canHandleDuplicate) throw new _errors.UsageGraphError('Graph.' + name + ': the "' + edge + '" edge already exists in the graph.');else mustHandleDuplicate = true;
if (!merge) {
throw new _errors.UsageGraphError('Graph.' + name + ': the "' + edge + '" edge already exists in the graph.');
} else {
alreadyExistingEdge = edge;
}
}
// Here, we might have a source / target collision
if (!graph.multi && (undirected ? graph.hasUndirectedEdge(source, target) : graph.hasDirectedEdge(source, target))) {
if (!canHandleDuplicate) throw new _errors.UsageGraphError('Graph.' + name + ': an edge linking "' + source + '" to "' + target + '" already exists. If you really want to add multiple edges linking those nodes, you should create a multi graph by using the \'multi\' option. The \'onDuplicateEdge\' option might also interest you.');else mustHandleDuplicate = true;
if (!merge) throw new _errors.UsageGraphError('Graph.' + name + ': an edge linking "' + source + '" to "' + target + '" already exists. If you really want to add multiple edges linking those nodes, you should create a multi graph by using the \'multi\' option.');else {
alreadyExistingEdge = undirected ? graph.getUndirectedEdge(source, target) : graph.getDirectedEdge(source, target);
}
}

@@ -192,14 +231,17 @@

// Handling duplicates
if (mustHandleDuplicate) {
graph._options.onDuplicateEdge(graph, {
key: edge,
attributes: attributes,
source: source,
target: target,
undirected: undirected
});
if (alreadyExistingEdge) {
return edge;
// If the key collides but the source & target are inconsistent, we throw
if (graph.source(alreadyExistingEdge) !== source || graph.target(alreadyExistingEdge) !== target) {
throw new _errors.UsageGraphError('Graph.' + name + ': inconsitency detected when attempting to merge the "' + edge + '" edge with "' + source + '" source & "' + target + '" target vs. (' + graph.source(alreadyExistingEdge) + ', ' + graph.target(alreadyExistingEdge) + ').');
}
// Simply merging the attributes of the already existing edge
graph.mergeEdgeAttributes(alreadyExistingEdge, attributes);
return alreadyExistingEdge;
}
if (mustAddSource) graph.addNode(source);
if (mustAddTarget) graph.addNode(target);
// Storing some data

@@ -327,6 +369,2 @@ var data = {

if (options.onDuplicateEdge && typeof options.onDuplicateEdge !== 'function') throw new _errors.InvalidArgumentsGraphError('Graph.constructor: invalid \'onDuplicateEdge\' option. Expecting a function but got "' + options.onDuplicateEdge + '".');
if (options.onDuplicateNode && typeof options.onDuplicateNode !== 'function') throw new _errors.InvalidArgumentsGraphError('Graph.constructor: invalid \'onDuplicateNode\' option. Expecting a function but got "' + options.onDuplicateNode + '".');
//-- Private properties

@@ -786,6 +824,6 @@

Graph.prototype.relatedNode = function relatedNode(node, edge) {
if (!this.hasNode(node)) throw new _errors.NotFoundGraphError('Graph.relatedNode: could not find the "' + node + '" node in the graph.');
Graph.prototype.opposite = function opposite(node, edge) {
if (!this.hasNode(node)) throw new _errors.NotFoundGraphError('Graph.opposite: could not find the "' + node + '" node in the graph.');
if (!this.hasEdge(edge)) throw new _errors.NotFoundGraphError('Graph.relatedNode: could not find the "' + edge + '" edge in the graph.');
if (!this.hasEdge(edge)) throw new _errors.NotFoundGraphError('Graph.opposite: could not find the "' + edge + '" edge in the graph.');

@@ -800,3 +838,3 @@ var _extremities = this.extremities(edge);

if (node !== node1 && node !== node2) throw new _errors.NotFoundGraphError('Graph.relatedNode: the "' + node + '" node is not attached to the "' + edge + '" edge (' + node1 + ', ' + node2 + ').');
if (node !== node1 && node !== node2) throw new _errors.NotFoundGraphError('Graph.opposite: the "' + node + '" node is not attached to the "' + edge + '" edge (' + node1 + ', ' + node2 + ').');

@@ -879,14 +917,4 @@ return node === node1 ? node2 : node1;

if (this.hasNode(node)) {
if (this.hasNode(node)) throw new _errors.UsageGraphError('Graph.addNode: the "' + node + '" node already exist in the graph.');
// Triggering duplicate callback
if (typeof this._options.onDuplicateNode === 'function') {
this._options.onDuplicateNode(this, { key: node, attributes: attributes });
return node;
} else {
throw new _errors.UsageGraphError('Graph.addNode: the "' + node + '" node already exist in the graph. You might want to check out the \'onDuplicateNode\' option.');
}
}
var data = {

@@ -927,2 +955,23 @@ attributes: attributes

/**
* Method used to merge a node into the graph.
*
* @param {any} node - The node.
* @param {object} [attributes] - Optional attributes.
* @return {any} - The node.
*/
Graph.prototype.mergeNode = function mergeNode(node, attributes) {
// If the node already exists, we merge the attributes
if (this.hasNode(node)) {
if (attributes) this.mergeNodeAttributes(node, attributes);
return node;
}
// Else, we create it
return this.addNode(node, attributes);
};
/**
* Method used to add a nodes from a bunch.

@@ -950,94 +999,2 @@ *

/**
* Method used to add an edge of the type of the graph or directed if the
* graph is mixed using the given key.
*
* @param {any} edge - The edge's key.
* @param {any} source - The source node.
* @param {any} target - The target node.
* @param {object} [attributes] - Optional attributes.
* @return {any} - The edge.
*/
Graph.prototype.addEdgeWithKey = function addEdgeWithKey(edge, source, target, attributes) {
return _addEdge(this, 'addEdgeWithKey', false, this.type === 'undirected', edge, source, target, attributes);
};
/**
* Method used to add a directed edge to the graph using the given key.
*
* @param {any} edge - The edge's key.
* @param {any} source - The source node.
* @param {any} target - The target node.
* @param {object} [attributes] - Optional attributes.
* @return {any} - The edge.
*/
Graph.prototype.addDirectedEdgeWithKey = function addDirectedEdgeWithKey(edge, source, target, attributes) {
return _addEdge(this, 'addDirectedEdgeWithKey', false, false, edge, source, target, attributes);
};
/**
* Method used to add an undirected edge to the graph using the given key.
*
* @param {any} edge - The edge's key.
* @param {any} source - The source node.
* @param {any} target - The target node.
* @param {object} [attributes] - Optional attributes.
* @return {any} - The edge.
*/
Graph.prototype.addUndirectedEdgeWithKey = function addUndirectedEdgeWithKey(edge, source, target, attributes) {
return _addEdge(this, 'addUndirectedEdgeWithKey', false, true, edge, source, target, attributes);
};
/**
* Method used to add an edge of the type of the graph or directed if the
* graph is mixed. An id will automatically be created for it using the
* 'edgeKeyGenerator' option.
*
* @param {any} source - The source node.
* @param {any} target - The target node.
* @param {object} [attributes] - Optional attributes.
* @return {any} - The edge.
*/
Graph.prototype.addEdge = function addEdge(source, target, attributes) {
return _addEdge(this, 'addEdge', true, this.type === 'undirected', null, source, target, attributes);
};
/**
* Method used to add a directed edge to the graph. An id will automatically
* be created for it using the 'edgeKeyGenerator' option.
*
* @param {any} source - The source node.
* @param {any} target - The target node.
* @param {object} [attributes] - Optional attributes.
* @return {any} - The edge.
*/
Graph.prototype.addDirectedEdge = function addDirectedEdge(source, target, attributes) {
return _addEdge(this, 'addDirectedEdge', true, false, null, source, target, attributes);
};
/**
* Method used to add an undirected edge to the graph. An id will automatically
* be created for it using the 'edgeKeyGenerator' option.
*
* @param {any} source - The source node.
* @param {any} target - The target node.
* @param {object} [attributes] - Optional attributes.
* @return {any} - The edge.
*/
Graph.prototype.addUndirectedEdge = function addUndirectedEdge(source, target, attributes) {
return _addEdge(this, 'addUndirectedEdge', true, true, null, source, target, attributes);
};
/**
* Method used to drop a single node & all its attached edges from the graph.

@@ -1719,3 +1676,3 @@ *

/**
* Attributes-related.
* Related to edge addition.
*/

@@ -1725,2 +1682,21 @@

exports.default = Graph;
EDGE_ADD_METHODS.forEach(function (method) {
['add', 'merge'].forEach(function (verb) {
var name = method.name(verb);
if (method.generateKey) {
Graph.prototype[name] = function (source, target, attributes) {
return addEdge(this, name, verb === 'merge', method.generateKey, (method.type || this.type) === 'undirected', null, source, target, attributes);
};
} else {
Graph.prototype[name] = function (edge, source, target, attributes) {
return addEdge(this, name, verb === 'merge', method.generateKey, (method.type || this.type) === 'undirected', edge, source, target, attributes);
};
}
});
});
/**
* Attributes-related.
*/
(0, _attributes.attachAttributesMethods)(Graph);

@@ -1727,0 +1703,0 @@

@@ -107,10 +107,19 @@ 'use strict';

* @param {object|undefined} map - Target object.
* @param {string} key - Sub key.
*/
function mergeEdges(edges, object) {
function mergeEdges(edges, object, key) {
if (!object) return;
for (var k in object) {
object[k].forEach(function (value) {
if (key) {
var target = object[key];
if (target) target.forEach(function (value) {
return edges.add(value);
});
} else {
for (var k in object) {
object[k].forEach(function (value) {
return edges.add(value);
});
}
}

@@ -223,2 +232,9 @@ }

if (type === 'selfLoops') {
mergeEdges(edges, nodeData.out, node);
mergeEdges(edges, nodeData.undirectedOut, node);
return;
}
if (type === 'mixed' || type === 'directed') {

@@ -225,0 +241,0 @@

{
"name": "graphology",
"version": "0.1.1",
"version": "0.2.0",
"description": "A robust and multipurpose Graph object for JavaScript.",

@@ -20,3 +20,7 @@ "main": "dist/index.js",

"keywords": [
"graph"
"graph",
"graph theory",
"directed",
"undirected",
"network"
],

@@ -23,0 +27,0 @@ "repository": {

@@ -5,4 +5,35 @@ [![Build Status](https://travis-ci.org/graphology/graphology.svg)](https://travis-ci.org/graphology/graphology)

A robust & multipurpose Graph object for JavaScript.
`graphology` is a specification for a robust & multipurpose JavaScript `Graph` object and aiming at supporting various kinds of graphs under a same unified interface.
Current spec [here](https://graphology.github.io).
You will also find here the source for the reference implementation of this specification.
## Installation
```
npm install graphology
```
## Documentation
Full documentation for the library/specs is available [here](https://graphology.github.io).
## Contribution
Contributions are obviously welcome. Just be sure to lint & add/run relevant unit tests.
```
# Installing locally
git clone git@github.com:graphology/graphology.git
cd graphology
npm install
# Linting
npm run lint
# Running the unit tests
npm test
# Building & Distribution
npm run build
npm run dist
```

@@ -24,3 +24,3 @@ 'use strict';

var METHODS = ['getNodeAttribute', 'getNodeAttributes', 'getEdgeAttribute', 'getEdgeAttributes', 'setNodeAttribute', 'setEdgeAttribute', 'updateNodeAttribute', 'updateEdgeAttribute', 'replaceNodeAttributes', 'replaceEdgeAttributes', 'mergeNodeAttributes', 'mergeEdgeAttributes'];
var METHODS = ['getNodeAttribute', 'getNodeAttributes', 'hasNodeAttribute', 'getEdgeAttribute', 'getEdgeAttributes', 'hasEdgeAttribute', 'setNodeAttribute', 'setEdgeAttribute', 'updateNodeAttribute', 'updateEdgeAttribute', 'replaceNodeAttributes', 'replaceEdgeAttributes', 'mergeNodeAttributes', 'mergeEdgeAttributes'];

@@ -135,2 +135,40 @@ function attributes(Graph, checkers) {

'#.hasNodeAttribute': {
'it should correctly return whether the attribute is set.': function itShouldCorrectlyReturnWhetherTheAttributeIsSet() {
var graph = new Graph();
graph.addNode('John', { age: 20 });
_assert2.default.strictEqual(graph.hasNodeAttribute('John', 'age'), true);
_assert2.default.strictEqual(graph.hasNodeAttribute('John', 'eyes'), false);
},
'it does not fail with typical prototypal properties.': function itDoesNotFailWithTypicalPrototypalProperties() {
var graph = new Graph();
graph.addNode('John', { age: 20 });
_assert2.default.strictEqual(graph.hasNodeAttribute('John', 'toString'), false);
}
},
'#.hasEdgeAttribute': {
'it should correctly return whether the attribute is set.': function itShouldCorrectlyReturnWhetherTheAttributeIsSet() {
var graph = new Graph();
graph.addNodesFrom(['John', 'Martha']);
graph.addEdgeWithKey('J->M', 'John', 'Martha', { weight: 10 });
_assert2.default.strictEqual(graph.hasEdgeAttribute('J->M', 'weight'), true);
_assert2.default.strictEqual(graph.hasEdgeAttribute('J->M', 'type'), false);
},
'it does not fail with typical prototypal properties.': function itDoesNotFailWithTypicalPrototypalProperties() {
var graph = new Graph();
graph.addNodesFrom(['John', 'Martha']);
graph.addEdgeWithKey('J->M', 'John', 'Martha', { weight: 10 });
_assert2.default.strictEqual(graph.hasEdgeAttribute('J->M', 'toString'), false);
}
},
'#.setNodeAttribute': {

@@ -137,0 +175,0 @@

@@ -169,83 +169,2 @@ 'use strict';

/**
* onDuplicateEdge
*/
'onDuplicateEdge': {
'providing a non-function truthy value should throw.': function providingANonFunctionTruthyValueShouldThrow() {
_assert2.default.throws(function () {
var graph = new Graph(null, { onDuplicateEdge: 'test' });
}, invalid());
},
'the callback should fire if the user add the same edge twice.': function theCallbackShouldFireIfTheUserAddTheSameEdgeTwice() {
var callback = (0, _helpers.spy)(function (g, data) {
(0, _assert2.default)(g instanceof Graph);
_assert2.default.deepEqual(data.attributes, { type: 'KNOWS' });
_assert2.default.strictEqual(data.source, 'John');
_assert2.default.strictEqual(data.target, 'Martha');
_assert2.default.strictEqual(data.undirected, false);
g.updateEdgeAttribute(data.source, data.target, 'weight', function (x) {
return (x || 1) + 1;
});
});
var graph = new Graph(null, { onDuplicateEdge: callback });
graph.addNodesFrom(['John', 'Martha']);
var edge = graph.addEdge('John', 'Martha', { type: 'KNOWS' });
_assert2.default.doesNotThrow(function () {
graph.addEdge('John', 'Martha', { type: 'KNOWS' });
});
_assert2.default.strictEqual(graph.size, 1);
_assert2.default.deepEqual(graph.getEdgeAttributes('John', 'Martha'), { type: 'KNOWS', weight: 2 });
(0, _assert2.default)(callback.called);
(0, _assert2.default)(callback.times, 1);
}
},
/**
* onDuplicateNode
*/
'onDuplicateNode': {
'providing a non-function truthy value should throw.': function providingANonFunctionTruthyValueShouldThrow() {
_assert2.default.throws(function () {
var graph = new Graph(null, { onDuplicateNode: 'test' });
}, invalid());
},
'the callback should fire if the user add the same node twice.': function theCallbackShouldFireIfTheUserAddTheSameNodeTwice() {
var callback = (0, _helpers.spy)(function (g, data) {
(0, _assert2.default)(g instanceof Graph);
_assert2.default.strictEqual(data.key, 'John');
_assert2.default.deepEqual(data.attributes, { age: 34 });
g.updateNodeAttribute('John', 'occurrences', function (x) {
return (x || 1) + 1;
});
});
var graph = new Graph(null, { onDuplicateNode: callback });
graph.addNode('John', { age: 34 });
_assert2.default.doesNotThrow(function () {
graph.addNode('John', { age: 34 });
});
_assert2.default.strictEqual(graph.order, 1);
_assert2.default.deepEqual(graph.getNodeAttributes('John'), { age: 34, occurrences: 2 });
(0, _assert2.default)(callback.called);
(0, _assert2.default)(callback.times, 1);
}
},
/**
* type

@@ -252,0 +171,0 @@ */

@@ -170,3 +170,3 @@ 'use strict';

var graphWithSelfLoops = new Graph(null, { multi: true });
graphWithSelfLoops.addNodesFrom(['John', 'Tabitha', 'Alone']);
graphWithSelfLoops.addNodesFrom(['John', 'Tabitha', 'Marcia', 'Alone']);
graphWithSelfLoops.addEdgeWithKey('J->T', 'John', 'Tabitha');

@@ -176,9 +176,14 @@ graphWithSelfLoops.addEdgeWithKey('J1', 'John', 'John');

graphWithSelfLoops.addEdgeWithKey('T1', 'Tabitha', 'Tabitha');
graphWithSelfLoops.addEdgeWithKey('M1', 'Marcia', 'Marcia');
var SELF_LOOPS_TEST_DATA = {
selfLoops: {
all: ['J1', 'J2', 'T1'],
all: ['J1', 'J2', 'T1', 'M1'],
node: {
key: 'John',
loops: ['J1', 'J2']
},
bunch: {
keys: ['John', 'Tabitha'],
edges: ['J1', 'J2', 'T1']
}

@@ -302,2 +307,11 @@ }

_assert2.default.deepEqual(graphWithSelfLoops[name]('Alone'), []);
},
'it should return a bunch of nodes\' relevant edges.': function itShouldReturnABunchOfNodesRelevantEdges() {
(0, _helpers.testBunches)(data.bunch.keys, function (bunch) {
var edges = graphWithSelfLoops[name](bunch);
(0, _assert2.default)((0, _helpers.sameMembers)(edges, data.bunch.edges));
_assert2.default.deepEqual(graphWithSelfLoops[name](['Alone']), []);
});
}

@@ -316,2 +330,10 @@ }), _defineProperty(_ref3, '#.' + counterName, {

_assert2.default.deepEqual(graphWithSelfLoops[counterName]('Alone'), 0);
},
'it should count a bunch of nodes\' relevant edges.': function itShouldCountABunchOfNodesRelevantEdges() {
(0, _helpers.testBunches)(data.bunch.keys, function (bunch) {
_assert2.default.strictEqual(graphWithSelfLoops[counterName](bunch), data.bunch.edges.length);
_assert2.default.deepEqual(graphWithSelfLoops[counterName](['Alone']), 0);
});
}

@@ -318,0 +340,0 @@ }), _ref3;

@@ -65,2 +65,32 @@ 'use strict';

'#.mergeNode': {
'it should add the node if it does not exist yet.': function itShouldAddTheNodeIfItDoesNotExistYet() {
var graph = new Graph();
graph.mergeNode('John');
_assert2.default.deepEqual(graph.nodes(), ['John']);
},
'it should do nothing if the node already exists.': function itShouldDoNothingIfTheNodeAlreadyExists() {
var graph = new Graph();
graph.addNode('John');
graph.mergeNode('John');
_assert2.default.deepEqual(graph.nodes(), ['John']);
},
'it should merge the attributes.': function itShouldMergeTheAttributes() {
var graph = new Graph();
graph.addNode('John', { eyes: 'blue' });
graph.mergeNode('John', { age: 15 });
_assert2.default.deepEqual(graph.nodes(), ['John']);
_assert2.default.deepEqual(graph.getNodeAttributes('John'), {
eyes: 'blue',
age: 15
});
}
},
'#.addNodesFrom': {

@@ -288,2 +318,59 @@

'#.mergeEdge': {
'it should add the edge if it does not yet exist.': function itShouldAddTheEdgeIfItDoesNotYetExist() {
var graph = new Graph();
graph.addNodesFrom(['John', 'Martha']);
graph.mergeEdge('John', 'Martha');
_assert2.default.strictEqual(graph.size, 1);
_assert2.default.strictEqual(graph.hasEdge('John', 'Martha'), true);
},
'it should do nothing if the edge already exists.': function itShouldDoNothingIfTheEdgeAlreadyExists() {
var graph = new Graph();
graph.addNodesFrom(['John', 'Martha']);
graph.addEdge('John', 'Martha');
graph.mergeEdge('John', 'Martha');
_assert2.default.strictEqual(graph.size, 1);
_assert2.default.strictEqual(graph.hasEdge('John', 'Martha'), true);
},
'it should merge existing attributes if any.': function itShouldMergeExistingAttributesIfAny() {
var graph = new Graph();
graph.addNodesFrom(['John', 'Martha']);
graph.addEdge('John', 'Martha', { type: 'KNOWS' });
graph.mergeEdge('John', 'Martha', { weight: 2 });
_assert2.default.strictEqual(graph.size, 1);
_assert2.default.strictEqual(graph.hasEdge('John', 'Martha'), true);
_assert2.default.deepEqual(graph.getEdgeAttributes('John', 'Martha'), {
type: 'KNOWS',
weight: 2
});
},
'it should add missing nodes in the path.': function itShouldAddMissingNodesInThePath() {
var graph = new Graph();
graph.mergeEdge('John', 'Martha');
_assert2.default.strictEqual(graph.order, 2);
_assert2.default.strictEqual(graph.size, 1);
_assert2.default.deepEqual(graph.nodes(), ['John', 'Martha']);
},
'it should throw in case of inconsistencies.': function itShouldThrowInCaseOfInconsistencies() {
var graph = new Graph();
graph.mergeEdgeWithKey('J->M', 'John', 'Martha');
_assert2.default.throws(function () {
graph.mergeEdgeWithKey('J->M', 'John', 'Thomas');
}, usage());
}
},
'#.dropEdge': {

@@ -290,0 +377,0 @@

@@ -253,3 +253,3 @@ 'use strict';

'#.relatedNode': {
'#.opposite': {

@@ -261,7 +261,7 @@ 'it should throw if either the node or the edge is not found in the graph.': function itShouldThrowIfEitherTheNodeOrTheEdgeIsNotFoundInTheGraph() {

_assert2.default.throws(function () {
graph.relatedNode('Jeremy', 'T->J');
graph.opposite('Jeremy', 'T->J');
}, notFound());
_assert2.default.throws(function () {
graph.relatedNode('Thomas', 'T->J');
graph.opposite('Thomas', 'T->J');
}, notFound());

@@ -276,3 +276,3 @@ },

_assert2.default.throws(function () {
graph.relatedNode('Thomas', 'I->E');
graph.opposite('Thomas', 'I->E');
}, notFound());

@@ -286,3 +286,3 @@ },

_assert2.default.strictEqual(graph.relatedNode('Thomas', edge), 'Estelle');
_assert2.default.strictEqual(graph.opposite('Thomas', edge), 'Estelle');
}

@@ -289,0 +289,0 @@ },

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc