Skip to content

Commit

Permalink
feat(expect, @jest/expect): infer type of *ReturnedWith matchers ar…
Browse files Browse the repository at this point in the history
…gument (#13278)
  • Loading branch information
mrazauskas committed Sep 20, 2022
1 parent d0f1b0a commit 3d626a5
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 9 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -3,6 +3,7 @@
### Features

- `[expect, @jest/expect]` support type inference for function parameters in `CalledWith` assertions ([#13268](https://github.com/facebook/jest/pull/13268))
- `[expect, @jest/expect]` Infer type of `*ReturnedWith` matchers argument ([#13278](https://github.com/facebook/jest/pull/13278))
- `[@jest/environment, jest-runtime]` Allow `jest.requireActual` and `jest.requireMock` to take a type argument ([#13253](https://github.com/facebook/jest/pull/13253))
- `[@jest/environment]` Allow `jest.mock` and `jest.doMock` to take a type argument ([#13254](https://github.com/facebook/jest/pull/13254))
- `[@jest/fake-timers]` Add `jest.now()` to return the current fake clock time ([#13244](https://github.com/facebook/jest/pull/13244), [13246](https://github.com/facebook/jest/pull/13246))
Expand Down
3 changes: 2 additions & 1 deletion packages/expect/__typetests__/expect.test.ts
Expand Up @@ -16,7 +16,8 @@ import {
} from 'expect';
import type * as jestMatcherUtils from 'jest-matcher-utils';

type M = Matchers<void>;
type M = Matchers<void, unknown>;
type N = Matchers<void>;

expectError(() => {
type E = Matchers;
Expand Down
15 changes: 9 additions & 6 deletions packages/expect/src/types.ts
Expand Up @@ -141,15 +141,15 @@ export interface Matchers<R extends void | Promise<void>, T = unknown> {
/**
* Ensure that the last call to a mock function has returned a specified value.
*/
lastReturnedWith(expected: unknown): R;
lastReturnedWith(expected: ReturnType<EnsureFunctionLike<T>>): R;
/**
* Ensure that a mock function is called with specific arguments on an Nth call.
*/
nthCalledWith(nth: number, ...expected: Parameters<EnsureFunctionLike<T>>): R;
/**
* Ensure that the nth call to a mock function has returned a specified value.
*/
nthReturnedWith(nth: number, expected: unknown): R;
nthReturnedWith(nth: number, expected: ReturnType<EnsureFunctionLike<T>>): R;
/**
* Checks that a value is what you expect. It calls `Object.is` to compare values.
* Don't use `toBe` with floating-point numbers.
Expand Down Expand Up @@ -267,7 +267,7 @@ export interface Matchers<R extends void | Promise<void>, T = unknown> {
* If the last call to the mock function threw an error, then this matcher will fail
* no matter what value you provided as the expected return value.
*/
toHaveLastReturnedWith(expected: unknown): R;
toHaveLastReturnedWith(expected: ReturnType<EnsureFunctionLike<T>>): R;
/**
* Used to check that an object has a `.length` property
* and it is set to a certain numeric value.
Expand All @@ -278,7 +278,10 @@ export interface Matchers<R extends void | Promise<void>, T = unknown> {
* If the nth call to the mock function threw an error, then this matcher will fail
* no matter what value you provided as the expected return value.
*/
toHaveNthReturnedWith(nth: number, expected: unknown): R;
toHaveNthReturnedWith(
nth: number,
expected: ReturnType<EnsureFunctionLike<T>>,
): R;
/**
* Use to check if property at provided reference keyPath exists for an object.
* For checking deeply nested properties in an object you may use dot notation or an array containing
Expand Down Expand Up @@ -308,7 +311,7 @@ export interface Matchers<R extends void | Promise<void>, T = unknown> {
/**
* Use to ensure that a mock function returned a specific value.
*/
toHaveReturnedWith(expected: unknown): R;
toHaveReturnedWith(expected: ReturnType<EnsureFunctionLike<T>>): R;
/**
* Check that a string matches a regular expression.
*/
Expand All @@ -330,7 +333,7 @@ export interface Matchers<R extends void | Promise<void>, T = unknown> {
/**
* Ensure that a mock function has returned a specified value at least once.
*/
toReturnWith(expected: unknown): R;
toReturnWith(expected: ReturnType<EnsureFunctionLike<T>>): R;
/**
* Use to test that objects have the same types as well as structure.
*/
Expand Down
27 changes: 25 additions & 2 deletions packages/jest-types/__typetests__/expect.test.ts
Expand Up @@ -278,21 +278,44 @@ expectError(expect(jest.fn()).toHaveReturnedTimes(true));
expectError(expect(jest.fn()).toHaveReturnedTimes());

expectType<void>(expect(jest.fn()).toReturnWith('value'));
expectType<void>(expect(jest.fn<() => string>()).toReturnWith('value'));
expectError(expect(jest.fn<() => number>()).toReturnWith('value'));
expectError(expect(123).toReturnWith('value'));
expectError(expect(jest.fn()).toReturnWith());

expectType<void>(expect(jest.fn()).toHaveReturnedWith(123));
expectType<void>(expect(jest.fn<() => number>()).toHaveReturnedWith(123));
expectError(expect(jest.fn<() => string>()).toHaveReturnedWith(123));
expectError(expect(123).toHaveReturnedWith(123));
expectError(expect(jest.fn()).toHaveReturnedWith());

expectType<void>(expect(jest.fn()).lastReturnedWith('value'));
expectType<void>(expect(jest.fn<() => string>()).lastReturnedWith('value'));
expectError(expect(jest.fn<() => number>()).lastReturnedWith('value'));
expectError(expect(123).lastReturnedWith('value'));
expectError(expect(jest.fn()).lastReturnedWith());

expectType<void>(expect(jest.fn()).toHaveLastReturnedWith(123));
expectType<void>(expect(jest.fn<() => number>()).toHaveLastReturnedWith(123));
expectError(expect(jest.fn<() => string>()).toHaveLastReturnedWith(123));
expectError(expect(123).toHaveLastReturnedWith(123));
expectError(expect(jest.fn()).toHaveLastReturnedWith());

expectType<void>(expect(jest.fn()).nthReturnedWith(1, 'value'));
expectType<void>(expect(jest.fn<() => string>()).nthReturnedWith(2, 'value'));
expectError(expect(jest.fn<() => number>()).nthReturnedWith(3, 'value'));
expectError(expect(123).nthReturnedWith(4, 'value'));
expectError(expect(123).nthReturnedWith(5));
expectError(expect(jest.fn()).nthReturnedWith());
expectError(expect(jest.fn()).nthReturnedWith(2));

expectType<void>(expect(jest.fn()).toHaveNthReturnedWith(1, 'value'));
expectType<void>(
expect(jest.fn<() => string>()).toHaveNthReturnedWith(2, 'value'),
);
expectError(expect(jest.fn<() => number>()).toHaveNthReturnedWith(3, 'value'));
expectError(expect(123).toHaveNthReturnedWith(4, 'value'));
expectError(expect(123).toHaveNthReturnedWith(5));
expectError(expect(jest.fn()).toHaveNthReturnedWith());
expectError(expect(jest.fn()).toHaveNthReturnedWith(2));

// snapshot matchers

Expand Down

0 comments on commit 3d626a5

Please sign in to comment.