@@ -42,6 +42,8 @@ export default createTestingLibraryRule<Options, MessageIds>({
42
42
} ,
43
43
defaultOptions : [ ] ,
44
44
create ( context , _ , helpers ) {
45
+ const sourceCode = getSourceCode ( context ) ;
46
+
45
47
function isCallerWaitFor (
46
48
node :
47
49
| TSESTree . AssignmentExpression
@@ -155,8 +157,6 @@ export default createTestingLibraryRule<Options, MessageIds>({
155
157
}
156
158
return false ;
157
159
} ) ;
158
-
159
- return false ;
160
160
}
161
161
162
162
function getSideEffectNodes (
@@ -195,7 +195,17 @@ export default createTestingLibraryRule<Options, MessageIds>({
195
195
} ) as TSESTree . ExpressionStatement [ ] ;
196
196
}
197
197
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
+ ) {
199
209
if ( ! isCallerWaitFor ( node ) ) {
200
210
return ;
201
211
}
@@ -204,10 +214,58 @@ export default createTestingLibraryRule<Options, MessageIds>({
204
214
return ;
205
215
}
206
216
207
- getSideEffectNodes ( node . body ) . forEach ( ( sideEffectNode ) =>
217
+ const sideEffects = getSideEffectNodes ( node . body ) ;
218
+ sideEffects . forEach ( ( sideEffectNode ) =>
208
219
context . report ( {
209
220
node : sideEffectNode ,
210
221
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
+ } ,
211
269
} )
212
270
) ;
213
271
}
@@ -260,7 +318,7 @@ export default createTestingLibraryRule<Options, MessageIds>({
260
318
const targetNode = isAwaitExpression ( callExpressionNode . parent )
261
319
? callExpressionNode . parent
262
320
: callExpressionNode ;
263
- const sourceCode = getSourceCode ( context ) ;
321
+
264
322
return fixer . replaceText ( targetNode , sourceCode . getText ( node ) ) ;
265
323
} ,
266
324
} ) ;
0 commit comments