-
-
Notifications
You must be signed in to change notification settings - Fork 6.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(expect, @jest/expect): support type inference for function parame… #13268
Changes from 5 commits
d447395
7c1f44c
f7d4b18
ff002fd
cac0bb1
4c37edc
a01e6d8
5860397
2c9dac7
e73f878
4080950
c87ad1c
f2bfab9
8969360
3bdf5f9
0655ce0
8332a60
e483fa1
b7e41d1
61d3fbc
6b62fe0
07333c1
59bbde0
4b15e90
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -94,9 +94,9 @@ export interface BaseExpect { | |
} | ||
|
||
export type Expect = { | ||
<T = unknown>(actual: T): Matchers<void> & | ||
Inverse<Matchers<void>> & | ||
PromiseMatchers; | ||
<T = unknown>(actual: T): Matchers<void, T> & | ||
Inverse<Matchers<void, T>> & | ||
PromiseMatchers<T>; | ||
} & BaseExpect & | ||
AsymmetricMatchers & | ||
Inverse<Omit<AsymmetricMatchers, 'any' | 'anything'>>; | ||
|
@@ -118,32 +118,39 @@ export interface AsymmetricMatchers { | |
stringMatching(sample: string | RegExp): AsymmetricMatcher; | ||
} | ||
|
||
type PromiseMatchers = { | ||
// if T is a function, return its parameters array type, otherwise return an unknown array type | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hm.. In this use case, can it be not a function? I mean, isn’t it that I just look at There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @mrazauskas So to sum up, yes, in this use case it can still not be a function (and will likely fail the test at run time) |
||
type ConditionalFunctionParameters<T> = T extends ( | ||
...args: Array<unknown> | ||
) => unknown | ||
? Parameters<T> | ||
: Array<unknown>; | ||
|
||
type PromiseMatchers<T = unknown> = { | ||
/** | ||
* Unwraps the reason of a rejected promise so any other matcher can be chained. | ||
* If the promise is fulfilled the assertion fails. | ||
*/ | ||
rejects: Matchers<Promise<void>> & Inverse<Matchers<Promise<void>>>; | ||
rejects: Matchers<Promise<void>> & Inverse<Matchers<Promise<void>, T>>; | ||
/** | ||
* Unwraps the value of a fulfilled promise so any other matcher can be chained. | ||
* If the promise is rejected the assertion fails. | ||
*/ | ||
resolves: Matchers<Promise<void>> & Inverse<Matchers<Promise<void>>>; | ||
resolves: Matchers<Promise<void>> & Inverse<Matchers<Promise<void>, T>>; | ||
}; | ||
|
||
export interface Matchers<R extends void | Promise<void>> { | ||
export interface Matchers<R extends void | Promise<void>, T = unknown> { | ||
/** | ||
* Ensures the last call to a mock function was provided specific args. | ||
*/ | ||
lastCalledWith(...expected: Array<unknown>): R; | ||
lastCalledWith(...expected: ConditionalFunctionParameters<T>): R; | ||
/** | ||
* Ensure that the last call to a mock function has returned a specified value. | ||
*/ | ||
lastReturnedWith(expected: unknown): R; | ||
/** | ||
* Ensure that a mock function is called with specific arguments on an Nth call. | ||
*/ | ||
nthCalledWith(nth: number, ...expected: Array<unknown>): R; | ||
nthCalledWith(nth: number, ...expected: ConditionalFunctionParameters<T>): R; | ||
/** | ||
* Ensure that the nth call to a mock function has returned a specified value. | ||
*/ | ||
|
@@ -164,7 +171,7 @@ export interface Matchers<R extends void | Promise<void>> { | |
/** | ||
* Ensure that a mock function is called with specific arguments. | ||
*/ | ||
toBeCalledWith(...expected: Array<unknown>): R; | ||
toBeCalledWith(...expected: ConditionalFunctionParameters<T>): R; | ||
/** | ||
* Using exact equality with floating point numbers is a bad idea. | ||
* Rounding means that intuitive things fail. | ||
|
@@ -247,16 +254,19 @@ export interface Matchers<R extends void | Promise<void>> { | |
/** | ||
* Ensure that a mock function is called with specific arguments. | ||
*/ | ||
toHaveBeenCalledWith(...expected: Array<unknown>): R; | ||
toHaveBeenCalledWith(...expected: ConditionalFunctionParameters<T>): R; | ||
/** | ||
* Ensure that a mock function is called with specific arguments on an Nth call. | ||
*/ | ||
toHaveBeenNthCalledWith(nth: number, ...expected: Array<unknown>): R; | ||
toHaveBeenNthCalledWith( | ||
nth: number, | ||
...expected: ConditionalFunctionParameters<T> | ||
): R; | ||
/** | ||
* If you have a mock function, you can use `.toHaveBeenLastCalledWith` | ||
* to test what arguments it was last called with. | ||
*/ | ||
toHaveBeenLastCalledWith(...expected: Array<unknown>): R; | ||
toHaveBeenLastCalledWith(...expected: ConditionalFunctionParameters<T>): 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 | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wanna send a separate PR for these to changes? That way CI will trigger when you push without me having to press a button 🙂
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not totally sure what you mean, maybe suggest a change?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Extract the removal of
feat
from the changelog to a separate PRThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried doing that and the workflow did not automatically run: 8969360
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I meant make those changes in a separate PR which I'll merge. Then approval is no longer needed (once you have a merged contribution)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sure