Comparing version 1.0.2 to 1.0.3
@@ -13,5 +13,5 @@ # How to contribute | ||
* Fork the repository on GitHub. | ||
* Fix the issue ensuring that your code follows the [style guide](https://github.com/hapijs/hapi/blob/master/docs/Style.md). | ||
* Fix the issue ensuring that your code follows the [style guide](https://github.com/hapijs/contrib/blob/master/Style.md). | ||
* Add tests for your new code ensuring that you have 100% code coverage (we can help you reach 100% but will not merge without it). | ||
* Run `npm test` to generate a report of test coverage | ||
* [Pull requests](http://help.github.com/send-pull-requests/) should be made to the [master branch](https://github.com/hapijs/topo/tree/master). | ||
* [Pull requests](http://help.github.com/send-pull-requests/) should be made to the [master branch](https://github.com/hapijs/topo/tree/master). |
@@ -77,3 +77,3 @@ // Load modules | ||
graph[seq] = [item.before]; | ||
graph[seq] = item.before; | ||
@@ -97,8 +97,9 @@ // Build second intermediary graph with 'after' | ||
for (j = 0, jl = graphNodeItems.length; j < jl; ++j) { | ||
var group = graph[node][graphNodeItems[j]]; | ||
group = graph[node][graphNodeItems[j]]; | ||
groups[group] = groups[group] || []; | ||
groups[group].forEach(function (d) { | ||
expandedGroups.push(d); | ||
}); | ||
for (var k = 0, kl = groups[group].length; k < kl; ++k) { | ||
expandedGroups.push(groups[group][k]); | ||
} | ||
} | ||
@@ -112,7 +113,7 @@ graph[node] = expandedGroups; | ||
for (i = 0, il = afterNodes.length; i < il; ++i) { | ||
var group = afterNodes[i]; | ||
group = afterNodes[i]; | ||
if (groups[group]) { | ||
for (j = 0, jl = groups[group].length; j < jl; ++j) { | ||
var node = groups[group][j]; | ||
node = groups[group][j]; | ||
graph[node] = graph[node].concat(graphAfters[group]); | ||
@@ -125,7 +126,8 @@ } | ||
var children; | ||
var ancestors = {}; | ||
graphNodes = Object.keys(graph); | ||
for (i = 0, il = graphNodes.length; i < il; ++i) { | ||
var node = graphNodes[i]; | ||
var children = graph[node]; | ||
node = graphNodes[i]; | ||
children = graph[node]; | ||
@@ -183,6 +185,7 @@ for (j = 0, jl = children.length; j < jl; ++j) { | ||
var seqIndex = {}; | ||
this._items.forEach(function (item) { | ||
for (i = 0, il = this._items.length; i < il; ++i) { | ||
item = this._items[i]; | ||
seqIndex[item.seq] = item; | ||
}); | ||
} | ||
@@ -192,5 +195,5 @@ var sortedNodes = []; | ||
var item = seqIndex[value]; | ||
sortedNodes.push(item.node); | ||
return item; | ||
var sortedItem = seqIndex[value]; | ||
sortedNodes.push(sortedItem.node); | ||
return sortedItem; | ||
}); | ||
@@ -197,0 +200,0 @@ |
{ | ||
"name": "topo", | ||
"description": "Topological sorting with grouping support", | ||
"version": "1.0.2", | ||
"version": "1.0.3", | ||
"repository": "git://github.com/hapijs/topo", | ||
"main": "index", | ||
"main": "lib/index.js", | ||
"keywords": [ | ||
@@ -17,16 +17,13 @@ "topological", | ||
"dependencies": { | ||
"hoek": "2.x.x" | ||
"hoek": "2.x.x" | ||
}, | ||
"devDependencies": { | ||
"lab": "4.x.x" | ||
"lab": "5.x.x", | ||
"code": "1.x.x" | ||
}, | ||
"scripts": { | ||
"test": "make test-cov" | ||
"test": "lab -a code -t 100 -L", | ||
"test-cov-html": "lab -a code -t 100 -L -r html -o coverage.html" | ||
}, | ||
"licenses": [ | ||
{ | ||
"type": "BSD", | ||
"url": "http://github.com/hapijs/topo/raw/master/LICENSE" | ||
} | ||
] | ||
"license": "BSD-3-Clause" | ||
} |
@@ -1,2 +0,2 @@ | ||
#topo | ||
# topo | ||
@@ -7,2 +7,39 @@ Topological sorting with grouping support. | ||
Lead Maintainer: [Eran Hammer](https://github.com/hueniverse) | ||
Lead Maintainer: [Devin Ivy](https://github.com/devinivy) | ||
## Usage | ||
```node | ||
var Topo = require('topo'); | ||
var topo = new Topo(); | ||
topo.add('Nap', { after: ['breakfast', 'prep'] }); | ||
topo.add([ | ||
'Make toast', | ||
'Pour juice' | ||
], { before: 'breakfast', group: 'prep' }); | ||
topo.add('Eat breakfast', { group: 'breakfast' }); | ||
topo.nodes; // ['Make toast', 'Pour juice', 'Eat breakfast', 'Nap'] | ||
``` | ||
### `Topo` | ||
The `Topo` object is the container for topologically sorting a list of nodes with non-circular interdependencies. | ||
#### `new Topo()` | ||
Creates a new `Topo` object. | ||
#### `topo.add(nodes, [options])` | ||
Specifies an additional node or list of nodes to be topologically sorted where: | ||
- `nodes` - a mixed value or array of mixed values to be added as nodes to the topologically sorted list. | ||
- `options` - optional sorting information about the `nodes`: | ||
- `group` - a string naming the group to which `nodes` should be assigned. The group name `'?'` is reserved. | ||
- `before` - a string or array of strings specifying the groups that `nodes` must precede in the topological sort. | ||
- `after` - a string or array of strings specifying the groups that `nodes` must succeed in the topological sort. | ||
Returns an array of the topologically sorted nodes. | ||
#### `topo.nodes` | ||
An array of the topologically sorted nodes. This list is renewed upon each call to [`topo.add()`](#topoaddnodes-options). |
// Load modules | ||
var Code = require('code'); | ||
var Lab = require('lab'); | ||
var Hoek = require('hoek'); | ||
var Topo = require('..'); | ||
@@ -17,3 +19,3 @@ | ||
var it = lab.it; | ||
var expect = Lab.expect; | ||
var expect = Code.expect; | ||
@@ -54,2 +56,27 @@ | ||
it('sorts dependencies (before as array)', function (done) { | ||
var scenario = [ | ||
{ id: '0', group: 'a' }, | ||
{ id: '1', group: 'b' }, | ||
{ id: '2', before: ['a', 'b'] } | ||
]; | ||
expect(testDeps(scenario)).to.equal('201'); | ||
done(); | ||
}); | ||
it('sorts dependencies (after as array)', function (done) { | ||
var scenario = [ | ||
{ id: '0', after: ['a', 'b'] }, | ||
{ id: '1', group: 'a' }, | ||
{ id: '2', group: 'b' } | ||
]; | ||
expect(testDeps(scenario)).to.equal('120'); | ||
done(); | ||
}); | ||
it('sorts dependencies (seq)', function (done) { | ||
@@ -68,17 +95,8 @@ | ||
it('sorts dependencies (explicit)', function (done) { | ||
it('sorts dependencies (explicitly using after or before)', function (done) { | ||
var set = '0123456789abcdefghijklmnopqrstuvwxyz'; | ||
var array = set.split(''); | ||
var groups = set.split(''); | ||
var scenario = []; | ||
for (var i = 0, il = array.length; i < il; ++i) { | ||
var item = { | ||
id: array[i], | ||
group: array[i], | ||
after: i ? array.slice(0, i) : [], | ||
before: array.slice(i + 1) | ||
}; | ||
scenario.push(item); | ||
} | ||
// Use Fisher-Yates for shuffling | ||
@@ -97,4 +115,25 @@ var fisherYates = function (array) { | ||
fisherYates(scenario); | ||
expect(testDeps(scenario)).to.equal(set); | ||
var scenarioAfter = []; | ||
var scenarioBefore = []; | ||
for (var i = 0, il = groups.length; i < il; ++i) { | ||
var item = { | ||
id: groups[i], | ||
group: groups[i] | ||
}; | ||
var afterMod = { | ||
after: i ? groups.slice(0, i) : [] | ||
}; | ||
var beforeMod = { | ||
before: groups.slice(i + 1) | ||
}; | ||
scenarioAfter.push(Hoek.applyToDefaults(item, afterMod)); | ||
scenarioBefore.push(Hoek.applyToDefaults(item, beforeMod)); | ||
} | ||
fisherYates(scenarioAfter); | ||
expect(testDeps(scenarioAfter)).to.equal(set); | ||
fisherYates(scenarioBefore); | ||
expect(testDeps(scenarioBefore)).to.equal(set); | ||
done(); | ||
@@ -101,0 +140,0 @@ }); |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
14058
253
45
2
8
1