Skip to content

Commit

Permalink
fix: correct isPromise implementation (#13314)
Browse files Browse the repository at this point in the history
  • Loading branch information
SimenB authored Sep 23, 2022
1 parent c3a000e commit 2e608c1
Show file tree
Hide file tree
Showing 8 changed files with 31 additions and 37 deletions.
4 changes: 2 additions & 2 deletions e2e/__tests__/__snapshots__/testFailingJasmine.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ FAIL __tests__/worksWithConcurrentMode.test.js
15 | });
16 |
at Function.failing (../../packages/jest-jasmine2/build/jasmineAsyncInstall.js:198:11)
at Function.failing (../../packages/jest-jasmine2/build/jasmineAsyncInstall.js:195:11)
at Suite.failing (__tests__/worksWithConcurrentMode.test.js:13:17)
at Object.describe (__tests__/worksWithConcurrentMode.test.js:8:1)
Expand Down Expand Up @@ -80,7 +80,7 @@ FAIL __tests__/worksWithConcurrentOnlyMode.test.js
15 | });
16 |
at Function.failing (../../packages/jest-jasmine2/build/jasmineAsyncInstall.js:198:11)
at Function.failing (../../packages/jest-jasmine2/build/jasmineAsyncInstall.js:195:11)
at Suite.failing (__tests__/worksWithConcurrentOnlyMode.test.js:13:22)
at Object.describe (__tests__/worksWithConcurrentOnlyMode.test.js:8:1)
Expand Down
7 changes: 1 addition & 6 deletions packages/expect/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

import {equals, iterableEquality, subsetEquality} from '@jest/expect-utils';
import * as matcherUtils from 'jest-matcher-utils';
import {isPromise} from 'jest-util';
import {
any,
anything,
Expand Down Expand Up @@ -69,12 +70,6 @@ export class JestAssertionError extends Error {
matcherResult?: Omit<SyncExpectationResult, 'message'> & {message: string};
}

// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-constraint
const isPromise = <T extends any>(obj: any): obj is PromiseLike<T> =>
!!obj &&
(typeof obj === 'object' || typeof obj === 'function') &&
typeof obj.then === 'function';

const createToThrowErrorMatchingSnapshotMatcher = function (
matcher: RawMatcherFn,
) {
Expand Down
15 changes: 7 additions & 8 deletions packages/jest-circus/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,12 @@ import slash = require('slash');
import StackUtils = require('stack-utils');
import type {AssertionResult, Status} from '@jest/test-result';
import type {Circus, Global} from '@jest/types';
import {ErrorWithStack, convertDescriptorToString, formatTime} from 'jest-util';
import {
ErrorWithStack,
convertDescriptorToString,
formatTime,
isPromise,
} from 'jest-util';
import {format as prettyFormat} from 'pretty-format';
import {ROOT_DESCRIBE_BLOCK_NAME, getState} from './state';

Expand Down Expand Up @@ -266,13 +271,7 @@ export const callAsyncCircusFn = (
}
}

// 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'
) {
if (isPromise(returnedValue)) {
returnedValue.then(() => resolve(), reject);
return;
}
Expand Down
5 changes: 1 addition & 4 deletions packages/jest-jasmine2/src/jasmineAsyncInstall.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,12 @@ import co from 'co';
import isGeneratorFn from 'is-generator-fn';
import pLimit = require('p-limit');
import type {Config, Global} from '@jest/types';
import {isPromise} from 'jest-util';
import isError from './isError';
import type Spec from './jasmine/Spec';
import type {DoneFn, QueueableFn} from './queueRunner';
import type {Jasmine} from './types';

function isPromise(obj: any): obj is PromiseLike<unknown> {
return obj && typeof obj.then === 'function';
}

// eslint-disable-next-line @typescript-eslint/no-empty-function
const doneFnNoop = () => {};

Expand Down
9 changes: 9 additions & 0 deletions packages/jest-util/src/__tests__/isPromise.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,12 @@ test('a resolved Promise', () => {
test('a rejected Promise', () => {
expect(isPromise(Promise.reject().catch(() => {}))).toBe(true);
});

test('a thenable', () => {
expect(isPromise({then: () => 'hello'})).toBe(true);
});

test('an async function', () => {
async function asyncFn() {}
expect(isPromise(asyncFn())).toBe(true);
});
16 changes: 9 additions & 7 deletions packages/jest-util/src/isPromise.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@
* LICENSE file in the root directory of this source tree.
*/

// capture globalThis.Promise before it may potentially be overwritten
const Promise = globalThis.Promise;

// see ES2015 spec 25.4.4.5, https://stackoverflow.com/a/38339199
const isPromise = (candidate: unknown): candidate is Promise<unknown> =>
Promise.resolve(candidate) === candidate;
export default isPromise;
export default function isPromise<T = unknown>(
candidate: unknown,
): candidate is PromiseLike<T> {
return (
candidate != null &&
(typeof candidate === 'object' || typeof candidate === 'function') &&
typeof (candidate as any).then === 'function'
);
}
6 changes: 1 addition & 5 deletions packages/jest-worker/src/workers/processChild.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
* LICENSE file in the root directory of this source tree.
*/

import {isPromise} from 'jest-util';
import {
CHILD_MESSAGE_CALL,
CHILD_MESSAGE_END,
Expand Down Expand Up @@ -158,11 +159,6 @@ function execMethod(method: string, args: Array<unknown>): void {
execFunction(main.setup, main, setupArgs, execHelper, reportInitializeError);
}

const isPromise = (obj: any): obj is PromiseLike<unknown> =>
!!obj &&
(typeof obj === 'object' || typeof obj === 'function') &&
typeof obj.then === 'function';

function execFunction(
fn: UnknownFunction,
ctx: unknown,
Expand Down
6 changes: 1 addition & 5 deletions packages/jest-worker/src/workers/threadChild.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*/

import {isMainThread, parentPort} from 'worker_threads';
import {isPromise} from 'jest-util';
import {
CHILD_MESSAGE_CALL,
CHILD_MESSAGE_END,
Expand Down Expand Up @@ -160,11 +161,6 @@ function execMethod(method: string, args: Array<unknown>): void {
execFunction(main.setup, main, setupArgs, execHelper, reportInitializeError);
}

const isPromise = (obj: any): obj is PromiseLike<unknown> =>
!!obj &&
(typeof obj === 'object' || typeof obj === 'function') &&
typeof obj.then === 'function';

function execFunction(
fn: UnknownFunction,
ctx: unknown,
Expand Down

0 comments on commit 2e608c1

Please sign in to comment.