1
+ import { InvalidTestCase , ValidTestCase } from '@typescript-eslint/rule-tester' ;
1
2
import { TSESLint } from '@typescript-eslint/utils' ;
2
3
3
- import rule , { RULE_NAME } from '../../../lib/rules/await-async-queries' ;
4
+ import rule , {
5
+ RULE_NAME ,
6
+ MessageIds ,
7
+ } from '../../../lib/rules/await-async-queries' ;
4
8
import {
5
9
ASYNC_QUERIES_COMBINATIONS ,
6
10
ASYNC_QUERIES_VARIANTS ,
@@ -11,6 +15,9 @@ import { createRuleTester } from '../test-utils';
11
15
12
16
const ruleTester = createRuleTester ( ) ;
13
17
18
+ type RuleValidTestCase = ValidTestCase < [ ] > ;
19
+ type RuleInvalidTestCase = InvalidTestCase < MessageIds , [ ] > ;
20
+
14
21
const SUPPORTED_TESTING_FRAMEWORKS = [
15
22
'@testing-library/dom' ,
16
23
'@testing-library/angular' ,
@@ -306,10 +313,8 @@ ruleTester.run(RULE_NAME, rule, {
306
313
} ) ) ,
307
314
308
315
// handled promise assigned to variable returned from async query wrapper is valid
309
- ...ALL_ASYNC_COMBINATIONS_TO_TEST . map (
310
- ( query ) =>
311
- ( {
312
- code : `
316
+ ...ALL_ASYNC_COMBINATIONS_TO_TEST . map < RuleValidTestCase > ( ( query ) => ( {
317
+ code : `
313
318
const queryWrapper = () => {
314
319
return screen.${ query } ('foo')
315
320
}
@@ -319,8 +324,7 @@ ruleTester.run(RULE_NAME, rule, {
319
324
expect(element).toBeVisible()
320
325
})
321
326
` ,
322
- } ) as const
323
- ) ,
327
+ } ) ) ,
324
328
325
329
// non-matching query is valid
326
330
`
@@ -413,66 +417,78 @@ ruleTester.run(RULE_NAME, rule, {
413
417
414
418
invalid : [
415
419
...SUPPORTED_TESTING_FRAMEWORKS . flatMap ( ( testingFramework ) =>
416
- ALL_ASYNC_COMBINATIONS_TO_TEST . map (
417
- ( query ) =>
418
- ( {
419
- code : `// async queries without await operator or then method are not valid
420
+ ALL_ASYNC_COMBINATIONS_TO_TEST . map < RuleInvalidTestCase > ( ( query ) => ( {
421
+ code : `// async queries without await operator or then method are not valid
420
422
import { render } from '${ testingFramework } '
421
423
422
424
test("An example test", async () => {
423
425
doSomething()
424
426
const foo = ${ query } ('foo')
425
427
});
426
428
` ,
427
- errors : [ { messageId : 'awaitAsyncQuery' , line : 6 , column : 21 } ] ,
428
- } ) as const
429
- )
429
+ errors : [ { messageId : 'awaitAsyncQuery' , line : 6 , column : 21 } ] ,
430
+ output : `// async queries without await operator or then method are not valid
431
+ import { render } from '${ testingFramework } '
432
+
433
+ test("An example test", async () => {
434
+ doSomething()
435
+ const foo = await ${ query } ('foo')
436
+ });
437
+ ` ,
438
+ } ) )
430
439
) ,
431
- ...ALL_ASYNC_COMBINATIONS_TO_TEST . map (
432
- ( query ) =>
433
- ( {
434
- code : `// async screen queries without await operator or then method are not valid
440
+ ...ALL_ASYNC_COMBINATIONS_TO_TEST . map < RuleInvalidTestCase > ( ( query ) => ( {
441
+ code : `// async screen queries without await operator or then method are not valid
435
442
import { render } from '@testing-library/react'
436
443
437
444
test("An example test", async () => {
438
445
screen.${ query } ('foo')
439
446
});
440
447
` ,
441
- errors : [
442
- {
443
- messageId : 'awaitAsyncQuery' ,
444
- line : 5 ,
445
- column : 16 ,
446
- data : { name : query } ,
447
- } ,
448
- ] ,
449
- } ) as const
450
- ) ,
451
- ...ALL_ASYNC_COMBINATIONS_TO_TEST . map (
452
- ( query ) =>
453
- ( {
454
- code : `
448
+ errors : [
449
+ {
450
+ messageId : 'awaitAsyncQuery' ,
451
+ line : 5 ,
452
+ column : 16 ,
453
+ data : { name : query } ,
454
+ } ,
455
+ ] ,
456
+ output : `// async screen queries without await operator or then method are not valid
457
+ import { render } from '@testing-library/react'
458
+
459
+ test("An example test", async () => {
460
+ await screen.${ query } ('foo')
461
+ });
462
+ ` ,
463
+ } ) ) ,
464
+ ...ALL_ASYNC_COMBINATIONS_TO_TEST . map < RuleInvalidTestCase > ( ( query ) => ( {
465
+ code : `
455
466
import { render } from '@testing-library/react'
456
467
457
468
test("An example test", async () => {
458
469
doSomething()
459
470
const foo = ${ query } ('foo')
460
471
});
461
472
` ,
462
- errors : [
463
- {
464
- messageId : 'awaitAsyncQuery' ,
465
- line : 6 ,
466
- column : 21 ,
467
- data : { name : query } ,
468
- } ,
469
- ] ,
470
- } ) as const
471
- ) ,
472
- ...ALL_ASYNC_COMBINATIONS_TO_TEST . map (
473
- ( query ) =>
474
- ( {
475
- code : `
473
+ errors : [
474
+ {
475
+ messageId : 'awaitAsyncQuery' ,
476
+ line : 6 ,
477
+ column : 21 ,
478
+ data : { name : query } ,
479
+ } ,
480
+ ] ,
481
+ output : `
482
+ import { render } from '@testing-library/react'
483
+
484
+ test("An example test", async () => {
485
+ doSomething()
486
+ const foo = await ${ query } ('foo')
487
+ });
488
+ ` ,
489
+ } ) ) ,
490
+ ...ALL_ASYNC_COMBINATIONS_TO_TEST . map < RuleInvalidTestCase > ( ( query ) => ( {
491
+ code : `
476
492
import { render } from '@testing-library/react'
477
493
478
494
test("An example test", async () => {
@@ -481,37 +497,47 @@ ruleTester.run(RULE_NAME, rule, {
481
497
expect(foo).toHaveAttribute('src', 'bar');
482
498
});
483
499
` ,
484
- errors : [
485
- {
486
- messageId : 'awaitAsyncQuery' ,
487
- line : 5 ,
488
- column : 21 ,
489
- data : { name : query } ,
490
- } ,
491
- ] ,
492
- } ) as const
493
- ) ,
500
+ errors : [
501
+ {
502
+ messageId : 'awaitAsyncQuery' ,
503
+ line : 5 ,
504
+ column : 21 ,
505
+ data : { name : query } ,
506
+ } ,
507
+ ] ,
508
+ output : `
509
+ import { render } from '@testing-library/react'
510
+
511
+ test("An example test", async () => {
512
+ const foo = ${ query } ('foo')
513
+ expect(await foo).toBeInTheDocument()
514
+ expect(await foo).toHaveAttribute('src', 'bar');
515
+ });
516
+ ` ,
517
+ } ) ) ,
494
518
495
519
// unresolved async queries are not valid (aggressive reporting)
496
- ...ALL_ASYNC_COMBINATIONS_TO_TEST . map (
497
- ( query ) =>
498
- ( {
499
- code : `
520
+ ...ALL_ASYNC_COMBINATIONS_TO_TEST . map < RuleInvalidTestCase > ( ( query ) => ( {
521
+ code : `
500
522
import { render } from "another-library"
501
523
502
524
test('An example test', async () => {
503
525
const example = ${ query } ("my example")
504
526
})
505
527
` ,
506
- errors : [ { messageId : 'awaitAsyncQuery' , line : 5 , column : 27 } ] ,
507
- } ) as const
508
- ) ,
528
+ errors : [ { messageId : 'awaitAsyncQuery' , line : 5 , column : 27 } ] ,
529
+ output : `
530
+ import { render } from "another-library"
531
+
532
+ test('An example test', async () => {
533
+ const example = await ${ query } ("my example")
534
+ })
535
+ ` ,
536
+ } ) ) ,
509
537
510
538
// unhandled promise from async query function wrapper is invalid
511
- ...ALL_ASYNC_COMBINATIONS_TO_TEST . map (
512
- ( query ) =>
513
- ( {
514
- code : `
539
+ ...ALL_ASYNC_COMBINATIONS_TO_TEST . map < RuleInvalidTestCase > ( ( query ) => ( {
540
+ code : `
515
541
function queryWrapper() {
516
542
doSomethingElse();
517
543
@@ -526,14 +552,26 @@ ruleTester.run(RULE_NAME, rule, {
526
552
const element = await queryWrapper()
527
553
})
528
554
` ,
529
- errors : [ { messageId : 'asyncQueryWrapper' , line : 9 , column : 27 } ] ,
530
- } ) as const
531
- ) ,
555
+ errors : [ { messageId : 'asyncQueryWrapper' , line : 9 , column : 27 } ] ,
556
+ output : `
557
+ function queryWrapper() {
558
+ doSomethingElse();
559
+
560
+ return screen.${ query } ('foo')
561
+ }
562
+
563
+ test("An invalid example test", async () => {
564
+ const element = await queryWrapper()
565
+ })
566
+
567
+ test("An invalid example test", async () => {
568
+ const element = await queryWrapper()
569
+ })
570
+ ` ,
571
+ } ) ) ,
532
572
// unhandled promise from async query arrow function wrapper is invalid
533
- ...ALL_ASYNC_COMBINATIONS_TO_TEST . map (
534
- ( query ) =>
535
- ( {
536
- code : `
573
+ ...ALL_ASYNC_COMBINATIONS_TO_TEST . map < RuleInvalidTestCase > ( ( query ) => ( {
574
+ code : `
537
575
const queryWrapper = () => {
538
576
doSomethingElse();
539
577
@@ -548,14 +586,26 @@ ruleTester.run(RULE_NAME, rule, {
548
586
const element = await queryWrapper()
549
587
})
550
588
` ,
551
- errors : [ { messageId : 'asyncQueryWrapper' , line : 9 , column : 27 } ] ,
552
- } ) as const
553
- ) ,
589
+ errors : [ { messageId : 'asyncQueryWrapper' , line : 9 , column : 27 } ] ,
590
+ output : `
591
+ const queryWrapper = () => {
592
+ doSomethingElse();
593
+
594
+ return ${ query } ('foo')
595
+ }
596
+
597
+ test("An invalid example test", async () => {
598
+ const element = await queryWrapper()
599
+ })
600
+
601
+ test("An invalid example test", async () => {
602
+ const element = await queryWrapper()
603
+ })
604
+ ` ,
605
+ } ) ) ,
554
606
// unhandled promise implicitly returned from async query arrow function wrapper is invalid
555
- ...ALL_ASYNC_COMBINATIONS_TO_TEST . map (
556
- ( query ) =>
557
- ( {
558
- code : `
607
+ ...ALL_ASYNC_COMBINATIONS_TO_TEST . map < RuleInvalidTestCase > ( ( query ) => ( {
608
+ code : `
559
609
const queryWrapper = () => screen.${ query } ('foo')
560
610
561
611
test("An invalid example test", () => {
@@ -566,9 +616,19 @@ ruleTester.run(RULE_NAME, rule, {
566
616
const element = await queryWrapper()
567
617
})
568
618
` ,
569
- errors : [ { messageId : 'asyncQueryWrapper' , line : 5 , column : 27 } ] ,
570
- } ) as const
571
- ) ,
619
+ errors : [ { messageId : 'asyncQueryWrapper' , line : 5 , column : 27 } ] ,
620
+ output : `
621
+ const queryWrapper = () => screen.${ query } ('foo')
622
+
623
+ test("An invalid example test", async () => {
624
+ const element = await queryWrapper()
625
+ })
626
+
627
+ test("An invalid example test", async () => {
628
+ const element = await queryWrapper()
629
+ })
630
+ ` ,
631
+ } ) ) ,
572
632
573
633
// unhandled promise from custom query matching custom-queries setting is invalid
574
634
{
@@ -581,6 +641,11 @@ ruleTester.run(RULE_NAME, rule, {
581
641
})
582
642
` ,
583
643
errors : [ { messageId : 'awaitAsyncQuery' , line : 3 , column : 25 } ] ,
644
+ output : `
645
+ test('An invalid example test', () => {
646
+ const element = await findByIcon('search')
647
+ })
648
+ ` ,
584
649
} ,
585
650
586
651
{
@@ -609,6 +674,30 @@ ruleTester.run(RULE_NAME, rule, {
609
674
})
610
675
` ,
611
676
errors : [ { messageId : 'asyncQueryWrapper' , line : 19 , column : 34 } ] ,
677
+ output : `// similar to issue #359 but forcing an error in no-awaited wrapper
678
+ import { render, screen } from 'mocks/test-utils'
679
+ import userEvent from '@testing-library/user-event'
680
+
681
+ const testData = {
682
+ name: 'John Doe',
683
+
684
+ password: 'extremeSecret',
685
+ }
686
+
687
+ const selectors = {
688
+ username: () => screen.findByRole('textbox', { name: /username/i }),
689
+ email: () => screen.findByRole('textbox', { name: /e-mail/i }),
690
+ password: () => screen.findByLabelText(/password/i),
691
+ }
692
+
693
+ test('this is a valid case', async () => {
694
+ render(<SomeComponent />)
695
+ userEvent.type(await selectors.username(), testData.name) // <-- unhandled here
696
+ userEvent.type(await selectors.email(), testData.email)
697
+ userEvent.type(await selectors.password(), testData.password)
698
+ // ...
699
+ })
700
+ ` ,
612
701
} ,
613
702
] ,
614
703
} ) ;
0 commit comments