Skip to content

Commit 0fd748f

Browse files
committed
Merge branch 'main' into next
2 parents 5c0504c + 84688e9 commit 0fd748f

33 files changed

+2245
-800
lines changed

CHANGELOG.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,30 @@
4242

4343
* Drop support for Node 10 and 15
4444

45+
# [24.5.0](https://github.com/jest-community/eslint-plugin-jest/compare/v24.4.3...v24.5.0) (2021-09-29)
46+
47+
48+
### Bug Fixes
49+
50+
* **no-deprecated-functions:** remove `process.cwd` from resolve paths ([#889](https://github.com/jest-community/eslint-plugin-jest/issues/889)) ([6940488](https://github.com/jest-community/eslint-plugin-jest/commit/6940488d7b5a47577e2823e6d4385b511c5becf4))
51+
* **no-identical-title:** always consider `.each` titles unique ([#910](https://github.com/jest-community/eslint-plugin-jest/issues/910)) ([a41a40e](https://github.com/jest-community/eslint-plugin-jest/commit/a41a40eafaf1db444ba940cccd2014cb0dc41be9))
52+
53+
54+
### Features
55+
56+
* create `prefer-expect-resolves` rule ([#822](https://github.com/jest-community/eslint-plugin-jest/issues/822)) ([2556020](https://github.com/jest-community/eslint-plugin-jest/commit/2556020a777f9daaf1d362a04e3f990415e82db8))
57+
* create `prefer-to-be` rule ([#864](https://github.com/jest-community/eslint-plugin-jest/issues/864)) ([3a64aea](https://github.com/jest-community/eslint-plugin-jest/commit/3a64aea5bdc55465f1ef34f1426ae626d6c8a230))
58+
* **require-top-level-describe:** support enforcing max num of describes ([#912](https://github.com/jest-community/eslint-plugin-jest/issues/912)) ([14a2d13](https://github.com/jest-community/eslint-plugin-jest/commit/14a2d1391c9f6f52509316542f45df35853c9b79))
59+
* **valid-title:** allow custom matcher messages ([#913](https://github.com/jest-community/eslint-plugin-jest/issues/913)) ([ffc9392](https://github.com/jest-community/eslint-plugin-jest/commit/ffc93921348b0d4a394125f665d2bb09148ea37e))
60+
61+
## [24.4.3](https://github.com/jest-community/eslint-plugin-jest/compare/v24.4.2...v24.4.3) (2021-09-28)
62+
63+
64+
### Bug Fixes
65+
66+
* **valid-expect-in-promise:** support `finally` ([#914](https://github.com/jest-community/eslint-plugin-jest/issues/914)) ([9c89855](https://github.com/jest-community/eslint-plugin-jest/commit/9c89855d23534272230afe6d9e665b8e11ef3075))
67+
* **valid-expect-in-promise:** support additional test functions ([#915](https://github.com/jest-community/eslint-plugin-jest/issues/915)) ([4798005](https://github.com/jest-community/eslint-plugin-jest/commit/47980058d8d1ff86ee69a376c4edd182d462d594))
68+
4569
## [24.4.2](https://github.com/jest-community/eslint-plugin-jest/compare/v24.4.1...v24.4.2) (2021-09-17)
4670

4771

README.md

Lines changed: 72 additions & 49 deletions
Large diffs are not rendered by default.

docs/rules/max-nested-describe.md

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -116,16 +116,15 @@ describe('foo', () => {
116116
});
117117
});
118118

119-
describe('foo2', function()) {
120-
describe('bar2', function() {
121-
it('should get something', function() {
119+
describe('foo2', function () {
120+
describe('bar2', function () {
121+
it('should get something', function () {
122122
expect(getSomething()).toBe('Something');
123123
});
124124

125-
it('should get else', function() {
125+
it('should get else', function () {
126126
expect(getSomething()).toBe('Something');
127127
});
128128
});
129129
});
130-
131130
```

docs/rules/no-conditional-expect.md

Lines changed: 57 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ assumed to be promises.
88

99
## Rule Details
1010

11-
Jest considered a test to have failed if it throws an error, rather than on if
12-
any particular function is called, meaning conditional calls to `expect` could
13-
result in tests silently being skipped.
11+
Jest only considers a test to have failed if it throws an error, meaning if
12+
calls to assertion functions like `expect` occur in conditional code such as a
13+
`catch` statement, tests can end up passing but not actually test anything.
1414

1515
Additionally, conditionals tend to make tests more brittle and complex, as they
1616
increase the amount of mental thinking needed to understand what is actually
@@ -79,3 +79,57 @@ it('throws an error', async () => {
7979
await expect(foo).rejects.toThrow(Error);
8080
});
8181
```
82+
83+
### How to catch a thrown error for testing without violating this rule
84+
85+
A common situation that comes up with this rule is when wanting to test
86+
properties on a thrown error, as Jest's `toThrow` matcher only checks the
87+
`message` property.
88+
89+
Most people write something like this:
90+
91+
```typescript
92+
describe('when the http request fails', () => {
93+
it('includes the status code in the error', async () => {
94+
try {
95+
await makeRequest(url);
96+
} catch (error) {
97+
expect(error).toHaveProperty('statusCode', 404);
98+
}
99+
});
100+
});
101+
```
102+
103+
As stated above, the problem with this is that if `makeRequest()` doesn't throw
104+
the test will still pass as if the `expect` had been called.
105+
106+
While you can use `expect.assertions` & `expect.hasAssertions` for these
107+
situations, they only work with `expect`.
108+
109+
A better way to handle this situation is to introduce a wrapper to handle the
110+
catching, and otherwise returns a specific "no error thrown" error if nothing is
111+
thrown by the wrapped function:
112+
113+
```typescript
114+
class NoErrorThrownError extends Error {}
115+
116+
const getError = async <TError>(call: () => unknown): Promise<TError> => {
117+
try {
118+
await call();
119+
120+
throw new NoErrorThrownError();
121+
} catch (error: unknown) {
122+
return error as TError;
123+
}
124+
};
125+
126+
describe('when the http request fails', () => {
127+
it('includes the status code in the error', async () => {
128+
const error = await getError(async () => makeRequest(url));
129+
130+
// check that the returned error wasn't that no error was thrown
131+
expect(error).not.toBeInstanceOf(NoErrorThrownError);
132+
expect(error).toHaveProperty('statusCode', 404);
133+
});
134+
});
135+
```

docs/rules/no-deprecated-functions.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@ either been renamed for clarity, or replaced with more powerful APIs.
66
While typically these deprecated functions are kept in the codebase for a number
77
of majors, eventually they are removed completely.
88

9+
This rule requires knowing which version of Jest you're using - see
10+
[this section of the readme](../../README.md#jest-version-setting) for details
11+
on how that is obtained automatically and how you can explicitly provide a
12+
version if needed.
13+
914
## Rule details
1015

1116
This rule warns about calls to deprecated functions, and provides details on

docs/rules/no-done-callback.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
When calling asynchronous code in hooks and tests, `jest` needs to know when the
44
asynchronous work is complete to progress the current run.
55

6-
Originally the most common pattern to archive this was to use callbacks:
6+
Originally the most common pattern to achieve this was to use callbacks:
77

88
```js
99
test('the data is peanut butter', done => {
@@ -20,11 +20,11 @@ test('the data is peanut butter', done => {
2020
});
2121
```
2222

23-
This can be very error prone however, as it requires careful understanding of
23+
This can be very error-prone however, as it requires careful understanding of
2424
how assertions work in tests or otherwise tests won't behave as expected.
2525

2626
For example, if the `try/catch` was left out of the above code, the test would
27-
timeout rather than fail. Even with the `try/catch`, forgetting to pass the
27+
time out rather than fail. Even with the `try/catch`, forgetting to pass the
2828
caught error to `done` will result in `jest` believing the test has passed.
2929

3030
A more straightforward way to handle asynchronous code is to use Promises:

docs/rules/no-standalone-expect.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ trigger this rule.
88

99
This rule aims to eliminate `expect` statements that will not be executed. An
1010
`expect` inside of a `describe` block but outside of a `test` or `it` block or
11-
outside of a `describe` will not execute and therefore will trigger this rule.
12-
It is viable, however, to have an `expect` in a helper function that is called
13-
from within a `test` or `it` block so `expect` statements in a function will not
11+
outside a `describe` will not execute and therefore will trigger this rule. It
12+
is viable, however, to have an `expect` in a helper function that is called from
13+
within a `test` or `it` block so `expect` statements in a function will not
1414
trigger this rule.
1515

1616
Statements like `expect.hasAssertions()` will NOT trigger this rule since these

docs/rules/no-test-return-statement.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,7 @@ If you are returning Promises then you should update the test to use
77

88
## Rule details
99

10-
This rule triggers a warning if you use a return statement inside of a test
11-
body.
10+
This rule triggers a warning if you use a return statement inside a test body.
1211

1312
```js
1413
/*eslint jest/no-test-return-statement: "error"*/

docs/rules/prefer-expect-resolves.md

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# Prefer `await expect(...).resolves` over `expect(await ...)` syntax (`prefer-expect-resolves`)
2+
3+
When working with promises, there are two primary ways you can test the resolved
4+
value:
5+
6+
1. use the `resolve` modifier on `expect`
7+
(`await expect(...).resolves.<matcher>` style)
8+
2. `await` the promise and assert against its result
9+
(`expect(await ...).<matcher>` style)
10+
11+
While the second style is arguably less dependent on `jest`, if the promise
12+
rejects it will be treated as a general error, resulting in less predictable
13+
behaviour and output from `jest`.
14+
15+
Additionally, favoring the first style ensures consistency with its `rejects`
16+
counterpart, as there is no way of "awaiting" a rejection.
17+
18+
## Rule details
19+
20+
This rule triggers a warning if an `await` is done within an `expect`, and
21+
recommends using `resolves` instead.
22+
23+
Examples of **incorrect** code for this rule
24+
25+
```js
26+
it('passes', async () => {
27+
expect(await someValue()).toBe(true);
28+
});
29+
30+
it('is true', async () => {
31+
const myPromise = Promise.resolve(true);
32+
33+
expect(await myPromise).toBe(true);
34+
});
35+
```
36+
37+
Examples of **correct** code for this rule
38+
39+
```js
40+
it('passes', async () => {
41+
await expect(someValue()).resolves.toBe(true);
42+
});
43+
44+
it('is true', async () => {
45+
const myPromise = Promise.resolve(true);
46+
47+
await expect(myPromise).resolves.toBe(true);
48+
});
49+
50+
it('errors', async () => {
51+
await expect(Promise.rejects('oh noes!')).rejects.toThrow('oh noes!');
52+
});
53+
```

docs/rules/prefer-to-be.md

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# Suggest using `toBe()` for primitive literals (`prefer-to-be`)
2+
3+
When asserting against primitive literals such as numbers and strings, the
4+
equality matchers all operate the same, but read slightly differently in code.
5+
6+
This rule recommends using the `toBe` matcher in these situations, as it forms
7+
the most grammatically natural sentence. For `null`, `undefined`, and `NaN` this
8+
rule recommends using their specific `toBe` matchers, as they give better error
9+
messages as well.
10+
11+
## Rule details
12+
13+
This rule triggers a warning if `toEqual()` or `toStrictEqual()` are used to
14+
assert a primitive literal value such as numbers, strings, and booleans.
15+
16+
The following patterns are considered warnings:
17+
18+
```js
19+
expect(value).not.toEqual(5);
20+
expect(getMessage()).toStrictEqual('hello world');
21+
expect(loadMessage()).resolves.toEqual('hello world');
22+
```
23+
24+
The following pattern is not warning:
25+
26+
```js
27+
expect(value).not.toBe(5);
28+
expect(getMessage()).toBe('hello world');
29+
expect(loadMessage()).resolves.toBe('hello world');
30+
expect(didError).not.toBe(true);
31+
32+
expect(catchError()).toStrictEqual({ message: 'oh noes!' });
33+
```
34+
35+
For `null`, `undefined`, and `NaN`, this rule triggers a warning if `toBe` is
36+
used to assert against those literal values instead of their more specific
37+
`toBe` counterparts:
38+
39+
```js
40+
expect(value).not.toBe(undefined);
41+
expect(getMessage()).toBe(null);
42+
expect(countMessages()).resolves.not.toBe(NaN);
43+
```
44+
45+
The following pattern is not warning:
46+
47+
```js
48+
expect(value).toBeDefined();
49+
expect(getMessage()).toBeNull();
50+
expect(countMessages()).resolves.not.toBeNaN();
51+
52+
expect(catchError()).toStrictEqual({ message: undefined });
53+
```

0 commit comments

Comments
 (0)