Skip to content

Commit 7a49c58

Browse files
authored
feat(valid-expect-in-promise): re-implement rule (#916)
* feat(valid-expect-in-promise): re-write implementation * fix(valid-expect-in-promise): check number of arguments being passed * fix(valid-expect-in-promise): bailout if `done` callback is present * fix(valid-expect-in-promise): allow awaited promises * fix(valid-expect-in-promise): handle multi-chained promises properly Method call chains are represented in AST in a nested fashion, meaning it's not enough to just separately track if we're both in a promise chain call and then if we've found an `expect` call, because when we exit another CallExpression in the same chain it'll look like that has an `expect` call. Instead, we need to track our depth as we enter CallExpression nodes so that when we exit those nodes we can check if we encountered an `expect` call at that same depth. * fix(valid-expect-in-promise): handle promises assigned to variables * refactor(valid-expect-in-promise): adjust conditions to dedent code * fix(valid-expect-in-promise): allow variables assigned awaited promises * feat(valid-expect-in-promise): track promise vars across reassignments * feat(valid-expect-in-promise): support blocks and multi-variable assigns * feat(valid-expect-in-promise): support re-assignment promise chaining * refactor(valid-expect-in-promise): remove unneeded condition * refactor(valid-expect-in-promise): inline reporting function We only call it in one place, and so it lets us also remove some minor types that can be otherwise inferred * fix(valid-expect-in-promise): rewrite rule message to be clearer * fix(valid-expect-in-promise): rewrite rule description to be clearer * fix(valid-expect-in-promise): ignore unreachable code after return * fix(valid-expect-in-promise): support `Promise.all` * fix(valid-expect-in-promise): support `resolve` & `reject` methods * refactor(valid-expect-in-promise): remove unneeded optional chain * refactor(valid-expect-in-promise): adjust conditions slightly * chore(valid-expect-in-promise): add a bunch of comments * feat(valid-expect-in-promise): support `Promise.allSettled` * docs(valid-expect-in-promise): add more examples and reword
1 parent a4f66f6 commit 7a49c58

File tree

4 files changed

+1335
-179
lines changed

4 files changed

+1335
-179
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ installations requiring long-term consistency.
193193
| [require-top-level-describe](docs/rules/require-top-level-describe.md) | Require test cases and hooks to be inside a `describe` block | | |
194194
| [valid-describe](docs/rules/valid-describe.md) | Enforce valid `describe()` callback | ![recommended][] | |
195195
| [valid-expect](docs/rules/valid-expect.md) | Enforce valid `expect()` usage | ![recommended][] | |
196-
| [valid-expect-in-promise](docs/rules/valid-expect-in-promise.md) | Enforce having return statement when testing with promises | ![recommended][] | |
196+
| [valid-expect-in-promise](docs/rules/valid-expect-in-promise.md) | Ensure promises that have expectations in their chain are valid | ![recommended][] | |
197197
| [valid-title](docs/rules/valid-title.md) | Enforce valid titles | ![recommended][] | ![fixable][] |
198198

199199
<!-- end base rules list -->

docs/rules/valid-expect-in-promise.md

+55-14
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,72 @@
1-
# Enforce having return statement when testing with promises (`valid-expect-in-promise`)
1+
# Ensure promises that have expectations in their chain are valid (`valid-expect-in-promise`)
22

3-
Ensure to return promise when having assertions in `then` or `catch` block of
4-
promise
3+
Ensure promises that include expectations are returned or awaited.
54

65
## Rule details
76

8-
This rule looks for tests that have assertions in `then` and `catch` methods on
9-
promises that are not returned by the test.
7+
This rule flags any promises within the body of a test that include expectations
8+
that have either not been returned or awaited.
109

11-
### Default configuration
12-
13-
The following pattern is considered warning:
10+
The following patterns is considered warning:
1411

1512
```js
16-
it('promise test', () => {
17-
somePromise.then(data => {
18-
expect(data).toEqual('foo');
13+
it('promises a person', () => {
14+
api.getPersonByName('bob').then(person => {
15+
expect(person).toHaveProperty('name', 'Bob');
16+
});
17+
});
18+
19+
it('promises a counted person', () => {
20+
const promise = api.getPersonByName('bob').then(person => {
21+
expect(person).toHaveProperty('name', 'Bob');
22+
});
23+
24+
promise.then(() => {
25+
expect(analytics.gottenPeopleCount).toBe(1);
1926
});
2027
});
28+
29+
it('promises multiple people', () => {
30+
const firstPromise = api.getPersonByName('bob').then(person => {
31+
expect(person).toHaveProperty('name', 'Bob');
32+
});
33+
const secondPromise = api.getPersonByName('alice').then(person => {
34+
expect(person).toHaveProperty('name', 'Alice');
35+
});
36+
37+
return Promise.any([firstPromise, secondPromise]);
38+
});
2139
```
2240

2341
The following pattern is not warning:
2442

2543
```js
26-
it('promise test', () => {
27-
return somePromise.then(data => {
28-
expect(data).toEqual('foo');
44+
it('promises a person', async () => {
45+
await api.getPersonByName('bob').then(person => {
46+
expect(person).toHaveProperty('name', 'Bob');
2947
});
3048
});
49+
50+
it('promises a counted person', () => {
51+
let promise = api.getPersonByName('bob').then(person => {
52+
expect(person).toHaveProperty('name', 'Bob');
53+
});
54+
55+
promise = promise.then(() => {
56+
expect(analytics.gottenPeopleCount).toBe(1);
57+
});
58+
59+
return promise;
60+
});
61+
62+
it('promises multiple people', () => {
63+
const firstPromise = api.getPersonByName('bob').then(person => {
64+
expect(person).toHaveProperty('name', 'Bob');
65+
});
66+
const secondPromise = api.getPersonByName('alice').then(person => {
67+
expect(person).toHaveProperty('name', 'Alice');
68+
});
69+
70+
return Promise.allSettled([firstPromise, secondPromise]);
71+
});
3172
```

0 commit comments

Comments
 (0)