]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
test: add more cases
authordaiwei <daiwei521@126.com>
Fri, 21 Feb 2025 13:59:44 +0000 (21:59 +0800)
committerdaiwei <daiwei521@126.com>
Fri, 21 Feb 2025 13:59:44 +0000 (21:59 +0800)
packages/runtime-core/__tests__/components/Suspense.spec.ts

index 0944c40d6b23b91e1970f8b7e1fc36d9a94e561f..999e18f4b931ef3fc1412b0510db7d241ef02738 100644 (file)
@@ -26,7 +26,14 @@ import {
   watch,
   watchEffect,
 } from '@vue/runtime-test'
-import { computed, createApp, defineComponent, inject, provide } from 'vue'
+import {
+  computed,
+  createApp,
+  defineAsyncComponent as defineAsyncComp,
+  defineComponent,
+  inject,
+  provide,
+} from 'vue'
 import type { RawSlots } from 'packages/runtime-core/src/componentSlots'
 import { resetSuspenseId } from '../../src/components/Suspense'
 import { PatchFlags } from '@vue/shared'
@@ -2166,12 +2173,12 @@ describe('Suspense', () => {
   })
 
   // #12920
-  test('unmount Suspense after children self-update', async () => {
-    const Comp = defineAsyncComponent({
+  test('unmount Suspense after async child (with defineAsyncComponent) self-triggered update', async () => {
+    const Comp = defineComponent({
       setup() {
         const show = ref(true)
         onMounted(() => {
-          // trigger self-update
+          // trigger update
           show.value = !show.value
         })
         return () =>
@@ -2181,6 +2188,77 @@ describe('Suspense', () => {
       },
     })
 
+    const AsyncComp = defineAsyncComp(() => {
+      const p = new Promise(resolve => {
+        resolve(Comp)
+      })
+      deps.push(p.then(() => Promise.resolve()))
+      return p as any
+    })
+
+    const toggle = ref(true)
+    const root = nodeOps.createElement('div')
+    const App = {
+      render() {
+        return (
+          openBlock(),
+          createElementBlock(
+            Fragment,
+            null,
+            [
+              h('h1', null, toggle.value),
+              toggle.value
+                ? (openBlock(),
+                  createBlock(
+                    Suspense,
+                    { key: 0 },
+                    {
+                      default: h(AsyncComp),
+                    },
+                  ))
+                : createCommentVNode('v-if', true),
+            ],
+            PatchFlags.STABLE_FRAGMENT,
+          )
+        )
+      },
+    }
+    render(h(App), root)
+    expect(serializeInner(root)).toBe(`<h1>true</h1><!---->`)
+
+    await Promise.all(deps)
+    await nextTick()
+    await nextTick()
+    expect(serializeInner(root)).toBe(`<h1>true</h1><div>show</div>`)
+
+    await nextTick()
+    expect(serializeInner(root)).toBe(`<h1>true</h1><div>hidden</div>`)
+
+    // unmount suspense
+    toggle.value = false
+    await Promise.all(deps)
+    await nextTick()
+    expect(serializeInner(root)).toBe(`<h1>true</h1><!--v-if-->`)
+  })
+
+  test('unmount Suspense after async child (with async setup) self-triggered update', async () => {
+    const AsyncComp = defineComponent({
+      async setup() {
+        const show = ref(true)
+        onMounted(() => {
+          // trigger update
+          show.value = !show.value
+        })
+        const p = new Promise(r => setTimeout(r, 1))
+        // extra tick needed for Node 12+
+        deps.push(p.then(() => Promise.resolve()))
+        return () =>
+          show.value
+            ? (openBlock(), createElementBlock('div', { key: 0 }, 'show'))
+            : (openBlock(), createElementBlock('div', { key: 1 }, 'hidden'))
+      },
+    })
+
     const toggle = ref(true)
     const root = nodeOps.createElement('div')
     const App = {
@@ -2198,7 +2276,7 @@ describe('Suspense', () => {
                     Suspense,
                     { key: 0 },
                     {
-                      default: h(Comp),
+                      default: h(AsyncComp),
                     },
                   ))
                 : createCommentVNode('v-if', true),