first commit

This commit is contained in:
Stefan Hacker
2026-04-03 09:38:48 +02:00
commit 37ad745546
47450 changed files with 3120798 additions and 0 deletions
+55
View File
@@ -0,0 +1,55 @@
'use strict';
const fs = require('fs');
const path = require('path');
const async = require('async');
const spawn = require('child_process').spawn;
const clc = require('cli-color');
const allFailed = clc.red.bold;
const allPassed = clc.green;
const failed = clc.yellow;
const passed = (t) => t;
const files = fs.readdirSync(__dirname).filter(function (filename) {
return filename.slice(0, 5) === 'test-';
});
async.mapSeries(files, runTest, function (err, passed) {
if (err) throw err;
let failed = 0;
for (const ok of passed) {
if (!ok) failed += 1;
}
if (failed > 0) {
console.log(allFailed('failed') + ` - ${failed} tests failed`);
} else {
console.log(allPassed('passed') + ` - ${passed.length} tests passed`);
}
});
function runTest(filename, done) {
process.stdout.write(` - running ${filename} ...`);
const p = spawn(process.execPath, [path.resolve(__dirname, filename)], {
stdio: ['ignore', 1, 2],
env: {
'NODE_ASYNC_HOOK_NO_WARNING': '1'
}
});
p.once('close', function (statusCode) {
const ok = (statusCode === 0);
if (ok) {
console.log(' ' + passed('ok'));
} else {
console.log(' - ' + failed('failed'));
}
done(null, ok);
});
}
+11
View File
@@ -0,0 +1,11 @@
'use strict';
const assert = require('assert');
const existing = global._asyncHook = {
version: require('../package.json').version
};
const asyncHook = require('../');
assert.equal(asyncHook, existing);
+13
View File
@@ -0,0 +1,13 @@
'use strict';
const assert = require('assert');
global._asyncHook = {
version: '0.0.0'
};
try {
require('../');
} catch (e) {
assert.equal(e.message, 'Conflicting version of async-hook-jl found');
}
+33
View File
@@ -0,0 +1,33 @@
'use strict';
const asyncHook = require('../');
const assert = require('assert');
const fs = require('fs');
let called = false;
asyncHook.addHooks({
init: function () {
assert(false);
},
pre: function () {
assert(false);
},
post: function () {
assert(false);
},
destroy: function () {
assert(false);
}
});
asyncHook.enable();
asyncHook.disable();
fs.access(__filename, function () {
called = true;
});
process.once('exit', function () {
assert.equal(called, true);
});
+75
View File
@@ -0,0 +1,75 @@
'use strict';
const asyncHook = require('../');
const assert = require('assert');
const fs = require('fs');
let called = false;
let initCalls = 0;
let destroyCalls = 0;
let initUid = NaN;
let initHandle = {};
let initParent = {};
let initProvider = NaN;
let preHandle = {};
let preUid = NaN;
let postHandle = {};
let postUid = NaN;
let postDidThrow = NaN;
let destroyUid = NaN;
asyncHook.addHooks({
init: function (uid, handle, provider, parent) {
initUid = uid;
initHandle = handle;
initParent = parent;
initProvider = provider;
initCalls += 1;
},
pre: function (uid, handle) {
preUid = uid;
preHandle = handle;
},
post: function (uid, handle, didThrow) {
postUid = uid;
postHandle = handle;
postDidThrow = didThrow;
},
destroy: function (uid) {
destroyUid = uid;
destroyCalls += 1;
}
});
asyncHook.enable();
fs.access(__filename, function () {
called = true;
});
asyncHook.disable();
process.once('exit', function () {
assert.equal(initUid, preUid);
assert.equal(initUid, postUid);
assert.equal(initUid, destroyUid);
assert.equal(initHandle, preHandle);
assert.equal(initHandle, postHandle);
assert.equal(initHandle.constructor.name, 'FSReqWrap');
assert.equal(initParent, null);
assert.equal(initProvider, asyncHook.providers.FSREQWRAP);
assert.equal(postDidThrow, false);
assert.equal(called, true);
assert.equal(initCalls, 1);
assert.equal(destroyCalls, 1);
});
+48
View File
@@ -0,0 +1,48 @@
'use strict';
const asyncHook = require('../');
const assert = require('assert');
const fs = require('fs');
let called = false;
let initCalls = 0;
let preCalls = 0;
let postCalls = 0;
let destroyCalls = 0;
const hooks = {
init: function () {
initCalls += 1;
},
pre: function () {
preCalls += 1;
},
post: function () {
postCalls += 1;
},
destroy: function () {
destroyCalls += 1;
}
};
asyncHook.addHooks(hooks);
asyncHook.addHooks(hooks);
asyncHook.removeHooks(hooks);
asyncHook.enable();
fs.access(__filename, function () {
called = true;
});
asyncHook.disable();
process.once('exit', function () {
assert.equal(called, true);
assert.equal(initCalls, 1);
assert.equal(preCalls, 1);
assert.equal(postCalls, 1);
assert.equal(destroyCalls, 1);
});
+47
View File
@@ -0,0 +1,47 @@
'use strict';
const asyncHook = require('../');
const assert = require('assert');
const fs = require('fs');
let called = false;
let initCalls = 0;
let preCalls = 0;
let postCalls = 0;
let destroyCalls = 0;
const hooks = {
init: function () {
initCalls += 1;
},
pre: function () {
preCalls += 1;
},
post: function () {
postCalls += 1;
},
destroy: function () {
destroyCalls += 1;
}
};
asyncHook.addHooks(hooks);
asyncHook.addHooks(hooks);
asyncHook.enable();
fs.access(__filename, function () {
called = true;
});
asyncHook.disable();
process.once('exit', function () {
assert.equal(called, true);
assert.equal(initCalls, 2);
assert.equal(preCalls, 2);
assert.equal(postCalls, 2);
assert.equal(destroyCalls, 2);
});
+38
View File
@@ -0,0 +1,38 @@
'use strict';
const asyncHook = require('../');
const assert = require('assert');
const timings = [];
asyncHook.addHooks({
init: function (uid, handle) {
timings.push(`init#${uid} - ${handle.constructor.name}`);
},
pre: function (uid) {
timings.push(`pre#${uid}`);
},
post: function (uid) {
timings.push(`post#${uid}`);
},
destroy: function (uid) {
timings.push(`destroy#${uid}`);
}
});
asyncHook.enable();
const timerId = setImmediate(() => {
timings.push('callback');
clearImmediate(timerId);
}, 100);
asyncHook.disable();
process.once('exit', function () {
assert.deepEqual(timings, [
'init#-1 - ImmediateWrap',
'pre#-1',
'callback',
'post#-1',
'destroy#-1'
]);
});
+59
View File
@@ -0,0 +1,59 @@
'use strict';
const asyncHook = require('../');
const assert = require('assert');
let timerCalled = false;
let initCalls = 0;
let destroyCalls = 0;
let initUid = NaN;
let initHandleName = '';
let initParent = {};
let initProvider = NaN;
let destroyUid = NaN;
asyncHook.addHooks({
init: function (uid, handle, provider, parent) {
initUid = uid;
initHandleName = handle.constructor.name;
initParent = parent;
initProvider = provider;
initCalls += 1;
},
pre: function () {
assert(false);
},
post: function () {
assert(false);
},
destroy: function (uid) {
destroyUid = uid;
destroyCalls += 1;
}
});
asyncHook.enable();
const timerId = setImmediate(function () {
timerCalled = true;
});
clearImmediate(timerId);
asyncHook.disable();
process.once('exit', function () {
assert.equal(initUid, destroyUid);
assert.equal(initHandleName, 'ImmediateWrap');
assert.equal(initParent, null);
assert.equal(initProvider, 0);
assert.equal(timerCalled, false);
assert.equal(initCalls, 1);
assert.equal(destroyCalls, 1);
});
+46
View File
@@ -0,0 +1,46 @@
'use strict';
const asyncHook = require('../');
const assert = require('assert');
const eventOrder = [];
let throwFlag = null;
asyncHook.addHooks({
init: function (uid, handle) {
eventOrder.push(`init#${uid} ${handle.constructor.name}`);
},
pre: function (uid) {
eventOrder.push(`pre#${uid}`);
},
post: function (uid, handle, didThrow) {
throwFlag = didThrow;
eventOrder.push(`post#${uid}`);
},
destroy: function (uid) {
eventOrder.push(`destroy#${uid}`);
}
});
asyncHook.enable();
process.once('uncaughtException', function () {
eventOrder.push('exception');
});
setImmediate(function () {
eventOrder.push('callback');
throw new Error('error');
});
asyncHook.disable();
process.once('exit', function () {
assert.strictEqual(throwFlag, true);
assert.deepEqual(eventOrder, [
'init#-1 ImmediateWrap', 'pre#-1',
'callback', 'exception',
'post#-1', 'destroy#-1'
]);
});
+42
View File
@@ -0,0 +1,42 @@
'use strict';
const asyncHook = require('../');
const assert = require('assert');
let timerACalled = false;
let timerBCalled = false;
asyncHook.addHooks({
init: function () {
assert(false);
},
pre: function () {
assert(false);
},
post: function () {
assert(false);
},
destroy: function () {
assert(false);
}
});
asyncHook.enable();
asyncHook.disable();
const timerId = setImmediate(function () {
timerACalled = true;
});
clearImmediate(timerId);
setImmediate(function (arg1, arg2) {
timerBCalled = true;
assert.equal(arg1, 'a');
assert.equal(arg2, 'b');
}, 'a', 'b');
process.once('exit', function () {
assert.equal(timerACalled, false);
assert.equal(timerBCalled, true);
});
+76
View File
@@ -0,0 +1,76 @@
'use strict';
const asyncHook = require('../');
const assert = require('assert');
let timerCalled = false;
let initCalls = 0;
let destroyCalls = 0;
let initUid = NaN;
let initHandle = {};
let initParent = {};
let initProvider = NaN;
let preHandle = {};
let preUid = NaN;
let postHandle = {};
let postUid = NaN;
let postDidThrow = NaN;
let destroyUid = NaN;
asyncHook.addHooks({
init: function (uid, handle, provider, parent) {
initUid = uid;
initHandle = handle;
initParent = parent;
initProvider = provider;
initCalls += 1;
},
pre: function (uid, handle) {
preUid = uid;
preHandle = handle;
},
post: function (uid, handle, didThrow) {
postUid = uid;
postHandle = handle;
postDidThrow = didThrow;
},
destroy: function (uid) {
destroyUid = uid;
destroyCalls += 1;
}
});
asyncHook.enable();
setImmediate(function (arg1, arg2) {
timerCalled = true;
assert.equal(arg1, 'a');
assert.equal(arg2, 'b');
}, 'a', 'b');
asyncHook.disable();
process.once('exit', function () {
assert.equal(initUid, preUid);
assert.equal(initUid, postUid);
assert.equal(initUid, destroyUid);
assert.equal(initHandle, preHandle);
assert.equal(initHandle, postHandle);
assert.equal(initHandle.constructor.name, 'ImmediateWrap');
assert.equal(initParent, null);
assert.equal(initProvider, 0);
assert.equal(postDidThrow, false);
assert.equal(timerCalled, true);
assert.equal(initCalls, 1);
assert.equal(destroyCalls, 1);
});
+32
View File
@@ -0,0 +1,32 @@
'use strict';
if (process.env.hasOwnProperty('ASYNC_HOOK_TEST_CHILD')) {
const asyncHook = require('../');
asyncHook.enable();
setImmediate(function () {
throw new Error('test error');
});
} else {
const spawn = require('child_process').spawn;
const endpoint = require('endpoint');
const child = spawn(process.execPath, [__filename], {
env: Object.assign({ ASYNC_HOOK_TEST_CHILD: '' }, process.env),
stdio: ['ignore', 1, 'pipe']
});
let stderr = null;
child.stderr.pipe(endpoint(function (err, _stderr) {
if (err) throw err;
stderr = _stderr;
}));
child.once('close', function (statusCode) {
if (statusCode !== 1 || stderr.toString().indexOf('test error') === -1) {
process.stderr.write(stderr);
process.exit(statusCode);
}
});
}
+21
View File
@@ -0,0 +1,21 @@
'use strict';
const asyncHook = require('../');
const assert = require('assert');
asyncHook.enable();
let throws = false;
try {
setImmediate(undefined, 1);
} catch (e) {
assert.equal(e.message, '"callback" argument must be a function');
assert.equal(e.name, 'TypeError');
throws = true;
}
asyncHook.disable();
process.once('exit', function () {
assert(throws);
});
+38
View File
@@ -0,0 +1,38 @@
'use strict';
const asyncHook = require('../');
const assert = require('assert');
const timings = [];
asyncHook.addHooks({
init: function (uid, handle) {
timings.push(`init#${uid} - ${handle.constructor.name}`);
},
pre: function (uid) {
timings.push(`pre#${uid}`);
},
post: function (uid) {
timings.push(`post#${uid}`);
},
destroy: function (uid) {
timings.push(`destroy#${uid}`);
}
});
asyncHook.enable();
const timerId = setInterval(() => {
timings.push('callback');
clearInterval(timerId);
}, 100);
asyncHook.disable();
process.once('exit', function () {
assert.deepEqual(timings, [
'init#-1 - IntervalWrap',
'pre#-1',
'callback',
'post#-1',
'destroy#-1'
]);
});
+59
View File
@@ -0,0 +1,59 @@
'use strict';
const asyncHook = require('../');
const assert = require('assert');
let timerCalled = false;
let initCalls = 0;
let destroyCalls = 0;
let initUid = NaN;
let initHandleName = '';
let initParent = {};
let initProvider = NaN;
let destroyUid = NaN;
asyncHook.addHooks({
init: function (uid, handle, provider, parent) {
initUid = uid;
initHandleName = handle.constructor.name;
initParent = parent;
initProvider = provider;
initCalls += 1;
},
pre: function () {
assert(false);
},
post: function () {
assert(false);
},
destroy: function (uid) {
destroyUid = uid;
destroyCalls += 1;
}
});
asyncHook.enable();
const timerId = setInterval(function () {
timerCalled = true;
});
clearInterval(timerId);
asyncHook.disable();
process.once('exit', function () {
assert.equal(initUid, destroyUid);
assert.equal(initHandleName, 'IntervalWrap');
assert.equal(initParent, null);
assert.equal(initProvider, 0);
assert.equal(timerCalled, false);
assert.equal(initCalls, 1);
assert.equal(destroyCalls, 1);
});
+46
View File
@@ -0,0 +1,46 @@
'use strict';
const asyncHook = require('../');
const assert = require('assert');
const eventOrder = [];
let throwFlag = null;
asyncHook.addHooks({
init: function (uid, handle) {
eventOrder.push(`init#${uid} ${handle.constructor.name}`);
},
pre: function (uid) {
eventOrder.push(`pre#${uid}`);
},
post: function (uid, handle, didThrow) {
throwFlag = didThrow;
eventOrder.push(`post#${uid}`);
},
destroy: function (uid) {
eventOrder.push(`destroy#${uid}`);
}
});
asyncHook.enable();
process.once('uncaughtException', function () {
eventOrder.push('exception');
});
setInterval(function () {
eventOrder.push('callback');
throw new Error('error');
});
asyncHook.disable();
process.once('exit', function () {
assert.strictEqual(throwFlag, true);
assert.deepEqual(eventOrder, [
'init#-1 IntervalWrap', 'pre#-1',
'callback', 'exception',
'post#-1', 'destroy#-1'
]);
});
+42
View File
@@ -0,0 +1,42 @@
'use strict';
const asyncHook = require('../');
const assert = require('assert');
let timerACalled = false;
let timerBCalled = false;
asyncHook.addHooks({
init: function () {
assert(false);
},
pre: function () {
assert(false);
},
post: function () {
assert(false);
},
destroy: function () {
assert(false);
}
});
asyncHook.enable();
asyncHook.disable();
const timerAId = setInterval(function () {
timerACalled = true;
});
clearInterval(timerAId);
const timerBId = setInterval(function (arg1, arg2) {
timerBCalled = true;
assert.equal(arg1, 'a');
assert.equal(arg2, 'b');
clearInterval(timerBId);
}, 0, 'a', 'b');
process.once('exit', function () {
assert.equal(timerACalled, false);
assert.equal(timerBCalled, true);
});
+86
View File
@@ -0,0 +1,86 @@
'use strict';
const asyncHook = require('../');
const assert = require('assert');
let timerCalled = 0;
let initCalls = 0;
let preCalls = 0;
let postCalls = 0;
let destroyCalls = 0;
let initUid = NaN;
let initHandle = {};
let initParent = {};
let initProvider = NaN;
let preHandle = {};
let preUid = NaN;
let postHandle = {};
let postUid = NaN;
let postDidThrow = NaN;
let destroyUid = NaN;
asyncHook.addHooks({
init: function (uid, handle, provider, parent) {
initUid = uid;
initHandle = handle;
initParent = parent;
initProvider = provider;
initCalls += 1;
},
pre: function (uid, handle) {
preUid = uid;
preHandle = handle;
preCalls += 1;
},
post: function (uid, handle, didThrow) {
postUid = uid;
postHandle = handle;
postDidThrow = didThrow;
postCalls += 1;
},
destroy: function (uid) {
destroyUid = uid;
destroyCalls += 1;
}
});
asyncHook.enable();
const timerId = setInterval(function (arg1, arg2) {
timerCalled += 1;
assert.equal(arg1, 'a');
assert.equal(arg2, 'b');
if (timerCalled === 2) clearInterval(timerId);
}, 0, 'a', 'b');
asyncHook.disable();
process.once('exit', function () {
assert.equal(initUid, preUid);
assert.equal(initUid, postUid);
assert.equal(initUid, destroyUid);
assert.equal(initHandle, preHandle);
assert.equal(initHandle, postHandle);
assert.equal(initHandle.constructor.name, 'IntervalWrap');
assert.equal(initParent, null);
assert.equal(initProvider, 0);
assert.equal(postDidThrow, false);
assert.equal(timerCalled, 2);
assert.equal(initCalls, 1);
assert.equal(preCalls, 2);
assert.equal(postCalls, 2);
assert.equal(destroyCalls, 1);
});
+32
View File
@@ -0,0 +1,32 @@
'use strict';
if (process.env.hasOwnProperty('ASYNC_HOOK_TEST_CHILD')) {
const asyncHook = require('../');
asyncHook.enable();
setInterval(function () {
throw new Error('test error');
});
} else {
const spawn = require('child_process').spawn;
const endpoint = require('endpoint');
const child = spawn(process.execPath, [__filename], {
env: Object.assign({ ASYNC_HOOK_TEST_CHILD: '' }, process.env),
stdio: ['ignore', 1, 'pipe']
});
let stderr = null;
child.stderr.pipe(endpoint(function (err, _stderr) {
if (err) throw err;
stderr = _stderr;
}));
child.once('close', function (statusCode) {
if (statusCode !== 1 || stderr.toString().indexOf('test error') === -1) {
process.stderr.write(stderr);
process.exit(statusCode);
}
});
}
+21
View File
@@ -0,0 +1,21 @@
'use strict';
const asyncHook = require('../');
const assert = require('assert');
asyncHook.enable();
let throws = false;
try {
setInterval(undefined, 1);
} catch (e) {
assert.equal(e.message, '"callback" argument must be a function');
assert.equal(e.name, 'TypeError');
throws = true;
}
asyncHook.disable();
process.once('exit', function () {
assert(throws);
});
+46
View File
@@ -0,0 +1,46 @@
'use strict';
const asyncHook = require('../');
const assert = require('assert');
const eventOrder = [];
let throwFlag = null;
asyncHook.addHooks({
init: function (uid, handle) {
eventOrder.push(`init#${uid} ${handle.constructor.name}`);
},
pre: function (uid) {
eventOrder.push(`pre#${uid}`);
},
post: function (uid, handle, didThrow) {
throwFlag = didThrow;
eventOrder.push(`post#${uid}`);
},
destroy: function (uid) {
eventOrder.push(`destroy#${uid}`);
}
});
asyncHook.enable();
process.once('uncaughtException', function () {
eventOrder.push('exception');
});
process.nextTick(function () {
eventOrder.push('callback');
throw new Error('error');
});
asyncHook.disable();
process.once('exit', function () {
assert.strictEqual(throwFlag, true);
assert.deepEqual(eventOrder, [
'init#-1 NextTickWrap', 'pre#-1',
'callback', 'exception',
'post#-1', 'destroy#-1'
]);
});
+34
View File
@@ -0,0 +1,34 @@
'use strict';
const asyncHook = require('../');
const assert = require('assert');
let called = false;
asyncHook.addHooks({
init: function () {
assert(false);
},
pre: function () {
assert(false);
},
post: function () {
assert(false);
},
destroy: function () {
assert(false);
}
});
asyncHook.enable();
asyncHook.disable();
process.nextTick(function (arg1, arg2) {
called = true;
assert.equal(arg1, 'a');
assert.equal(arg2, 'b');
}, 'a', 'b');
process.once('exit', function () {
assert.equal(called, true);
});
+76
View File
@@ -0,0 +1,76 @@
'use strict';
const asyncHook = require('../');
const assert = require('assert');
let called = false;
let initCalls = 0;
let destroyCalls = 0;
let initUid = NaN;
let initHandle = {};
let initParent = {};
let initProvider = NaN;
let preHandle = {};
let preUid = NaN;
let postDidThrow = NaN;
let postHandle = {};
let postUid = NaN;
let destroyUid = NaN;
asyncHook.addHooks({
init: function (uid, handle, provider, parent) {
initUid = uid;
initHandle = handle;
initParent = parent;
initProvider = provider;
initCalls += 1;
},
pre: function (uid, handle) {
preUid = uid;
preHandle = handle;
},
post: function (uid, handle, didThrow) {
postUid = uid;
postHandle = handle;
postDidThrow = didThrow;
},
destroy: function (uid) {
destroyUid = uid;
destroyCalls += 1;
}
});
asyncHook.enable();
process.nextTick(function (arg1, arg2) {
called = true;
assert.equal(arg1, 'a');
assert.equal(arg2, 'b');
}, 'a', 'b');
asyncHook.disable();
process.once('exit', function () {
assert.equal(initUid, preUid);
assert.equal(initUid, postUid);
assert.equal(initUid, destroyUid);
assert.equal(initHandle, preHandle);
assert.equal(initHandle, postHandle);
assert.equal(initHandle.constructor.name, 'NextTickWrap');
assert.equal(initParent, null);
assert.equal(initProvider, 0);
assert.equal(postDidThrow, false);
assert.equal(called, true);
assert.equal(initCalls, 1);
assert.equal(destroyCalls, 1);
});
+32
View File
@@ -0,0 +1,32 @@
'use strict';
if (process.env.hasOwnProperty('ASYNC_HOOK_TEST_CHILD')) {
const asyncHook = require('../');
asyncHook.enable();
process.nextTick(function () {
throw new Error('test error');
});
} else {
const spawn = require('child_process').spawn;
const endpoint = require('endpoint');
const child = spawn(process.execPath, [__filename], {
env: Object.assign({ ASYNC_HOOK_TEST_CHILD: '' }, process.env),
stdio: ['ignore', 1, 'pipe']
});
let stderr = null;
child.stderr.pipe(endpoint(function (err, _stderr) {
if (err) throw err;
stderr = _stderr;
}));
child.once('close', function (statusCode) {
if (statusCode !== 1 || stderr.toString().indexOf('test error') === -1) {
process.stderr.write(stderr);
process.exit(statusCode);
}
});
}
+21
View File
@@ -0,0 +1,21 @@
'use strict';
const asyncHook = require('../');
const assert = require('assert');
asyncHook.enable();
let throws = false;
try {
process.nextTick(undefined, 1);
} catch (e) {
assert.equal(e.message, 'callback is not a function');
assert.equal(e.name, 'TypeError');
throws = true;
}
asyncHook.disable();
process.once('exit', function () {
assert(throws);
});
+58
View File
@@ -0,0 +1,58 @@
'use strict';
const asyncHook = require('../');
const assert = require('assert');
const net = require('net');
let called = false;
let firstHook = true;
let initCalls = 0;
let serverHandle = {};
let serverUid = NaN;
let clientParentHandle = {};
let clientParentUid = NaN;
asyncHook.addHooks({
init: function (uid, handle, provider, parentUid, parentHandle) {
if (provider != asyncHook.providers.TCPWRAP) return;
if (firstHook) {
firstHook = false;
serverUid = uid;
serverHandle = handle;
assert.equal(parentUid, null);
assert.equal(parentHandle, null);
} else {
clientParentHandle = parentHandle;
clientParentUid = parentUid;
}
initCalls += 1;
}
});
asyncHook.enable();
const server = net.createServer(function (socket) {
socket.end();
server.close();
called = true;
}).listen(function () {
net.connect(this.address());
});
asyncHook.disable();
process.once('exit', function () {
assert.equal(serverHandle, clientParentHandle);
assert.equal(serverUid, clientParentUid);
assert.equal(called, true);
assert.equal(initCalls, 2);
});
+75
View File
@@ -0,0 +1,75 @@
'use strict';
const asyncHook = require('../');
const assert = require('assert');
let rejctedCalled = false;
let rejectedArg = null;
let initCalls = 0;
let destroyCalls = 0;
let initUid = NaN;
let initHandle = {};
let initParent = {};
let initProvider = NaN;
let preHandle = {};
let preUid = NaN;
let postHandle = {};
let postUid = NaN;
let destroyUid = NaN;
asyncHook.addHooks({
init: function (uid, handle, provider, parent) {
initUid = uid;
initHandle = handle;
initParent = parent;
initProvider = provider;
initCalls += 1;
},
pre: function (uid, handle) {
preUid = uid;
preHandle = handle;
},
post: function (uid, handle) {
postUid = uid;
postHandle = handle;
},
destroy: function (uid) {
destroyUid = uid;
destroyCalls += 1;
}
});
asyncHook.enable();
Promise
.reject('a')
.catch(arg => {
rejctedCalled = true;
rejectedArg = arg;
});
asyncHook.disable();
process.once('exit', function () {
assert.equal(initUid, preUid);
assert.equal(initUid, postUid);
assert.equal(initUid, destroyUid);
assert.equal(initHandle, preHandle);
assert.equal(initHandle, postHandle);
assert.equal(initHandle.constructor.name, 'PromiseWrap');
assert.equal(initParent, null);
assert.equal(initProvider, 0);
assert.equal(rejctedCalled, true);
assert.equal(rejectedArg, 'a');
assert.equal(initCalls, 1);
assert.equal(destroyCalls, 1);
});
@@ -0,0 +1,80 @@
'use strict';
const asyncHook = require('../');
const assert = require('assert');
let rejectedCalled = false;
let fulfilledCalled = false;
let fulfilledArg = null;
const initUid = [];
const initHandle = [];
const initProvider = [];
const initParent = [];
const preUid = [];
const preHandle = [];
const postUid = [];
const postHandle = [];
const destroyUid = [];
asyncHook.addHooks({
init: function (uid, handle, provider, parent) {
initUid.push(uid);
initHandle.push(handle);
initProvider.push(provider);
initParent.push(parent);
},
pre: function (uid, handle) {
preUid.push(uid);
preHandle.push(handle);
},
post: function (uid, handle) {
postUid.push(uid);
postHandle.push(handle);
},
destroy: function (uid) {
destroyUid.push(uid);
}
});
asyncHook.enable();
Promise
.resolve('a')
.catch(() => {
rejectedCalled = true;
})
.then(arg => {
fulfilledCalled = true;
fulfilledArg = arg;
});
asyncHook.disable();
process.once('exit', function () {
assert.equal(initUid.length, 2, 'both handlers should init');
assert.equal(preUid.length, 1, 'only the .then should pre');
assert.equal(postUid.length, 1, 'only the .then should post');
assert.equal(destroyUid.length, 2, 'both handlers should destroy');
assert.equal(initUid[0], destroyUid[0]);
assert.equal(initUid[1], preUid[0]);
assert.equal(initUid[1], postUid[0]);
assert.equal(initUid[1], destroyUid[1]);
assert.equal(initHandle[1], preHandle[0]);
assert.equal(initHandle[1], postHandle[0]);
for (let i = 0; i < 2; ++i) {
assert.equal(initHandle[i].constructor.name, 'PromiseWrap');
assert.equal(initParent[i], null);
assert.equal(initProvider[i], 0);
}
assert.equal(rejectedCalled, false);
assert.equal(fulfilledCalled, true);
assert.equal(fulfilledArg, 'a');
});
+72
View File
@@ -0,0 +1,72 @@
'use strict';
const asyncHook = require('../');
const assert = require('assert');
const thenHandlersCalledA = [false, false];
const thenHandlersCalledB = [false, false];
let catchHandlerCalledC = false;
let catchHandlerCalledD = false;
let fulfilledArgA = null;
let rejectedArgB = null;
let rejectedArgC = null;
asyncHook.addHooks({
init: function () {
assert(false);
},
pre: function () {
assert(false);
},
post: function () {
assert(false);
},
destroy: function () {
assert(false);
}
});
asyncHook.enable();
asyncHook.disable();
Promise
.resolve('a')
.then(arg => {
fulfilledArgA = arg;
thenHandlersCalledA[0] = true;
}, () => {
thenHandlersCalledA[1] = true;
});
Promise
.reject('b')
.then(() => {
thenHandlersCalledB[0] = true;
}, arg => {
rejectedArgB = arg;
thenHandlersCalledB[1] = true;
});
Promise
.reject('c')
.catch(arg => {
rejectedArgC = arg;
catchHandlerCalledC = true;
});
Promise
.resolve('d')
.catch(() => {
catchHandlerCalledD = true;
});
process.once('exit', function () {
assert.deepStrictEqual(thenHandlersCalledA, [true, false]);
assert.equal(fulfilledArgA, 'a');
assert.deepStrictEqual(thenHandlersCalledB, [false, true]);
assert.equal(rejectedArgB, 'b');
assert.equal(catchHandlerCalledC, true);
assert.equal(rejectedArgC, 'c');
assert.equal(catchHandlerCalledD, false);
});
@@ -0,0 +1,81 @@
'use strict';
const asyncHook = require('../');
const assert = require('assert');
let fulfilledCalled = false;
let rejectedCalled = false;
let rejectedArg = null;
const initUid = [];
const initHandle = [];
const initProvider = [];
const initParent = [];
const preUid = [];
const preHandle = [];
const postUid = [];
const postHandle = [];
const destroyUid = [];
asyncHook.addHooks({
init: function (uid, handle, provider, parent) {
initUid.push(uid);
initHandle.push(handle);
initProvider.push(provider);
initParent.push(parent);
},
pre: function (uid, handle) {
preUid.push(uid);
preHandle.push(handle);
},
post: function (uid, handle) {
postUid.push(uid);
postHandle.push(handle);
},
destroy: function (uid) {
destroyUid.push(uid);
}
});
asyncHook.enable();
Promise
.reject('a')
.then(() => {
fulfilledCalled = true;
})
.catch(arg => {
rejectedCalled = true;
rejectedArg = arg;
});
asyncHook.disable();
process.once('exit', function () {
assert.equal(initUid.length, 2, 'both handlers should init');
assert.equal(preUid.length, 1, 'only the .catch should pre');
assert.equal(postUid.length, 1, 'only the .catch should post');
assert.equal(destroyUid.length, 2, 'both handlers should destroy');
assert.equal(initUid[0], destroyUid[0]);
assert.equal(initUid[1], preUid[0]);
assert.equal(initUid[1], postUid[0]);
assert.equal(initUid[1], destroyUid[1]);
assert.equal(initHandle[1], preHandle[0]);
assert.equal(initHandle[1], postHandle[0]);
for (let i = 0; i < 2; ++i) {
assert.equal(initHandle[i].constructor.name, 'PromiseWrap');
assert.equal(initParent[i], null);
assert.equal(initProvider[i], 0);
}
assert.equal(fulfilledCalled, false);
assert.equal(rejectedCalled, true);
assert.equal(rejectedArg, 'a');
});
@@ -0,0 +1,80 @@
'use strict';
const asyncHook = require('../');
const assert = require('assert');
let fulfilledCalledA = false;
let fulfilledArgA = null;
let fulfilledCalledB = false;
let fulfilledArgB = null;
const initUid = [];
const initHandle = [];
const initProvider = [];
const initParent = [];
const preUid = [];
const preHandle = [];
const postUid = [];
const postHandle = [];
const destroyUid = [];
asyncHook.addHooks({
init: function (uid, handle, provider, parent) {
initUid.push(uid);
initHandle.push(handle);
initProvider.push(provider);
initParent.push(parent);
},
pre: function (uid, handle) {
preUid.push(uid);
preHandle.push(handle);
},
post: function (uid, handle) {
postUid.push(uid);
postHandle.push(handle);
},
destroy: function (uid) {
destroyUid.push(uid);
}
});
asyncHook.enable();
Promise
.resolve('a')
.then(arg => {
fulfilledCalledA = true;
fulfilledArgA = arg;
return 'b';
})
.then(arg => {
fulfilledCalledB = true;
fulfilledArgB = arg;
});
asyncHook.disable();
process.once('exit', function () {
assert.equal(initUid.length, 2);
for (let i = 0; i < 2; ++i) {
assert.equal(initUid[i], preUid[i]);
assert.equal(initUid[i], postUid[i]);
assert.equal(initUid[i], destroyUid[i]);
assert.equal(initHandle[i], preHandle[i]);
assert.equal(initHandle[i], postHandle[i]);
assert.equal(initHandle[i].constructor.name, 'PromiseWrap');
assert.equal(initParent[i], null);
assert.equal(initProvider[i], 0);
}
assert.equal(fulfilledCalledA, true);
assert.equal(fulfilledArgA, 'a');
assert.equal(fulfilledCalledB, true);
assert.equal(fulfilledArgB, 'b');
});
+79
View File
@@ -0,0 +1,79 @@
'use strict';
const asyncHook = require('../');
const assert = require('assert');
let fulfilledCalled = false;
let fulfilledArg = null;
let initCalls = 0;
let destroyCalls = 0;
let initUid = NaN;
let initHandle = {};
let initParent = {};
let initProvider = NaN;
let preHandle = {};
let preUid = NaN;
let postHandle = {};
let postUid = NaN;
let postDidThrow = NaN;
let destroyUid = NaN;
asyncHook.addHooks({
init: function (uid, handle, provider, parent) {
initUid = uid;
initHandle = handle;
initParent = parent;
initProvider = provider;
initCalls += 1;
},
pre: function (uid, handle) {
preUid = uid;
preHandle = handle;
},
post: function (uid, handle, didThrow) {
postUid = uid;
postHandle = handle;
postDidThrow = didThrow;
},
destroy: function (uid) {
destroyUid = uid;
destroyCalls += 1;
}
});
asyncHook.enable();
Promise
.resolve('a')
.then(arg => {
fulfilledCalled = true;
fulfilledArg = arg;
});
asyncHook.disable();
process.once('exit', function () {
assert.equal(initUid, preUid);
assert.equal(initUid, postUid);
assert.equal(initUid, destroyUid);
assert.equal(initHandle, preHandle);
assert.equal(initHandle, postHandle);
assert.equal(initHandle.constructor.name, 'PromiseWrap');
assert.equal(initParent, null);
assert.equal(initProvider, 0);
assert.equal(postDidThrow, false);
assert.equal(fulfilledCalled, true);
assert.equal(fulfilledArg, 'a');
assert.equal(initCalls, 1);
assert.equal(destroyCalls, 1);
});
@@ -0,0 +1,75 @@
'use strict';
const asyncHook = require('../');
const assert = require('assert');
const fulfilledCalled = [];
const fulfilledArg = [];
const initUid = [];
const initHandle = [];
const initProvider = [];
const initParent = [];
const preUid = [];
const preHandle = [];
const postUid = [];
const postHandle = [];
const destroyUid = [];
asyncHook.addHooks({
init: function (uid, handle, provider, parent) {
initUid.push(uid);
initHandle.push(handle);
initProvider.push(provider);
initParent.push(parent);
},
pre: function (uid, handle) {
preUid.push(uid);
preHandle.push(handle);
},
post: function (uid, handle) {
postUid.push(uid);
postHandle.push(handle);
},
destroy: function (uid) {
destroyUid.push(uid);
}
});
asyncHook.enable();
const p = Promise.resolve('a');
p.then(arg => {
fulfilledCalled.push(true);
fulfilledArg.push(arg);
});
p.then(arg => {
fulfilledCalled.push(true);
fulfilledArg.push(arg);
});
asyncHook.disable();
process.once('exit', function () {
assert.equal(initUid.length, 2);
for (let i = 0; i < 2; ++i) {
assert.equal(initUid[i], preUid[i]);
assert.equal(initUid[i], postUid[i]);
assert.equal(initUid[i], destroyUid[i]);
assert.equal(initHandle[i], preHandle[i]);
assert.equal(initHandle[i], postHandle[i]);
assert.equal(initHandle[i].constructor.name, 'PromiseWrap');
assert.equal(initParent[i], null);
assert.equal(initProvider[i], 0);
assert.equal(fulfilledCalled[i], true);
assert.equal(fulfilledArg[i], 'a');
}
});
+75
View File
@@ -0,0 +1,75 @@
'use strict';
const asyncHook = require('../');
const assert = require('assert');
let rejectedCalled = false;
let rejectedArg = null;
let initCalls = 0;
let destroyCalls = 0;
let initUid = NaN;
let initHandle = {};
let initParent = {};
let initProvider = NaN;
let preHandle = {};
let preUid = NaN;
let postHandle = {};
let postUid = NaN;
let destroyUid = NaN;
asyncHook.addHooks({
init: function (uid, handle, provider, parent) {
initUid = uid;
initHandle = handle;
initParent = parent;
initProvider = provider;
initCalls += 1;
},
pre: function (uid, handle) {
preUid = uid;
preHandle = handle;
},
post: function (uid, handle) {
postUid = uid;
postHandle = handle;
},
destroy: function (uid) {
destroyUid = uid;
destroyCalls += 1;
}
});
asyncHook.enable();
Promise
.reject('a')
.then(null, arg => {
rejectedCalled = true;
rejectedArg = arg;
});
asyncHook.disable();
process.once('exit', function () {
assert.equal(initUid, preUid);
assert.equal(initUid, postUid);
assert.equal(initUid, destroyUid);
assert.equal(initHandle, preHandle);
assert.equal(initHandle, postHandle);
assert.equal(initHandle.constructor.name, 'PromiseWrap');
assert.equal(initParent, null);
assert.equal(initProvider, 0);
assert.equal(rejectedCalled, true);
assert.equal(rejectedArg, 'a');
assert.equal(initCalls, 1);
assert.equal(destroyCalls, 1);
});
+75
View File
@@ -0,0 +1,75 @@
'use strict';
const asyncHook = require('../');
const assert = require('assert');
const eventOrder = [];
asyncHook.addHooks({
init: function (uid, handle) {
eventOrder.push(`init#${uid} ${handle.constructor.name}`);
},
pre: function (uid) {
eventOrder.push(`pre#${uid}`);
},
post: function (uid) {
eventOrder.push(`post#${uid}`);
},
destroy: function (uid) {
eventOrder.push(`destroy#${uid}`);
}
});
asyncHook.enable();
new Promise(function (s) {
setTimeout(s, 100); // 1
})
.then(function () {
return new Promise((s) => setTimeout(s, 100)); // 4
})
.then();
process.once('exit', function () {
const nodeMajor = parseInt(process.versions.node.split('.')[0], 10);
if (nodeMajor >= 6) {
assert.deepEqual(eventOrder, [
'init#-1 TimeoutWrap',
'init#-2 PromiseWrap',
'init#-3 PromiseWrap',
'pre#-1',
'post#-1',
'destroy#-1',
'pre#-2',
'init#-4 TimeoutWrap',
'post#-2',
'destroy#-2',
'init#-5 PromiseWrap',
'pre#-4',
'post#-4',
'destroy#-4',
'pre#-5',
'post#-5',
'destroy#-5',
'destroy#-3'
]);
} else {
assert.deepEqual(eventOrder, [
'init#-1 TimeoutWrap',
'init#-2 PromiseWrap',
'init#-3 PromiseWrap',
'pre#-1',
'post#-1',
'destroy#-1',
'pre#-2',
'init#-4 TimeoutWrap',
'post#-2',
'destroy#-2',
'pre#-4',
'post#-4',
'destroy#-4',
'destroy#-3'
]);
}
});
+9
View File
@@ -0,0 +1,9 @@
'use strict';
const assert = require('assert');
require('../');
let e;
eval('(function() { e = new Error(); })()');
assert.equal(e.stack.split('\n').length, 10);
+38
View File
@@ -0,0 +1,38 @@
'use strict';
const asyncHook = require('../');
const assert = require('assert');
const timings = [];
asyncHook.addHooks({
init: function (uid, handle) {
timings.push(`init#${uid} - ${handle.constructor.name}`);
},
pre: function (uid) {
timings.push(`pre#${uid}`);
},
post: function (uid) {
timings.push(`post#${uid}`);
},
destroy: function (uid) {
timings.push(`destroy#${uid}`);
}
});
asyncHook.enable();
const timerId = setTimeout(() => {
timings.push('callback');
clearTimeout(timerId);
}, 100);
asyncHook.disable();
process.once('exit', function () {
assert.deepEqual(timings, [
'init#-1 - TimeoutWrap',
'pre#-1',
'callback',
'post#-1',
'destroy#-1'
]);
});
+59
View File
@@ -0,0 +1,59 @@
'use strict';
const asyncHook = require('../');
const assert = require('assert');
let timerCalled = false;
let initCalls = 0;
let destroyCalls = 0;
let initUid = NaN;
let initHandleName = '';
let initParent = {};
let initProvider = NaN;
let destroyUid = NaN;
asyncHook.addHooks({
init: function (uid, handle, provider, parent) {
initUid = uid;
initHandleName = handle.constructor.name;
initParent = parent;
initProvider = provider;
initCalls += 1;
},
pre: function () {
assert(false);
},
post: function () {
assert(false);
},
destroy: function (uid) {
destroyUid = uid;
destroyCalls += 1;
}
});
asyncHook.enable();
const timerId = setTimeout(function () {
timerCalled = true;
});
clearTimeout(timerId);
asyncHook.disable();
process.once('exit', function () {
assert.equal(initUid, destroyUid);
assert.equal(initHandleName, 'TimeoutWrap');
assert.equal(initParent, null);
assert.equal(initProvider, 0);
assert.equal(timerCalled, false);
assert.equal(initCalls, 1);
assert.equal(destroyCalls, 1);
});
+46
View File
@@ -0,0 +1,46 @@
'use strict';
const asyncHook = require('../');
const assert = require('assert');
const eventOrder = [];
let throwFlag = null;
asyncHook.addHooks({
init: function (uid, handle) {
eventOrder.push(`init#${uid} ${handle.constructor.name}`);
},
pre: function (uid) {
eventOrder.push(`pre#${uid}`);
},
post: function (uid, handle, didThrow) {
throwFlag = didThrow;
eventOrder.push(`post#${uid}`);
},
destroy: function (uid) {
eventOrder.push(`destroy#${uid}`);
}
});
asyncHook.enable();
process.once('uncaughtException', function () {
eventOrder.push('exception');
});
setTimeout(function () {
eventOrder.push('callback');
throw new Error('error');
});
asyncHook.disable();
process.once('exit', function () {
assert.strictEqual(throwFlag, true);
assert.deepEqual(eventOrder, [
'init#-1 TimeoutWrap', 'pre#-1',
'callback', 'exception',
'post#-1', 'destroy#-1'
]);
});
+42
View File
@@ -0,0 +1,42 @@
'use strict';
const asyncHook = require('../');
const assert = require('assert');
let timerACalled = false;
let timerBCalled = false;
asyncHook.addHooks({
init: function () {
assert(false);
},
pre: function () {
assert(false);
},
post: function () {
assert(false);
},
destroy: function () {
assert(false);
}
});
asyncHook.enable();
asyncHook.disable();
const timerId = setTimeout(function () {
timerACalled = true;
});
clearTimeout(timerId);
setTimeout(function (arg1, arg2) {
timerBCalled = true;
assert.equal(arg1, 'a');
assert.equal(arg2, 'b');
}, 0, 'a', 'b');
process.once('exit', function () {
assert.equal(timerACalled, false);
assert.equal(timerBCalled, true);
});
+72
View File
@@ -0,0 +1,72 @@
'use strict';
const asyncHook = require('../');
const assert = require('assert');
let timerCalled = false;
let initCalls = 0;
let destroyCalls = 0;
let initUid = NaN;
let initHandle = {};
let initParent = {};
let initProvider = NaN;
let preHandle = {};
let preUid = NaN;
let postHandle = {};
let postUid = NaN;
let destroyUid = NaN;
asyncHook.addHooks({
init: function (uid, handle, provider, parent) {
initUid = uid;
initHandle = handle;
initParent = parent;
initProvider = provider;
initCalls += 1;
},
pre: function (uid, handle) {
preUid = uid;
preHandle = handle;
},
post: function (uid, handle) {
postUid = uid;
postHandle = handle;
},
destroy: function (uid) {
destroyUid = uid;
destroyCalls += 1;
}
});
asyncHook.enable();
setTimeout(function (arg1, arg2) {
timerCalled = true;
assert.equal(arg1, 'a');
assert.equal(arg2, 'b');
}, 0, 'a', 'b');
asyncHook.disable();
process.once('exit', function () {
assert.equal(initUid, preUid);
assert.equal(initUid, postUid);
assert.equal(initUid, destroyUid);
assert.equal(initHandle, preHandle);
assert.equal(initHandle, postHandle);
assert.equal(initHandle.constructor.name, 'TimeoutWrap');
assert.equal(initParent, null);
assert.equal(initProvider, 0);
assert.equal(timerCalled, true);
assert.equal(initCalls, 1);
assert.equal(destroyCalls, 1);
});
+32
View File
@@ -0,0 +1,32 @@
'use strict';
if (process.env.hasOwnProperty('ASYNC_HOOK_TEST_CHILD')) {
const asyncHook = require('../');
asyncHook.enable();
setTimeout(function () {
throw new Error('test error');
});
} else {
const spawn = require('child_process').spawn;
const endpoint = require('endpoint');
const child = spawn(process.execPath, [__filename], {
env: Object.assign({ ASYNC_HOOK_TEST_CHILD: '' }, process.env),
stdio: ['ignore', 1, 'pipe']
});
let stderr = null;
child.stderr.pipe(endpoint(function (err, _stderr) {
if (err) throw err;
stderr = _stderr;
}));
child.once('close', function (statusCode) {
if (statusCode !== 1 || stderr.toString().indexOf('test error') === -1) {
process.stderr.write(stderr);
process.exit(statusCode);
}
});
}
+21
View File
@@ -0,0 +1,21 @@
'use strict';
const asyncHook = require('../');
const assert = require('assert');
asyncHook.enable();
let throws = false;
try {
setTimeout(undefined, 1);
} catch (e) {
assert.equal(e.message, '"callback" argument must be a function');
assert.equal(e.name, 'TypeError');
throws = true;
}
asyncHook.disable();
process.once('exit', function () {
assert(throws);
});