From d65d4cc66245506898b57e3cc832659f920ee77e Mon Sep 17 00:00:00 2001 From: Eyal Roth Date: Mon, 24 Jun 2024 15:29:34 +0300 Subject: [PATCH] feat: Type inference in 'have been called with' parameters (#15129) --- CHANGELOG.md | 1 + packages/expect/package.json | 1 + .../expect/src/__tests__/spyMatchers.test.ts | 5 +- packages/expect/src/types.ts | 152 +++++++- packages/expect/tsconfig.json | 1 + .../src/__tests__/throwMatcher.test.ts | 4 +- .../{expect.test.ts => expect/base.test.ts} | 53 --- .../expect/toHaveBeenCalledWith.test.ts | 305 ++++++++++++++++ .../expect/toHaveBeenLastCalledWith.test.ts | 299 ++++++++++++++++ .../expect/toHaveBeenNthCalledWith.test.ts | 329 ++++++++++++++++++ .../jest-worker/src/__tests__/Farm.test.ts | 6 +- .../src/base/__tests__/BaseWorkerPool.test.ts | 5 +- yarn.lock | 1 + 13 files changed, 1100 insertions(+), 62 deletions(-) rename packages/jest-types/__typetests__/{expect.test.ts => expect/base.test.ts} (89%) create mode 100644 packages/jest-types/__typetests__/expect/toHaveBeenCalledWith.test.ts create mode 100644 packages/jest-types/__typetests__/expect/toHaveBeenLastCalledWith.test.ts create mode 100644 packages/jest-types/__typetests__/expect/toHaveBeenNthCalledWith.test.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 8c0004c09728..b33270d10468 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ - `[jest-environment-jsdom]` [**BREAKING**] Upgrade JSDOM to v22 ([#13825](https://github.com/jestjs/jest/pull/13825)) - `[@jest/environment-jsdom-abstract]` Introduce new package which abstracts over the `jsdom` environment, allowing usage of custom versions of JSDOM ([#14717](https://github.com/jestjs/jest/pull/14717)) - `[jest-environment-node]` Update jest environment with dispose symbols `Symbol` ([#14888](https://github.com/jestjs/jest/pull/14888) & [#14909](https://github.com/jestjs/jest/pull/14909)) +- `[expect, @jest/expect]` [**BREAKING**] Add type inference for function parameters in `CalledWith` assertions ([#15129](https://github.com/facebook/jest/pull/15129)) - `[@jest/fake-timers]` [**BREAKING**] Upgrade `@sinonjs/fake-timers` to v11 ([#14544](https://github.com/jestjs/jest/pull/14544)) - `[@jest/fake-timers]` Exposing new modern timers function `advanceTimersToFrame()` which advances all timers by the needed milliseconds to execute callbacks currently scheduled with `requestAnimationFrame` ([#14598](https://github.com/jestjs/jest/pull/14598)) - `[jest-matcher-utils]` Add `SERIALIZABLE_PROPERTIES` to allow custom serialization of objects ([#14893](https://github.com/jestjs/jest/pull/14893)) diff --git a/packages/expect/package.json b/packages/expect/package.json index 73e850b65b7a..da4bbed33a2f 100644 --- a/packages/expect/package.json +++ b/packages/expect/package.json @@ -25,6 +25,7 @@ "jest-get-type": "workspace:*", "jest-matcher-utils": "workspace:*", "jest-message-util": "workspace:*", + "jest-mock": "workspace:*", "jest-util": "workspace:*" }, "devDependencies": { diff --git a/packages/expect/src/__tests__/spyMatchers.test.ts b/packages/expect/src/__tests__/spyMatchers.test.ts index 368f30ae4686..fd8d40d87f83 100644 --- a/packages/expect/src/__tests__/spyMatchers.test.ts +++ b/packages/expect/src/__tests__/spyMatchers.test.ts @@ -7,6 +7,7 @@ import * as Immutable from 'immutable'; import {alignedAnsiStyleSerializer} from '@jest/test-utils'; +import type {FunctionLike} from 'jest-mock'; import jestExpect from '../'; expect.addSnapshotSerializer(alignedAnsiStyleSerializer); @@ -25,7 +26,7 @@ declare module '../types' { } // Given a Jest mock function, return a minimal mock of a spy. -const createSpy = (fn: jest.Mock) => { +const createSpy = (fn: jest.Mock): jest.Mock => { const spy = function () {}; spy.calls = { @@ -37,7 +38,7 @@ const createSpy = (fn: jest.Mock) => { }, }; - return spy; + return spy as unknown as jest.Mock; }; describe('toHaveBeenCalled', () => { diff --git a/packages/expect/src/types.ts b/packages/expect/src/types.ts index d29bc6b4a92c..ec3fe6494953 100644 --- a/packages/expect/src/types.ts +++ b/packages/expect/src/types.ts @@ -8,6 +8,7 @@ import type {EqualsFunction, Tester} from '@jest/expect-utils'; import type * as jestMatcherUtils from 'jest-matcher-utils'; +import type {MockInstance} from 'jest-mock'; import type {INTERNAL_MATCHER_FLAG} from './jestMatchersObject'; export type SyncExpectationResult = { @@ -231,16 +232,16 @@ export interface Matchers, T = unknown> { /** * Ensure that a mock function is called with specific arguments. */ - toHaveBeenCalledWith(...expected: Array): R; + toHaveBeenCalledWith(...expected: MockParameters): R; /** * Ensure that a mock function is called with specific arguments on an Nth call. */ - toHaveBeenNthCalledWith(nth: number, ...expected: Array): R; + toHaveBeenNthCalledWith(nth: number, ...expected: MockParameters): R; /** * If you have a mock function, you can use `.toHaveBeenLastCalledWith` * to test what arguments it was last called with. */ - toHaveBeenLastCalledWith(...expected: Array): R; + toHaveBeenLastCalledWith(...expected: MockParameters): R; /** * Use to test the specific value that a mock function last returned. * If the last call to the mock function threw an error, then this matcher will fail @@ -307,3 +308,148 @@ export interface Matchers, T = unknown> { */ toThrow(expected?: unknown): R; } + +/** + * Obtains the parameters of the given function or {@link MockInstance}'s function type. + * ```ts + * type P = MockParameters void>>; + * // or without an explicit mock + * // type P = MockParameters<(foo: number) => void>; + * + * const params1: P = [1]; // compiles + * const params2: P = ['bar']; // error + * const params3: P = []; // error + * ``` + * + * This is similar to {@link Parameters}, with these notable differences: + * + * 1. Each of the parameters can also accept an {@link AsymmetricMatcher}. + * ```ts + * const params4: P = [expect.anything()]; // compiles + * ``` + * This works with nested types as well: + * ```ts + * type Nested = MockParameters void>>; + * + * const params1: Nested = [{ foo: { a: 1 }}, ['value']]; // compiles + * const params2: Nested = [expect.anything(), expect.anything()]; // compiles + * const params3: Nested = [{ foo: { a: expect.anything() }}, [expect.anything()]]; // compiles + * ``` + * + * 2. This type works with overloaded functions (up to 15 overloads): + * ```ts + * function overloaded(): void; + * function overloaded(foo: number): void; + * function overloaded(foo: number, bar: string): void; + * function overloaded(foo?: number, bar?: string): void {} + * + * type Overloaded = MockParameters>; + * + * const params1: Overloaded = []; // compiles + * const params2: Overloaded = [1]; // compiles + * const params3: Overloaded = [1, 'value']; // compiles + * const params4: Overloaded = ['value']; // error + * const params5: Overloaded = ['value', 1]; // error + * ``` + * + * Mocks generated with the default `MockInstance` type will evaluate to `Array`: + * ```ts + * MockParameters // Array + * ``` + * + * If the given type is not a `MockInstance` nor a function, this type will evaluate to `Array`: + * ```ts + * MockParameters // Array + * ``` + */ +type MockParameters = + M extends MockInstance + ? FunctionParameters + : FunctionParameters; + +/** + * A wrapper over `FunctionParametersInternal` which converts `never` evaluations to `Array`. + * + * This is only necessary for Typescript versions prior to 5.3. + * + * In those versions, a function without parameters (`() => any`) is interpreted the same as an overloaded function, + * causing `FunctionParametersInternal` to evaluate it to `[] | Array`, which is incorrect. + * + * The workaround is to "catch" this edge-case in `WithAsymmetricMatchers` and interpret it as `never`. + * However, this also affects {@link UnknownFunction} (the default generic type of `MockInstance`): + * ```ts + * FunctionParametersInternal<() => any> // [] | never --> [] --> correct + * FunctionParametersInternal // never --> incorrect + * ``` + * An empty array is the expected type for a function without parameters, + * so all that's left is converting `never` to `Array` for the case of `UnknownFunction`, + * as it needs to accept _any_ combination of parameters. + */ +type FunctionParameters = + FunctionParametersInternal extends never + ? Array + : FunctionParametersInternal; + +/** + * 1. If the function is overloaded or has no parameters -> overloaded form (union of tuples). + * 2. If the function has parameters -> simple form. + * 3. else -> `never`. + */ +type FunctionParametersInternal = F extends { + (...args: infer P1): any; + (...args: infer P2): any; + (...args: infer P3): any; + (...args: infer P4): any; + (...args: infer P5): any; + (...args: infer P6): any; + (...args: infer P7): any; + (...args: infer P8): any; + (...args: infer P9): any; + (...args: infer P10): any; + (...args: infer P11): any; + (...args: infer P12): any; + (...args: infer P13): any; + (...args: infer P14): any; + (...args: infer P15): any; +} + ? + | WithAsymmetricMatchers + | WithAsymmetricMatchers + | WithAsymmetricMatchers + | WithAsymmetricMatchers + | WithAsymmetricMatchers + | WithAsymmetricMatchers + | WithAsymmetricMatchers + | WithAsymmetricMatchers + | WithAsymmetricMatchers + | WithAsymmetricMatchers + | WithAsymmetricMatchers + | WithAsymmetricMatchers + | WithAsymmetricMatchers + | WithAsymmetricMatchers + | WithAsymmetricMatchers + : F extends (...args: infer P) => any + ? WithAsymmetricMatchers

+ : never; + +/** + * @see FunctionParameters + */ +type WithAsymmetricMatchers

> = + Array extends P + ? never + : {[K in keyof P]: DeepAsymmetricMatcher}; + +/** + * Replaces `T` with `T | AsymmetricMatcher`. + * + * If `T` is an object or an array, recursively replaces all nested types with the same logic: + * ```ts + * type DeepAsymmetricMatcher; // AsymmetricMatcher | boolean + * type DeepAsymmetricMatcher<{ foo: number }>; // AsymmetricMatcher | { foo: AsymmetricMatcher | number } + * type DeepAsymmetricMatcher<[string]>; // AsymmetricMatcher | [AsymmetricMatcher | string] + * ``` + */ +type DeepAsymmetricMatcher = T extends object + ? AsymmetricMatcher | {[K in keyof T]: DeepAsymmetricMatcher} + : AsymmetricMatcher | T; diff --git a/packages/expect/tsconfig.json b/packages/expect/tsconfig.json index 3804c7c3ac38..b40e9d98b54c 100644 --- a/packages/expect/tsconfig.json +++ b/packages/expect/tsconfig.json @@ -12,6 +12,7 @@ {"path": "../jest-get-type"}, {"path": "../jest-matcher-utils"}, {"path": "../jest-message-util"}, + {"path": "../jest-mock"}, {"path": "../jest-util"} ] } diff --git a/packages/jest-snapshot/src/__tests__/throwMatcher.test.ts b/packages/jest-snapshot/src/__tests__/throwMatcher.test.ts index 9293e8e24762..3f6a42924df3 100644 --- a/packages/jest-snapshot/src/__tests__/throwMatcher.test.ts +++ b/packages/jest-snapshot/src/__tests__/throwMatcher.test.ts @@ -7,7 +7,9 @@ import {type Context, toThrowErrorMatchingSnapshot} from '../'; -const mockedMatch = jest.fn(() => ({ +const mockedMatch = jest.fn< + (args: {received: string; testName: string}) => unknown +>(() => ({ actual: 'coconut', expected: 'coconut', })); diff --git a/packages/jest-types/__typetests__/expect.test.ts b/packages/jest-types/__typetests__/expect/base.test.ts similarity index 89% rename from packages/jest-types/__typetests__/expect.test.ts rename to packages/jest-types/__typetests__/expect/base.test.ts index 15bd00f847d8..dd3283b89ecc 100644 --- a/packages/jest-types/__typetests__/expect.test.ts +++ b/packages/jest-types/__typetests__/expect/base.test.ts @@ -16,12 +16,6 @@ expect(jestExpect('value').toEqual(jestExpect.any(String))).type.toBeVoid(); expect(jestExpect(123).toEqual(jestExpect.any())).type.toRaiseError(); expect(jestExpect.not).type.not.toHaveProperty('any'); -expect( - jestExpect(jest.fn()).toHaveBeenCalledWith(jestExpect.anything()), -).type.toBeVoid(); -expect( - jestExpect(jest.fn()).toHaveBeenCalledWith(jestExpect.anything(true)), -).type.toRaiseError(); expect(jestExpect.not).type.not.toHaveProperty('anything'); expect( @@ -291,53 +285,6 @@ expect( ).type.toRaiseError(); expect(jestExpect(jest.fn()).toHaveBeenCalledTimes()).type.toRaiseError(); -expect(jestExpect(jest.fn()).toHaveBeenCalledWith()).type.toBeVoid(); -expect(jestExpect(jest.fn()).toHaveBeenCalledWith(123)).type.toBeVoid(); -expect(jestExpect(jest.fn()).toHaveBeenCalledWith('value')).type.toBeVoid(); -expect( - jestExpect(jest.fn()).toHaveBeenCalledWith(123, 'value'), -).type.toBeVoid(); -expect( - jestExpect(jest.fn()).toHaveBeenCalledWith('value', 123), -).type.toBeVoid(); -expect( - jestExpect(jest.fn<(a: string, b: number) => void>()).toHaveBeenCalledWith( - jestExpect.stringContaining('value'), - 123, - ), -).type.toBeVoid(); - -expect(jestExpect(jest.fn()).toHaveBeenLastCalledWith()).type.toBeVoid(); -expect(jestExpect(jest.fn()).toHaveBeenLastCalledWith('value')).type.toBeVoid(); -expect(jestExpect(jest.fn()).toHaveBeenLastCalledWith(123)).type.toBeVoid(); -expect( - jestExpect(jest.fn()).toHaveBeenLastCalledWith(123, 'value'), -).type.toBeVoid(); -expect( - jestExpect(jest.fn()).toHaveBeenLastCalledWith('value', 123), -).type.toBeVoid(); -expect( - jestExpect( - jest.fn<(a: string, b: number) => void>(), - ).toHaveBeenLastCalledWith(jestExpect.stringContaining('value'), 123), -).type.toBeVoid(); - -expect(jestExpect(jest.fn()).toHaveBeenNthCalledWith(2)).type.toBeVoid(); -expect( - jestExpect(jest.fn()).toHaveBeenNthCalledWith(1, 'value'), -).type.toBeVoid(); -expect( - jestExpect(jest.fn()).toHaveBeenNthCalledWith(1, 'value', 123), -).type.toBeVoid(); -expect( - jestExpect(jest.fn<(a: string, b: number) => void>()).toHaveBeenNthCalledWith( - 1, - jestExpect.stringContaining('value'), - 123, - ), -).type.toBeVoid(); -expect(jestExpect(jest.fn()).toHaveBeenNthCalledWith()).type.toRaiseError(); - expect(jestExpect(jest.fn()).toHaveReturned()).type.toBeVoid(); expect(jestExpect(jest.fn()).toHaveReturned('value')).type.toRaiseError(); expect(jestExpect(jest.fn()).toHaveReturned(false)).type.toRaiseError(); diff --git a/packages/jest-types/__typetests__/expect/toHaveBeenCalledWith.test.ts b/packages/jest-types/__typetests__/expect/toHaveBeenCalledWith.test.ts new file mode 100644 index 000000000000..16da33ccfeac --- /dev/null +++ b/packages/jest-types/__typetests__/expect/toHaveBeenCalledWith.test.ts @@ -0,0 +1,305 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import {expect} from 'tstyche'; +import {jest, expect as jestExpect} from '@jest/globals'; + +export function overloaded(): void; +// eslint-disable-next-line @typescript-eslint/unified-signatures +export function overloaded(n: number): void; +// eslint-disable-next-line @typescript-eslint/unified-signatures +export function overloaded(n: number, s: string): void; +// eslint-disable-next-line @typescript-eslint/unified-signatures +export function overloaded(n: number, b: boolean): void; +export function overloaded(n?: number, sOrB?: string | boolean): void { + // noop +} + +expect( + jestExpect(jest.fn()).toHaveBeenCalledWith(jestExpect.anything()), +).type.toBeVoid(); +expect( + jestExpect(jest.fn()).toHaveBeenCalledWith(jestExpect.anything(true)), +).type.toRaiseError(); + +expect(jestExpect(jest.fn()).toHaveBeenCalledWith()).type.toBeVoid(); +expect(jestExpect(jest.fn()).toHaveBeenCalledWith(123)).type.toBeVoid(); +expect(jestExpect(jest.fn()).toHaveBeenCalledWith('value')).type.toBeVoid(); +expect( + jestExpect(jest.fn()).toHaveBeenCalledWith(123, 'value'), +).type.toBeVoid(); +expect( + jestExpect(jest.fn()).toHaveBeenCalledWith('value', 123), +).type.toBeVoid(); +expect( + jestExpect(jest.fn<(a: string, b: number) => void>()).toHaveBeenCalledWith( + jestExpect.stringContaining('value'), + 123, + ), +).type.toBeVoid(); + +expect(jestExpect(jest.fn()).toHaveBeenCalledWith()).type.toBeVoid(); +expect(jestExpect(jest.fn()).toHaveBeenCalledWith(123)).type.toBeVoid(); +expect(jestExpect(jest.fn()).toHaveBeenCalledWith('value')).type.toBeVoid(); +expect( + jestExpect(jest.fn()).toHaveBeenCalledWith(123, 'value'), +).type.toBeVoid(); +expect( + jestExpect(jest.fn()).toHaveBeenCalledWith('value', 123), +).type.toBeVoid(); +expect( + jestExpect(jest.fn<(a: string, b: number) => void>()).toHaveBeenCalledWith( + jestExpect.stringContaining('value'), + 123, + ), +).type.toBeVoid(); + +expect( + jestExpect(jest.fn<() => void>()).toHaveBeenCalledWith(), +).type.toBeVoid(); +expect( + jestExpect(jest.fn<() => void>()).toHaveBeenCalledWith(123), +).type.toRaiseError(); + +expect(jestExpect(() => {}).toHaveBeenCalledWith()).type.toBeVoid(); +expect(jestExpect(() => {}).toHaveBeenCalledWith(123)).type.toRaiseError(); + +expect( + jestExpect(jest.fn<(n?: number) => void>()).toHaveBeenCalledWith(), +).type.toBeVoid(); +expect( + jestExpect(jest.fn<(n?: number) => void>()).toHaveBeenCalledWith(123), +).type.toBeVoid(); +expect( + jestExpect(jest.fn<(n?: number) => void>()).toHaveBeenCalledWith('value'), +).type.toRaiseError(); + +expect( + jestExpect(jest.fn<(n: number) => void>()).toHaveBeenCalledWith(123), +).type.toBeVoid(); +expect( + jestExpect(jest.fn<(n: number) => void>()).toHaveBeenCalledWith(), +).type.toRaiseError(); +expect( + jestExpect(jest.fn<(n: number) => void>()).toHaveBeenCalledWith('value'), +).type.toRaiseError(); + +expect(jestExpect((n: number) => {}).toHaveBeenCalledWith(123)).type.toBeVoid(); +expect( + jestExpect((n: number) => {}).toHaveBeenCalledWith(jestExpect.any(Number)), +).type.toBeVoid(); +expect( + jestExpect((n: number) => {}).toHaveBeenCalledWith(), +).type.toRaiseError(); +expect( + jestExpect((n: number) => {}).toHaveBeenCalledWith('value'), +).type.toRaiseError(); + +expect( + jestExpect(jest.fn<(s: string) => void>()).toHaveBeenCalledWith('value'), +).type.toBeVoid(); +expect( + jestExpect(jest.fn<(s: string) => void>()).toHaveBeenCalledWith(), +).type.toRaiseError(); +expect( + jestExpect(jest.fn<(s: string) => void>()).toHaveBeenCalledWith(123), +).type.toRaiseError(); + +expect( + jestExpect(jest.fn<(n: number, s: string) => void>()).toHaveBeenCalledWith( + 123, + 'value', + ), +).type.toBeVoid(); +expect( + jestExpect(jest.fn<(n: number, s: string) => void>()).toHaveBeenCalledWith(), +).type.toRaiseError(); +expect( + jestExpect(jest.fn<(n: number, s: string) => void>()).toHaveBeenCalledWith( + 123, + ), +).type.toRaiseError(); +expect( + jestExpect(jest.fn<(n: number, s: string) => void>()).toHaveBeenCalledWith( + 123, + 123, + ), +).type.toRaiseError(); +expect( + jestExpect(jest.fn<(n: number, s: string) => void>()).toHaveBeenCalledWith( + 'value', + 'value', + ), +).type.toRaiseError(); +expect( + jestExpect(jest.fn<(n: number, s: string) => void>()).toHaveBeenCalledWith( + 'value', + 123, + ), +).type.toRaiseError(); + +expect( + jestExpect(jest.fn<(n: number, s?: string) => void>()).toHaveBeenCalledWith( + 123, + 'value', + ), +).type.toBeVoid(); +expect( + jestExpect(jest.fn<(n: number, s?: string) => void>()).toHaveBeenCalledWith( + 123, + ), +).type.toBeVoid(); +expect( + jestExpect(jest.fn<(n: number, s?: string) => void>()).toHaveBeenCalledWith(), +).type.toRaiseError(); +expect( + jestExpect(jest.fn<(n: number, s?: string) => void>()).toHaveBeenCalledWith( + 'value', + ), +).type.toRaiseError(); +expect( + jestExpect(jest.fn<(n: number, s?: string) => void>()).toHaveBeenCalledWith( + 'value', + 'value', + ), +).type.toRaiseError(); +expect( + jestExpect(jest.fn<(n: number, s?: string) => void>()).toHaveBeenCalledWith( + 'value', + 123, + ), +).type.toRaiseError(); +expect( + jestExpect(jest.fn<(n: number, s?: string) => void>()).toHaveBeenCalledWith( + 123, + 123, + ), +).type.toRaiseError(); + +expect( + jestExpect(jest.fn()).toHaveBeenCalledWith(), +).type.toBeVoid(); +expect( + jestExpect(jest.fn()).toHaveBeenCalledWith(123), +).type.toBeVoid(); +expect( + jestExpect(jest.fn()).toHaveBeenCalledWith(123, 'value'), +).type.toBeVoid(); +expect( + jestExpect(jest.fn()).toHaveBeenCalledWith(123, true), +).type.toBeVoid(); +expect( + jestExpect(jest.fn()).toHaveBeenCalledWith(123, 123), +).type.toRaiseError(); +expect( + jestExpect(jest.fn()).toHaveBeenCalledWith('value'), +).type.toRaiseError(); +expect( + jestExpect(jest.fn()).toHaveBeenCalledWith(true), +).type.toRaiseError(); +expect( + jestExpect(jest.fn()).toHaveBeenCalledWith( + 'value', + 'value', + ), +).type.toRaiseError(); +expect( + jestExpect(jest.fn()).toHaveBeenCalledWith(true, false), +).type.toRaiseError(); + +expect( + jestExpect( + jest.fn<(date: Date, name?: [string, string]) => void>(), + ).toHaveBeenCalledWith(jestExpect.any(Date), [ + jestExpect.any(String), + jestExpect.any(String), + ]), +).type.toBeVoid(); +expect( + jestExpect( + jest.fn<(date: Date, name?: [string, string]) => void>(), + ).toHaveBeenCalledWith(jestExpect.any(Date), jestExpect.any(Array)), +).type.toBeVoid(); +expect( + jestExpect( + jest.fn<(date: Date, name?: [string, string]) => void>(), + ).toHaveBeenCalledWith(jestExpect.any(Date)), +).type.toBeVoid(); +expect( + jestExpect( + jest.fn<(date: Date, name?: [string, string]) => void>(), + ).toHaveBeenCalledWith(jestExpect.any(Date), []), +).type.toRaiseError(); +expect( + jestExpect( + jest.fn<(date: Date, name?: [string, string]) => void>(), + ).toHaveBeenCalledWith(jestExpect.any(Date), [jestExpect.any(String)]), +).type.toRaiseError(); +expect( + jestExpect( + jest.fn<(date: Date, name?: [string, string]) => void>(), + ).toHaveBeenCalledWith(jestExpect.any(Date), [jestExpect.any(String), 123]), +).type.toRaiseError(); + +expect( + jestExpect( + jest.fn<(date: Date, name: {foo: string}) => void>(), + ).toHaveBeenCalledWith(jestExpect.any(Date), {foo: jestExpect.any(String)}), +).type.toBeVoid(); +expect( + jestExpect( + jest.fn<(date: Date, name: {foo: string}) => void>(), + ).toHaveBeenCalledWith(jestExpect.any(Date), jestExpect.any(Object)), +).type.toBeVoid(); +expect( + jestExpect( + jest.fn<(date: Date, name: {foo: string}) => void>(), + ).toHaveBeenCalledWith(jestExpect.any(Date)), +).type.toRaiseError(); +expect( + jestExpect( + jest.fn<(date: Date, name: {foo: string}) => void>(), + ).toHaveBeenCalledWith(jestExpect.any(Date), {bar: jestExpect.any(String)}), +).type.toRaiseError(); +expect( + jestExpect( + jest.fn<(date: Date, name: {foo: string}) => void>(), + ).toHaveBeenCalledWith(jestExpect.any(Date), { + bar: jestExpect.any(String), + foo: jestExpect.any(String), + }), +).type.toRaiseError(); + +expect( + jestExpect( + jest.fn<(date: Date, name: [string, [string]]) => void>(), + ).toHaveBeenCalledWith(jestExpect.any(Date), [ + jestExpect.any(String), + [jestExpect.any(String)], + ]), +).type.toBeVoid(); +expect( + jestExpect( + jest.fn<(date: Date, name: [string, [string]]) => void>(), + ).toHaveBeenCalledWith(jestExpect.any(Date), [ + 'value', + [jestExpect.any(String)], + ]), +).type.toBeVoid(); +expect( + jestExpect( + jest.fn<(date: Date, name: [string, [string]]) => void>(), + ).toHaveBeenCalledWith(jestExpect.any(Date), [ + jestExpect.any(String), + ['value'], + ]), +).type.toBeVoid(); +expect( + jestExpect( + jest.fn<(date: Date, name: [string, [string]]) => void>(), + ).toHaveBeenCalledWith(jestExpect.any(Date), ['value', ['value']]), +).type.toBeVoid(); diff --git a/packages/jest-types/__typetests__/expect/toHaveBeenLastCalledWith.test.ts b/packages/jest-types/__typetests__/expect/toHaveBeenLastCalledWith.test.ts new file mode 100644 index 000000000000..7d42ba741a6f --- /dev/null +++ b/packages/jest-types/__typetests__/expect/toHaveBeenLastCalledWith.test.ts @@ -0,0 +1,299 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import {expect} from 'tstyche'; +import {jest, expect as jestExpect} from '@jest/globals'; +import type {overloaded} from './toHaveBeenCalledWith.test'; + +expect(jestExpect(jest.fn()).toHaveBeenLastCalledWith()).type.toBeVoid(); +expect(jestExpect(jest.fn()).toHaveBeenLastCalledWith('value')).type.toBeVoid(); +expect(jestExpect(jest.fn()).toHaveBeenLastCalledWith(123)).type.toBeVoid(); +expect( + jestExpect(jest.fn()).toHaveBeenLastCalledWith(123, 'value'), +).type.toBeVoid(); +expect( + jestExpect(jest.fn()).toHaveBeenLastCalledWith('value', 123), +).type.toBeVoid(); +expect( + jestExpect( + jest.fn<(a: string, b: number) => void>(), + ).toHaveBeenLastCalledWith(jestExpect.stringContaining('value'), 123), +).type.toBeVoid(); + +expect(jestExpect(jest.fn()).toHaveBeenLastCalledWith()).type.toBeVoid(); +expect(jestExpect(jest.fn()).toHaveBeenLastCalledWith('value')).type.toBeVoid(); +expect(jestExpect(jest.fn()).toHaveBeenLastCalledWith(123)).type.toBeVoid(); +expect( + jestExpect(jest.fn()).toHaveBeenLastCalledWith(123, 'value'), +).type.toBeVoid(); +expect( + jestExpect(jest.fn()).toHaveBeenLastCalledWith('value', 123), +).type.toBeVoid(); +expect( + jestExpect( + jest.fn<(a: string, b: number) => void>(), + ).toHaveBeenLastCalledWith(jestExpect.stringContaining('value'), 123), +).type.toBeVoid(); + +expect( + jestExpect(jest.fn<() => void>()).toHaveBeenLastCalledWith(), +).type.toBeVoid(); +expect( + jestExpect(jest.fn<() => void>()).toHaveBeenLastCalledWith(1), +).type.toRaiseError(); + +expect(jestExpect(() => {}).toHaveBeenLastCalledWith()).type.toBeVoid(); +expect(jestExpect(() => {}).toHaveBeenLastCalledWith(123)).type.toRaiseError(); + +expect( + jestExpect(jest.fn<(n?: number) => void>()).toHaveBeenLastCalledWith(), +).type.toBeVoid(); +expect( + jestExpect(jest.fn<(n?: number) => void>()).toHaveBeenLastCalledWith(123), +).type.toBeVoid(); +expect( + jestExpect(jest.fn<(n?: number) => void>()).toHaveBeenLastCalledWith('value'), +).type.toRaiseError(); + +expect( + jestExpect(jest.fn<(n: number) => void>()).toHaveBeenLastCalledWith(123), +).type.toBeVoid(); +expect( + jestExpect(jest.fn<(n: number) => void>()).toHaveBeenLastCalledWith(), +).type.toRaiseError(); +expect( + jestExpect(jest.fn<(n: number) => void>()).toHaveBeenLastCalledWith('value'), +).type.toRaiseError(); + +expect( + jestExpect((n: number) => {}).toHaveBeenLastCalledWith(123), +).type.toBeVoid(); +expect( + jestExpect((n: number) => {}).toHaveBeenLastCalledWith( + jestExpect.any(Number), + ), +).type.toBeVoid(); +expect( + jestExpect((n: number) => {}).toHaveBeenLastCalledWith(), +).type.toRaiseError(); +expect( + jestExpect((n: number) => {}).toHaveBeenLastCalledWith('value'), +).type.toRaiseError(); + +expect( + jestExpect(jest.fn<(s: string) => void>()).toHaveBeenLastCalledWith('value'), +).type.toBeVoid(); +expect( + jestExpect(jest.fn<(s: string) => void>()).toHaveBeenLastCalledWith(), +).type.toRaiseError(); +expect( + jestExpect(jest.fn<(s: string) => void>()).toHaveBeenLastCalledWith(123), +).type.toRaiseError(); + +expect( + jestExpect( + jest.fn<(n: number, s: string) => void>(), + ).toHaveBeenLastCalledWith(123, 'value'), +).type.toBeVoid(); +expect( + jestExpect( + jest.fn<(n: number, s: string) => void>(), + ).toHaveBeenLastCalledWith(), +).type.toRaiseError(); +expect( + jestExpect( + jest.fn<(n: number, s: string) => void>(), + ).toHaveBeenLastCalledWith(123), +).type.toRaiseError(); +expect( + jestExpect( + jest.fn<(n: number, s: string) => void>(), + ).toHaveBeenLastCalledWith(123, 123), +).type.toRaiseError(); +expect( + jestExpect( + jest.fn<(n: number, s: string) => void>(), + ).toHaveBeenLastCalledWith('value', 'value'), +).type.toRaiseError(); +expect( + jestExpect( + jest.fn<(n: number, s: string) => void>(), + ).toHaveBeenLastCalledWith('value', 123), +).type.toRaiseError(); + +expect( + jestExpect( + jest.fn<(n: number, s?: string) => void>(), + ).toHaveBeenLastCalledWith(123, 'value'), +).type.toBeVoid(); +expect( + jestExpect( + jest.fn<(n: number, s?: string) => void>(), + ).toHaveBeenLastCalledWith(123), +).type.toBeVoid(); +expect( + jestExpect( + jest.fn<(n: number, s?: string) => void>(), + ).toHaveBeenLastCalledWith(), +).type.toRaiseError(); +expect( + jestExpect( + jest.fn<(n: number, s?: string) => void>(), + ).toHaveBeenLastCalledWith('value'), +).type.toRaiseError(); +expect( + jestExpect( + jest.fn<(n: number, s?: string) => void>(), + ).toHaveBeenLastCalledWith('value', 'value'), +).type.toRaiseError(); +expect( + jestExpect( + jest.fn<(n: number, s?: string) => void>(), + ).toHaveBeenLastCalledWith('value', 123), +).type.toRaiseError(); +expect( + jestExpect( + jest.fn<(n: number, s?: string) => void>(), + ).toHaveBeenLastCalledWith(123, 123), +).type.toRaiseError(); + +expect( + jestExpect(jest.fn()).toHaveBeenLastCalledWith(), +).type.toBeVoid(); +expect( + jestExpect(jest.fn()).toHaveBeenLastCalledWith(123), +).type.toBeVoid(); +expect( + jestExpect(jest.fn()).toHaveBeenLastCalledWith( + 123, + 'value', + ), +).type.toBeVoid(); +expect( + jestExpect(jest.fn()).toHaveBeenLastCalledWith(123, true), +).type.toBeVoid(); +expect( + jestExpect(jest.fn()).toHaveBeenLastCalledWith(123, 123), +).type.toRaiseError(); +expect( + jestExpect(jest.fn()).toHaveBeenLastCalledWith('value'), +).type.toRaiseError(); +expect( + jestExpect(jest.fn()).toHaveBeenLastCalledWith(true), +).type.toRaiseError(); +expect( + jestExpect(jest.fn()).toHaveBeenLastCalledWith( + 'value', + 'value', + ), +).type.toRaiseError(); +expect( + jestExpect(jest.fn()).toHaveBeenLastCalledWith( + true, + false, + ), +).type.toRaiseError(); + +expect( + jestExpect( + jest.fn<(date: Date, name?: [string, string]) => void>(), + ).toHaveBeenLastCalledWith(jestExpect.any(Date), [ + jestExpect.any(String), + jestExpect.any(String), + ]), +).type.toBeVoid(); +expect( + jestExpect( + jest.fn<(date: Date, name?: [string, string]) => void>(), + ).toHaveBeenLastCalledWith(jestExpect.any(Date), jestExpect.any(Array)), +).type.toBeVoid(); +expect( + jestExpect( + jest.fn<(date: Date, name?: [string, string]) => void>(), + ).toHaveBeenLastCalledWith(jestExpect.any(Date)), +).type.toBeVoid(); +expect( + jestExpect( + jest.fn<(date: Date, name?: [string, string]) => void>(), + ).toHaveBeenLastCalledWith(jestExpect.any(Date), []), +).type.toRaiseError(); +expect( + jestExpect( + jest.fn<(date: Date, name?: [string, string]) => void>(), + ).toHaveBeenLastCalledWith(jestExpect.any(Date), [jestExpect.any(String)]), +).type.toRaiseError(); +expect( + jestExpect( + jest.fn<(date: Date, name?: [string, string]) => void>(), + ).toHaveBeenLastCalledWith(jestExpect.any(Date), [ + jestExpect.any(String), + 123, + ]), +).type.toRaiseError(); + +expect( + jestExpect( + jest.fn<(date: Date, name: {foo: string}) => void>(), + ).toHaveBeenLastCalledWith(jestExpect.any(Date), { + foo: jestExpect.any(String), + }), +).type.toBeVoid(); +expect( + jestExpect( + jest.fn<(date: Date, name: {foo: string}) => void>(), + ).toHaveBeenLastCalledWith(jestExpect.any(Date), jestExpect.any(Object)), +).type.toBeVoid(); +expect( + jestExpect( + jest.fn<(date: Date, name: {foo: string}) => void>(), + ).toHaveBeenLastCalledWith(jestExpect.any(Date)), +).type.toRaiseError(); +expect( + jestExpect( + jest.fn<(date: Date, name: {foo: string}) => void>(), + ).toHaveBeenLastCalledWith(jestExpect.any(Date), { + bar: jestExpect.any(String), + }), +).type.toRaiseError(); +expect( + jestExpect( + jest.fn<(date: Date, name: {foo: string}) => void>(), + ).toHaveBeenLastCalledWith(jestExpect.any(Date), { + bar: jestExpect.any(String), + foo: jestExpect.any(String), + }), +).type.toRaiseError(); + +expect( + jestExpect( + jest.fn<(date: Date, name: [string, [string]]) => void>(), + ).toHaveBeenLastCalledWith(jestExpect.any(Date), [ + jestExpect.any(String), + [jestExpect.any(String)], + ]), +).type.toBeVoid(); +expect( + jestExpect( + jest.fn<(date: Date, name: [string, [string]]) => void>(), + ).toHaveBeenLastCalledWith(jestExpect.any(Date), [ + 'value', + [jestExpect.any(String)], + ]), +).type.toBeVoid(); +expect( + jestExpect( + jest.fn<(date: Date, name: [string, [string]]) => void>(), + ).toHaveBeenLastCalledWith(jestExpect.any(Date), [ + jestExpect.any(String), + ['value'], + ]), +).type.toBeVoid(); +expect( + jestExpect( + jest.fn<(date: Date, name: [string, [string]]) => void>(), + ).toHaveBeenLastCalledWith(jestExpect.any(Date), ['value', ['value']]), +).type.toBeVoid(); diff --git a/packages/jest-types/__typetests__/expect/toHaveBeenNthCalledWith.test.ts b/packages/jest-types/__typetests__/expect/toHaveBeenNthCalledWith.test.ts new file mode 100644 index 000000000000..6399fa20c48f --- /dev/null +++ b/packages/jest-types/__typetests__/expect/toHaveBeenNthCalledWith.test.ts @@ -0,0 +1,329 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import {expect} from 'tstyche'; +import {jest, expect as jestExpect} from '@jest/globals'; +import type {overloaded} from './toHaveBeenCalledWith.test'; + +expect(jestExpect(jest.fn()).toHaveBeenNthCalledWith(2)).type.toBeVoid(); +expect( + jestExpect(jest.fn()).toHaveBeenNthCalledWith(1, 'value'), +).type.toBeVoid(); +expect( + jestExpect(jest.fn()).toHaveBeenNthCalledWith(1, 'value', 123), +).type.toBeVoid(); +expect( + jestExpect(jest.fn<(a: string, b: number) => void>()).toHaveBeenNthCalledWith( + 1, + jestExpect.stringContaining('value'), + 123, + ), +).type.toBeVoid(); +expect(jestExpect(jest.fn()).toHaveBeenNthCalledWith()).type.toRaiseError(); + +expect(jestExpect(jest.fn()).toHaveBeenNthCalledWith(2)).type.toBeVoid(); +expect( + jestExpect(jest.fn()).toHaveBeenNthCalledWith(1, 'value'), +).type.toBeVoid(); +expect( + jestExpect(jest.fn()).toHaveBeenNthCalledWith(1, 'value', 123), +).type.toBeVoid(); +expect( + jestExpect(jest.fn<(a: string, b: number) => void>()).toHaveBeenNthCalledWith( + 1, + jestExpect.stringContaining('value'), + 123, + ), +).type.toBeVoid(); +expect(jestExpect(jest.fn()).toHaveBeenNthCalledWith()).type.toRaiseError(); + +expect( + jestExpect(jest.fn<() => void>()).toHaveBeenNthCalledWith(1), +).type.toBeVoid(); +expect( + jestExpect(jest.fn<() => void>()).toHaveBeenNthCalledWith(1, 123), +).type.toRaiseError(); + +expect(jestExpect(() => {}).toHaveBeenNthCalledWith(1)).type.toBeVoid(); +expect( + jestExpect(() => {}).toHaveBeenNthCalledWith(1, 123), +).type.toRaiseError(); + +expect( + jestExpect(jest.fn<(n?: number) => void>()).toHaveBeenNthCalledWith(1), +).type.toBeVoid(); +expect( + jestExpect(jest.fn<(n?: number) => void>()).toHaveBeenNthCalledWith(1, 123), +).type.toBeVoid(); +expect( + jestExpect(jest.fn<(n?: number) => void>()).toHaveBeenNthCalledWith( + 1, + 'value', + ), +).type.toRaiseError(); + +expect( + jestExpect(jest.fn<(n: number) => void>()).toHaveBeenNthCalledWith(1, 123), +).type.toBeVoid(); +expect( + jestExpect(jest.fn<(n: number) => void>()).toHaveBeenNthCalledWith(1), +).type.toRaiseError(); +expect( + jestExpect(jest.fn<(n: number) => void>()).toHaveBeenNthCalledWith( + 1, + 'value', + ), +).type.toRaiseError(); + +expect( + jestExpect((n: number) => {}).toHaveBeenNthCalledWith(1, 123), +).type.toBeVoid(); +expect( + jestExpect((n: number) => {}).toHaveBeenNthCalledWith( + 1, + jestExpect.any(Number), + ), +).type.toBeVoid(); +expect( + jestExpect((n: number) => {}).toHaveBeenNthCalledWith(1), +).type.toRaiseError(); +expect( + jestExpect((n: number) => {}).toHaveBeenNthCalledWith(1, 'value'), +).type.toRaiseError(); + +expect( + jestExpect(jest.fn<(s: string) => void>()).toHaveBeenNthCalledWith( + 1, + 'value', + ), +).type.toBeVoid(); +expect( + jestExpect(jest.fn<(s: string) => void>()).toHaveBeenNthCalledWith(1), +).type.toRaiseError(); +expect( + jestExpect(jest.fn<(s: string) => void>()).toHaveBeenNthCalledWith(1, 123), +).type.toRaiseError(); + +expect( + jestExpect(jest.fn<(n: number, s: string) => void>()).toHaveBeenNthCalledWith( + 1, + 123, + 'value', + ), +).type.toBeVoid(); +expect( + jestExpect(jest.fn<(n: number, s: string) => void>()).toHaveBeenNthCalledWith( + 1, + ), +).type.toRaiseError(); +expect( + jestExpect(jest.fn<(n: number, s: string) => void>()).toHaveBeenNthCalledWith( + 1, + 123, + ), +).type.toRaiseError(); +expect( + jestExpect(jest.fn<(n: number, s: string) => void>()).toHaveBeenNthCalledWith( + 1, + 123, + 123, + ), +).type.toRaiseError(); +expect( + jestExpect(jest.fn<(n: number, s: string) => void>()).toHaveBeenNthCalledWith( + 1, + 'value', + 'value', + ), +).type.toRaiseError(); +expect( + jestExpect(jest.fn<(n: number, s: string) => void>()).toHaveBeenNthCalledWith( + 1, + 'value', + 123, + ), +).type.toRaiseError(); + +expect( + jestExpect( + jest.fn<(n: number, s?: string) => void>(), + ).toHaveBeenNthCalledWith(1, 123, 'value'), +).type.toBeVoid(); +expect( + jestExpect( + jest.fn<(n: number, s?: string) => void>(), + ).toHaveBeenNthCalledWith(1, 123), +).type.toBeVoid(); +expect( + jestExpect( + jest.fn<(n: number, s?: string) => void>(), + ).toHaveBeenNthCalledWith(1), +).type.toRaiseError(); +expect( + jestExpect( + jest.fn<(n: number, s?: string) => void>(), + ).toHaveBeenNthCalledWith(1, 'value'), +).type.toRaiseError(); +expect( + jestExpect( + jest.fn<(n: number, s?: string) => void>(), + ).toHaveBeenNthCalledWith(1, 'value', 'value'), +).type.toRaiseError(); +expect( + jestExpect( + jest.fn<(n: number, s?: string) => void>(), + ).toHaveBeenNthCalledWith(1, 'value', 123), +).type.toRaiseError(); +expect( + jestExpect( + jest.fn<(n: number, s?: string) => void>(), + ).toHaveBeenNthCalledWith(1, 123, 123), +).type.toRaiseError(); + +expect( + jestExpect(jest.fn()).toHaveBeenNthCalledWith(1), +).type.toBeVoid(); +expect( + jestExpect(jest.fn()).toHaveBeenNthCalledWith(1, 123), +).type.toBeVoid(); +expect( + jestExpect(jest.fn()).toHaveBeenNthCalledWith( + 1, + 123, + 'value', + ), +).type.toBeVoid(); +expect( + jestExpect(jest.fn()).toHaveBeenNthCalledWith( + 1, + 123, + true, + ), +).type.toBeVoid(); +expect( + jestExpect(jest.fn()).toHaveBeenNthCalledWith(1, 123, 123), +).type.toRaiseError(); +expect( + jestExpect(jest.fn()).toHaveBeenNthCalledWith(1, 'value'), +).type.toRaiseError(); +expect( + jestExpect(jest.fn()).toHaveBeenNthCalledWith(1, true), +).type.toRaiseError(); +expect( + jestExpect(jest.fn()).toHaveBeenNthCalledWith( + 1, + 'value', + 'value', + ), +).type.toRaiseError(); +expect( + jestExpect(jest.fn()).toHaveBeenNthCalledWith( + 1, + true, + false, + ), +).type.toRaiseError(); + +expect( + jestExpect( + jest.fn<(date: Date, name?: [string, string]) => void>(), + ).toHaveBeenNthCalledWith(1, jestExpect.any(Date), [ + jestExpect.any(String), + jestExpect.any(String), + ]), +).type.toBeVoid(); +expect( + jestExpect( + jest.fn<(date: Date, name?: [string, string]) => void>(), + ).toHaveBeenNthCalledWith(1, jestExpect.any(Date), jestExpect.any(Array)), +).type.toBeVoid(); +expect( + jestExpect( + jest.fn<(date: Date, name?: [string, string]) => void>(), + ).toHaveBeenNthCalledWith(1, jestExpect.any(Date)), +).type.toBeVoid(); +expect( + jestExpect( + jest.fn<(date: Date, name?: [string, string]) => void>(), + ).toHaveBeenNthCalledWith(1, jestExpect.any(Date), []), +).type.toRaiseError(); +expect( + jestExpect( + jest.fn<(date: Date, name?: [string, string]) => void>(), + ).toHaveBeenNthCalledWith(1, jestExpect.any(Date), [jestExpect.any(String)]), +).type.toRaiseError(); +expect( + jestExpect( + jest.fn<(date: Date, name?: [string, string]) => void>(), + ).toHaveBeenNthCalledWith(1, jestExpect.any(Date), [ + jestExpect.any(String), + 123, + ]), +).type.toRaiseError(); + +expect( + jestExpect( + jest.fn<(date: Date, name: {foo: string}) => void>(), + ).toHaveBeenNthCalledWith(1, jestExpect.any(Date), { + foo: jestExpect.any(String), + }), +).type.toBeVoid(); +expect( + jestExpect( + jest.fn<(date: Date, name: {foo: string}) => void>(), + ).toHaveBeenNthCalledWith(1, jestExpect.any(Date), jestExpect.any(Object)), +).type.toBeVoid(); +expect( + jestExpect( + jest.fn<(date: Date, name: {foo: string}) => void>(), + ).toHaveBeenNthCalledWith(1, jestExpect.any(Date)), +).type.toRaiseError(); +expect( + jestExpect( + jest.fn<(date: Date, name: {foo: string}) => void>(), + ).toHaveBeenNthCalledWith(1, jestExpect.any(Date), { + bar: jestExpect.any(String), + }), +).type.toRaiseError(); +expect( + jestExpect( + jest.fn<(date: Date, name: {foo: string}) => void>(), + ).toHaveBeenNthCalledWith(1, jestExpect.any(Date), { + bar: jestExpect.any(String), + foo: jestExpect.any(String), + }), +).type.toRaiseError(); + +expect( + jestExpect( + jest.fn<(date: Date, name: [string, [string]]) => void>(), + ).toHaveBeenNthCalledWith(1, jestExpect.any(Date), [ + jestExpect.any(String), + [jestExpect.any(String)], + ]), +).type.toBeVoid(); +expect( + jestExpect( + jest.fn<(date: Date, name: [string, [string]]) => void>(), + ).toHaveBeenNthCalledWith(1, jestExpect.any(Date), [ + 'value', + [jestExpect.any(String)], + ]), +).type.toBeVoid(); +expect( + jestExpect( + jest.fn<(date: Date, name: [string, [string]]) => void>(), + ).toHaveBeenNthCalledWith(1, jestExpect.any(Date), [ + jestExpect.any(String), + ['value'], + ]), +).type.toBeVoid(); +expect( + jestExpect( + jest.fn<(date: Date, name: [string, [string]]) => void>(), + ).toHaveBeenNthCalledWith(1, jestExpect.any(Date), ['value', ['value']]), +).type.toBeVoid(); diff --git a/packages/jest-worker/src/__tests__/Farm.test.ts b/packages/jest-worker/src/__tests__/Farm.test.ts index 4a2268fb7f5d..6fb134839b98 100644 --- a/packages/jest-worker/src/__tests__/Farm.test.ts +++ b/packages/jest-worker/src/__tests__/Farm.test.ts @@ -120,7 +120,9 @@ describe('Farm', () => { }); it('handles null computeWorkerKey, sending to first worker', async () => { - const computeWorkerKey = jest.fn(() => null); + const computeWorkerKey = jest.fn< + (method: string, ...args: Array) => string | null + >(() => null); const farm = new Farm(4, callback, {computeWorkerKey}); @@ -144,7 +146,7 @@ describe('Farm', () => { it('sends the same worker key to the same worker', async () => { const computeWorkerKey = jest - .fn<() => string>() + .fn<(method: string, ...args: Array) => string | null>() .mockReturnValueOnce('one') .mockReturnValueOnce('two') .mockReturnValueOnce('one'); diff --git a/packages/jest-worker/src/base/__tests__/BaseWorkerPool.test.ts b/packages/jest-worker/src/base/__tests__/BaseWorkerPool.test.ts index a1fa6978f6db..0c67ce4892ef 100644 --- a/packages/jest-worker/src/base/__tests__/BaseWorkerPool.test.ts +++ b/packages/jest-worker/src/base/__tests__/BaseWorkerPool.test.ts @@ -13,7 +13,10 @@ import { } from '../../types'; import BaseWorkerPool from '../BaseWorkerPool'; -const Worker = jest.fn<(workerOptions: WorkerOptions) => WorkerInterface>(); +const Worker = + jest.fn< + (workerOptions: Omit) => WorkerInterface + >(); const mockSend = jest.fn(); diff --git a/yarn.lock b/yarn.lock index 969d6f086f6c..502ee1c72589 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10072,6 +10072,7 @@ __metadata: jest-get-type: "workspace:*" jest-matcher-utils: "workspace:*" jest-message-util: "workspace:*" + jest-mock: "workspace:*" jest-util: "workspace:*" languageName: unknown linkType: soft