Repository: facebook/jest
File: packages/jest-circus/src/utils.ts (TypeScript)

Code before:
    isHook ? 'hook' : 'test'
  }${
    takesDoneCallback && ' while waiting for done to be called'
  }.\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} = globalThis;

function checkIsError(error: unknown): error is Error {
  return !!(error && (error as Error).message && (error as Error).stack);
}

export const callAsyncCircusFn = (
  testOrHook: Circus.TestEntry | Circus.Hook,
  testContext: Circus.TestContext,
  {isHook, timeout}: {isHook: boolean; timeout: number},
): Promise<unknown> => {
  let timeoutID: NodeJS.Timeout;
  let completed = false;

  const {fn, asyncError} = testOrHook;

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

    // If this fn accepts `done` callback we return a promise that fulfills as
    // soon as `done` called.
    if (takesDoneCallback(fn)) {
      let returnedValue: unknown = undefined;

      const done = (reason?: Error | string): void => {
        // We need to keep a stack here before the promise tick
        const errorAtDone = new ErrorWithStack(undefined, done);

        if (!completed && testOrHook.seenDone) {
          errorAtDone.message =
            'Expected done to be called once, but it was called multiple times.';

          if (reason) {
            errorAtDone.message += ` Reason: ${prettyFormat(reason, {
              maxDepth: 3,
            })}`;
          }
          reject(errorAtDone);
          throw errorAtDone;
        } else {
          testOrHook.seenDone = true;

Review comment (refactor):
extract `takesDoneCallback(fn)` - no need to call it twice

Code after:
  `Exceeded timeout of ${formatTime(timeout)} for a ${
    isHook ? 'hook' : 'test'
  }${
    takesDoneCallback && ' while waiting for `done()` to be called'
  }.\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} = globalThis;

function checkIsError(error: unknown): error is Error {
  return !!(error && (error as Error).message && (error as Error).stack);
}

export const callAsyncCircusFn = (
  testOrHook: Circus.TestEntry | Circus.Hook,
  testContext: Circus.TestContext,
  {isHook, timeout}: {isHook: boolean; timeout: number},
): Promise<unknown> => {
  let timeoutID: NodeJS.Timeout;
  let completed = false;

  const {fn, asyncError} = testOrHook;
  const doneCallback = takesDoneCallback(fn);

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

    // If this fn accepts `done` callback we return a promise that fulfills as
    // soon as `done` called.
    if (doneCallback) {
      let returnedValue: unknown = undefined;

      const done = (reason?: Error | string): void => {
        // We need to keep a stack here before the promise tick
        const errorAtDone = new ErrorWithStack(undefined, done);

        if (!completed && testOrHook.seenDone) {
          errorAtDone.message =
            'Expected done to be called once, but it was called multiple times.';

          if (reason) {
            errorAtDone.message += ` Reason: ${prettyFormat(reason, {
              maxDepth: 3,
            })}`;
          }
          reject(errorAtDone);
          throw errorAtDone;