You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

158 lines
3.5 KiB

var vows = require('vows')
, toposort = require('./index')
, assert = require('assert')
var suite = vows.describe('toposort')
suite.addBatch(
{ 'acyclic graphs':
{ topic: function() {
/*(read downwards)
6 3
| |
5->2
| |
4 1
*/
return toposort(
[ ["3", '2']
, ["2", "1"]
, ["6", "5"]
, ["5", "2"]
, ["5", "4"]
])
}
, 'should be sorted correctly': function(er, result) {
assert.instanceOf(result, Array)
var failed = [], passed
// valid permutations
;[ [ '3','6','5','2','1','4' ]
, [ '3','6','5','2','4','1' ]
, [ '6','3','5','2','1','4' ]
, [ '6','5','3','2','1','4' ]
, [ '6','5','3','2','4','1' ]
, [ '6','5', '4','3','2','1' ]
].forEach(function(solution) {
try {
assert.deepEqual(result, solution)
passed = true
}catch (e) {
failed.push(e)
}
})
if (!passed) {
console.log(failed)
throw failed[0];
}
}
}
, 'simple cyclic graphs':
{ topic: function() {
/*
foo<->bar
*/
return toposort(
[ ["foo", 'bar']
, ["bar", "foo"]// cyclic dependecy
])
}
, 'should throw an exception': function(_, val) {
assert.instanceOf(val, Error)
}
}
, 'complex cyclic graphs':
{ topic: function() {
/*
foo
|
bar<-john
| ^
ron->tom
*/
return toposort(
[ ["foo", 'bar']
, ["bar", "ron"]
, ["john", "bar"]
, ["tom", "john"]
, ["ron", "tom"]// cyclic dependecy
])
}
, 'should throw an exception': function(_, val) {
assert.instanceOf(val, Error)
}
}
, 'unknown nodes in edges':
{ topic: function() {
return toposort.array(['bla']
[ ["foo", 'bar']
, ["bar", "ron"]
, ["john", "bar"]
, ["tom", "john"]
, ["ron", "tom"]
])
}
, 'should throw an exception': function(_, val) {
assert.instanceOf(val, Error)
}
}
, 'triangular dependency':
{ topic: function() {
/*
a-> b
| /
c<-
*/
return toposort([
['a', 'b']
, ['a', 'c']
, ['b', 'c']
]);
}
, 'shouldn\'t throw an error': function(er, result) {
assert.deepEqual(result, ['a', 'b', 'c'])
}
}
, 'toposort.array':
{ topic: function() {
return toposort.array(['d', 'c', 'a', 'b'], [['a','b'],['b','c']])
}
, 'should include unconnected nodes': function(er, result){
var i = result.indexOf('d')
assert(i >= 0)
result.splice(i, 1)
assert.deepEqual(result, ['a', 'b', 'c'])
}
}
, 'toposort.array mutation':
{ topic: function() {
var array = ['d', 'c', 'a', 'b']
toposort.array(array, [['a','b'],['b','c']])
return array
}
, 'should not mutate its arguments': function(er, result){
assert.deepEqual(result, ['d', 'c', 'a', 'b'])
}
}
, 'giant graphs':
{
topic: function() {
var graph = []
, nodeCount = 10000
for (var i = 0; i < nodeCount; i++) {
graph.push([i, i + 1])
}
return graph
}
, 'should sort quickly': function(er, result){
var start = (new Date).getTime()
var sorted = toposort(result)
var end = (new Date).getTime()
var elapsedSeconds = (end - start) / 1000
assert(elapsedSeconds < 1)
}
}
})
.run(null, function() {
(suite.results.broken+suite.results.errored) > 0 && process.exit(1)
process.exit(0)
})