@tdb/web
Version:
Common condiguration for serving a web-site and testing web-based UI components.
1,204 lines (1,124 loc) • 33.4 kB
JavaScript
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
;
require("babel-polyfill");
describe("HookTester", () => {
it("should run", () => {});
});
process.on("unhandledRejection", err => console.error(err.stack));
class HookTester {
constructor(hookCreator, sync) {
this.hookCreator = hookCreator;
this.sync = sync;
}
async run(syncOnly) {
const result = {
sync: {},
async: {},
intercept: {}
};
if (syncOnly) {
await this.runSync(result.sync, "call");
} else {
await this.runAsync(result.async, "callAsync");
await this.runAsync(result.async, "promise");
await this.runIntercept(result.intercept, "callAsync");
await this.runIntercept(result.intercept, "promise");
}
await this.runSync(result.sync, "callAsync");
await this.runSync(result.sync, "promise");
return result;
}
async runForLoop(syncOnly) {
const result = {
sync: {},
async: {}
};
if (syncOnly) {
await this.runForLoopSync(result.sync, "call");
} else {
await this.runForLoopAsync(result.async, "callAsync");
await this.runForLoopAsync(result.async, "promise");
}
await this.runForLoopSync(result.sync, "callAsync");
await this.runForLoopSync(result.sync, "promise");
return result;
}
async runForLoopAsync(result, method) {
{
const hook = this.createHook([], `${method}BrokenPromise`);
hook.tapPromise("promise", () => "this is not a promise");
result[`${method}BrokenPromise`] = await this.gainResult(cb =>
hook[method](cb)
);
}
{
const hook = this.createHook([], `${method}SinglePromise`);
hook.tapPromise("promise", () => {
result[`${method}SinglePromiseCalled`] =
(result[`${method}SinglePromiseCalled`] || 0) + 1;
if (result[`${method}SinglePromiseCalled`] < 42)
return Promise.resolve().then(() => true);
return Promise.resolve().then(() => {});
});
result[`${method}SinglePromise`] = await this.gainResult(cb =>
hook[method](cb)
);
}
{
const hook = this.createHook([], `${method}MultiplePromise`);
hook.tapPromise("promise1", () => {
result[`${method}MultiplePromiseCalled1`] =
(result[`${method}MultiplePromiseCalled1`] || 0) + 1;
if (result[`${method}MultiplePromiseCalled1`] < 42)
return Promise.resolve().then(() => true);
return Promise.resolve().then(() => {});
});
hook.tapPromise("promise2", () => {
result[`${method}MultiplePromiseCalled2`] =
(result[`${method}MultiplePromiseCalled2`] || 0) + 1;
if (result[`${method}MultiplePromiseCalled2`] < 42)
return Promise.resolve().then(() => true);
return Promise.resolve().then(() => {});
});
result[`${method}MultiplePromise`] = await this.gainResult(cb =>
hook[method](cb)
);
}
{
const hook = this.createHook([], `${method}SingleAsync`);
hook.tapAsync("async", callback => {
result[`${method}SingleAsyncCalled`] =
(result[`${method}SingleAsyncCalled`] || 0) + 1;
if (result[`${method}SingleAsyncCalled`] < 42)
return Promise.resolve().then(() => callback(null, true));
return Promise.resolve().then(() => callback());
});
result[`${method}SingleAsync`] = await this.gainResult(cb =>
hook[method](cb)
);
}
{
const hook = this.createHook([], `${method}MultipleAsync`);
hook.tapAsync("async1", callback => {
result[`${method}MultipleAsyncCalled1`] =
(result[`${method}MultipleAsyncCalled1`] || 0) + 1;
if (result[`${method}MultipleAsyncCalled1`] < 42)
return Promise.resolve().then(() => callback(null, true));
return Promise.resolve().then(() => callback());
});
hook.tapAsync("async2", callback => {
result[`${method}MultipleAsyncCalled2`] =
(result[`${method}MultipleAsyncCalled2`] || 0) + 1;
if (result[`${method}MultipleAsyncCalled2`] < 42)
return Promise.resolve().then(() => callback(null, true));
return Promise.resolve().then(() => callback());
});
result[`${method}MultipleAsync`] = await this.gainResult(cb =>
hook[method](cb)
);
}
{
const hook = this.createHook([], `${method}Mixed`);
hook.tapAsync("async1", callback => {
result[`${method}MixedCalled1`] =
(result[`${method}MixedCalled1`] || 0) + 1;
if (result[`${method}MixedCalled1`] < 42)
return Promise.resolve().then(() => callback(null, true));
return Promise.resolve().then(() => callback());
});
hook.tap("sync2", () => {
result[`${method}MixedCalled2`] =
(result[`${method}MixedCalled2`] || 0) + 1;
if (result[`${method}MixedCalled2`] < 42) return true;
});
hook.tapPromise("promise3", () => {
result[`${method}MixedCalled3`] =
(result[`${method}MixedCalled3`] || 0) + 1;
if (result[`${method}MixedCalled3`] < 42)
return Promise.resolve().then(() => true);
return Promise.resolve().then(() => {});
});
result[`${method}Mixed`] = await this.gainResult(cb => hook[method](cb));
}
}
async runForLoopSync(result, method) {
{
const hook = this.createHook([], `${method}None`);
result[`${method}None`] = await this.gainResult(cb => hook[method](cb));
}
{
const hook = this.createHook(["arg"], `${method}NoneWithArg`);
result[`${method}NoneWithArg`] = await this.gainResult(cb =>
hook[method](42, cb)
);
}
{
const hook = this.createHook([], `${method}SingleSync`);
hook.tap("sync", () => {
result[`${method}SingleSyncCalled`] =
(result[`${method}SingleSyncCalled`] || 0) + 1;
if (result[`${method}SingleSyncCalled`] < 42) return true;
});
result[`${method}SingleSync`] = await this.gainResult(cb =>
hook[method](cb)
);
}
{
const hook = this.createHook([], `${method}MultipleSync`);
hook.tap("sync1", () => {
result[`${method}MultipleSyncCalled1`] =
(result[`${method}MultipleSyncCalled1`] || 0) + 1;
if (result[`${method}MultipleSyncCalled1`] < 42) return true;
});
hook.tap("sync2", () => {
result[`${method}MultipleSyncCalled2`] =
(result[`${method}MultipleSyncCalled2`] || 0) + 1;
if (result[`${method}MultipleSyncCalled2`] < 42) return true;
});
result[`${method}MultipleSync`] = await this.gainResult(cb =>
hook[method](cb)
);
}
{
const hook = this.createHook([], `${method}InterceptedSync`);
hook.tap("sync1", () => {
result[`${method}InterceptedSyncCalled1`] =
(result[`${method}InterceptedSyncCalled1`] || 0) + 1;
if (result[`${method}InterceptedSyncCalled1`] < 42) return true;
});
hook.tap("sync2", () => {
result[`${method}InterceptedSyncCalled2`] =
(result[`${method}InterceptedSyncCalled2`] || 0) + 1;
if (result[`${method}InterceptedSyncCalled2`] < 42) return true;
});
hook.intercept({
call: a =>
(result[`${method}InterceptedSyncCalledCall`] =
(result[`${method}InterceptedSyncCalledCall`] || 0) + 1),
loop: a =>
(result[`${method}InterceptedSyncCalledLoop`] =
(result[`${method}InterceptedSyncCalledLoop`] || 0) + 1),
tap: tap => {
result[`${method}InterceptedSyncCalledTap`] =
(result[`${method}InterceptedSyncCalledTap`] || 0) + 1;
}
});
result[`${method}InterceptedSync`] = await this.gainResult(cb =>
hook[method](cb)
);
}
}
async runSync(result, method) {
{
const hook = this.createHook([], `${method}None`);
result[`${method}None`] = await this.gainResult(cb => hook[method](cb));
}
{
const hook = this.createHook(["arg"], `${method}NoneWithArg`);
result[`${method}NoneWithArg`] = await this.gainResult(cb =>
hook[method](42, cb)
);
}
{
const hook = this.createHook([], `${method}SingleSync`);
hook.tap("sync", () => {
result[`${method}SingleSyncCalled`] = true;
return 42;
});
result[`${method}SingleSync`] = await this.gainResult(cb =>
hook[method](cb)
);
}
{
const hook = this.createHook(["myArg"], `${method}SingleSyncWithArg`);
hook.tap("sync", nr => {
result[`${method}SingleSyncWithArgCalled`] = nr;
return nr;
});
result[`${method}SingleSyncWithArg`] = await this.gainResult(cb =>
hook[method](42, cb)
);
}
{
const hook = this.createHook([], `${method}MultipleSync`);
hook.tap("sync1", () => {
result[`${method}MultipleSyncCalled1`] = true;
return 42;
});
hook.tap("sync2", () => {
result[`${method}MultipleSyncCalled2`] = true;
return 43;
});
result[`${method}MultipleSync`] = await this.gainResult(cb =>
hook[method](cb)
);
}
{
const hook = this.createHook(["a"], `${method}MultipleSyncWithArg`);
hook.tap("sync1", a => {
result[`${method}MultipleSyncWithArgCalled1`] = a;
return 42 + a;
});
hook.tap("sync2", a => {
result[`${method}MultipleSyncWithArgCalled2`] = a;
return 43 + a;
});
result[`${method}MultipleSyncWithArg`] = await this.gainResult(cb =>
hook[method](42, cb)
);
}
{
const hook = this.createHook(
["a"],
`${method}MultipleSyncWithArgNoReturn`
);
hook.tap("sync1", a => {
result[`${method}MultipleSyncWithArgNoReturnCalled1`] = a;
});
hook.tap("sync2", a => {
result[`${method}MultipleSyncWithArgNoReturnCalled2`] = a;
});
result[`${method}MultipleSyncWithArgNoReturn`] = await this.gainResult(
cb => hook[method](42, cb)
);
}
{
const hook = this.createHook(
["a"],
`${method}MultipleSyncWithArgFirstReturn`
);
hook.tap("sync1", a => {
result[`${method}MultipleSyncWithArgFirstReturnCalled1`] = a;
return 42 + a;
});
hook.tap("sync2", a => {
result[`${method}MultipleSyncWithArgFirstReturnCalled2`] = a;
});
result[`${method}MultipleSyncWithArgFirstReturn`] = await this.gainResult(
cb => hook[method](42, cb)
);
}
{
const hook = this.createHook(
["a"],
`${method}MultipleSyncWithArgLastReturn`
);
hook.tap("sync1", a => {
result[`${method}MultipleSyncWithArgLastReturnCalled1`] = a;
});
hook.tap("sync2", a => {
result[`${method}MultipleSyncWithArgLastReturnCalled2`] = a;
return 43 + a;
});
result[`${method}MultipleSyncWithArgLastReturn`] = await this.gainResult(
cb => hook[method](42, cb)
);
}
{
const hook = this.createHook(
["a", "b", "c"],
`${method}MultipleSyncWithArgs`
);
hook.tap("sync1", (a, b, c) => {
result[`${method}MultipleSyncWithArgsCalled1`] = [a, b, c];
return a + b + c;
});
hook.tap("sync2", (a, b, c) => {
result[`${method}MultipleSyncWithArgsCalled2`] = [a, b, c];
return a + b + c + 1;
});
result[`${method}MultipleSyncWithArgs`] = await this.gainResult(cb =>
hook[method](42, 43, 44, cb)
);
}
{
const hook = this.createHook([], `${method}MultipleSyncError`);
hook.tap("sync1", () => {
result[`${method}MultipleSyncErrorCalled1`] = true;
});
hook.tap("sync2", () => {
result[`${method}MultipleSyncErrorCalled2`] = true;
throw new Error("Error in sync2");
});
hook.tap("sync3", () => {
result[`${method}MultipleSyncErrorCalled3`] = true;
});
result[`${method}MultipleSyncError`] = await this.gainResult(cb =>
hook[method](cb)
);
}
{
const hook = this.createHook(["a", "b", "c"], `${method}Intercepted`);
hook.intercept({
call: (a, b, c) => {
result[`${method}InterceptedCall1`] = [a, b, c];
},
tap: tap => {
result[`${method}InterceptedTap1`] = Object.assign({}, tap, {
fn: tap.fn.length
});
}
});
hook.intercept({
call: (a, b, c) => {
result[`${method}InterceptedCall2`] = [a, b, c];
},
tap: tap => {
if (!result[`${method}InterceptedTap2`])
result[`${method}InterceptedTap2`] = Object.assign({}, tap, {
fn: tap.fn.length
});
}
});
hook.tap("sync1", (a, b, c) => a + b + c);
hook.tap("sync2", (a, b) => a + b + 1);
result[`${method}Intercepted`] = await this.gainResult(cb =>
hook[method](1, 2, 3, cb)
);
}
}
async runAsync(result, type) {
{
const hook = this.createHook([], `${type}None`);
result[`${type}None`] = await this.gainResult(cb => hook[type](cb));
}
{
const hook = this.createHook(["arg"], `${type}NoneWithArg`);
result[`${type}NoneWithArg`] = await this.gainResult(cb =>
hook[type](42, cb)
);
}
{
const hook = this.createHook([], `${type}SingleSync`);
hook.tap("sync", () => {
result[`${type}SingleSyncCalled1`] = true;
return 42;
});
result[`${type}SingleSync`] = await this.gainResult(cb => hook[type](cb));
}
{
const hook = this.createHook(["x"], `${type}SingleSyncWithArg`);
hook.tap("sync", arg => {
result[`${type}SingleSyncWithArgCalled1`] = arg;
return arg + 1;
});
result[`${type}SingleSyncWithArg`] = await this.gainResult(cb =>
hook[type](42, cb)
);
}
{
const hook = this.createHook(["x"], `${type}SingleSyncWithArgNoReturn`);
hook.tap("sync", arg => {
result[`${type}SingleSyncWithArgNoReturnCalled1`] = arg;
});
result[`${type}SingleSyncWithArgNoReturn`] = await this.gainResult(cb =>
hook[type](42, cb)
);
}
{
const hook = this.createHook([], `${type}MultipleSync`);
hook.tap("sync1", () => {
result[`${type}MultipleSyncCalled1`] = true;
return 42;
});
hook.tap("sync2", () => {
result[`${type}MultipleSyncCalled2`] = true;
return 43;
});
result[`${type}MultipleSync`] = await this.gainResult(cb =>
hook[type](cb)
);
}
{
const hook = this.createHook([], `${type}MultipleSyncLastReturn`);
hook.tap("sync1", () => {
result[`${type}MultipleSyncLastReturnCalled1`] = true;
});
hook.tap("sync2", () => {
result[`${type}MultipleSyncLastReturnCalled2`] = true;
return 43;
});
result[`${type}MultipleSyncLastReturn`] = await this.gainResult(cb =>
hook[type](cb)
);
}
{
const hook = this.createHook([], `${type}MultipleSyncNoReturn`);
hook.tap("sync1", () => {
result[`${type}MultipleSyncNoReturnCalled1`] = true;
});
hook.tap("sync2", () => {
result[`${type}MultipleSyncNoReturnCalled2`] = true;
});
result[`${type}MultipleSyncNoReturn`] = await this.gainResult(cb =>
hook[type](cb)
);
}
{
const hook = this.createHook(["arg"], `${type}MultipleSyncWithArg`);
hook.tap("sync1", arg => {
result[`${type}MultipleSyncWithArgCalled1`] = arg;
return arg + 1;
});
hook.tap("sync2", arg => {
result[`${type}MultipleSyncWithArgCalled2`] = arg;
return arg + 2;
});
result[`${type}MultipleSyncWithArg`] = await this.gainResult(cb =>
hook[type](42, cb)
);
}
{
const hook = this.createHook(
["arg"],
`${type}MultipleSyncWithArgNoReturn`
);
hook.tap("sync1", arg => {
result[`${type}MultipleSyncWithArgNoReturnCalled1`] = arg;
});
hook.tap("sync2", arg => {
result[`${type}MultipleSyncWithArgNoReturnCalled2`] = arg;
});
result[`${type}MultipleSyncWithArgNoReturn`] = await this.gainResult(cb =>
hook[type](42, cb)
);
}
{
const hook = this.createHook(
["arg"],
`${type}MultipleSyncWithArgLastReturn`
);
hook.tap("sync1", arg => {
result[`${type}MultipleSyncWithArgLastReturnCalled1`] = arg;
});
hook.tap("sync2", arg => {
result[`${type}MultipleSyncWithArgLastReturnCalled2`] = arg;
return arg + 2;
});
result[`${type}MultipleSyncWithArgLastReturn`] = await this.gainResult(
cb => hook[type](42, cb)
);
}
{
const hook = this.createHook(
["arg"],
`${type}MultipleSyncWithArgFirstReturn`
);
hook.tap("sync1", arg => {
result[`${type}MultipleSyncWithArgFirstReturnCalled1`] = arg;
return arg + 1;
});
hook.tap("sync2", arg => {
result[`${type}MultipleSyncWithArgFirstReturnCalled2`] = arg;
});
result[`${type}MultipleSyncWithArgFirstReturn`] = await this.gainResult(
cb => hook[type](42, cb)
);
}
{
const hook = this.createHook(["x"], `${type}SingleAsyncWithArg`);
hook.tapAsync("async", (arg, callback) => {
result[`${type}SingleAsyncWithArgCalled1`] = arg;
callback(null, arg);
});
result[`${type}SingleAsyncWithArg`] = await this.gainResult(cb =>
hook[type](42, cb)
);
}
{
const hook = this.createHook(["x"], `${type}MultipleAsyncWithArg`);
hook.tapAsync("async1", (arg, callback) => {
result[`${type}MultipleAsyncWithArgCalled1`] = arg;
callback(null, arg + 1);
});
hook.tapAsync("async2", (arg, callback) => {
result[`${type}MultipleAsyncWithArgCalled2`] = arg;
callback(null, arg + 2);
});
result[`${type}MultipleAsyncWithArg`] = await this.gainResult(cb =>
hook[type](42, cb)
);
}
{
const hook = this.createHook(
["x"],
`${type}MultipleAsyncWithArgNoReturn`
);
hook.tapAsync("async1", (arg, callback) => {
result[`${type}MultipleAsyncWithArgNoReturnCalled1`] = arg;
callback();
});
hook.tapAsync("async2", (arg, callback) => {
result[`${type}MultipleAsyncWithArgNoReturnCalled2`] = arg;
callback();
});
result[`${type}MultipleAsyncWithArgNoReturn`] = await this.gainResult(
cb => hook[type](42, cb)
);
}
{
const hook = this.createHook(
["x"],
`${type}MultipleAsyncWithArgFirstReturn`
);
hook.tapAsync("async1", (arg, callback) => {
result[`${type}MultipleAsyncWithArgFirstReturnCalled1`] = arg;
callback(null, arg + 1);
});
hook.tapAsync("async2", (arg, callback) => {
result[`${type}MultipleAsyncWithArgFirstReturnCalled2`] = arg;
callback();
});
result[`${type}MultipleAsyncWithArgFirstReturn`] = await this.gainResult(
cb => hook[type](42, cb)
);
}
{
const hook = this.createHook(
["x"],
`${type}MultipleAsyncWithArgLastReturn`
);
hook.tapAsync("async1", (arg, callback) => {
result[`${type}MultipleAsyncWithArgLastReturnCalled1`] = arg;
callback();
});
hook.tapAsync("async2", (arg, callback) => {
result[`${type}MultipleAsyncWithArgLastReturnCalled2`] = arg;
callback(null, arg + 2);
});
result[`${type}MultipleAsyncWithArgLastReturn`] = await this.gainResult(
cb => hook[type](42, cb)
);
}
{
const hook = this.createHook(["x"], `${type}SinglePromiseWithArg`);
hook.tapPromise("promise", arg => {
result[`${type}SinglePromiseWithArgCalled1`] = arg;
return Promise.resolve(arg + 1);
});
result[`${type}SinglePromiseWithArg`] = await this.gainResult(cb =>
hook[type](42, cb)
);
}
{
const hook = this.createHook(["x"], `${type}MultiplePromiseWithArg`);
hook.tapPromise("promise1", arg => {
result[`${type}MultiplePromiseWithArgCalled1`] = arg;
return Promise.resolve(arg + 1);
});
hook.tapPromise("promise2", arg => {
result[`${type}MultiplePromiseWithArgCalled2`] = arg;
return Promise.resolve(arg + 2);
});
result[`${type}MultiplePromiseWithArg`] = await this.gainResult(cb =>
hook[type](42, cb)
);
}
{
const hook = this.createHook(
["x"],
`${type}MultiplePromiseWithArgNoReturn`
);
hook.tapPromise("promise1", arg => {
result[`${type}MultiplePromiseWithArgNoReturnCalled1`] = arg;
return Promise.resolve();
});
hook.tapPromise("promise2", arg => {
result[`${type}MultiplePromiseWithArgNoReturnCalled2`] = arg;
return Promise.resolve();
});
result[`${type}MultiplePromiseWithArgNoReturn`] = await this.gainResult(
cb => hook[type](42, cb)
);
}
{
const hook = this.createHook(
["x"],
`${type}MultiplePromiseWithArgFirstReturn`
);
hook.tapPromise("promise1", arg => {
result[`${type}MultiplePromiseWithArgFirstReturnCalled1`] = arg;
return Promise.resolve(arg + 1);
});
hook.tapPromise("promise2", arg => {
result[`${type}MultiplePromiseWithArgFirstReturnCalled2`] = arg;
return Promise.resolve();
});
result[
`${type}MultiplePromiseWithArgFirstReturn`
] = await this.gainResult(cb => hook[type](42, cb));
}
{
const hook = this.createHook(
["x"],
`${type}MultiplePromiseWithArgLastReturn`
);
hook.tapPromise("promise1", arg => {
result[`${type}MultiplePromiseWithArgLastReturnCalled1`] = arg;
return Promise.resolve();
});
hook.tapPromise("promise2", arg => {
result[`${type}MultiplePromiseWithArgLastReturnCalled2`] = arg;
return Promise.resolve(arg + 2);
});
result[`${type}MultiplePromiseWithArgLastReturn`] = await this.gainResult(
cb => hook[type](42, cb)
);
}
{
const hook = this.createHook(["x"], `${type}MultipleMixed1WithArg`);
hook.tapAsync("async", (arg, callback) => {
result[`${type}MultipleMixed1WithArgCalled1`] = arg;
callback(null, arg + 1);
});
hook.tapPromise("promise", arg => {
result[`${type}MultipleMixed1WithArgCalled2`] = arg;
return Promise.resolve(arg + 2);
});
hook.tap("sync", arg => {
result[`${type}MultipleMixed1WithArgCalled3`] = arg;
return arg + 3;
});
result[`${type}MultipleMixed1WithArg`] = await this.gainResult(cb =>
hook[type](42, cb)
);
}
{
const hook = this.createHook(["x"], `${type}MultipleMixed2WithArg`);
hook.tapAsync("async", (arg, callback) => {
result[`${type}MultipleMixed2WithArgCalled1`] = arg;
setTimeout(() => callback(null, arg + 1), 100);
});
hook.tapPromise("promise", arg => {
result[`${type}MultipleMixed2WithArgCalled2`] = arg;
return Promise.resolve(arg + 2);
});
result[`${type}MultipleMixed2WithArg`] = await this.gainResult(cb =>
hook[type](42, cb)
);
}
{
const hook = this.createHook(["x"], `${type}MultipleMixed3WithArg`);
hook.tapAsync("async1", (arg, callback) => {
result[`${type}MultipleMixed3WithArgCalled1`] = arg;
callback(null, arg + 1);
});
hook.tapPromise("promise", arg => {
result[`${type}MultipleMixed3WithArgCalled2`] = arg;
return Promise.resolve(arg + 2);
});
hook.tapAsync("async2", (arg, callback) => {
result[`${type}MultipleMixed3WithArgCalled3`] = arg;
setTimeout(() => callback(null, arg + 3), 100);
});
result[`${type}MultipleMixed3WithArg`] = await this.gainResult(cb =>
hook[type](42, cb)
);
}
{
const hook = this.createHook([], `${type}MultipleSyncError`);
hook.tap("sync1", () => {
result[`${type}MultipleSyncErrorCalled1`] = true;
});
hook.tap("sync2", () => {
throw new Error("Error in sync2");
});
hook.tap("sync3", () => {
result[`${type}MultipleSyncErrorCalled3`] = true;
});
result[`${type}MultipleSyncError`] = await this.gainResult(cb =>
hook[type](cb)
);
}
{
const hook = this.createHook([], `${type}MultipleAsyncError`);
hook.tapAsync("async1", callback => {
result[`${type}MultipleAsyncErrorCalled1`] = true;
callback();
});
hook.tapAsync("async2", callback => {
callback(new Error("Error in async2"));
});
hook.tapAsync("async3", callback => {
result[`${type}MultipleAsyncErrorCalled3`] = true;
callback();
});
result[`${type}MultipleAsyncError`] = await this.gainResult(cb =>
hook[type](cb)
);
}
{
const hook = this.createHook([], `${type}MultipleAsyncLateError`);
hook.tapAsync("async1", callback => {
result[`${type}MultipleAsyncLateErrorCalled1`] = true;
callback();
});
hook.tapAsync("async2", callback => {
setTimeout(() => callback(new Error("Error in async2")), 100);
});
hook.tapAsync("async3", callback => {
result[`${type}MultipleAsyncLateErrorCalled3`] = true;
callback();
});
result[`${type}MultipleAsyncLateError`] = await this.gainResult(cb =>
hook[type](cb)
);
}
{
const hook = this.createHook(
[],
`${type}MultipleAsyncLateErrorEarlyResult1`
);
hook.tapAsync("async1", callback => {
result[`${type}MultipleAsyncLateErrorEarlyResult1Called1`] = true;
callback();
});
hook.tapAsync("async2", callback => {
setTimeout(() => callback(new Error("Error in async2")), 100);
});
hook.tapAsync("async3", callback => {
result[`${type}MultipleAsyncLateErrorEarlyResult1Called3`] = true;
callback(null, 7);
});
result[
`${type}MultipleAsyncLateErrorEarlyResult1`
] = await this.gainResult(cb => hook[type](cb));
}
{
const hook = this.createHook(
[],
`${type}MultipleAsyncLateErrorEarlyResult2`
);
hook.tapAsync("async1", callback => {
result[`${type}MultipleAsyncLateErrorEarlyResult2Called1`] = true;
setTimeout(() => callback(null, 42), 200);
});
hook.tapAsync("async2", callback => {
setTimeout(() => callback(new Error("Error in async2")), 100);
});
hook.tapAsync("async3", callback => {
result[`${type}MultipleAsyncLateErrorEarlyResult2Called3`] = true;
callback(null, 7);
});
result[
`${type}MultipleAsyncLateErrorEarlyResult2`
] = await this.gainResult(cb => hook[type](cb));
}
{
const hook = this.createHook([], `${type}MultipleAsyncEarlyError`);
hook.tapAsync("async1", callback => {
result[`${type}MultipleAsyncEarlyErrorCalled1`] = true;
setTimeout(() => callback(), 100);
});
hook.tapAsync("async2", callback => {
callback(new Error("Error in async2"));
});
hook.tapAsync("async3", callback => {
result[`${type}MultipleAsyncEarlyErrorCalled3`] = true;
setTimeout(() => callback(), 100);
});
result[`${type}MultipleAsyncEarlyError`] = await this.gainResult(cb =>
hook[type](cb)
);
}
{
const hook = this.createHook([], `${type}MultiplePromiseError`);
hook.tapPromise("promise1", () => {
result[`${type}MultiplePromiseErrorCalled1`] = true;
return Promise.resolve();
});
hook.tapPromise("promise2", () => {
return Promise.resolve().then(() => {
throw new Error("Error in async2");
});
});
hook.tapPromise("promise3", () => {
result[`${type}MultiplePromiseErrorCalled3`] = true;
return Promise.resolve();
});
result[`${type}MultiplePromiseError`] = await this.gainResult(cb =>
hook[type](cb)
);
}
{
const hook = this.createHook([], `${type}MultiplePromiseLateError`);
hook.tapPromise("promise1", () => {
result[`${type}MultiplePromiseLateErrorCalled1`] = true;
return Promise.resolve();
});
hook.tapPromise("promise2", () => {
return new Promise((resolve, reject) => {
setTimeout(() => reject(new Error("Error in async2")), 100);
});
});
hook.tapPromise("promise3", () => {
result[`${type}MultiplePromiseLateErrorCalled3`] = true;
return Promise.resolve();
});
result[`${type}MultiplePromiseLateError`] = await this.gainResult(cb =>
hook[type](cb)
);
}
{
const hook = this.createHook([], `${type}MultiplePromiseEarlyError`);
hook.tapPromise("promise1", () => {
result[`${type}MultiplePromiseEarlyErrorCalled1`] = true;
return new Promise(resolve => setTimeout(() => resolve(), 100));
});
hook.tapPromise("promise2", () => {
return Promise.resolve().then(() => {
throw new Error("Error in async2");
});
});
hook.tapPromise("promise3", () => {
result[`${type}MultiplePromiseEarlyErrorCalled3`] = true;
return new Promise(resolve => setTimeout(() => resolve(), 100));
});
result[`${type}MultiplePromiseEarlyError`] = await this.gainResult(cb =>
hook[type](cb)
);
}
{
const hook = this.createHook(["x"], `${type}MultipleMixedError1WithArg`);
hook.tapAsync("async", (arg, callback) => {
result[`${type}MultipleMixedError1WithArgCalled1`] = arg;
callback(null, arg);
});
hook.tapPromise("promise", arg => {
result[`${type}MultipleMixedError1WithArgCalled2`] = arg;
return Promise.resolve(arg + 1);
});
hook.tap("sync", arg => {
result[`${type}MultipleMixedError1WithArgCalled3`] = arg;
throw new Error("Error in sync");
});
result[`${type}MultipleMixedError1WithArg`] = await this.gainResult(cb =>
hook[type](42, cb)
);
}
{
const hook = this.createHook(["x"], `${type}MultipleMixedError2WithArg`);
hook.tapAsync("async", (arg, callback) => {
result[`${type}MultipleMixedError2WithArgCalled1`] = arg;
callback(null, arg);
});
hook.tapPromise("promise", arg => {
result[`${type}MultipleMixedError2WithArgCalled2`] = arg;
return Promise.resolve().then(() => {
throw new Error("Error in promise");
});
});
hook.tap("sync", arg => {
result[`${type}MultipleMixedError2WithArgCalled3`] = arg;
return arg + 2;
});
result[`${type}MultipleMixedError2WithArg`] = await this.gainResult(cb =>
hook[type](42, cb)
);
}
{
const hook = this.createHook(["x"], `${type}MultipleMixedError3WithArg`);
hook.tapAsync("async", (arg, callback) => {
result[`${type}MultipleMixedError3WithArgCalled1`] = arg;
callback(new Error("Error in async"));
});
hook.tapPromise("promise", arg => {
result[`${type}MultipleMixedError3WithArgCalled2`] = arg;
return Promise.resolve(arg + 1);
});
hook.tap("sync", arg => {
result[`${type}MultipleMixedError3WithArgCalled3`] = arg;
return arg + 2;
});
result[`${type}MultipleMixedError3WithArg`] = await this.gainResult(cb =>
hook[type](42, cb)
);
}
{
const hook = this.createHook([], `${type}MultipleMixedLateError`);
hook.tapAsync("async", callback => {
result[`${type}MultipleMixedLateErrorCalled1`] = true;
setTimeout(() => callback(new Error("Error in async")), 100);
});
hook.tapPromise("promise", () => {
result[`${type}MultipleMixedLateErrorCalled2`] = true;
return Promise.resolve(42);
});
hook.tap("sync", () => {
result[`${type}MultipleMixedLateErrorCalled3`] = true;
return 43;
});
result[`${type}MultipleMixedLateError`] = await this.gainResult(cb =>
hook[type](cb)
);
}
}
async runIntercept(result, type) {
{
const hook = this.createHook(["a", "b", "c"], `${type}Intercepted`);
hook.intercept({
call: (a, b, c) => {
result[`${type}InterceptedCall1`] = [a, b, c];
},
tap: tap => {
result[`${type}InterceptedTap1`] = Object.assign({}, tap, {
fn: tap.fn.length
});
}
});
hook.intercept({
call: (a, b, c) => {
result[`${type}InterceptedCall2`] = [a, b, c];
},
tap: tap => {
if (!result[`${type}InterceptedTap2`])
result[`${type}InterceptedTap2`] = Object.assign({}, tap, {
fn: tap.fn.length
});
}
});
hook.tap("sync", (a, b, c) => a + b + c);
hook.tapPromise("promise", (a, b) => Promise.resolve(a + b + 1));
result[`${type}Intercepted`] = await this.gainResult(cb =>
hook[type](1, 2, 3, cb)
);
}
{
const hook = this.createHook(
["a", "b", "c"],
`${type}ContextIntercepted`
);
hook.intercept({
call: (context, a, b, c) => {
context.number = 42;
result[`${type}ContextInterceptedCall1`] = [context, a, b, c];
},
loop: (context, a, b, c) => {
context.number2 = 88;
result[`${type}ContextInterceptedLoop1`] = [context, a, b, c];
},
tap: (context, tap) => {
result[`${type}ContextInterceptedTap1`] = context;
},
context: true
});
hook.intercept({
call: (a, b, c) => {
result[`${type}ContextInterceptedCall2`] = [a, b, c];
}
});
hook.tap(
{
name: "sync",
context: true
},
(context, a, b, c) => context.number + a + b + c
);
result[`${type}ContextIntercepted`] = await this.gainResult(cb =>
hook[type](1, 2, 3, cb)
);
}
{
const hook = this.createHook(
["a", "b", "c"],
`${type}UnusedContextIntercepted`
);
hook.intercept({
call: (context, a, b, c) => {
result[`${type}UnusedContextInterceptedCall1`] = [context, a, b, c];
},
tap: (context, tap) => {
result[`${type}UnusedContextInterceptedTap1`] = context;
},
context: true
});
hook.intercept({
call: (a, b, c) => {
result[`${type}UnusedContextInterceptedCall2`] = [a, b, c];
}
});
hook.tap("sync", (a, b, c) => a + b + c);
result[`${type}UnusedContextIntercepted`] = await this.gainResult(cb =>
hook[type](1, 2, 3, cb)
);
}
}
gainResult(fn) {
return Promise.race([
new Promise(resolve => {
try {
const ret = fn((err, result) => {
if (err) {
resolve({
type: "async",
error: err.message
});
} else {
resolve({
type: "async",
value: result
});
}
});
if (ret instanceof Promise) {
resolve(
ret.then(
res => ({
type: "promise",
value: res
}),
err => ({
type: "promise",
error: err.message
})
)
);
} else if (ret !== undefined) {
resolve({
type: "return",
value: ret
});
}
} catch (e) {
resolve({
error: e.message
});
}
}),
new Promise(resolve => {
setTimeout(
() =>
resolve({
type: "no result"
}),
1000
);
})
]);
}
createHook(args, name) {
try {
return this.hookCreator(args, name);
} catch (err) {
return {
tap: () => {},
tapPromise: () => {},
tapAsync: () => {},
intercept: () => {},
call: () => {
throw err;
},
callAsync: () => {
throw err;
},
promise: () => {
throw err;
}
};
}
}
}
module.exports = HookTester;