Skip to content

Commit 95b88d5

Browse files
authored
feat(no-wait-for-multiple-assertions): improve autofix (#1091)
Fixes #1081
1 parent bd01e08 commit 95b88d5

File tree

2 files changed

+403
-6
lines changed

2 files changed

+403
-6
lines changed

lib/rules/no-wait-for-side-effects.ts

Lines changed: 63 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ export default createTestingLibraryRule<Options, MessageIds>({
4242
},
4343
defaultOptions: [],
4444
create(context, _, helpers) {
45+
const sourceCode = getSourceCode(context);
46+
4547
function isCallerWaitFor(
4648
node:
4749
| TSESTree.AssignmentExpression
@@ -155,8 +157,6 @@ export default createTestingLibraryRule<Options, MessageIds>({
155157
}
156158
return false;
157159
});
158-
159-
return false;
160160
}
161161

162162
function getSideEffectNodes(
@@ -195,7 +195,17 @@ export default createTestingLibraryRule<Options, MessageIds>({
195195
}) as TSESTree.ExpressionStatement[];
196196
}
197197

198-
function reportSideEffects(node: TSESTree.BlockStatement) {
198+
function reportSideEffects(
199+
node: TSESTree.BlockStatement & {
200+
parent: (
201+
| TSESTree.ArrowFunctionExpression
202+
| TSESTree.FunctionDeclaration
203+
| TSESTree.FunctionExpression
204+
) & {
205+
parent: TSESTree.CallExpression;
206+
};
207+
}
208+
) {
199209
if (!isCallerWaitFor(node)) {
200210
return;
201211
}
@@ -204,10 +214,58 @@ export default createTestingLibraryRule<Options, MessageIds>({
204214
return;
205215
}
206216

207-
getSideEffectNodes(node.body).forEach((sideEffectNode) =>
217+
const sideEffects = getSideEffectNodes(node.body);
218+
sideEffects.forEach((sideEffectNode) =>
208219
context.report({
209220
node: sideEffectNode,
210221
messageId: 'noSideEffectsWaitFor',
222+
fix(fixer) {
223+
const { parent: callExpressionNode } = node.parent;
224+
const targetNode = isAwaitExpression(callExpressionNode.parent)
225+
? callExpressionNode.parent
226+
: callExpressionNode;
227+
228+
const lines = sourceCode.getText().split('\n');
229+
const line = lines[targetNode.loc.start.line - 1];
230+
const indent = line.match(/^\s*/)?.[0] ?? '';
231+
const sideEffectLines = lines.slice(
232+
sideEffectNode.loc.start.line - 1,
233+
sideEffectNode.loc.end.line
234+
);
235+
const sideEffectNodeText = sideEffectLines.join('\n').trimStart();
236+
if (
237+
sideEffects.length === node.body.length &&
238+
sideEffects.length === 1
239+
) {
240+
const tokenAfter = sourceCode.getTokenAfter(targetNode);
241+
return [
242+
fixer.insertTextBefore(targetNode, sideEffectNodeText),
243+
tokenAfter?.value === ';'
244+
? fixer.removeRange([
245+
targetNode.range[0],
246+
tokenAfter.range[1],
247+
])
248+
: fixer.remove(targetNode),
249+
];
250+
}
251+
252+
const lineStart = sourceCode.getIndexFromLoc({
253+
line: sideEffectNode.loc.start.line,
254+
column: 0,
255+
});
256+
const lineEnd = sourceCode.getIndexFromLoc({
257+
line: sideEffectNode.loc.end.line + 1,
258+
column: 0,
259+
});
260+
261+
return [
262+
fixer.insertTextBefore(
263+
targetNode,
264+
sideEffectNodeText + '\n' + indent
265+
),
266+
fixer.removeRange([lineStart, lineEnd]),
267+
];
268+
},
211269
})
212270
);
213271
}
@@ -260,7 +318,7 @@ export default createTestingLibraryRule<Options, MessageIds>({
260318
const targetNode = isAwaitExpression(callExpressionNode.parent)
261319
? callExpressionNode.parent
262320
: callExpressionNode;
263-
const sourceCode = getSourceCode(context);
321+
264322
return fixer.replaceText(targetNode, sourceCode.getText(node));
265323
},
266324
});

0 commit comments

Comments
 (0)