-
-
Notifications
You must be signed in to change notification settings - Fork 6.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
jest-circus Timeouts #3760
jest-circus Timeouts #3760
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -110,46 +110,59 @@ const getEachHooksForTest = ( | |
return result; | ||
}; | ||
|
||
const _makeTimeoutMessage = (timeout, isHook) => { | ||
const message = `Exceeded timeout of ${timeout}ms for a ${isHook ? 'hook' : 'test'}.`; | ||
return new Error(message); | ||
}; | ||
|
||
const callAsyncFn = ( | ||
fn: AsyncFn, | ||
testContext: ?TestContext, | ||
{isHook}: {isHook?: boolean} = {isHook: false}, | ||
{ | ||
isHook, | ||
timeout, | ||
test, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Shouldn't it be sorted alphabetically? It seems pretty important to @cpojer though, so I'm just stealing his thunder. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yes, it must be. It is sacred. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @cpojer that will go into your performance review! 😃 |
||
}: {isHook?: ?boolean, timeout: number, test?: TestEntry}, | ||
): Promise<any> => { | ||
// If this fn accepts `done` callback we return a promise that fullfills as | ||
// soon as `done` called. | ||
if (fn.length) { | ||
return new Promise((resolve, reject) => { | ||
return new Promise((resolve, reject) => { | ||
setTimeout(() => reject(_makeTimeoutMessage(timeout, isHook)), timeout); | ||
|
||
// If this fn accepts `done` callback we return a promise that fullfills as | ||
// soon as `done` called. | ||
if (fn.length) { | ||
const done = (reason?: Error | string): void => | ||
reason ? reject(reason) : resolve(); | ||
|
||
fn.call(testContext, done); | ||
}); | ||
} | ||
return fn.call(testContext, done); | ||
} | ||
|
||
let returnedValue; | ||
try { | ||
returnedValue = fn.call(testContext); | ||
} catch (error) { | ||
return Promise.reject(error); | ||
} | ||
let returnedValue; | ||
try { | ||
returnedValue = fn.call(testContext); | ||
} catch (error) { | ||
return reject(error); | ||
} | ||
|
||
// If it's a Promise, return it. | ||
if (returnedValue instanceof Promise) { | ||
return returnedValue; | ||
} | ||
// If it's a Promise, return it. | ||
if (returnedValue instanceof Promise) { | ||
return returnedValue.then(resolve).catch(reject); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
} | ||
|
||
if (!isHook && returnedValue !== void 0) { | ||
throw 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 Promise.resolve(); | ||
// Otherwise this test is synchronous, and if it didn't throw it means | ||
// it passed. | ||
return resolve(); | ||
}); | ||
}; | ||
|
||
const getTestDuration = (test: TestEntry): ?number => { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you think about also receiving
testEntry.name
as a parameter? So that it is a bit more explicit about in which test this happenedThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i actually did it first and then realized that the name of the test is already printed right before the error (cause it's going to be under the failing test) 🙂
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What does this look like? Currently, timeouts are the hardest thing to deal with and the signal they give is so bad.
Also, you can write this function without curly braces, return statements or new variables. I believe in you.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
timeouts are hard to deal with, but mostly because of the quality of the test.
There's not much we can do here. We can try to print the exact hook that timeouted (if it happened in a hook) or we can try to print test coverage of the test function (to see which parts weren't called), but i'm not sure how helpful it is
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we add "Use jest.setTimeout(…) to update the timeout" maybe?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that's actually a good idea