@@ -517,6 +517,45 @@ describe('scheduler', () => {
517
517
await nextTick ( )
518
518
} )
519
519
520
+ test ( 'jobs can be re-queued after an error' , async ( ) => {
521
+ const err = new Error ( 'test' )
522
+ let shouldThrow = true
523
+
524
+ const job1 : SchedulerJob = vi . fn ( ( ) => {
525
+ if ( shouldThrow ) {
526
+ shouldThrow = false
527
+ throw err
528
+ }
529
+ } )
530
+ job1 . id = 1
531
+
532
+ const job2 : SchedulerJob = vi . fn ( )
533
+ job2 . id = 2
534
+
535
+ queueJob ( job1 )
536
+ queueJob ( job2 )
537
+
538
+ try {
539
+ await nextTick ( )
540
+ } catch ( e : any ) {
541
+ expect ( e ) . toBe ( err )
542
+ }
543
+ expect (
544
+ `Unhandled error during execution of scheduler flush` ,
545
+ ) . toHaveBeenWarned ( )
546
+
547
+ expect ( job1 ) . toHaveBeenCalledTimes ( 1 )
548
+ expect ( job2 ) . toHaveBeenCalledTimes ( 0 )
549
+
550
+ queueJob ( job1 )
551
+ queueJob ( job2 )
552
+
553
+ await nextTick ( )
554
+
555
+ expect ( job1 ) . toHaveBeenCalledTimes ( 2 )
556
+ expect ( job2 ) . toHaveBeenCalledTimes ( 1 )
557
+ } )
558
+
520
559
test ( 'should prevent self-triggering jobs by default' , async ( ) => {
521
560
let count = 0
522
561
const job = ( ) => {
@@ -558,6 +597,113 @@ describe('scheduler', () => {
558
597
expect ( count ) . toBe ( 5 )
559
598
} )
560
599
600
+ test ( 'recursive jobs can only be queued once non-recursively' , async ( ) => {
601
+ const job : SchedulerJob = vi . fn ( )
602
+ job . id = 1
603
+ job . flags = SchedulerJobFlags . ALLOW_RECURSE
604
+
605
+ queueJob ( job )
606
+ queueJob ( job )
607
+
608
+ await nextTick ( )
609
+
610
+ expect ( job ) . toHaveBeenCalledTimes ( 1 )
611
+ } )
612
+
613
+ test ( 'recursive jobs can only be queued once recursively' , async ( ) => {
614
+ let recurse = true
615
+
616
+ const job : SchedulerJob = vi . fn ( ( ) => {
617
+ if ( recurse ) {
618
+ queueJob ( job )
619
+ queueJob ( job )
620
+ recurse = false
621
+ }
622
+ } )
623
+ job . id = 1
624
+ job . flags = SchedulerJobFlags . ALLOW_RECURSE
625
+
626
+ queueJob ( job )
627
+
628
+ await nextTick ( )
629
+
630
+ expect ( job ) . toHaveBeenCalledTimes ( 2 )
631
+ } )
632
+
633
+ test ( `recursive jobs can't be re-queued by other jobs` , async ( ) => {
634
+ let recurse = true
635
+
636
+ const job1 : SchedulerJob = ( ) => {
637
+ if ( recurse ) {
638
+ // job2 is already queued, so this shouldn't do anything
639
+ queueJob ( job2 )
640
+ recurse = false
641
+ }
642
+ }
643
+ job1 . id = 1
644
+
645
+ const job2 : SchedulerJob = vi . fn ( ( ) => {
646
+ if ( recurse ) {
647
+ queueJob ( job1 )
648
+ queueJob ( job2 )
649
+ }
650
+ } )
651
+ job2 . id = 2
652
+ job2 . flags = SchedulerJobFlags . ALLOW_RECURSE
653
+
654
+ queueJob ( job2 )
655
+
656
+ await nextTick ( )
657
+
658
+ expect ( job2 ) . toHaveBeenCalledTimes ( 2 )
659
+ } )
660
+
661
+ test ( 'jobs are de-duplicated correctly when calling flushPreFlushCbs' , async ( ) => {
662
+ let recurse = true
663
+
664
+ const job1 : SchedulerJob = vi . fn ( ( ) => {
665
+ queueJob ( job3 )
666
+ queueJob ( job3 )
667
+ flushPreFlushCbs ( )
668
+ } )
669
+ job1 . id = 1
670
+ job1 . flags = SchedulerJobFlags . PRE
671
+
672
+ const job2 : SchedulerJob = vi . fn ( ( ) => {
673
+ if ( recurse ) {
674
+ // job2 does not allow recurse, so this shouldn't do anything
675
+ queueJob ( job2 )
676
+
677
+ // job3 is already queued, so this shouldn't do anything
678
+ queueJob ( job3 )
679
+ recurse = false
680
+ }
681
+ } )
682
+ job2 . id = 2
683
+ job2 . flags = SchedulerJobFlags . PRE
684
+
685
+ const job3 : SchedulerJob = vi . fn ( ( ) => {
686
+ if ( recurse ) {
687
+ queueJob ( job2 )
688
+ queueJob ( job3 )
689
+
690
+ // The jobs are already queued, so these should have no effect
691
+ queueJob ( job2 )
692
+ queueJob ( job3 )
693
+ }
694
+ } )
695
+ job3 . id = 3
696
+ job3 . flags = SchedulerJobFlags . ALLOW_RECURSE | SchedulerJobFlags . PRE
697
+
698
+ queueJob ( job1 )
699
+
700
+ await nextTick ( )
701
+
702
+ expect ( job1 ) . toHaveBeenCalledTimes ( 1 )
703
+ expect ( job2 ) . toHaveBeenCalledTimes ( 1 )
704
+ expect ( job3 ) . toHaveBeenCalledTimes ( 2 )
705
+ } )
706
+
561
707
// #1947 flushPostFlushCbs should handle nested calls
562
708
// e.g. app.mount inside app.mount
563
709
test ( 'flushPostFlushCbs' , async ( ) => {
0 commit comments