From 12b632ca6b6efc4ebf8ba5e5d265586d3ee93ce3 Mon Sep 17 00:00:00 2001 From: Simen Bekkhus Date: Thu, 28 Feb 2019 19:55:56 +0100 Subject: [PATCH] chore: fix broken test in circus --- e2e/__tests__/detectOpenHandles.ts | 2 +- packages/jest-circus/src/utils.ts | 133 +++++++++++++++-------------- 2 files changed, 69 insertions(+), 66 deletions(-) diff --git a/e2e/__tests__/detectOpenHandles.ts b/e2e/__tests__/detectOpenHandles.ts index f6b4503e980f..70420b49e21d 100644 --- a/e2e/__tests__/detectOpenHandles.ts +++ b/e2e/__tests__/detectOpenHandles.ts @@ -22,7 +22,7 @@ try { } } -function getTextAfterTest(stderr) { +function getTextAfterTest(stderr: string) { return (stderr.split(/Ran all test suites(.*)\n/)[2] || '').trim(); } diff --git a/packages/jest-circus/src/utils.ts b/packages/jest-circus/src/utils.ts index 19e115baec86..fbad7a725c77 100644 --- a/packages/jest-circus/src/utils.ts +++ b/packages/jest-circus/src/utils.ts @@ -157,89 +157,92 @@ function checkIsError(error: any): error is Error { return !!(error && (error as Error).message && (error as Error).stack); } -export const callAsyncCircusFn = async ( +export const callAsyncCircusFn = ( fn: AsyncFn, testContext: TestContext | undefined, {isHook, timeout}: {isHook?: boolean | null; timeout: number}, ): Promise => { - let timeoutID: NodeJS.Timeout | undefined; + let timeoutID: NodeJS.Timeout; let completed = false; - try { - return await new Promise((resolve, reject) => { - timeoutID = setTimeout( - () => reject(_makeTimeoutMessage(timeout, !!isHook)), - timeout, - ); - - // If this fn accepts `done` callback we return a promise that fulfills as - // soon as `done` called. - if (fn.length) { - const done = (reason?: Error | string): void => { - const errorAsErrorObject = checkIsError(reason) - ? reason - : new Error(`Failed: ${prettyFormat(reason, {maxDepth: 3})}`); - - // Consider always throwing, regardless if `reason` is set or not - if (completed && reason) { - errorAsErrorObject.message = - 'Caught error after test environment was torn down\n\n' + - errorAsErrorObject.message; - - throw errorAsErrorObject; - } + return new Promise((resolve, reject) => { + timeoutID = setTimeout( + () => reject(_makeTimeoutMessage(timeout, !!isHook)), + timeout, + ); + + // If this fn accepts `done` callback we return a promise that fulfills as + // soon as `done` called. + if (fn.length) { + const done = (reason?: Error | string): void => { + const errorAsErrorObject = checkIsError(reason) + ? reason + : new Error(`Failed: ${prettyFormat(reason, {maxDepth: 3})}`); + + // Consider always throwing, regardless if `reason` is set or not + if (completed && reason) { + errorAsErrorObject.message = + 'Caught error after test environment was torn down\n\n' + + errorAsErrorObject.message; + + throw errorAsErrorObject; + } - return reason ? reject(errorAsErrorObject) : resolve(); - }; + return reason ? reject(errorAsErrorObject) : resolve(); + }; - return fn.call(testContext, done); - } + return fn.call(testContext, done); + } - let returnedValue; - if (isGeneratorFn(fn)) { - returnedValue = co.wrap(fn).call({}); - } else { - try { - returnedValue = fn.call(testContext); - } catch (error) { - return reject(error); - } + let returnedValue; + if (isGeneratorFn(fn)) { + returnedValue = co.wrap(fn).call({}); + } else { + try { + returnedValue = fn.call(testContext); + } catch (error) { + return reject(error); } + } - // If it's a Promise, return it. Test for an object with a `then` function - // to support custom Promise implementations. - if ( - typeof returnedValue === 'object' && - returnedValue !== null && - typeof returnedValue.then === 'function' - ) { - return returnedValue.then(resolve, reject); - } + // If it's a Promise, return it. Test for an object with a `then` function + // to support custom Promise implementations. + if ( + typeof returnedValue === 'object' && + returnedValue !== null && + typeof returnedValue.then === 'function' + ) { + return returnedValue.then(resolve, reject); + } - if (!isHook && returnedValue !== void 0) { - return reject( - new Error( - ` + if (!isHook && returnedValue !== void 0) { + return reject( + new Error( + ` test functions can only return Promise or undefined. Returned value: ${String(returnedValue)} `, - ), - ); - } + ), + ); + } - // Otherwise this test is synchronous, and if it didn't throw it means - // it passed. - return resolve(); - }); - } finally { - completed = true; - // If timeout is not cleared/unrefed the node process won't exit until - // it's resolved. - if (timeoutID) { + // Otherwise this test is synchronous, and if it didn't throw it means + // it passed. + return resolve(); + }) + .then(() => { + completed = true; + // If timeout is not cleared/unrefed the node process won't exit until + // it's resolved. timeoutID.unref && timeoutID.unref(); clearTimeout(timeoutID); - } - } + }) + .catch(error => { + completed = true; + timeoutID.unref && timeoutID.unref(); + clearTimeout(timeoutID); + throw error; + }); }; export const getTestDuration = (test: TestEntry): number | null => {