Skip to content

Commit bd01e08

Browse files
authored
feat(no-wait-for-multiple-assertions): add partial fix support (#1090)
1 parent 54ee4ae commit bd01e08

File tree

4 files changed

+81
-2
lines changed

4 files changed

+81
-2
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -341,7 +341,7 @@ module.exports = [
341341
| [no-test-id-queries](docs/rules/no-test-id-queries.md) | Ensure no `data-testid` queries are used | | | |
342342
| [no-unnecessary-act](docs/rules/no-unnecessary-act.md) | Disallow wrapping Testing Library utils or empty callbacks in `act` | ![badge-marko][] ![badge-react][] | | |
343343
| [no-wait-for-multiple-assertions](docs/rules/no-wait-for-multiple-assertions.md) | Disallow the use of multiple `expect` calls inside `waitFor` | ![badge-angular][] ![badge-dom][] ![badge-marko][] ![badge-react][] ![badge-svelte][] ![badge-vue][] | | |
344-
| [no-wait-for-side-effects](docs/rules/no-wait-for-side-effects.md) | Disallow the use of side effects in `waitFor` | ![badge-angular][] ![badge-dom][] ![badge-marko][] ![badge-react][] ![badge-svelte][] ![badge-vue][] | | |
344+
| [no-wait-for-side-effects](docs/rules/no-wait-for-side-effects.md) | Disallow the use of side effects in `waitFor` | ![badge-angular][] ![badge-dom][] ![badge-marko][] ![badge-react][] ![badge-svelte][] ![badge-vue][] | | 🔧 |
345345
| [no-wait-for-snapshot](docs/rules/no-wait-for-snapshot.md) | Ensures no snapshot is generated inside of a `waitFor` call | ![badge-angular][] ![badge-dom][] ![badge-marko][] ![badge-react][] ![badge-svelte][] ![badge-vue][] | | |
346346
| [prefer-explicit-assert](docs/rules/prefer-explicit-assert.md) | Suggest using explicit assertions rather than standalone queries | | | |
347347
| [prefer-find-by](docs/rules/prefer-find-by.md) | Suggest using `find(All)By*` query instead of `waitFor` + `get(All)By*` to wait for elements | ![badge-angular][] ![badge-dom][] ![badge-marko][] ![badge-react][] ![badge-svelte][] ![badge-vue][] | | 🔧 |

docs/rules/no-wait-for-side-effects.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
💼 This rule is enabled in the following configs: `angular`, `dom`, `marko`, `react`, `svelte`, `vue`.
44

5+
🔧 This rule is automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix).
6+
57
<!-- end auto-generated rule header -->
68

79
## Rule Details

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

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { isAwaitExpression } from '@typescript-eslint/utils/ast-utils';
2+
13
import { createTestingLibraryRule } from '../create-testing-library-rule';
24
import {
35
getPropertyIdentifierNode,
@@ -8,6 +10,7 @@ import {
810
isSequenceExpression,
911
hasThenProperty,
1012
} from '../node-utils';
13+
import { getSourceCode } from '../utils';
1114

1215
import type { TSESTree } from '@typescript-eslint/utils';
1316

@@ -35,6 +38,7 @@ export default createTestingLibraryRule<Options, MessageIds>({
3538
'Avoid using side effects within `waitFor` callback',
3639
},
3740
schema: [],
41+
fixable: 'code',
3842
},
3943
defaultOptions: [],
4044
create(context, _, helpers) {
@@ -209,10 +213,19 @@ export default createTestingLibraryRule<Options, MessageIds>({
209213
}
210214

211215
function reportImplicitReturnSideEffect(
212-
node:
216+
node: (
213217
| TSESTree.AssignmentExpression
214218
| TSESTree.CallExpression
215219
| TSESTree.SequenceExpression
220+
) & {
221+
parent: (
222+
| TSESTree.ArrowFunctionExpression
223+
| TSESTree.FunctionDeclaration
224+
| TSESTree.FunctionExpression
225+
) & {
226+
parent: TSESTree.CallExpression;
227+
};
228+
}
216229
) {
217230
if (!isCallerWaitFor(node)) {
218231
return;
@@ -242,6 +255,14 @@ export default createTestingLibraryRule<Options, MessageIds>({
242255
context.report({
243256
node,
244257
messageId: 'noSideEffectsWaitFor',
258+
fix: (fixer) => {
259+
const { parent: callExpressionNode } = node.parent;
260+
const targetNode = isAwaitExpression(callExpressionNode.parent)
261+
? callExpressionNode.parent
262+
: callExpressionNode;
263+
const sourceCode = getSourceCode(context);
264+
return fixer.replaceText(targetNode, sourceCode.getText(node));
265+
},
245266
});
246267
}
247268

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

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,10 @@ ruleTester.run(RULE_NAME, rule, {
360360
await waitFor(() => render(<App />))
361361
`,
362362
errors: [{ line: 3, column: 29, messageId: 'noSideEffectsWaitFor' }],
363+
output: `
364+
import { waitFor } from '${testingFramework}';
365+
render(<App />)
366+
`,
363367
},
364368
{
365369
code: `
@@ -387,6 +391,11 @@ ruleTester.run(RULE_NAME, rule, {
387391
await waitFor(() => renderHelper(<App />))
388392
`,
389393
errors: [{ line: 4, column: 29, messageId: 'noSideEffectsWaitFor' }],
394+
output: `
395+
import { waitFor } from '${testingFramework}';
396+
import { renderHelper } from 'somewhere-else';
397+
renderHelper(<App />)
398+
`,
390399
},
391400
{
392401
settings: { 'testing-library/custom-renders': ['renderHelper'] },
@@ -428,13 +437,21 @@ ruleTester.run(RULE_NAME, rule, {
428437
await waitFor(() => result = render(<App />))
429438
`,
430439
errors: [{ line: 3, column: 29, messageId: 'noSideEffectsWaitFor' }],
440+
output: `
441+
import { waitFor } from '${testingFramework}';
442+
result = render(<App />)
443+
`,
431444
},
432445
{
433446
code: `
434447
import { waitFor } from '${testingFramework}';
435448
await waitFor(() => (a = 5, result = render(<App />)))
436449
`,
437450
errors: [{ line: 3, column: 30, messageId: 'noSideEffectsWaitFor' }],
451+
output: `
452+
import { waitFor } from '${testingFramework}';
453+
a = 5, result = render(<App />)
454+
`,
438455
},
439456
{
440457
code: `
@@ -443,20 +460,33 @@ ruleTester.run(RULE_NAME, rule, {
443460
await waitFor(() => rerender(<App />))
444461
`,
445462
errors: [{ line: 4, column: 29, messageId: 'noSideEffectsWaitFor' }],
463+
output: `
464+
import { waitFor } from '${testingFramework}';
465+
const { rerender } = render(<App />)
466+
rerender(<App />)
467+
`,
446468
},
447469
{
448470
code: `
449471
import { waitFor, render } from '${testingFramework}';
450472
await waitFor(() => render(<App />))
451473
`,
452474
errors: [{ line: 3, column: 29, messageId: 'noSideEffectsWaitFor' }],
475+
output: `
476+
import { waitFor, render } from '${testingFramework}';
477+
render(<App />)
478+
`,
453479
},
454480
{
455481
code: `
456482
import { waitFor } from '${testingFramework}';
457483
await waitFor(() => renderHelper(<App />))
458484
`,
459485
errors: [{ line: 3, column: 29, messageId: 'noSideEffectsWaitFor' }],
486+
output: `
487+
import { waitFor } from '${testingFramework}';
488+
renderHelper(<App />)
489+
`,
460490
},
461491
{
462492
code: `
@@ -465,6 +495,11 @@ ruleTester.run(RULE_NAME, rule, {
465495
await waitFor(() => render(<App />))
466496
`,
467497
errors: [{ line: 4, column: 29, messageId: 'noSideEffectsWaitFor' }],
498+
output: `
499+
import { waitFor } from '${testingFramework}';
500+
import { render } from 'somewhere-else';
501+
render(<App />)
502+
`,
468503
},
469504
]
470505
),
@@ -475,6 +510,10 @@ ruleTester.run(RULE_NAME, rule, {
475510
await waitFor(() => render(<App />))
476511
`,
477512
errors: [{ line: 3, column: 29, messageId: 'noSideEffectsWaitFor' }],
513+
output: `
514+
import { waitFor, render } from '~/test-utils';
515+
render(<App />)
516+
`,
478517
},
479518
...SUPPORTED_TESTING_FRAMEWORKS.flatMap<RuleInvalidTestCase>(
480519
(testingFramework) => [
@@ -486,6 +525,11 @@ ruleTester.run(RULE_NAME, rule, {
486525
await waitFor(() => renderWrapper(<App />))
487526
`,
488527
errors: [{ line: 4, column: 29, messageId: 'noSideEffectsWaitFor' }],
528+
output: `
529+
import { waitFor } from '${testingFramework}';
530+
import { renderWrapper } from 'somewhere-else';
531+
renderWrapper(<App />)
532+
`,
489533
},
490534
{
491535
code: `
@@ -570,6 +614,10 @@ ruleTester.run(RULE_NAME, rule, {
570614
await waitFor(() => fireEvent.keyDown(input, {key: 'ArrowDown'}))
571615
`,
572616
errors: [{ line: 3, column: 29, messageId: 'noSideEffectsWaitFor' }],
617+
output: `
618+
import { waitFor } from '${testingFramework}';
619+
fireEvent.keyDown(input, {key: 'ArrowDown'})
620+
`,
573621
})
574622
),
575623
{
@@ -579,6 +627,10 @@ ruleTester.run(RULE_NAME, rule, {
579627
await waitFor(() => fireEvent.keyDown(input, {key: 'ArrowDown'}))
580628
`,
581629
errors: [{ line: 3, column: 29, messageId: 'noSideEffectsWaitFor' }],
630+
output: `
631+
import { waitFor, fireEvent } from '~/test-utils';
632+
fireEvent.keyDown(input, {key: 'ArrowDown'})
633+
`,
582634
},
583635
...SUPPORTED_TESTING_FRAMEWORKS.flatMap<RuleInvalidTestCase>(
584636
(testingFramework) => [
@@ -674,6 +726,10 @@ ruleTester.run(RULE_NAME, rule, {
674726
await waitFor(() => userEvent.click(button))
675727
`,
676728
errors: [{ line: 3, column: 29, messageId: 'noSideEffectsWaitFor' }],
729+
output: `
730+
import { waitFor } from '${testingFramework}';
731+
userEvent.click(button)
732+
`,
677733
},
678734
{
679735
code: `

0 commit comments

Comments
 (0)