@@ -506,4 +506,141 @@ describe('useSWR - local mutation', () => {
506
506
expect ( mutationRecivedValues ) . toEqual ( [ 0 , 1 ] )
507
507
expect ( renderRecivedValues ) . toEqual ( [ undefined , 0 , 1 , 2 ] )
508
508
} )
509
+
510
+ it ( 'async mutation case 1 (startAt <= MUTATION_TS[key])' , async ( ) => {
511
+ let result = 0
512
+ const fetcher = jest . fn ( createResponse )
513
+ function Component ( ) {
514
+ const { data, mutate : boundMutate } = useSWR (
515
+ 'mutate-7' ,
516
+ ( ) =>
517
+ fetcher ( 0 , {
518
+ delay : 300
519
+ } ) ,
520
+ {
521
+ dedupingInterval : 200
522
+ }
523
+ )
524
+ return (
525
+ < div
526
+ onClick = { ( ) => {
527
+ boundMutate ( async ( ) => {
528
+ result += 1
529
+ return createResponse ( result , {
530
+ delay : 100
531
+ } )
532
+ } , false )
533
+ } }
534
+ >
535
+ { data !== undefined ? `data: ${ data . toString ( ) } ` : 'loading' }
536
+ </ div >
537
+ )
538
+ }
539
+
540
+ render ( < Component /> )
541
+ screen . getByText ( 'loading' )
542
+
543
+ await act ( ( ) => sleep ( 50 ) )
544
+
545
+ fireEvent . click ( screen . getByText ( 'loading' ) )
546
+
547
+ await act ( ( ) => sleep ( 100 ) )
548
+ // mutate success
549
+ await screen . findByText ( 'data: 1' )
550
+
551
+ await act ( ( ) => sleep ( 150 ) )
552
+ // fetcher result should be ignored
553
+ expect ( fetcher ) . toBeCalledTimes ( 1 )
554
+ await screen . findByText ( 'data: 1' )
555
+ } )
556
+
557
+ it ( 'async mutation case 2 (startAt <= MUTATION_END_TS[key])' , async ( ) => {
558
+ let result = 0
559
+ const fetcher = jest . fn ( createResponse )
560
+ function Component ( ) {
561
+ const [ key , setKey ] = useState ( null )
562
+ const { data } = useSWR (
563
+ key ,
564
+ ( ) =>
565
+ fetcher ( 0 , {
566
+ delay : 400
567
+ } ) ,
568
+ {
569
+ dedupingInterval : 200
570
+ }
571
+ )
572
+ useEffect ( ( ) => {
573
+ mutate (
574
+ 'mutate-8' ,
575
+ async ( ) => {
576
+ result += 1
577
+ return createResponse ( result , {
578
+ delay : 200
579
+ } )
580
+ } ,
581
+ false
582
+ )
583
+ setKey ( 'mutate-8' )
584
+ } , [ ] )
585
+ return (
586
+ < div > { data !== undefined ? `data: ${ data . toString ( ) } ` : 'loading' } </ div >
587
+ )
588
+ }
589
+
590
+ render ( < Component /> )
591
+ screen . getByText ( 'loading' )
592
+
593
+ // mutate success
594
+ await act ( ( ) => sleep ( 200 ) )
595
+ fireEvent . click ( screen . getByText ( 'data: 1' ) )
596
+
597
+ // fetcher result should be ignored
598
+ await act ( ( ) => sleep ( 200 ) )
599
+ expect ( fetcher ) . toBeCalledTimes ( 1 )
600
+ await screen . findByText ( 'data: 1' )
601
+ } )
602
+
603
+ it ( 'async mutation case 3 (MUTATION_END_TS[key] === 0)' , async ( ) => {
604
+ let result = 0
605
+ const fetcher = jest . fn ( createResponse )
606
+ function Component ( ) {
607
+ const [ key , setKey ] = useState ( null )
608
+ const { data } = useSWR (
609
+ key ,
610
+ ( ) =>
611
+ fetcher ( 0 , {
612
+ delay : 100
613
+ } ) ,
614
+ {
615
+ dedupingInterval : 200
616
+ }
617
+ )
618
+ useEffect ( ( ) => {
619
+ setKey ( 'mutate-9' )
620
+ mutate (
621
+ 'mutate-9' ,
622
+ async ( ) => {
623
+ result += 1
624
+ return createResponse ( result , { delay : 200 } )
625
+ } ,
626
+ false
627
+ )
628
+ } , [ ] )
629
+ return (
630
+ < div > { data !== undefined ? `data: ${ data . toString ( ) } ` : 'loading' } </ div >
631
+ )
632
+ }
633
+
634
+ render ( < Component /> )
635
+ screen . getByText ( 'loading' )
636
+
637
+ // fetcher result should be ignored
638
+ await act ( ( ) => sleep ( 100 ) )
639
+ expect ( fetcher ) . toBeCalledTimes ( 1 )
640
+ screen . getByText ( 'loading' )
641
+
642
+ // mutate success
643
+ await act ( ( ) => sleep ( 100 ) )
644
+ await screen . findByText ( 'data: 1' )
645
+ } )
509
646
} )
0 commit comments