Skip to content

Commit

Permalink
fix: override t.fail, t.notThrows, t.notThrowsAsync
Browse files Browse the repository at this point in the history
  • Loading branch information
erights committed Apr 28, 2021
1 parent 279e14d commit d14b4dc
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 7 deletions.
53 changes: 46 additions & 7 deletions packages/ses-ava/src/ses-ava-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,45 @@ const logErrorFirst = (func, args, name, logger = defaultLogger) => {
}
};

/**
* @param {Assertions} originalT
* @param {Logger} logger
* @returns {Assertions}
*/
const wrapAssertions = (originalT, logger) => {
/**
* Inherits all methods from the originalT that it does not override.
* Those that it does override it wraps behavior around a `super` call,
* and so uses concise method syntax rather than arrow functions.
*
* See TODO comment on cast below to remove the `{unknown}` type declaration.
*
* @type {unknown}
*/
const newT = harden({
__proto__: originalT,
fail(message) {
const err = new Error(message);
logger('FAILED by t.fail', err);
return super.fail(message);
},
notThrows(originalFn, message) {
const newFn = (...args) =>
logErrorFirst(originalFn, args, 'notThrows', logger);
return super.notThrows(newFn, message);
},
notThrowsAsync(originalFn, message) {
const newFn = (...args) =>
logErrorFirst(originalFn, args, 'notThrowsAsync', logger);
return super.notThrowsAsync(newFn, message);
},
});
// TODO The `{unknown}` above and the cast here seem to be needed
// because TypeScript doesn't understand `__proto__:` in an object
// literal implies inheritance, and thus usually subtyping.
return /** @type {Assertions} */ (newT);
};

const testerMethodsWhitelist = [
'after',
'afterEach',
Expand All @@ -59,16 +98,16 @@ const testerMethodsWhitelist = [

/**
* @param {TesterFunc} testerFunc
* @param {Logger} [logger]
* @param {Logger} logger
* @returns {TesterFunc} Not yet frozen!
*/
const wrapTester = (testerFunc, logger = defaultLogger) => {
const wrapTester = (testerFunc, logger) => {
/** @type {TesterFunc} */
const testerWrapper = (title, implFunc, ...otherArgs) => {
/** @type {ImplFunc} */
const testFuncWrapper = t => {
harden(t);
return logErrorFirst(implFunc, [t, ...otherArgs], 'ava test', logger);
const testFuncWrapper = originalT => {
const newT = wrapAssertions(originalT, logger);
return logErrorFirst(implFunc, [newT, ...otherArgs], 'ava test', logger);
};
if (implFunc && implFunc.title) {
testFuncWrapper.title = implFunc.title;
Expand Down Expand Up @@ -104,7 +143,7 @@ const wrapTester = (testerFunc, logger = defaultLogger) => {
* propagating into `rawTest`.
*
* @param {TesterInterface} avaTest
* @param {Logger} [logger]
* @param {Logger=} logger
* @returns {TesterInterface}
*/
const wrapTest = (avaTest, logger = defaultLogger) => {
Expand All @@ -115,7 +154,7 @@ const wrapTest = (avaTest, logger = defaultLogger) => {
/** @type {TesterFunc} */
const testerMethod = (title, implFunc, ...otherArgs) =>
avaTest[methodName](title, implFunc, ...otherArgs);
testerWrapper[methodName] = wrapTester(testerMethod);
testerWrapper[methodName] = wrapTester(testerMethod, logger);
}
}
harden(testerWrapper);
Expand Down
6 changes: 6 additions & 0 deletions packages/ses-ava/src/types.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,12 @@
*
* @typedef {Object} Assertions
* @property {(actual: unknown, message?: string) => void} assert
* @property {(message?: string) => void} fail
* @property {(fn: () => any, message?: string) => void} notThrows
* @property {(
* fn: () => PromiseLike<any>,
* message?: string
* ) => Promise<void>} notThrowsAsync
* // TODO is, deepEqual, truthy, falsy, etc...
*/

Expand Down

0 comments on commit d14b4dc

Please sign in to comment.