| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157 | 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)})
 |