]> git.r.bdr.sh - rbdr/grafn/blob - test/grafn.js
Initial release
[rbdr/grafn] / test / grafn.js
1 'use strict';
2
3 const Grafn = require('..');
4 const Tap = require('tap');
5
6 Tap.beforeEach((done, t) => {
7
8 t.graph = new Grafn();
9 t.verticesRan = 0;
10 done();
11 });
12
13 Tap.test(async (t) => {
14
15 await t.rejects(t.graph.run('nonExisting'), 'It throws an error if you try to run a non-existing vertex');
16 });
17
18 Tap.test(async (t) => {
19
20 t.graph.vertex({
21 name: 'root',
22 action() {
23
24 t.verticesRan++;
25 }
26 });
27
28 await t.graph.run('root');
29 t.equal(t.verticesRan, 1, 'It runs a vertex if no dependencies are defined');
30 });
31
32 Tap.test(async (t) => {
33
34 t.graph.vertex({
35 name: 'unfulfilled',
36 dependencies: ['nonExisting'],
37 action() {
38
39 t.verticesRan++;
40 }
41 });
42
43 await t.graph.run('unfulfilled');
44 t.equal(t.verticesRan, 0, 'It does not run a vertex if it has unfulfilled dependencies');
45 });
46
47 Tap.test(async (t) => {
48
49 t.graph.vertex({
50 name: 'root',
51 action() { }
52 });
53
54 t.graph.vertex({
55 name: 'firstDependent',
56 dependencies: ['root'],
57 action() {
58
59 t.verticesRan++;
60 }
61 });
62
63 t.graph.vertex({
64 name: 'secondDependent',
65 dependencies: ['root'],
66 action() {
67
68 t.verticesRan += 2;
69 }
70 });
71
72 await t.graph.run('root');
73 t.equal(t.verticesRan, 3, 'It runs dependent vertices on completion of a vertex\'s action');
74 });
75
76 Tap.test(async (t) => {
77
78 t.graph.vertex({
79 name: 'root',
80 action() { }
81 });
82
83 t.graph.vertex({
84 name: 'firstDependent',
85 dependencies: ['root'],
86 action() {
87
88 return 1;
89 }
90 });
91
92 t.graph.vertex({
93 name: 'secondDependent',
94 dependencies: ['root'],
95 action() {
96
97 return 2;
98 }
99 });
100
101 t.graph.vertex({
102 name: 'final',
103 dependencies: ['firstDependent', 'secondDependent'],
104 action(state) {
105
106 t.verticesRan = state.firstDependent + state.secondDependent;
107 }
108 });
109
110 await t.graph.run('root');
111 t.equal(t.verticesRan, 3, 'It ensures dependencies state is available before running dependents');
112 });
113
114 Tap.test(async (t) => {
115
116 t.graph.vertex({
117 name: 'root',
118 action() {
119
120 return 101;
121 }
122 });
123
124 t.graph.vertex({
125 name: 'stateDependent',
126 dependencies: ['root'],
127 action(state) {
128
129 t.verticesRan = state.root;
130 }
131 });
132
133 await t.graph.run('root');
134 t.equal(t.verticesRan, 101, 'It gives dependent vertices a state including their dependencies\' results');
135 });
136
137 Tap.test(async (t) => {
138
139 t.graph.vertex({
140 name: 'root',
141 action() {
142
143 throw new Error('Unexpected root problem');
144 }
145 });
146
147 await t.rejects(t.graph.run('root'), 'It throws an error if a vertex throws an error');
148 });
149
150 Tap.test(async (t) => {
151
152 t.graph.vertex({
153 name: 'root',
154 action() {
155
156 t.verticesRan++;
157 return 1;
158 }
159 });
160
161 await t.graph.run('root');
162 await t.graph.run('root');
163 t.equal(t.verticesRan, 1, 'It runs a vertex only once');
164 });
165
166 Tap.test( (t) => {
167
168 t.graph.vertex({
169 name: 'root',
170 action() {}
171 });
172
173 t.graph.vertex({
174 name: 'firstDependent',
175 dependencies: ['root'],
176 action() {}
177 });
178
179 t.graph.vertex({
180 name: 'secondDependent',
181 dependencies: ['root'],
182 action() {}
183 });
184
185 t.graph.vertex({
186 name: 'final',
187 dependencies: ['firstDependent', 'secondDependent'],
188 action() {}
189 });
190
191 t.matchSnapshot(t.graph.toString(), 'It can convert to a string representing the graph in graphviz format');
192 t.end();
193 });
194
195 Tap.test('It colorizes the graph based on execution results', async (t) => {
196
197 t.graph.vertex({
198 name: 'root',
199 action() {}
200 });
201
202 t.graph.vertex({
203 name: 'firstDependent',
204 dependencies: ['root'],
205 action() {}
206 });
207
208 t.graph.vertex({
209 name: 'secondDependent',
210 dependencies: ['root'],
211 action() {
212
213 throw new Error('Second dependent has failed');
214 }
215 });
216
217 t.graph.vertex({
218 name: 'final',
219 dependencies: ['firstDependent', 'secondDependent'],
220 action() {}
221 });
222
223 await t.rejects(t.graph.run('root'), 'It throws an error if a sub-step fails');
224 t.matchSnapshot(t.graph.toString(), 'It adds the right colors according to execution');
225 });