First commit
This commit is contained in:
104
node_modules/vasync/tests/compat.js
generated
vendored
Normal file
104
node_modules/vasync/tests/compat.js
generated
vendored
Normal file
@ -0,0 +1,104 @@
|
||||
/*
|
||||
* tests/compat.js: Some of the APIs provided by vasync are intended to be
|
||||
* API-compatible with node-async, so we incorporate the tests from node-async
|
||||
* directly here. These are copied from https://github.com/caolan/async,
|
||||
* available under the MIT license. To make it easy to update this from the
|
||||
* source, this file should remain unchanged from the source except for this
|
||||
* header comment, the change to the "require" line, and deleted lines for
|
||||
* unimplemented functions.
|
||||
*
|
||||
* The following tests are deliberately omitted:
|
||||
*
|
||||
* o "waterfall non-array": Per Joyent's Best Practices for Node.js Error
|
||||
* Handling, we're strict about argument types and throw on these programmer
|
||||
* errors rather than emitting them asynchronously.
|
||||
*
|
||||
* o "waterfall multiple callback calls": We deliberately disallow a waterfall
|
||||
* function to invoke its callback more than once, so we don't test for that
|
||||
* here. The behavior that node-async allows can potentially be used to fork
|
||||
* the waterfall, which may be useful, but it's often used instead as an
|
||||
* excuse to write code sloppily. And the downside is that it makes it really
|
||||
* hard to understand bugs where the waterfall was resumed too early. For
|
||||
* now, we're disallowing it, but if the forking behavior becomes useful, we
|
||||
* can always make our version less strict.
|
||||
*/
|
||||
var async = require('../lib/vasync');
|
||||
|
||||
exports['waterfall'] = function(test){
|
||||
test.expect(6);
|
||||
var call_order = [];
|
||||
async.waterfall([
|
||||
function(callback){
|
||||
call_order.push('fn1');
|
||||
setTimeout(function(){callback(null, 'one', 'two');}, 0);
|
||||
},
|
||||
function(arg1, arg2, callback){
|
||||
call_order.push('fn2');
|
||||
test.equals(arg1, 'one');
|
||||
test.equals(arg2, 'two');
|
||||
setTimeout(function(){callback(null, arg1, arg2, 'three');}, 25);
|
||||
},
|
||||
function(arg1, arg2, arg3, callback){
|
||||
call_order.push('fn3');
|
||||
test.equals(arg1, 'one');
|
||||
test.equals(arg2, 'two');
|
||||
test.equals(arg3, 'three');
|
||||
callback(null, 'four');
|
||||
},
|
||||
function(arg4, callback){
|
||||
call_order.push('fn4');
|
||||
test.same(call_order, ['fn1','fn2','fn3','fn4']);
|
||||
callback(null, 'test');
|
||||
}
|
||||
], function(err){
|
||||
test.done();
|
||||
});
|
||||
};
|
||||
|
||||
exports['waterfall empty array'] = function(test){
|
||||
async.waterfall([], function(err){
|
||||
test.done();
|
||||
});
|
||||
};
|
||||
|
||||
exports['waterfall no callback'] = function(test){
|
||||
async.waterfall([
|
||||
function(callback){callback();},
|
||||
function(callback){callback(); test.done();}
|
||||
]);
|
||||
};
|
||||
|
||||
exports['waterfall async'] = function(test){
|
||||
var call_order = [];
|
||||
async.waterfall([
|
||||
function(callback){
|
||||
call_order.push(1);
|
||||
callback();
|
||||
call_order.push(2);
|
||||
},
|
||||
function(callback){
|
||||
call_order.push(3);
|
||||
callback();
|
||||
},
|
||||
function(){
|
||||
test.same(call_order, [1,2,3]);
|
||||
test.done();
|
||||
}
|
||||
]);
|
||||
};
|
||||
|
||||
exports['waterfall error'] = function(test){
|
||||
test.expect(1);
|
||||
async.waterfall([
|
||||
function(callback){
|
||||
callback('error');
|
||||
},
|
||||
function(callback){
|
||||
test.ok(false, 'next function should not be called');
|
||||
callback();
|
||||
}
|
||||
], function(err){
|
||||
test.equals(err, 'error');
|
||||
});
|
||||
setTimeout(test.done, 50);
|
||||
};
|
||||
91
node_modules/vasync/tests/compat_tryEach.js
generated
vendored
Normal file
91
node_modules/vasync/tests/compat_tryEach.js
generated
vendored
Normal file
@ -0,0 +1,91 @@
|
||||
var async = require('../lib/vasync');
|
||||
|
||||
/*
|
||||
* tryEach tests, transliterated from mocha to tap.
|
||||
*
|
||||
* They are nearly identical except for some details related to vasync. For
|
||||
* example, we don't support calling the callback more than once from any of
|
||||
* the given functions.
|
||||
*/
|
||||
|
||||
|
||||
exports['tryEach no callback'] = function (test) {
|
||||
async.tryEach([]);
|
||||
test.done();
|
||||
};
|
||||
exports['tryEach empty'] = function (test) {
|
||||
async.tryEach([], function (err, results) {
|
||||
test.equals(err, null);
|
||||
test.same(results, undefined);
|
||||
test.done();
|
||||
});
|
||||
};
|
||||
exports['tryEach one task, multiple results'] = function (test) {
|
||||
var RESULTS = ['something', 'something2'];
|
||||
async.tryEach([
|
||||
function (callback) {
|
||||
callback(null, RESULTS[0], RESULTS[1]);
|
||||
}
|
||||
], function (err, results) {
|
||||
test.equals(err, null);
|
||||
test.same(results, RESULTS);
|
||||
test.done();
|
||||
});
|
||||
};
|
||||
exports['tryEach one task'] = function (test) {
|
||||
var RESULT = 'something';
|
||||
async.tryEach([
|
||||
function (callback) {
|
||||
callback(null, RESULT);
|
||||
}
|
||||
], function (err, results) {
|
||||
test.equals(err, null);
|
||||
test.same(results, RESULT);
|
||||
test.done();
|
||||
});
|
||||
};
|
||||
exports['tryEach two tasks, one failing'] = function (test) {
|
||||
var RESULT = 'something';
|
||||
async.tryEach([
|
||||
function (callback) {
|
||||
callback(new Error('Failure'), {});
|
||||
},
|
||||
function (callback) {
|
||||
callback(null, RESULT);
|
||||
}
|
||||
], function (err, results) {
|
||||
test.equals(err, null);
|
||||
test.same(results, RESULT);
|
||||
test.done();
|
||||
});
|
||||
};
|
||||
exports['tryEach two tasks, both failing'] = function (test) {
|
||||
var ERROR_RESULT = new Error('Failure2');
|
||||
async.tryEach([
|
||||
function (callback) {
|
||||
callback(new Error('Should not stop here'));
|
||||
},
|
||||
function (callback) {
|
||||
callback(ERROR_RESULT);
|
||||
}
|
||||
], function (err, results) {
|
||||
test.equals(err, ERROR_RESULT);
|
||||
test.same(results, undefined);
|
||||
test.done();
|
||||
});
|
||||
};
|
||||
exports['tryEach two tasks, non failing'] = function (test) {
|
||||
var RESULT = 'something';
|
||||
async.tryEach([
|
||||
function (callback) {
|
||||
callback(null, RESULT);
|
||||
},
|
||||
function () {
|
||||
test.fail('Should not been called');
|
||||
}
|
||||
], function (err, results) {
|
||||
test.equals(err, null);
|
||||
test.same(results, RESULT);
|
||||
test.done();
|
||||
});
|
||||
};
|
||||
226
node_modules/vasync/tests/filter.js
generated
vendored
Normal file
226
node_modules/vasync/tests/filter.js
generated
vendored
Normal file
@ -0,0 +1,226 @@
|
||||
/*
|
||||
* Tests the "filter", "filterSeries", and "filterLimit" functions
|
||||
*/
|
||||
|
||||
var mod_util = require('util');
|
||||
|
||||
var mod_tap = require('tap');
|
||||
var mod_vasync = require('..');
|
||||
|
||||
mod_tap.test('filterSeries', function (test) {
|
||||
var inputs = [0, 1, 2, 3, 4, 5];
|
||||
var curTasks = 0;
|
||||
var maxTasks = 0;
|
||||
// filterSeries has an implicit limit of 1 concurrent operation
|
||||
var limit = 1;
|
||||
|
||||
function filterFunc(input, cb) {
|
||||
curTasks++;
|
||||
if (curTasks > maxTasks) {
|
||||
maxTasks = curTasks;
|
||||
}
|
||||
test.ok(curTasks <= limit, mod_util.format(
|
||||
'input %d: current tasks %d <= %d',
|
||||
input, curTasks, limit));
|
||||
|
||||
setTimeout(function () {
|
||||
curTasks--;
|
||||
cb(null, input < 2 || input === 4);
|
||||
}, 50);
|
||||
}
|
||||
|
||||
mod_vasync.filterSeries(inputs, filterFunc,
|
||||
function filterDone(err, results) {
|
||||
|
||||
test.ok(!err, 'error unset');
|
||||
test.equal(maxTasks, limit, 'max tasks reached limit');
|
||||
test.deepEqual(results, [0, 1, 4], 'results array correct');
|
||||
test.end();
|
||||
});
|
||||
});
|
||||
|
||||
mod_tap.test('filterLimit', function (test) {
|
||||
var inputs = [0, 1, 2, 3, 4, 5];
|
||||
var curTasks = 0;
|
||||
var maxTasks = 0;
|
||||
var limit = 2;
|
||||
|
||||
function filterFunc(input, cb) {
|
||||
curTasks++;
|
||||
if (curTasks > maxTasks) {
|
||||
maxTasks = curTasks;
|
||||
}
|
||||
test.ok(curTasks <= limit, mod_util.format(
|
||||
'input %d: current tasks %d <= %d',
|
||||
input, curTasks, limit));
|
||||
|
||||
setTimeout(function () {
|
||||
curTasks--;
|
||||
cb(null, input < 2 || input === 4);
|
||||
}, 50);
|
||||
}
|
||||
|
||||
mod_vasync.filterLimit(inputs, limit, filterFunc,
|
||||
function filterDone(err, results) {
|
||||
|
||||
test.ok(!err, 'error unset');
|
||||
test.equal(maxTasks, limit, 'max tasks reached limit');
|
||||
test.deepEqual(results, [0, 1, 4], 'results array correct');
|
||||
test.end();
|
||||
});
|
||||
});
|
||||
|
||||
mod_tap.test('filter (maintain order)', function (test) {
|
||||
var inputs = [0, 1, 2, 3, 4, 5];
|
||||
var limit = inputs.length;
|
||||
var storedValues = [];
|
||||
|
||||
function filterFunc(input, cb) {
|
||||
/*
|
||||
* Hold every callback in an array to be called when all
|
||||
* filterFunc's have run. This way, we can ensure that all
|
||||
* tasks have started without waiting for any others to finish.
|
||||
*/
|
||||
storedValues.push({
|
||||
input: input,
|
||||
cb: cb
|
||||
});
|
||||
|
||||
test.ok(storedValues.length <= limit, mod_util.format(
|
||||
'input %d: current tasks %d <= %d',
|
||||
input, storedValues.length, limit));
|
||||
|
||||
/*
|
||||
* When this constraint is true, all filterFunc's have run for
|
||||
* each input. We now call all callbacks in a pre-determined
|
||||
* order (out of order of the original) to ensure the final
|
||||
* array is in the correct order.
|
||||
*/
|
||||
if (storedValues.length === inputs.length) {
|
||||
[5, 2, 0, 1, 4, 3].forEach(function (i) {
|
||||
var o = storedValues[i];
|
||||
o.cb(null, o.input < 2 || o.input === 4);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
mod_vasync.filter(inputs, filterFunc,
|
||||
function filterDone(err, results) {
|
||||
|
||||
test.ok(!err, 'error unset');
|
||||
test.equal(storedValues.length, inputs.length,
|
||||
'max tasks reached limit');
|
||||
test.deepEqual(results, [0, 1, 4], 'results array correct');
|
||||
test.end();
|
||||
});
|
||||
});
|
||||
|
||||
mod_tap.test('filterSeries error handling', function (test) {
|
||||
/*
|
||||
* We will error half way through the list of inputs to ensure that
|
||||
* first half are processed while the second half are ignored.
|
||||
*/
|
||||
var inputs = [0, 1, 2, 3, 4, 5];
|
||||
|
||||
function filterFunc(input, cb) {
|
||||
switch (input) {
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
cb(null, true);
|
||||
break;
|
||||
case 3:
|
||||
cb(new Error('error on ' + input));
|
||||
break;
|
||||
case 4:
|
||||
case 5:
|
||||
test.ok(false, 'processed too many inputs');
|
||||
cb(new Error('processed too many inputs'));
|
||||
break;
|
||||
default:
|
||||
test.ok(false, 'unexpected input: ' + input);
|
||||
cb(new Error('unexpected input'));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
mod_vasync.filterSeries(inputs, filterFunc,
|
||||
function filterDone(err, results) {
|
||||
|
||||
test.ok(err, 'error set');
|
||||
test.ok(err.message === 'error on 3', 'error on input 3');
|
||||
test.ok(results === undefined, 'results is unset');
|
||||
test.end();
|
||||
});
|
||||
});
|
||||
|
||||
mod_tap.test('filterSeries double callback', function (test) {
|
||||
var inputs = [0, 1, 2, 3, 4, 5];
|
||||
|
||||
function filterFunc(input, cb) {
|
||||
switch (input) {
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
cb(null, true);
|
||||
break;
|
||||
case 3:
|
||||
/*
|
||||
* The first call to cb() should "win" - meaning this
|
||||
* value will be filtered out of the final array of
|
||||
* results.
|
||||
*/
|
||||
cb(null, false);
|
||||
test.throws(function () {
|
||||
cb(null, true);
|
||||
});
|
||||
break;
|
||||
case 4:
|
||||
/*
|
||||
* Like input 3, all subsequent calls to cb() will
|
||||
* throw an error and not affect the original call to
|
||||
* cb().
|
||||
*/
|
||||
cb(null, true);
|
||||
test.throws(function () {
|
||||
cb(new Error('uh oh'));
|
||||
});
|
||||
break;
|
||||
case 5:
|
||||
cb(null, true);
|
||||
break;
|
||||
default:
|
||||
test.ok(false, 'unexpected input: ' + input);
|
||||
cb(new Error('unexpected input'));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
mod_vasync.filterSeries(inputs, filterFunc,
|
||||
function filterDone(err, results) {
|
||||
|
||||
test.ok(!err, 'error not set');
|
||||
test.deepEqual(results, [0, 1, 2, 4, 5],
|
||||
'results array correct');
|
||||
test.end();
|
||||
});
|
||||
});
|
||||
|
||||
mod_tap.test('filter push to queue object error', function (test) {
|
||||
var inputs = [0, 1, 2, 3, 4, 5];
|
||||
|
||||
function filterFunc(input, cb) {
|
||||
cb(null, true);
|
||||
}
|
||||
|
||||
var q = mod_vasync.filterSeries(inputs, filterFunc,
|
||||
function filterDone(err, results) {
|
||||
|
||||
test.end();
|
||||
});
|
||||
|
||||
test.equal(q.closed, true, 'queue is closed');
|
||||
test.throws(function () {
|
||||
q.push(6);
|
||||
});
|
||||
});
|
||||
25
node_modules/vasync/tests/issue-21.js
generated
vendored
Normal file
25
node_modules/vasync/tests/issue-21.js
generated
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Tests that if the user modifies the list of functions passed to
|
||||
* vasync.pipeline, vasync ignores the changes and does not crash.
|
||||
*/
|
||||
var assert = require('assert');
|
||||
var vasync = require('../lib/vasync');
|
||||
var count = 0;
|
||||
var funcs;
|
||||
|
||||
function doStuff(_, callback)
|
||||
{
|
||||
count++;
|
||||
setImmediate(callback);
|
||||
}
|
||||
|
||||
funcs = [ doStuff, doStuff, doStuff ];
|
||||
|
||||
vasync.pipeline({
|
||||
'funcs': funcs
|
||||
}, function (err) {
|
||||
assert.ok(!err);
|
||||
assert.ok(count === 3);
|
||||
});
|
||||
|
||||
funcs.push(doStuff);
|
||||
132
node_modules/vasync/tests/pipeline.js
generated
vendored
Normal file
132
node_modules/vasync/tests/pipeline.js
generated
vendored
Normal file
@ -0,0 +1,132 @@
|
||||
/*
|
||||
* Tests the "pipeline" primitive.
|
||||
*/
|
||||
|
||||
var mod_tap = require('tap');
|
||||
var mod_vasync = require('..');
|
||||
var st;
|
||||
|
||||
|
||||
mod_tap.test('empty pipeline', function (test) {
|
||||
var count = 0;
|
||||
st = mod_vasync.pipeline({'funcs': [], 'arg': null},
|
||||
function (err, result) {
|
||||
|
||||
test.ok(err === null);
|
||||
test.ok(result.ndone === 0);
|
||||
test.ok(result.nerrors === 0);
|
||||
test.ok(result.operations.length === 0);
|
||||
test.ok(result.successes.length === 0);
|
||||
test.equal(count, 1);
|
||||
test.end();
|
||||
});
|
||||
count++;
|
||||
test.ok(st.ndone === 0);
|
||||
test.ok(st.nerrors === 0);
|
||||
test.ok(st.operations.length === 0);
|
||||
test.ok(st.successes.length === 0);
|
||||
});
|
||||
|
||||
mod_tap.test('normal 4-stage pipeline', function (test) {
|
||||
var count = 0;
|
||||
st = mod_vasync.pipeline({'funcs': [
|
||||
function func1(_, cb) {
|
||||
test.equal(st.successes[0], undefined,
|
||||
'func1: successes');
|
||||
test.ok(count === 0, 'func1: count === 0');
|
||||
test.ok(st.ndone === 0);
|
||||
count++;
|
||||
setImmediate(cb, null, count);
|
||||
},
|
||||
function func2(_, cb) {
|
||||
test.equal(st.successes[0], 1, 'func2: successes');
|
||||
test.ok(count == 1, 'func2: count == 1');
|
||||
test.ok(st.ndone === 1);
|
||||
test.ok(st.operations[0].status == 'ok');
|
||||
test.ok(st.operations[1].status == 'pending');
|
||||
test.ok(st.operations[2].status == 'waiting');
|
||||
count++;
|
||||
setImmediate(cb, null, count);
|
||||
},
|
||||
function (_, cb) {
|
||||
test.equal(st.successes[0], 1, 'func3: successes');
|
||||
test.equal(st.successes[1], 2, 'func3: successes');
|
||||
test.ok(count == 2, 'func3: count == 2');
|
||||
test.ok(st.ndone === 2);
|
||||
count++;
|
||||
setImmediate(cb, null, count);
|
||||
},
|
||||
function func4(_, cb) {
|
||||
test.equal(st.successes[0], 1, 'func4: successes');
|
||||
test.equal(st.successes[1], 2, 'func4: successes');
|
||||
test.equal(st.successes[2], 3, 'func4: successes');
|
||||
test.ok(count == 3, 'func4: count == 3');
|
||||
test.ok(st.ndone === 3);
|
||||
count++;
|
||||
setImmediate(cb, null, count);
|
||||
}
|
||||
]}, function (err, result) {
|
||||
test.ok(count == 4, 'final: count == 4');
|
||||
test.ok(err === null, 'no error');
|
||||
test.ok(result === st);
|
||||
test.equal(result, st, 'final-cb: st == result');
|
||||
test.equal(st.successes[0], 1, 'final-cb: successes');
|
||||
test.equal(st.successes[1], 2, 'final-cb: successes');
|
||||
test.equal(st.successes[2], 3, 'final-cb: successes');
|
||||
test.equal(st.successes[3], 4, 'final-cb: successes');
|
||||
test.ok(st.ndone === 4);
|
||||
test.ok(st.nerrors === 0);
|
||||
test.ok(st.operations.length === 4);
|
||||
test.ok(st.successes.length === 4);
|
||||
test.ok(st.operations[0].status == 'ok');
|
||||
test.ok(st.operations[1].status == 'ok');
|
||||
test.ok(st.operations[2].status == 'ok');
|
||||
test.ok(st.operations[3].status == 'ok');
|
||||
test.end();
|
||||
});
|
||||
test.ok(st.ndone === 0);
|
||||
test.ok(st.nerrors === 0);
|
||||
test.ok(st.operations.length === 4);
|
||||
test.ok(st.operations[0].funcname == 'func1', 'func1 name');
|
||||
test.ok(st.operations[0].status == 'pending');
|
||||
test.ok(st.operations[1].funcname == 'func2', 'func2 name');
|
||||
test.ok(st.operations[1].status == 'waiting');
|
||||
test.ok(st.operations[2].funcname == '(anon)', 'anon name');
|
||||
test.ok(st.operations[2].status == 'waiting');
|
||||
test.ok(st.operations[3].funcname == 'func4', 'func4 name');
|
||||
test.ok(st.operations[3].status == 'waiting');
|
||||
test.ok(st.successes.length === 0);
|
||||
});
|
||||
|
||||
mod_tap.test('bailing out early', function (test) {
|
||||
var count = 0;
|
||||
st = mod_vasync.pipeline({'funcs': [
|
||||
function func1(_, cb) {
|
||||
test.ok(count === 0, 'func1: count === 0');
|
||||
count++;
|
||||
setImmediate(cb, null, count);
|
||||
},
|
||||
function func2(_, cb) {
|
||||
test.ok(count == 1, 'func2: count == 1');
|
||||
count++;
|
||||
setImmediate(cb, new Error('boom!'));
|
||||
},
|
||||
function func3(_, cb) {
|
||||
test.ok(count == 2, 'func3: count == 2');
|
||||
count++;
|
||||
setImmediate(cb, null, count);
|
||||
}
|
||||
]}, function (err, result) {
|
||||
test.ok(count == 2, 'final: count == 3');
|
||||
test.equal(err.message, 'boom!');
|
||||
test.ok(result === st);
|
||||
test.equal(result, st, 'final-cb: st == result');
|
||||
test.ok(st.ndone == 2);
|
||||
test.ok(st.nerrors == 1);
|
||||
test.ok(st.operations[0].status == 'ok');
|
||||
test.ok(st.operations[1].status == 'fail');
|
||||
test.ok(st.operations[2].status == 'waiting');
|
||||
test.ok(st.successes.length == 1);
|
||||
test.end();
|
||||
});
|
||||
});
|
||||
284
node_modules/vasync/tests/queue.js
generated
vendored
Normal file
284
node_modules/vasync/tests/queue.js
generated
vendored
Normal file
@ -0,0 +1,284 @@
|
||||
/* vim: set ts=8 sts=8 sw=8 noet: */
|
||||
|
||||
var mod_tap = require('tap');
|
||||
var mod_vasync = require('..');
|
||||
|
||||
function
|
||||
immediate_worker(task, next)
|
||||
{
|
||||
setImmediate(function () {
|
||||
next();
|
||||
});
|
||||
}
|
||||
|
||||
function
|
||||
sametick_worker(task, next)
|
||||
{
|
||||
next();
|
||||
}
|
||||
|
||||
function
|
||||
random_delay_worker(task, next)
|
||||
{
|
||||
setTimeout(function () {
|
||||
next();
|
||||
}, Math.floor(Math.random() * 250));
|
||||
}
|
||||
|
||||
mod_tap.test('must not push after close', function (test) {
|
||||
test.plan(3);
|
||||
|
||||
var q = mod_vasync.queuev({
|
||||
worker: immediate_worker,
|
||||
concurrency: 10
|
||||
});
|
||||
test.ok(q);
|
||||
|
||||
test.doesNotThrow(function () {
|
||||
q.push({});
|
||||
}, 'push should not throw _before_ close()');
|
||||
|
||||
q.close();
|
||||
|
||||
/*
|
||||
* If we attempt to add tasks to the queue _after_ calling close(),
|
||||
* we should get an exception:
|
||||
*/
|
||||
test.throws(function () {
|
||||
q.push({});
|
||||
}, 'push should throw _after_ close()');
|
||||
|
||||
test.end();
|
||||
});
|
||||
|
||||
mod_tap.test('get \'end\' event with close()', function (test) {
|
||||
var task_count = 45;
|
||||
var tasks_finished = 0;
|
||||
var seen_end = false;
|
||||
var seen_drain = false;
|
||||
|
||||
test.plan(14 + task_count);
|
||||
|
||||
var q = mod_vasync.queuev({
|
||||
worker: random_delay_worker,
|
||||
concurrency: 5
|
||||
});
|
||||
test.ok(q);
|
||||
|
||||
/*
|
||||
* Enqueue a bunch of tasks; more than our concurrency:
|
||||
*/
|
||||
for (var i = 0; i < 45; i++) {
|
||||
q.push({}, function () {
|
||||
tasks_finished++;
|
||||
test.ok(true);
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
* Close the queue to signify that we're done now.
|
||||
*/
|
||||
test.equal(q.ended, false);
|
||||
test.equal(q.closed, false);
|
||||
q.close();
|
||||
test.equal(q.closed, true);
|
||||
test.equal(q.ended, false);
|
||||
|
||||
q.on('drain', function () {
|
||||
/*
|
||||
* 'drain' should fire before 'end':
|
||||
*/
|
||||
test.notOk(seen_drain);
|
||||
test.notOk(seen_end);
|
||||
seen_drain = true;
|
||||
});
|
||||
q.on('end', function () {
|
||||
/*
|
||||
* 'end' should fire after 'drain':
|
||||
*/
|
||||
test.ok(seen_drain);
|
||||
test.notOk(seen_end);
|
||||
seen_end = true;
|
||||
|
||||
/*
|
||||
* Check the public state:
|
||||
*/
|
||||
test.equal(q.closed, true);
|
||||
test.equal(q.ended, true);
|
||||
|
||||
/*
|
||||
* We should have fired the callbacks for _all_ enqueued
|
||||
* tasks by now:
|
||||
*/
|
||||
test.equal(task_count, tasks_finished);
|
||||
test.end();
|
||||
});
|
||||
|
||||
/*
|
||||
* Check that we see neither the 'drain', nor the 'end' event before
|
||||
* the end of this tick:
|
||||
*/
|
||||
test.notOk(seen_drain);
|
||||
test.notOk(seen_end);
|
||||
});
|
||||
|
||||
mod_tap.test('get \'end\' event with close() and no tasks', function (test) {
|
||||
var seen_drain = false;
|
||||
var seen_end = false;
|
||||
|
||||
test.plan(10);
|
||||
|
||||
var q = mod_vasync.queuev({
|
||||
worker: immediate_worker,
|
||||
concurrency: 10
|
||||
});
|
||||
|
||||
setImmediate(function () {
|
||||
test.notOk(seen_end);
|
||||
});
|
||||
|
||||
test.equal(q.ended, false);
|
||||
test.equal(q.closed, false);
|
||||
q.close();
|
||||
test.equal(q.closed, true);
|
||||
test.equal(q.ended, false);
|
||||
test.notOk(seen_end);
|
||||
|
||||
q.on('drain', function () {
|
||||
seen_drain = true;
|
||||
});
|
||||
q.on('end', function () {
|
||||
/*
|
||||
* We do not expect to see a 'drain' event, as there were no
|
||||
* tasks pushed onto the queue before we closed it.
|
||||
*/
|
||||
test.notOk(seen_drain);
|
||||
test.notOk(seen_end);
|
||||
test.equal(q.closed, true);
|
||||
test.equal(q.ended, true);
|
||||
seen_end = true;
|
||||
test.end();
|
||||
});
|
||||
});
|
||||
|
||||
/*
|
||||
* We want to ensure that both the 'drain' event and the q.drain() hook are
|
||||
* called the same number of times:
|
||||
*/
|
||||
mod_tap.test('equivalence of on(\'drain\') and q.drain()', function (test) {
|
||||
var enqcount = 4;
|
||||
var drains = 4;
|
||||
var ee_count = 0;
|
||||
var fn_count = 0;
|
||||
|
||||
test.plan(enqcount + drains + 3);
|
||||
|
||||
var q = mod_vasync.queuev({
|
||||
worker: immediate_worker,
|
||||
concurrency: 10
|
||||
});
|
||||
|
||||
var enq = function () {
|
||||
if (--enqcount < 0)
|
||||
return;
|
||||
|
||||
q.push({}, function () {
|
||||
test.ok(true, 'task completion');
|
||||
});
|
||||
};
|
||||
|
||||
var draino = function () {
|
||||
test.ok(true, 'drain called');
|
||||
if (--drains === 0) {
|
||||
test.equal(q.closed, false, 'not closed');
|
||||
test.equal(q.ended, false, 'not ended');
|
||||
test.equal(fn_count, ee_count, 'same number of calls');
|
||||
test.end();
|
||||
}
|
||||
};
|
||||
|
||||
enq();
|
||||
enq();
|
||||
|
||||
q.on('drain', function () {
|
||||
ee_count++;
|
||||
enq();
|
||||
draino();
|
||||
});
|
||||
q.drain = function () {
|
||||
fn_count++;
|
||||
enq();
|
||||
draino();
|
||||
};
|
||||
});
|
||||
|
||||
/*
|
||||
* In the past, we've only handed on the _first_ argument to the task completion
|
||||
* callback. Make sure we hand on _all_ of the arguments now:
|
||||
*/
|
||||
mod_tap.test('ensure all arguments passed to push() callback', function (test) {
|
||||
test.plan(13);
|
||||
|
||||
var q = mod_vasync.queuev({
|
||||
worker: function (task, callback) {
|
||||
if (task.fail) {
|
||||
callback(new Error('guru meditation'));
|
||||
return;
|
||||
}
|
||||
callback(null, 1, 2, 3, 5, 8);
|
||||
},
|
||||
concurrency: 1
|
||||
});
|
||||
|
||||
q.push({ fail: true }, function (err, a, b, c, d, e) {
|
||||
test.ok(err, 'got the error');
|
||||
test.equal(err.message, 'guru meditation');
|
||||
test.type(a, 'undefined');
|
||||
test.type(b, 'undefined');
|
||||
test.type(c, 'undefined');
|
||||
test.type(d, 'undefined');
|
||||
test.type(e, 'undefined');
|
||||
});
|
||||
|
||||
q.push({ fail: false }, function (err, a, b, c, d, e) {
|
||||
test.notOk(err, 'got no error');
|
||||
test.equal(a, 1);
|
||||
test.equal(b, 2);
|
||||
test.equal(c, 3);
|
||||
test.equal(d, 5);
|
||||
test.equal(e, 8);
|
||||
});
|
||||
|
||||
q.drain = function () {
|
||||
test.end();
|
||||
};
|
||||
});
|
||||
|
||||
mod_tap.test('queue kill', function (test) {
|
||||
// Derived from async queue.kill test
|
||||
var count = 0;
|
||||
var q = mod_vasync.queuev({
|
||||
worker: function (task, callback) {
|
||||
setImmediate(function () {
|
||||
test.ok(++count < 2,
|
||||
'Function should be called once');
|
||||
callback();
|
||||
});
|
||||
},
|
||||
concurrency: 1
|
||||
});
|
||||
q.drain = function () {
|
||||
test.ok(false, 'Function should never be called');
|
||||
};
|
||||
|
||||
// Queue twice, the first will exec immediately
|
||||
q.push(0);
|
||||
q.push(0);
|
||||
|
||||
q.kill();
|
||||
|
||||
q.on('end', function () {
|
||||
test.ok(q.killed);
|
||||
test.end();
|
||||
});
|
||||
});
|
||||
181
node_modules/vasync/tests/queue_concurrency.js
generated
vendored
Normal file
181
node_modules/vasync/tests/queue_concurrency.js
generated
vendored
Normal file
@ -0,0 +1,181 @@
|
||||
/* vim: set ts=8 sts=8 sw=8 noet: */
|
||||
|
||||
var mod_tap = require('tap');
|
||||
var mod_vasync = require('..');
|
||||
|
||||
function
|
||||
latched_worker(task, cb)
|
||||
{
|
||||
if (task.immediate) {
|
||||
cb();
|
||||
} else {
|
||||
task.latched = true;
|
||||
task.unlatch = function () {
|
||||
task.latched = false;
|
||||
cb();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
function
|
||||
unlatchAll(tasks)
|
||||
{
|
||||
tasks.forEach(function (t) {
|
||||
if (t.latched) {
|
||||
t.unlatch();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function
|
||||
setAllImmediate(tasks)
|
||||
{
|
||||
tasks.forEach(function (t) {
|
||||
t.immediate = true;
|
||||
});
|
||||
}
|
||||
|
||||
mod_tap.test('test serial tasks', function (test) {
|
||||
test.plan(2);
|
||||
|
||||
var q = mod_vasync.queuev({
|
||||
worker: latched_worker,
|
||||
concurrency: 1
|
||||
});
|
||||
test.ok(q);
|
||||
|
||||
var tasks = [];
|
||||
for (var i = 0; i < 2; ++i) {
|
||||
tasks.push({
|
||||
'id': i,
|
||||
'latched': false,
|
||||
'immediate': false
|
||||
});
|
||||
}
|
||||
|
||||
setTimeout(function () {
|
||||
var latched = 0;
|
||||
tasks.forEach(function (t) {
|
||||
if (t.latched) {
|
||||
++latched;
|
||||
}
|
||||
});
|
||||
test.ok(latched === 1);
|
||||
unlatchAll(tasks);
|
||||
setAllImmediate(tasks);
|
||||
}, 10);
|
||||
|
||||
q.on('drain', function () {
|
||||
q.close();
|
||||
});
|
||||
|
||||
q.on('end', function () {
|
||||
test.end();
|
||||
});
|
||||
|
||||
q.push(tasks);
|
||||
});
|
||||
|
||||
mod_tap.test('test parallel tasks', function (test) {
|
||||
test.plan(2);
|
||||
|
||||
var q = mod_vasync.queuev({
|
||||
worker: latched_worker,
|
||||
concurrency: 2
|
||||
});
|
||||
test.ok(q);
|
||||
|
||||
var tasks = [];
|
||||
for (var i = 0; i < 3; ++i) {
|
||||
tasks.push({
|
||||
'id': i,
|
||||
'latched': false,
|
||||
'immediate': false
|
||||
});
|
||||
}
|
||||
|
||||
setTimeout(function () {
|
||||
var latched = 0;
|
||||
tasks.forEach(function (t) {
|
||||
if (t.latched) {
|
||||
++latched;
|
||||
}
|
||||
});
|
||||
test.ok(latched === 2);
|
||||
unlatchAll(tasks);
|
||||
setAllImmediate(tasks);
|
||||
}, 10);
|
||||
|
||||
q.on('drain', function () {
|
||||
q.close();
|
||||
});
|
||||
|
||||
q.on('end', function () {
|
||||
test.end();
|
||||
});
|
||||
|
||||
q.push(tasks);
|
||||
});
|
||||
|
||||
mod_tap.test('test ratchet up and down', function (test) {
|
||||
test.plan(8);
|
||||
|
||||
var q = mod_vasync.queuev({
|
||||
worker: latched_worker,
|
||||
concurrency: 2
|
||||
});
|
||||
test.ok(q);
|
||||
|
||||
var bounced = 0;
|
||||
var tasks = [];
|
||||
for (var i = 0; i < 21; ++i) {
|
||||
tasks.push({
|
||||
'id': i,
|
||||
'latched': false,
|
||||
'immediate': false
|
||||
});
|
||||
}
|
||||
|
||||
function count() {
|
||||
var latched = 0;
|
||||
tasks.forEach(function (t) {
|
||||
if (t.latched) {
|
||||
++latched;
|
||||
}
|
||||
});
|
||||
return (latched);
|
||||
}
|
||||
|
||||
function fiveLatch() {
|
||||
if (!q.closed) {
|
||||
++bounced;
|
||||
test.ok(count() === 5);
|
||||
q.updateConcurrency(2);
|
||||
unlatchAll(tasks);
|
||||
setTimeout(twoLatch, 10);
|
||||
}
|
||||
}
|
||||
|
||||
function twoLatch() {
|
||||
if (!q.closed) {
|
||||
++bounced;
|
||||
test.ok(count() === 2);
|
||||
q.updateConcurrency(5);
|
||||
unlatchAll(tasks);
|
||||
setTimeout(fiveLatch, 10);
|
||||
}
|
||||
}
|
||||
setTimeout(twoLatch, 10);
|
||||
|
||||
q.on('drain', function () {
|
||||
q.close();
|
||||
});
|
||||
|
||||
q.on('end', function () {
|
||||
// 21 tasks === 5 * 3 + 2 * 3 === 6 bounces
|
||||
test.ok(bounced === 6);
|
||||
test.end();
|
||||
});
|
||||
|
||||
q.push(tasks);
|
||||
});
|
||||
179
node_modules/vasync/tests/waterfall.js
generated
vendored
Normal file
179
node_modules/vasync/tests/waterfall.js
generated
vendored
Normal file
@ -0,0 +1,179 @@
|
||||
/*
|
||||
* Tests the "waterfall" primitive.
|
||||
*/
|
||||
|
||||
var mod_tap = require('tap');
|
||||
var mod_vasync = require('..');
|
||||
|
||||
var count = 0;
|
||||
var st;
|
||||
|
||||
mod_tap.test('empty waterfall', function (test) {
|
||||
st = mod_vasync.waterfall([], function (err) {
|
||||
test.ok(err === null);
|
||||
test.ok(st.ndone === 0);
|
||||
test.ok(st.nerrors === 0);
|
||||
test.ok(st.operations.length === 0);
|
||||
test.ok(st.successes.length === 0);
|
||||
test.equal(count, 1);
|
||||
test.end();
|
||||
});
|
||||
count++;
|
||||
test.ok(st.ndone === 0);
|
||||
test.ok(st.nerrors === 0);
|
||||
test.ok(st.operations.length === 0);
|
||||
test.ok(st.successes.length === 0);
|
||||
});
|
||||
|
||||
mod_tap.test('normal 4-stage waterfall', function (test) {
|
||||
count = 0;
|
||||
st = mod_vasync.waterfall([
|
||||
function func1(cb) {
|
||||
test.ok(count === 0, 'func1: count === 0');
|
||||
test.ok(st.ndone === 0);
|
||||
count++;
|
||||
setTimeout(cb, 20, null, { 'hello': 'world' });
|
||||
},
|
||||
function func2(extra, cb) {
|
||||
test.equal(extra.hello, 'world', 'func2: extra arg');
|
||||
test.ok(count == 1, 'func2: count == 1');
|
||||
test.ok(st.ndone === 1);
|
||||
test.ok(st.operations[0].status == 'ok');
|
||||
test.ok(st.operations[1].status == 'pending');
|
||||
test.ok(st.operations[2].status == 'waiting');
|
||||
count++;
|
||||
setTimeout(cb, 20, null, 5, 6, 7);
|
||||
},
|
||||
function (five, six, seven, cb) {
|
||||
test.equal(five, 5, 'func3: extra arg');
|
||||
test.equal(six, 6, 'func3: extra arg');
|
||||
test.equal(seven, 7, 'func3: extra arg');
|
||||
test.ok(count == 2, 'func3: count == 2');
|
||||
test.ok(st.ndone === 2);
|
||||
count++;
|
||||
setTimeout(cb, 20);
|
||||
},
|
||||
function func4(cb) {
|
||||
test.ok(count == 3, 'func4: count == 2');
|
||||
test.ok(st.ndone === 3);
|
||||
count++;
|
||||
setTimeout(cb, 20, null, 8, 9);
|
||||
}
|
||||
], function (err, eight, nine) {
|
||||
test.ok(count == 4, 'final: count == 4');
|
||||
test.ok(err === null, 'no error');
|
||||
test.ok(eight == 8);
|
||||
test.ok(nine == 9);
|
||||
test.ok(st.ndone === 4);
|
||||
test.ok(st.nerrors === 0);
|
||||
test.ok(st.operations.length === 4);
|
||||
test.ok(st.successes.length === 4);
|
||||
test.ok(st.operations[0].status == 'ok');
|
||||
test.ok(st.operations[1].status == 'ok');
|
||||
test.ok(st.operations[2].status == 'ok');
|
||||
test.ok(st.operations[3].status == 'ok');
|
||||
test.end();
|
||||
});
|
||||
test.ok(st.ndone === 0);
|
||||
test.ok(st.nerrors === 0);
|
||||
test.ok(st.operations.length === 4);
|
||||
test.ok(st.operations[0].funcname == 'func1', 'func1 name');
|
||||
test.ok(st.operations[0].status == 'pending');
|
||||
test.ok(st.operations[1].funcname == 'func2', 'func2 name');
|
||||
test.ok(st.operations[1].status == 'waiting');
|
||||
test.ok(st.operations[2].funcname == '(anon)', 'anon name');
|
||||
test.ok(st.operations[2].status == 'waiting');
|
||||
test.ok(st.operations[3].funcname == 'func4', 'func4 name');
|
||||
test.ok(st.operations[3].status == 'waiting');
|
||||
test.ok(st.successes.length === 0);
|
||||
});
|
||||
|
||||
mod_tap.test('bailing out early', function (test) {
|
||||
count = 0;
|
||||
st = mod_vasync.waterfall([
|
||||
function func1(cb) {
|
||||
test.ok(count === 0, 'func1: count === 0');
|
||||
count++;
|
||||
setTimeout(cb, 20);
|
||||
},
|
||||
function func2(cb) {
|
||||
test.ok(count == 1, 'func2: count == 1');
|
||||
count++;
|
||||
setTimeout(cb, 20, new Error('boom!'));
|
||||
},
|
||||
function func3(cb) {
|
||||
test.ok(count == 2, 'func3: count == 2');
|
||||
count++;
|
||||
setTimeout(cb, 20);
|
||||
}
|
||||
], function (err) {
|
||||
test.ok(count == 2, 'final: count == 3');
|
||||
test.equal(err.message, 'boom!');
|
||||
test.ok(st.ndone == 2);
|
||||
test.ok(st.nerrors == 1);
|
||||
test.ok(st.operations[0].status == 'ok');
|
||||
test.ok(st.operations[1].status == 'fail');
|
||||
test.ok(st.operations[2].status == 'waiting');
|
||||
test.ok(st.successes.length == 1);
|
||||
test.end();
|
||||
});
|
||||
});
|
||||
|
||||
mod_tap.test('bad function', function (test) {
|
||||
count = 0;
|
||||
st = mod_vasync.waterfall([
|
||||
function func1(cb) {
|
||||
count++;
|
||||
cb();
|
||||
setTimeout(function () {
|
||||
test.throws(
|
||||
function () { cb(); process.abort(); },
|
||||
'vasync.waterfall: ' +
|
||||
'function 0 ("func1") invoked its ' +
|
||||
'callback twice');
|
||||
test.equal(count, 2);
|
||||
test.end();
|
||||
}, 100);
|
||||
},
|
||||
function func2(cb) {
|
||||
count++;
|
||||
/* do nothing -- we'll throw an exception first */
|
||||
}
|
||||
], function (err) {
|
||||
/* not reached */
|
||||
console.error('didn\'t expect to finish');
|
||||
process.abort();
|
||||
});
|
||||
});
|
||||
|
||||
mod_tap.test('badargs', function (test) {
|
||||
test.throws(function () { mod_vasync.waterfall(); });
|
||||
test.throws(function () { mod_vasync.waterfall([], 'foo'); });
|
||||
test.throws(function () { mod_vasync.waterfall('foo', 'bar'); });
|
||||
test.end();
|
||||
});
|
||||
|
||||
mod_tap.test('normal waterfall, no callback', function (test) {
|
||||
count = 0;
|
||||
st = mod_vasync.waterfall([
|
||||
function func1(cb) {
|
||||
test.ok(count === 0);
|
||||
count++;
|
||||
setImmediate(cb);
|
||||
},
|
||||
function func2(cb) {
|
||||
test.ok(count == 1);
|
||||
count++;
|
||||
setImmediate(cb);
|
||||
setTimeout(function () {
|
||||
test.ok(count == 2);
|
||||
test.end();
|
||||
}, 100);
|
||||
}
|
||||
]);
|
||||
});
|
||||
|
||||
mod_tap.test('empty waterfall, no callback', function (test) {
|
||||
st = mod_vasync.waterfall([]);
|
||||
setTimeout(function () { test.end(); }, 100);
|
||||
});
|
||||
108
node_modules/vasync/tests/whilst.js
generated
vendored
Normal file
108
node_modules/vasync/tests/whilst.js
generated
vendored
Normal file
@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Tests the "whilst" function
|
||||
*/
|
||||
|
||||
var mod_util = require('util');
|
||||
|
||||
var mod_tap = require('tap');
|
||||
var mod_vasync = require('..');
|
||||
|
||||
mod_tap.test('basic whilst', function (test) {
|
||||
var n = 0;
|
||||
|
||||
mod_vasync.whilst(
|
||||
function condition() {
|
||||
return (n < 5);
|
||||
},
|
||||
function body(cb) {
|
||||
n++;
|
||||
cb(null, n);
|
||||
},
|
||||
function done(err, arg) {
|
||||
test.ok(!err, 'error unset');
|
||||
test.equal(n, 5, 'n == 5');
|
||||
test.equal(n, arg, 'n == arg');
|
||||
test.end();
|
||||
});
|
||||
});
|
||||
|
||||
mod_tap.test('whilst return object', function (test) {
|
||||
var n = 0;
|
||||
|
||||
var w = mod_vasync.whilst(
|
||||
function condition() {
|
||||
return (n < 5);
|
||||
},
|
||||
function body(cb) {
|
||||
n++;
|
||||
|
||||
test.equal(n, w.iterations, 'n == w.iterations: ' + n);
|
||||
|
||||
cb(null, n, 'foo');
|
||||
},
|
||||
function done(err, arg1, arg2, arg3) {
|
||||
test.ok(!err, 'error unset');
|
||||
test.equal(w.iterations, 5, 'whilst had 5 iterations');
|
||||
test.equal(w.finished, true, 'whilst has finished');
|
||||
test.equal(arg1, n, 'whilst arg1 == n');
|
||||
test.equal(arg2, 'foo', 'whilst arg2 == "foo"');
|
||||
test.equal(arg3, undefined, 'whilst arg3 == undefined');
|
||||
test.end();
|
||||
});
|
||||
|
||||
test.equal(typeof (w), 'object', 'whilst returns an object');
|
||||
test.equal(w.finished, false, 'whilst is not finished');
|
||||
test.equal(w.iterations, 0, 'whilst has not started yet');
|
||||
});
|
||||
|
||||
mod_tap.test('whilst false condition', function (test) {
|
||||
mod_vasync.whilst(
|
||||
function condition() {
|
||||
return (false);
|
||||
},
|
||||
function body(cb) {
|
||||
cb();
|
||||
},
|
||||
function done(err, arg) {
|
||||
test.ok(!err, 'error is unset');
|
||||
test.ok(!arg, 'arg is unset');
|
||||
test.end();
|
||||
});
|
||||
});
|
||||
|
||||
mod_tap.test('whilst error', function (test) {
|
||||
var n = 0;
|
||||
|
||||
var w = mod_vasync.whilst(
|
||||
function condition() {
|
||||
return (true);
|
||||
},
|
||||
function body(cb) {
|
||||
n++;
|
||||
|
||||
if (n > 5) {
|
||||
cb(new Error('n > 5'), 'bar');
|
||||
} else {
|
||||
cb(null, 'foo');
|
||||
}
|
||||
},
|
||||
function done(err, arg) {
|
||||
test.ok(err, 'error is set');
|
||||
test.equal(err.message, 'n > 5');
|
||||
test.equal(arg, 'bar');
|
||||
|
||||
test.equal(w.finished, true, 'whilst is finished');
|
||||
|
||||
/*
|
||||
* Iterations is bumped after the test condition is run and
|
||||
* before the iteration function is run. Because the condition
|
||||
* in this example is inside the iteration function (the test
|
||||
* condition always returns true), the iteration count will be
|
||||
* 1 higher than expected, since it will fail when (n > 5), or
|
||||
* when iterations is 6.
|
||||
*/
|
||||
test.equal(w.iterations, 6, 'whilst had 6 iterations');
|
||||
|
||||
test.end();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user