await nextTick()
})
+ test('jobs can be re-queued after an error', async () => {
+ const err = new Error('test')
+ let shouldThrow = true
+
+ const job1: SchedulerJob = vi.fn(() => {
+ if (shouldThrow) {
+ shouldThrow = false
+ throw err
+ }
+ })
+ job1.id = 1
+
+ const job2: SchedulerJob = vi.fn()
+ job2.id = 2
+
+ queueJob(job1)
+ queueJob(job2)
+
+ try {
+ await nextTick()
+ } catch (e: any) {
+ expect(e).toBe(err)
+ }
+ expect(
+ `Unhandled error during execution of scheduler flush`,
+ ).toHaveBeenWarned()
+
+ expect(job1).toHaveBeenCalledTimes(1)
+ expect(job2).toHaveBeenCalledTimes(0)
+
+ queueJob(job1)
+ queueJob(job2)
+
+ await nextTick()
+
+ expect(job1).toHaveBeenCalledTimes(2)
+ expect(job2).toHaveBeenCalledTimes(1)
+ })
+
test('should prevent self-triggering jobs by default', async () => {
let count = 0
const job = () => {
expect(count).toBe(5)
})
+ test('recursive jobs can only be queued once non-recursively', async () => {
+ const job: SchedulerJob = vi.fn()
+ job.id = 1
+ job.flags = SchedulerJobFlags.ALLOW_RECURSE
+
+ queueJob(job)
+ queueJob(job)
+
+ await nextTick()
+
+ expect(job).toHaveBeenCalledTimes(1)
+ })
+
+ test('recursive jobs can only be queued once recursively', async () => {
+ let recurse = true
+
+ const job: SchedulerJob = vi.fn(() => {
+ if (recurse) {
+ queueJob(job)
+ queueJob(job)
+ recurse = false
+ }
+ })
+ job.id = 1
+ job.flags = SchedulerJobFlags.ALLOW_RECURSE
+
+ queueJob(job)
+
+ await nextTick()
+
+ expect(job).toHaveBeenCalledTimes(2)
+ })
+
+ test(`recursive jobs can't be re-queued by other jobs`, async () => {
+ let recurse = true
+
+ const job1: SchedulerJob = () => {
+ if (recurse) {
+ // job2 is already queued, so this shouldn't do anything
+ queueJob(job2)
+ recurse = false
+ }
+ }
+ job1.id = 1
+
+ const job2: SchedulerJob = vi.fn(() => {
+ if (recurse) {
+ queueJob(job1)
+ queueJob(job2)
+ }
+ })
+ job2.id = 2
+ job2.flags = SchedulerJobFlags.ALLOW_RECURSE
+
+ queueJob(job2)
+
+ await nextTick()
+
+ expect(job2).toHaveBeenCalledTimes(2)
+ })
+
+ test('jobs are de-duplicated correctly when calling flushPreFlushCbs', async () => {
+ let recurse = true
+
+ const job1: SchedulerJob = vi.fn(() => {
+ queueJob(job3)
+ queueJob(job3)
+ flushPreFlushCbs()
+ })
+ job1.id = 1
+ job1.flags = SchedulerJobFlags.PRE
+
+ const job2: SchedulerJob = vi.fn(() => {
+ if (recurse) {
+ // job2 does not allow recurse, so this shouldn't do anything
+ queueJob(job2)
+
+ // job3 is already queued, so this shouldn't do anything
+ queueJob(job3)
+ recurse = false
+ }
+ })
+ job2.id = 2
+ job2.flags = SchedulerJobFlags.PRE
+
+ const job3: SchedulerJob = vi.fn(() => {
+ if (recurse) {
+ queueJob(job2)
+ queueJob(job3)
+
+ // The jobs are already queued, so these should have no effect
+ queueJob(job2)
+ queueJob(job3)
+ }
+ })
+ job3.id = 3
+ job3.flags = SchedulerJobFlags.ALLOW_RECURSE | SchedulerJobFlags.PRE
+
+ queueJob(job1)
+
+ await nextTick()
+
+ expect(job1).toHaveBeenCalledTimes(1)
+ expect(job2).toHaveBeenCalledTimes(1)
+ expect(job3).toHaveBeenCalledTimes(2)
+ })
+
// #1947 flushPostFlushCbs should handle nested calls
// e.g. app.mount inside app.mount
test('flushPostFlushCbs', async () => {