Skip to content

Commit

Permalink
fix bug when setTimeout is mocked (#3769)
Browse files Browse the repository at this point in the history
  • Loading branch information
aaronabramov authored and cpojer committed Jun 9, 2017
1 parent f3f3473 commit 0d43300
Showing 1 changed file with 22 additions and 2 deletions.
24 changes: 22 additions & 2 deletions packages/jest-circus/src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,10 @@ const _makeTimeoutMessage = (timeout, isHook) =>
`Exceeded timeout of ${timeout}ms for a ${isHook ? 'hook' : 'test'}.\nUse jest.setTimeout(newTimeout) to increase the timeout value, if this is a long-running test.`,
);

// Global values can be overwritten by mocks or tests. We'll capture
// the original values in the variables before we require any files.
const {setTimeout, clearTimeout} = global;

const callAsyncFn = (
fn: AsyncFn,
testContext: ?TestContext,
Expand All @@ -124,8 +128,13 @@ const callAsyncFn = (
timeout,
}: {isHook?: ?boolean, test?: TestEntry, timeout: number},
): Promise<any> => {
let timeoutID;

return new Promise((resolve, reject) => {
setTimeout(() => reject(_makeTimeoutMessage(timeout, isHook)), timeout);
timeoutID = setTimeout(
() => reject(_makeTimeoutMessage(timeout, isHook)),
timeout,
);

// If this fn accepts `done` callback we return a promise that fullfills as
// soon as `done` called.
Expand Down Expand Up @@ -162,7 +171,18 @@ const callAsyncFn = (
// Otherwise this test is synchronous, and if it didn't throw it means
// it passed.
return resolve();
});
})
.then(() => {
// If timeout is not cleared/unrefed the node process won't exit until
// it's resolved.
timeoutID.unref && timeoutID.unref();
clearTimeout(timeoutID);
})
.catch(error => {
timeoutID.unref && timeoutID.unref();
clearTimeout(timeoutID);
throw error;
});
};

const getTestDuration = (test: TestEntry): ?number => {
Expand Down

0 comments on commit 0d43300

Please sign in to comment.