@@ -336,6 +336,136 @@ describe('FakeTimers', () => {
336
336
} )
337
337
} )
338
338
339
+ describe ( 'runAllTimersAsync' , ( ) => {
340
+ it ( 'runs all timers in order' , async ( ) => {
341
+ const global = { Date : FakeDate , clearTimeout, process, setTimeout, Promise }
342
+ const timers = new FakeTimers ( { global } )
343
+ timers . useFakeTimers ( )
344
+
345
+ const runOrder = [ ]
346
+ const mock1 = vi . fn ( ( ) => runOrder . push ( 'mock1' ) )
347
+ const mock2 = vi . fn ( ( ) => runOrder . push ( 'mock2' ) )
348
+ const mock3 = vi . fn ( ( ) => runOrder . push ( 'mock3' ) )
349
+ const mock4 = vi . fn ( ( ) => runOrder . push ( 'mock4' ) )
350
+ const mock5 = vi . fn ( ( ) => runOrder . push ( 'mock5' ) )
351
+ const mock6 = vi . fn ( ( ) => runOrder . push ( 'mock6' ) )
352
+
353
+ global . setTimeout ( mock1 , 100 )
354
+ global . setTimeout ( mock2 , NaN )
355
+ global . setTimeout ( mock3 , 0 )
356
+ const intervalHandler = global . setInterval ( ( ) => {
357
+ mock4 ( )
358
+ global . clearInterval ( intervalHandler )
359
+ } , 200 )
360
+ global . setTimeout ( mock5 , Infinity )
361
+ global . setTimeout ( mock6 , - Infinity )
362
+
363
+ await timers . runAllTimersAsync ( )
364
+ expect ( runOrder ) . toEqual ( [
365
+ 'mock2' ,
366
+ 'mock3' ,
367
+ 'mock5' ,
368
+ 'mock6' ,
369
+ 'mock1' ,
370
+ 'mock4' ,
371
+ ] )
372
+ } )
373
+
374
+ it ( 'warns when trying to advance timers while real timers are used' , async ( ) => {
375
+ const timers = new FakeTimers ( {
376
+ config : {
377
+ rootDir : __dirname ,
378
+ } ,
379
+ global,
380
+ } )
381
+ await expect ( timers . runAllTimersAsync ( ) ) . rejects . toThrow ( / T i m e r s a r e n o t m o c k e d / )
382
+ } )
383
+
384
+ it ( 'only runs a setTimeout callback once (ever)' , async ( ) => {
385
+ const global = { Date : FakeDate , clearTimeout, process, setTimeout, Promise }
386
+ const timers = new FakeTimers ( { global } )
387
+ timers . useFakeTimers ( )
388
+
389
+ const fn = vi . fn ( )
390
+ global . setTimeout ( fn , 0 )
391
+ expect ( fn ) . toHaveBeenCalledTimes ( 0 )
392
+
393
+ await timers . runAllTimersAsync ( )
394
+ expect ( fn ) . toHaveBeenCalledTimes ( 1 )
395
+
396
+ await timers . runAllTimersAsync ( )
397
+ expect ( fn ) . toHaveBeenCalledTimes ( 1 )
398
+ } )
399
+
400
+ it ( 'runs callbacks with arguments after the interval' , async ( ) => {
401
+ const global = { Date : FakeDate , clearTimeout, process, setTimeout, Promise }
402
+ const timers = new FakeTimers ( { global } )
403
+ timers . useFakeTimers ( )
404
+
405
+ const fn = vi . fn ( )
406
+ global . setTimeout ( fn , 0 , 'mockArg1' , 'mockArg2' )
407
+
408
+ await timers . runAllTimersAsync ( )
409
+ expect ( fn ) . toHaveBeenCalledTimes ( 1 )
410
+ expect ( fn ) . toHaveBeenCalledWith ( 'mockArg1' , 'mockArg2' )
411
+ } )
412
+
413
+ it ( 'throws before allowing infinite recursion' , async ( ) => {
414
+ const global = { Date : FakeDate , clearTimeout, process, setTimeout, Promise }
415
+ const timers = new FakeTimers ( { global, config : { loopLimit : 20 } } )
416
+ timers . useFakeTimers ( )
417
+
418
+ global . setTimeout ( function infinitelyRecursingCallback ( ) {
419
+ global . setTimeout ( infinitelyRecursingCallback , 0 )
420
+ } , 0 )
421
+
422
+ await expect (
423
+ timers . runAllTimersAsync ( ) ,
424
+ ) . rejects . toThrow (
425
+ 'Aborting after running 20 timers, assuming an infinite loop!' ,
426
+ )
427
+ } )
428
+
429
+ it ( 'also clears ticks' , async ( ) => {
430
+ const global = { Date : FakeDate , clearTimeout, process, setTimeout, Promise }
431
+ const timers = new FakeTimers ( { global } )
432
+ timers . useFakeTimers ( )
433
+
434
+ const fn = vi . fn ( )
435
+ global . setTimeout ( ( ) => {
436
+ process . nextTick ( fn )
437
+ } , 0 )
438
+ expect ( fn ) . toHaveBeenCalledTimes ( 0 )
439
+
440
+ await timers . runAllTimersAsync ( )
441
+ expect ( fn ) . toHaveBeenCalledTimes ( 1 )
442
+ } )
443
+
444
+ it ( 'all callbacks are called when setTimeout calls asynchronous method' , async ( ) => {
445
+ const global = { Date : FakeDate , clearTimeout, process, setTimeout, Promise }
446
+ const timers = new FakeTimers ( { global } )
447
+ timers . useFakeTimers ( )
448
+
449
+ const runOrder = [ ]
450
+ const mock2 = vi . fn ( async ( ) => {
451
+ runOrder . push ( 'mock2' )
452
+ return global . Promise . resolve ( true )
453
+ } )
454
+ const mock1 = vi . fn ( async ( ) => {
455
+ await mock2 ( )
456
+ runOrder . push ( 'mock1' )
457
+ } )
458
+
459
+ global . setTimeout ( mock1 , 100 )
460
+ await timers . runAllTimersAsync ( )
461
+
462
+ expect ( runOrder ) . toEqual ( [
463
+ 'mock2' ,
464
+ 'mock1' ,
465
+ ] )
466
+ } )
467
+ } )
468
+
339
469
describe ( 'advanceTimersByTime' , ( ) => {
340
470
it ( 'runs timers in order' , ( ) => {
341
471
const global = { Date : FakeDate , clearTimeout, process, setTimeout }
@@ -385,6 +515,55 @@ describe('FakeTimers', () => {
385
515
} )
386
516
} )
387
517
518
+ describe ( 'advanceTimersByTimeAsync' , ( ) => {
519
+ it ( 'runs timers in order' , async ( ) => {
520
+ const global = { Date : FakeDate , clearTimeout, clearInterval, process, setTimeout, setInterval, Promise }
521
+ const timers = new FakeTimers ( { global } )
522
+ timers . useFakeTimers ( )
523
+
524
+ const runOrder = [ ]
525
+ const mock1 = vi . fn ( ( ) => runOrder . push ( 'mock1' ) )
526
+ const mock2 = vi . fn ( ( ) => runOrder . push ( 'mock2' ) )
527
+ const mock3 = vi . fn ( ( ) => runOrder . push ( 'mock3' ) )
528
+ const mock4 = vi . fn ( ( ) => runOrder . push ( 'mock4' ) )
529
+
530
+ global . setTimeout ( mock1 , 100 )
531
+ global . setTimeout ( mock2 , 0 )
532
+ global . setTimeout ( mock3 , 0 )
533
+ global . setInterval ( ( ) => {
534
+ mock4 ( )
535
+ } , 200 )
536
+
537
+ // Move forward to t=50
538
+ await timers . advanceTimersByTimeAsync ( 50 )
539
+ expect ( runOrder ) . toEqual ( [ 'mock2' , 'mock3' ] )
540
+
541
+ // Move forward to t=60
542
+ await timers . advanceTimersByTimeAsync ( 10 )
543
+ expect ( runOrder ) . toEqual ( [ 'mock2' , 'mock3' ] )
544
+
545
+ // Move forward to t=100
546
+ await timers . advanceTimersByTimeAsync ( 40 )
547
+ expect ( runOrder ) . toEqual ( [ 'mock2' , 'mock3' , 'mock1' ] )
548
+
549
+ // Move forward to t=200
550
+ await timers . advanceTimersByTimeAsync ( 100 )
551
+ expect ( runOrder ) . toEqual ( [ 'mock2' , 'mock3' , 'mock1' , 'mock4' ] )
552
+
553
+ // Move forward to t=400
554
+ await timers . advanceTimersByTimeAsync ( 200 )
555
+ expect ( runOrder ) . toEqual ( [ 'mock2' , 'mock3' , 'mock1' , 'mock4' , 'mock4' ] )
556
+ } )
557
+
558
+ it ( 'does nothing when no timers have been scheduled' , async ( ) => {
559
+ const global = { Date : FakeDate , clearTimeout, process, setTimeout, Promise }
560
+ const timers = new FakeTimers ( { global } )
561
+ timers . useFakeTimers ( )
562
+
563
+ await timers . advanceTimersByTimeAsync ( 100 )
564
+ } )
565
+ } )
566
+
388
567
describe ( 'advanceTimersToNextTimer' , ( ) => {
389
568
it ( 'runs timers in order' , ( ) => {
390
569
const global = { Date : FakeDate , clearTimeout, process, setTimeout }
@@ -487,6 +666,108 @@ describe('FakeTimers', () => {
487
666
} )
488
667
} )
489
668
669
+ describe ( 'advanceTimersToNextTimerAsync' , ( ) => {
670
+ it ( 'runs timers in order' , async ( ) => {
671
+ const global = { Date : FakeDate , clearTimeout, process, setTimeout, Promise }
672
+ const timers = new FakeTimers ( { global } )
673
+ timers . useFakeTimers ( )
674
+
675
+ const runOrder : Array < string > = [ ]
676
+ const mock1 = vi . fn ( ( ) => runOrder . push ( 'mock1' ) )
677
+ const mock2 = vi . fn ( ( ) => runOrder . push ( 'mock2' ) )
678
+ const mock3 = vi . fn ( ( ) => runOrder . push ( 'mock3' ) )
679
+ const mock4 = vi . fn ( ( ) => runOrder . push ( 'mock4' ) )
680
+
681
+ global . setTimeout ( mock1 , 100 )
682
+ global . setTimeout ( mock2 , 0 )
683
+ global . setTimeout ( mock3 , 0 )
684
+ global . setInterval ( ( ) => {
685
+ mock4 ( )
686
+ } , 200 )
687
+
688
+ await timers . advanceTimersToNextTimer ( )
689
+ // Move forward to t=0
690
+ expect ( runOrder ) . toEqual ( [ 'mock2' , 'mock3' ] )
691
+
692
+ await timers . advanceTimersToNextTimer ( )
693
+ // Move forward to t=100
694
+ expect ( runOrder ) . toEqual ( [ 'mock2' , 'mock3' , 'mock1' ] )
695
+
696
+ await timers . advanceTimersToNextTimer ( )
697
+ // Move forward to t=200
698
+ expect ( runOrder ) . toEqual ( [ 'mock2' , 'mock3' , 'mock1' , 'mock4' ] )
699
+
700
+ await timers . advanceTimersToNextTimer ( )
701
+ // Move forward to t=400
702
+ expect ( runOrder ) . toEqual ( [ 'mock2' , 'mock3' , 'mock1' , 'mock4' , 'mock4' ] )
703
+ } )
704
+
705
+ it ( 'run correct amount of steps' , async ( ) => {
706
+ const global = { Date : FakeDate , clearTimeout, process, setTimeout, Promise }
707
+ const timers = new FakeTimers ( { global } )
708
+ timers . useFakeTimers ( )
709
+
710
+ const runOrder : Array < string > = [ ]
711
+ const mock1 = vi . fn ( ( ) => runOrder . push ( 'mock1' ) )
712
+ const mock2 = vi . fn ( ( ) => runOrder . push ( 'mock2' ) )
713
+ const mock3 = vi . fn ( ( ) => runOrder . push ( 'mock3' ) )
714
+ const mock4 = vi . fn ( ( ) => runOrder . push ( 'mock4' ) )
715
+
716
+ global . setTimeout ( mock1 , 100 )
717
+ global . setTimeout ( mock2 , 0 )
718
+ global . setTimeout ( mock3 , 0 )
719
+ global . setInterval ( ( ) => {
720
+ mock4 ( )
721
+ } , 200 )
722
+
723
+ // Move forward to t=100
724
+ await timers . advanceTimersToNextTimer ( 2 )
725
+ expect ( runOrder ) . toEqual ( [ 'mock2' , 'mock3' , 'mock1' ] )
726
+
727
+ // Move forward to t=600
728
+ await timers . advanceTimersToNextTimer ( 3 )
729
+ expect ( runOrder ) . toEqual ( [
730
+ 'mock2' ,
731
+ 'mock3' ,
732
+ 'mock1' ,
733
+ 'mock4' ,
734
+ 'mock4' ,
735
+ 'mock4' ,
736
+ ] )
737
+ } )
738
+
739
+ it ( 'setTimeout inside setTimeout' , async ( ) => {
740
+ const global = { Date : FakeDate , clearTimeout, process, setTimeout, Promise }
741
+ const timers = new FakeTimers ( { global } )
742
+ timers . useFakeTimers ( )
743
+
744
+ const runOrder : Array < string > = [ ]
745
+ const mock1 = vi . fn ( ( ) => runOrder . push ( 'mock1' ) )
746
+ const mock2 = vi . fn ( ( ) => runOrder . push ( 'mock2' ) )
747
+ const mock3 = vi . fn ( ( ) => runOrder . push ( 'mock3' ) )
748
+ const mock4 = vi . fn ( ( ) => runOrder . push ( 'mock4' ) )
749
+
750
+ global . setTimeout ( mock1 , 0 )
751
+ global . setTimeout ( ( ) => {
752
+ mock2 ( )
753
+ global . setTimeout ( mock3 , 50 )
754
+ } , 25 )
755
+ global . setTimeout ( mock4 , 100 )
756
+
757
+ // Move forward to t=75
758
+ await timers . advanceTimersToNextTimer ( 3 )
759
+ expect ( runOrder ) . toEqual ( [ 'mock1' , 'mock2' , 'mock3' ] )
760
+ } )
761
+
762
+ it ( 'does nothing when no timers have been scheduled' , async ( ) => {
763
+ const global = { Date : FakeDate , clearTimeout, process, setTimeout, Promise }
764
+ const timers = new FakeTimers ( { global } )
765
+ timers . useFakeTimers ( )
766
+
767
+ await timers . advanceTimersToNextTimer ( )
768
+ } )
769
+ } )
770
+
490
771
describe ( 'reset' , ( ) => {
491
772
it ( 'resets all pending setTimeouts' , ( ) => {
492
773
const global = { Date : FakeDate , clearTimeout, process, setTimeout }
@@ -639,6 +920,113 @@ describe('FakeTimers', () => {
639
920
} )
640
921
} )
641
922
923
+ describe ( 'runOnlyPendingTimersAsync' , ( ) => {
924
+ it ( 'runs all existing timers' , async ( ) => {
925
+ const global = {
926
+ Date : FakeDate ,
927
+ clearTimeout,
928
+ process,
929
+ setTimeout,
930
+ Promise,
931
+ }
932
+
933
+ const timers = new FakeTimers ( { global } )
934
+ timers . useFakeTimers ( )
935
+
936
+ const spies = [ vi . fn ( ) , vi . fn ( ) ]
937
+ global . setTimeout ( spies [ 0 ] , 10 )
938
+ global . setTimeout ( spies [ 1 ] , 50 )
939
+
940
+ await timers . runOnlyPendingTimersAsync ( )
941
+
942
+ expect ( spies [ 0 ] ) . toBeCalled ( )
943
+ expect ( spies [ 1 ] ) . toBeCalled ( )
944
+ } )
945
+
946
+ it ( 'runs all timers in order' , async ( ) => {
947
+ const global = {
948
+ Date : FakeDate ,
949
+ clearTimeout,
950
+ process,
951
+ setImmediate,
952
+ setTimeout,
953
+ Promise,
954
+ }
955
+
956
+ const timers = new FakeTimers ( { global } )
957
+ timers . useFakeTimers ( )
958
+
959
+ const runOrder = [ ]
960
+
961
+ global . setTimeout ( function cb ( ) {
962
+ runOrder . push ( 'mock1' )
963
+ global . setTimeout ( cb , 100 )
964
+ } , 100 )
965
+
966
+ global . setTimeout ( function cb ( ) {
967
+ runOrder . push ( 'mock2' )
968
+ global . setTimeout ( cb , 50 )
969
+ } , 0 )
970
+
971
+ global . setInterval ( ( ) => {
972
+ runOrder . push ( 'mock3' )
973
+ } , 200 )
974
+
975
+ global . setImmediate ( ( ) => {
976
+ runOrder . push ( 'mock4' )
977
+ } )
978
+
979
+ global . setImmediate ( function cb ( ) {
980
+ runOrder . push ( 'mock5' )
981
+ global . setTimeout ( cb , 400 )
982
+ } )
983
+
984
+ await timers . runOnlyPendingTimersAsync ( )
985
+ const firsRunOrder = [
986
+ 'mock4' ,
987
+ 'mock5' ,
988
+ 'mock2' ,
989
+ 'mock2' ,
990
+ 'mock1' ,
991
+ 'mock2' ,
992
+ 'mock2' ,
993
+ 'mock3' ,
994
+ 'mock1' ,
995
+ 'mock2' ,
996
+ ]
997
+
998
+ expect ( runOrder ) . toEqual ( firsRunOrder )
999
+
1000
+ await timers . runOnlyPendingTimersAsync ( )
1001
+ expect ( runOrder ) . toEqual ( [
1002
+ ...firsRunOrder ,
1003
+ 'mock2' ,
1004
+ 'mock1' ,
1005
+ 'mock2' ,
1006
+ 'mock2' ,
1007
+ 'mock3' ,
1008
+ 'mock5' ,
1009
+ 'mock1' ,
1010
+ 'mock2' ,
1011
+ ] )
1012
+ } )
1013
+
1014
+ it ( 'does not run timers that were cleared in another timer' , async ( ) => {
1015
+ const global = { Date : FakeDate , clearTimeout, process, setTimeout, Promise }
1016
+ const timers = new FakeTimers ( { global } )
1017
+ timers . useFakeTimers ( )
1018
+
1019
+ const fn = vi . fn ( )
1020
+ const timer = global . setTimeout ( fn , 10 )
1021
+ global . setTimeout ( ( ) => {
1022
+ global . clearTimeout ( timer )
1023
+ } , 0 )
1024
+
1025
+ await timers . runOnlyPendingTimersAsync ( )
1026
+ expect ( fn ) . not . toBeCalled ( )
1027
+ } )
1028
+ } )
1029
+
642
1030
describe ( 'useRealTimers' , ( ) => {
643
1031
it ( 'resets native timer APIs' , ( ) => {
644
1032
const nativeSetTimeout = vi . fn ( )
0 commit comments