Skip to content

Commit 2d24966

Browse files
authored
fix: declare .finally(...) usages as handled in async rules (#1074)
1 parent 9ba0041 commit 2d24966

File tree

6 files changed

+43
-6
lines changed

6 files changed

+43
-6
lines changed

docs/rules/await-async-queries.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ problems in the tests. The promise will be considered as handled when:
2323

2424
- using the `await` operator
2525
- wrapped within `Promise.all` or `Promise.allSettled` methods
26-
- chaining the `then` or `catch` method
26+
- chaining the `then`, `catch`, `finally` method
2727
- chaining `resolves` or `rejects` from jest
2828
- chaining `toResolve()` or `toReject()` from [jest-extended](https://github.com/jest-community/jest-extended#promise)
2929
- chaining jasmine [async matchers](https://jasmine.github.io/api/edge/async-matchers.html)

docs/rules/await-async-utils.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ problems in the tests. The promise will be considered as handled when:
2121

2222
- using the `await` operator
2323
- wrapped within `Promise.all` or `Promise.allSettled` methods
24-
- chaining the `then` or `catch` method
24+
- chaining the `then`, `catch`, `finally` method
2525
- chaining `resolves` or `rejects` from jest
2626
- chaining `toResolve()` or `toReject()` from [jest-extended](https://github.com/jest-community/jest-extended#promise)
2727
- chaining jasmine [async matchers](https://jasmine.github.io/api/edge/async-matchers.html)

lib/node-utils/index.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -152,19 +152,19 @@ export function hasPromiseHandlerProperty(node: TSESTree.Node): boolean {
152152
return (
153153
isMemberExpression(node) &&
154154
ASTUtils.isIdentifier(node.property) &&
155-
['then', 'catch'].includes(node.property.name)
155+
['then', 'catch', 'finally'].includes(node.property.name)
156156
);
157157
}
158158

159159
export function hasChainedPromiseHandler(node: TSESTree.Node): boolean {
160160
const parent = node.parent;
161161

162-
// wait(...).then(...) or wait(...).catch(...)
162+
// wait(...).then(...) or wait(...).catch(...) or wait(...).finally(...)
163163
if (isCallExpression(parent) && parent.parent) {
164164
return hasPromiseHandlerProperty(parent.parent);
165165
}
166166

167-
// promise.then(...) or promise.catch(...)
167+
// promise.then(...) or promise.catch(...) or promise(...).finally(...)
168168
return !!parent && hasPromiseHandlerProperty(parent);
169169
}
170170

@@ -219,7 +219,7 @@ export function isPromisesArrayResolved(node: TSESTree.Node): boolean {
219219
* - it belongs to the `await` expression
220220
* - it belongs to the `Promise.all` method
221221
* - it belongs to the `Promise.allSettled` method
222-
* - it's chained with the `then` or `catch` method
222+
* - it's chained with the `then`, `catch`, `finally` method
223223
* - it's returned from a function
224224
* - has `resolves` or `rejects` jest methods
225225
* - has `toResolve` or `toReject` jest-extended matchers

tests/lib/rules/await-async-events.test.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,16 @@ ruleTester.run(RULE_NAME, rule, {
108108
`,
109109
options: [{ eventModule: 'fireEvent' }] as const,
110110
})),
111+
...FIRE_EVENT_ASYNC_FUNCTIONS.map((eventMethod) => ({
112+
code: `
113+
import { fireEvent } from '${testingFramework}'
114+
test('chain finally method to promise from event method is valid', async (done) => {
115+
fireEvent.${eventMethod}(getByLabelText('username'))
116+
.finally(() => { done() })
117+
})
118+
`,
119+
options: [{ eventModule: 'fireEvent' }] as const,
120+
})),
111121
{
112122
code: `
113123
import { fireEvent } from '${testingFramework}'
@@ -349,6 +359,16 @@ ruleTester.run(RULE_NAME, rule, {
349359
...USER_EVENT_ASYNC_FUNCTIONS.map((eventMethod) => ({
350360
code: `
351361
import userEvent from '${testingFramework}'
362+
test('chain finally method to promise from event method is valid', async (done) => {
363+
userEvent.${eventMethod}(getByLabelText('username'))
364+
.finally(() => { done() })
365+
})
366+
`,
367+
options: [{ eventModule: 'userEvent' }] as const,
368+
})),
369+
...USER_EVENT_ASYNC_FUNCTIONS.map((eventMethod) => ({
370+
code: `
371+
import userEvent from '${testingFramework}'
352372
test('chain then method to several promises from event methods is valid', async (done) => {
353373
userEvent.${eventMethod}(getByLabelText('username')).then(() => {
354374
userEvent.${eventMethod}(getByLabelText('username')).then(() => { done() })

tests/lib/rules/await-async-queries.test.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,14 @@ ruleTester.run(RULE_NAME, rule, {
177177
`
178178
),
179179

180+
// async queries are valid with finally
181+
...createTestCase(
182+
(query) => `
183+
const promise = ${query}('foo')
184+
promise.finally((done) => done())
185+
`
186+
),
187+
180188
// async queries are valid when wrapped within Promise.all + await expression
181189
...createTestCase(
182190
(query) => `

tests/lib/rules/await-async-utils.test.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,15 @@ ruleTester.run(RULE_NAME, rule, {
7171
...ASYNC_UTILS.map<RuleValidTestCase>((asyncUtil) => ({
7272
code: `
7373
import { ${asyncUtil} } from '${testingFramework}';
74+
test('${asyncUtil} util directly chained with finally is valid', () => {
75+
doSomethingElse();
76+
${asyncUtil}(() => getByLabelText('email')).finally(() => { console.log('done') });
77+
});
78+
`,
79+
})),
80+
...ASYNC_UTILS.map((asyncUtil) => ({
81+
code: `
82+
import { ${asyncUtil} } from '${testingFramework}';
7483
test('${asyncUtil} util expect chained with .resolves is valid', () => {
7584
doSomethingElse();
7685
expect(${asyncUtil}(() => getByLabelText('email'))).resolves.toBe("foo");

0 commit comments

Comments
 (0)