@@ -3,17 +3,19 @@ import { ASTUtils } from '@typescript-eslint/utils';
33import { createTestingLibraryRule } from '../create-testing-library-rule' ;
44import {
55 findClosestCallExpressionNode ,
6+ findClosestFunctionExpressionNode ,
67 getDeepestIdentifierNode ,
78 getFunctionName ,
89 getInnermostReturningFunction ,
10+ getReferenceNode ,
911 getVariableReferences ,
1012 isCallExpression ,
1113 isObjectPattern ,
1214 isPromiseHandled ,
1315 isProperty ,
1416} from '../node-utils' ;
1517
16- import type { TSESTree } from '@typescript-eslint/utils' ;
18+ import type { TSESLint , TSESTree } from '@typescript-eslint/utils' ;
1719
1820export const RULE_NAME = 'await-async-utils' ;
1921export type MessageIds = 'asyncUtilWrapper' | 'awaitAsyncUtil' ;
@@ -40,6 +42,7 @@ export default createTestingLibraryRule<Options, MessageIds>({
4042 'Promise returned from {{ name }} wrapper over async util must be handled' ,
4143 } ,
4244 schema : [ ] ,
45+ fixable : 'code' ,
4346 } ,
4447 defaultOptions : [ ] ,
4548
@@ -90,6 +93,33 @@ export default createTestingLibraryRule<Options, MessageIds>({
9093 }
9194 }
9295 }
96+ function wrapWithFunctionExpressionFix (
97+ fixer : TSESLint . RuleFixer ,
98+ ruleFix : TSESLint . RuleFix ,
99+ functionExpression :
100+ | TSESTree . ArrowFunctionExpression
101+ | TSESTree . FunctionDeclaration
102+ | TSESTree . FunctionExpression
103+ | null
104+ ) {
105+ if ( functionExpression && ! functionExpression . async ) {
106+ /**
107+ * Mutate the actual node so if other nodes exist in this
108+ * function expression body they don't also try to fix it.
109+ */
110+ functionExpression . async = true ;
111+
112+ return [ ruleFix , fixer . insertTextBefore ( functionExpression , 'async ' ) ] ;
113+ }
114+ return ruleFix ;
115+ }
116+
117+ function insertAwaitBeforeNode (
118+ fixer : TSESLint . RuleFixer ,
119+ node : TSESTree . Node
120+ ) {
121+ return fixer . insertTextBefore ( node , 'await ' ) ;
122+ }
93123
94124 /*
95125 Either we report a direct usage of an async util or a usage of a wrapper
@@ -155,6 +185,7 @@ export default createTestingLibraryRule<Options, MessageIds>({
155185 context ,
156186 closestCallExpression . parent
157187 ) ;
188+ const functionExpression = findClosestFunctionExpressionNode ( node ) ;
158189
159190 if ( references . length === 0 ) {
160191 if ( ! isPromiseHandled ( callExpressionIdentifier ) ) {
@@ -164,6 +195,17 @@ export default createTestingLibraryRule<Options, MessageIds>({
164195 data : {
165196 name : callExpressionIdentifier . name ,
166197 } ,
198+ fix : ( fixer ) => {
199+ const referenceNode = getReferenceNode (
200+ callExpressionIdentifier
201+ ) ;
202+ const awaitFix = insertAwaitBeforeNode ( fixer , referenceNode ) ;
203+ return wrapWithFunctionExpressionFix (
204+ fixer ,
205+ awaitFix ,
206+ functionExpression
207+ ) ;
208+ } ,
167209 } ) ;
168210 }
169211 } else {
@@ -176,6 +218,14 @@ export default createTestingLibraryRule<Options, MessageIds>({
176218 data : {
177219 name : callExpressionIdentifier . name ,
178220 } ,
221+ fix : ( fixer ) => {
222+ const awaitFix = insertAwaitBeforeNode ( fixer , referenceNode ) ;
223+ return wrapWithFunctionExpressionFix (
224+ fixer ,
225+ awaitFix ,
226+ functionExpression
227+ ) ;
228+ } ,
179229 } ) ;
180230 return ;
181231 }
0 commit comments