diff options
| author | Ruben Beltran del Rio <ruben@unlimited.pizza> | 2020-09-20 16:55:36 +0200 |
|---|---|---|
| committer | Ruben Beltran del Rio <ruben@unlimited.pizza> | 2020-09-20 16:55:36 +0200 |
| commit | e4c7bafd276049c805039b240e0a83346c31f41b (patch) | |
| tree | 4c8788909ed67710a1628b9e4ae51c1a45b3b3ce /test | |
Initial release
Diffstat (limited to 'test')
| -rw-r--r-- | test/grafn.js | 225 |
1 files changed, 225 insertions, 0 deletions
diff --git a/test/grafn.js b/test/grafn.js new file mode 100644 index 0000000..1618eb2 --- /dev/null +++ b/test/grafn.js @@ -0,0 +1,225 @@ +'use strict'; + +const Grafn = require('..'); +const Tap = require('tap'); + +Tap.beforeEach((done, t) => { + + t.graph = new Grafn(); + t.verticesRan = 0; + done(); +}); + +Tap.test(async (t) => { + + await t.rejects(t.graph.run('nonExisting'), 'It throws an error if you try to run a non-existing vertex'); +}); + +Tap.test(async (t) => { + + t.graph.vertex({ + name: 'root', + action() { + + t.verticesRan++; + } + }); + + await t.graph.run('root'); + t.equal(t.verticesRan, 1, 'It runs a vertex if no dependencies are defined'); +}); + +Tap.test(async (t) => { + + t.graph.vertex({ + name: 'unfulfilled', + dependencies: ['nonExisting'], + action() { + + t.verticesRan++; + } + }); + + await t.graph.run('unfulfilled'); + t.equal(t.verticesRan, 0, 'It does not run a vertex if it has unfulfilled dependencies'); +}); + +Tap.test(async (t) => { + + t.graph.vertex({ + name: 'root', + action() { } + }); + + t.graph.vertex({ + name: 'firstDependent', + dependencies: ['root'], + action() { + + t.verticesRan++; + } + }); + + t.graph.vertex({ + name: 'secondDependent', + dependencies: ['root'], + action() { + + t.verticesRan += 2; + } + }); + + await t.graph.run('root'); + t.equal(t.verticesRan, 3, 'It runs dependent vertices on completion of a vertex\'s action'); +}); + +Tap.test(async (t) => { + + t.graph.vertex({ + name: 'root', + action() { } + }); + + t.graph.vertex({ + name: 'firstDependent', + dependencies: ['root'], + action() { + + return 1; + } + }); + + t.graph.vertex({ + name: 'secondDependent', + dependencies: ['root'], + action() { + + return 2; + } + }); + + t.graph.vertex({ + name: 'final', + dependencies: ['firstDependent', 'secondDependent'], + action(state) { + + t.verticesRan = state.firstDependent + state.secondDependent; + } + }); + + await t.graph.run('root'); + t.equal(t.verticesRan, 3, 'It ensures dependencies state is available before running dependents'); +}); + +Tap.test(async (t) => { + + t.graph.vertex({ + name: 'root', + action() { + + return 101; + } + }); + + t.graph.vertex({ + name: 'stateDependent', + dependencies: ['root'], + action(state) { + + t.verticesRan = state.root; + } + }); + + await t.graph.run('root'); + t.equal(t.verticesRan, 101, 'It gives dependent vertices a state including their dependencies\' results'); +}); + +Tap.test(async (t) => { + + t.graph.vertex({ + name: 'root', + action() { + + throw new Error('Unexpected root problem'); + } + }); + + await t.rejects(t.graph.run('root'), 'It throws an error if a vertex throws an error'); +}); + +Tap.test(async (t) => { + + t.graph.vertex({ + name: 'root', + action() { + + t.verticesRan++; + return 1; + } + }); + + await t.graph.run('root'); + await t.graph.run('root'); + t.equal(t.verticesRan, 1, 'It runs a vertex only once'); +}); + +Tap.test( (t) => { + + t.graph.vertex({ + name: 'root', + action() {} + }); + + t.graph.vertex({ + name: 'firstDependent', + dependencies: ['root'], + action() {} + }); + + t.graph.vertex({ + name: 'secondDependent', + dependencies: ['root'], + action() {} + }); + + t.graph.vertex({ + name: 'final', + dependencies: ['firstDependent', 'secondDependent'], + action() {} + }); + + t.matchSnapshot(t.graph.toString(), 'It can convert to a string representing the graph in graphviz format'); + t.end(); +}); + +Tap.test('It colorizes the graph based on execution results', async (t) => { + + t.graph.vertex({ + name: 'root', + action() {} + }); + + t.graph.vertex({ + name: 'firstDependent', + dependencies: ['root'], + action() {} + }); + + t.graph.vertex({ + name: 'secondDependent', + dependencies: ['root'], + action() { + + throw new Error('Second dependent has failed'); + } + }); + + t.graph.vertex({ + name: 'final', + dependencies: ['firstDependent', 'secondDependent'], + action() {} + }); + + await t.rejects(t.graph.run('root'), 'It throws an error if a sub-step fails'); + t.matchSnapshot(t.graph.toString(), 'It adds the right colors according to execution'); +}); |