UNPKG

5.42 kBJavaScriptView Raw
1var assert = require('assert');
2
3var wagner = require('../');
4
5/* `invokeAsync()` is the primary function you will use to execute
6 * async code with Wagner. It takes as arguments a function that
7 * takes an error and a list of parameters, and a map of *locals*. */
8describe('`wagner.invokeAsync()`', function() {
9 /* Wagner's most basic functionality is to register an async
10 * task by name, and then utilize the value computed by the
11 * async task in subsequent tasks. */
12 it('allows you to execute async tasks based on parameter names', function(done) {
13 wagner.task('eggs', function(callback) {
14 setTimeout(function() {
15 callback(null, 'done cooking!');
16 }, 5);
17 });
18
19 wagner.invokeAsync(function(error, eggs) {
20 assert.ok(!error);
21 assert.equal(eggs, 'done cooking!');
22 done();
23 }, {});
24 });
25
26 /* *locals* are values specific to a particular execution of
27 * `invokeAsync()`. They may be utilized by any task in the
28 * task graph. */
29 it('allows you to use locals', function(done) {
30 wagner.task('eggs', function(number, callback) {
31 setTimeout(function() {
32 callback(null, 'finished making ' + number + ' eggs');
33 }, 5);
34 });
35
36 wagner.invokeAsync(function(error, eggs) {
37 assert.ok(!error);
38 assert.equal(eggs, 'finished making 4 eggs');
39 done();
40 }, { number: 4 });
41 });
42
43 /* Tasks can rely on each other, and each task is executed as soon
44 * as all its dependencies are met. */
45 it('executes tasks with maximum parallelization', function(done) {
46 var executed = {};
47
48 wagner.task('pan', function(callback) {
49 setTimeout(function() {
50 executed['pan'] = true;
51 callback(null, 'finished heating pan');
52 }, 5);
53 });
54
55 wagner.task('eggs', function(counts, pan, callback) {
56 assert.ok(!executed['bacon']);
57 setTimeout(function() {
58 executed['eggs'] = true;
59 callback(null, 'finished making ' + counts.eggs + ' eggs');
60 }, 5);
61 });
62
63 wagner.task('bacon', function(counts, pan, callback) {
64 assert.ok(!executed['eggs']);
65 setTimeout(function() {
66 executed['bacon'] = true;
67 callback(null, 'finished making ' + counts.bacon + ' bacon strips');
68 }, 5);
69 });
70
71 wagner.invokeAsync(
72 function(error, eggs, bacon) {
73 assert.ok(!error);
74 assert.ok(executed['pan']);
75 assert.equal(eggs, 'finished making 4 eggs');
76 assert.equal(bacon, 'finished making 3 bacon strips');
77 done();
78 },
79 { counts: { eggs: 4, bacon: 3 } });
80 });
81
82 /* If any task in the execution tree returns an error, execution
83 * is stopped immediately and the function is called with the error
84 * as the first parameter. */
85 it('bubbles up the first error', function(done) {
86 wagner.task('eggs', function(callback) {
87 setTimeout(function() {
88 callback('no eggs left!');
89 }, 5);
90 });
91
92 wagner.task('bacon', function(callback) {
93 setTimeout(function() {
94 callback('no bacon left!');
95 }, 25);
96 });
97
98 wagner.invokeAsync(
99 function(error, eggs, bacon) {
100 assert.equal(error, 'no eggs left!');
101 assert.ok(!eggs);
102 assert.ok(!bacon);
103 done();
104 },
105 {});
106 });
107
108 /* For compatibility with the `yield` keyword, as well as chaining,
109 * `invokeAsync()` returns a
110 * [bluebird](https://www.npmjs.org/package/bluebird) promise that is
111 * rejected if an error occurs in any of the tasks, or fulfilled with
112 * the return value of the provided function otherwise. */
113 it('returns an Promises/A+ conformant promise', function(done) {
114 wagner.task('valkyrie', function(callback) {
115 setTimeout(function() {
116 callback(null, 'valkyrie');
117 }, 0);
118 });
119
120 var promise = wagner.invokeAsync(function(error, valkyrie) {
121 return valkyrie;
122 }, {});
123
124 promise.then(function(v) {
125 assert.equal(v, 'valkyrie');
126 done();
127 });
128 });
129});
130
131/* `invoke()` is the synchronous version of `invokeAsync()`. It will
132 * *only* execute sync tasks (tasks that don't take a parameter named
133 * 'callback' or 'cb') and throw an error if there are any async tasks. */
134describe('`wagner.invoke()`', function() {
135 it('executes sync tasks and returns the return value of the provided function', function() {
136 wagner.task('tristan', function() {
137 return 'tristan';
138 });
139
140 wagner.task('isolde', function() {
141 return 'isolde';
142 });
143
144 var e;
145 var t;
146 var i;
147 var returnValue = wagner.invoke(function(error, tristan, isolde) {
148 e = error;
149 t = tristan;
150 i = isolde;
151
152 return 'done';
153 });
154
155 assert.ok(!e);
156 assert.equal(t, 'tristan');
157 assert.equal(i, 'isolde');
158 assert.equal(returnValue, 'done');
159 });
160});
161
162/* For convenience, Wagner includes its own `.parallel()` function for
163 * executing a collection of async functions in parallel. */
164describe('`wagner.parallel()`', function() {
165 it('takes a map and executes a function for all key/value pairs', function(done) {
166 wagner.parallel(
167 { first: 'eggs', second: 'bacon' },
168 function(value, key, callback) {
169 callback(null, value.toUpperCase());
170 },
171 function(error, results) {
172 assert.ok(!error);
173 assert.equal(results.first.result, 'EGGS');
174 assert.equal(results.second.result, 'BACON');
175 done();
176 });
177 });
178});
\No newline at end of file