node_modules updated, buefy add to lib folder

This commit is contained in:
2019-06-04 14:29:48 +02:00
parent 0a3f6ff240
commit 5d28bc36e1
3957 changed files with 306575 additions and 21738 deletions
+104
View 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);
};
+25
View 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);
+284
View 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
View 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
View 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);
});