Skip to content

Commit ac99804

Browse files
committed
feat: create a fixer
1 parent 62d343c commit ac99804

File tree

1 file changed

+64
-0
lines changed

1 file changed

+64
-0
lines changed

lib/rules/await-async-queries.ts

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,12 @@ import { ASTUtils, TSESTree } from '@typescript-eslint/utils';
33
import { createTestingLibraryRule } from '../create-testing-library-rule';
44
import {
55
findClosestCallExpressionNode,
6+
findClosestFunctionExpressionNode,
67
getDeepestIdentifierNode,
78
getFunctionName,
89
getInnermostReturningFunction,
910
getVariableReferences,
11+
isMemberExpression,
1012
isPromiseHandled,
1113
} from '../node-utils';
1214

@@ -35,6 +37,7 @@ export default createTestingLibraryRule<Options, MessageIds>({
3537
asyncQueryWrapper:
3638
'promise returned from `{{ name }}` wrapper over async query must be handled',
3739
},
40+
fixable: 'code',
3841
schema: [],
3942
},
4043
defaultOptions: [],
@@ -83,6 +86,18 @@ export default createTestingLibraryRule<Options, MessageIds>({
8386
node: identifierNode,
8487
messageId: 'awaitAsyncQuery',
8588
data: { name: identifierNode.name },
89+
fix: (fixer) => {
90+
if (
91+
isMemberExpression(identifierNode.parent) &&
92+
ASTUtils.isIdentifier(identifierNode.parent.object)
93+
) {
94+
return fixer.insertTextBefore(
95+
identifierNode.parent,
96+
'await '
97+
);
98+
}
99+
return fixer.insertTextBefore(identifierNode, 'await ');
100+
},
86101
});
87102
return;
88103
}
@@ -100,6 +115,10 @@ export default createTestingLibraryRule<Options, MessageIds>({
100115
node: identifierNode,
101116
messageId: 'awaitAsyncQuery',
102117
data: { name: identifierNode.name },
118+
fix: (fixer) =>
119+
references.map((ref) =>
120+
fixer.insertTextBefore(ref.identifier, 'await ')
121+
),
103122
});
104123
return;
105124
}
@@ -113,6 +132,51 @@ export default createTestingLibraryRule<Options, MessageIds>({
113132
node: identifierNode,
114133
messageId: 'asyncQueryWrapper',
115134
data: { name: identifierNode.name },
135+
fix: (fixer) => {
136+
const functionExpression =
137+
findClosestFunctionExpressionNode(node);
138+
139+
if (!functionExpression) return null;
140+
141+
let IdentifierNodeFixer;
142+
if (isMemberExpression(identifierNode.parent)) {
143+
/**
144+
* If the wrapper is a property of an object,
145+
* add 'await' before the object, e.g.:
146+
* const obj = { wrapper: () => screen.findByText(/foo/i) };
147+
* await obj.wrapper();
148+
*/
149+
IdentifierNodeFixer = fixer.insertTextBefore(
150+
identifierNode.parent,
151+
'await '
152+
);
153+
} else {
154+
/**
155+
* Add 'await' before the wrapper function, e.g.:
156+
* const wrapper = () => screen.findByText(/foo/i);
157+
* await wrapper();
158+
*/
159+
IdentifierNodeFixer = fixer.insertTextBefore(
160+
identifierNode,
161+
'await '
162+
);
163+
}
164+
165+
if (functionExpression.async) {
166+
return IdentifierNodeFixer;
167+
} else {
168+
/**
169+
* Mutate the actual node so if other nodes exist in this
170+
* function expression body they don't also try to fix it.
171+
*/
172+
functionExpression.async = true;
173+
174+
return [
175+
IdentifierNodeFixer,
176+
fixer.insertTextBefore(functionExpression, 'async '),
177+
];
178+
}
179+
},
116180
});
117181
}
118182
},

0 commit comments

Comments
 (0)