Procházet zdrojové kódy

test(hmr): add HMR reload coverage for dynamic multi-instance and teleport branches

daiwei před 1 měsícem
rodič
revize
7508f67207
1 změnil soubory, kde provedl 121 přidání a 0 odebrání
  1. 121 0
      packages/runtime-vapor/__tests__/hmr.spec.ts

+ 121 - 0
packages/runtime-vapor/__tests__/hmr.spec.ts

@@ -1159,6 +1159,127 @@ describe('hot module replacement', () => {
     expect(root.innerHTML).toBe(`<div>child changed</div><!--if-->`)
   })
 
+  test('child reload with multiple instances in dynamic branch should keep parent reload stable', async () => {
+    const root = document.createElement('div')
+    const childId = 'test-dynamic-multi-child-reload'
+    const parentId = 'test-dynamic-multi-parent-reload'
+
+    const Child = defineVaporComponent({
+      __hmrId: childId,
+      setup() {
+        const msg = ref('child')
+        return { msg }
+      },
+      render: compileToFunction(`<div>{{ msg }}</div>`),
+    })
+    createRecord(childId, Child as any)
+
+    const { mount, component: Parent } = define({
+      __hmrId: parentId,
+      components: { Child },
+      setup() {
+        const ok = ref(true)
+        return { ok }
+      },
+      render: compileToFunction(
+        `<template v-if="ok"><Child/><Child/></template>`,
+      ),
+    }).create()
+    createRecord(parentId, Parent as any)
+
+    mount(root)
+    expect(root.textContent).toBe(`childchild`)
+
+    reload(childId, {
+      __vapor: true,
+      __hmrId: childId,
+      setup() {
+        const msg = ref('child changed')
+        return { msg }
+      },
+      render: compileToFunction(`<div>{{ msg }}</div>`),
+    })
+    expect(root.textContent).toBe(`child changedchild changed`)
+
+    reload(parentId, {
+      __vapor: true,
+      __hmrId: parentId,
+      components: { Child },
+      setup() {
+        const ok = ref(true)
+        return { ok }
+      },
+      render: compileToFunction(
+        `<template v-if="ok"><Child/><Child/></template>`,
+      ),
+    })
+
+    await nextTick()
+    expect(root.textContent).toBe(`child changedchild changed`)
+  })
+
+  test('child reload in teleport dynamic branch should not break subsequent parent reload', async () => {
+    const root = document.createElement('div')
+    const target = document.createElement('div')
+    document.body.appendChild(root)
+    document.body.appendChild(target)
+    const childId = 'test-teleport-dynamic-child-reload'
+    const parentId = 'test-teleport-dynamic-parent-reload'
+
+    const Child = defineVaporComponent({
+      __hmrId: childId,
+      setup() {
+        const msg = ref('child')
+        return { msg }
+      },
+      render: compileToFunction(`<div>{{ msg }}</div>`),
+    })
+    createRecord(childId, Child as any)
+
+    const { mount, component: Parent } = define({
+      __hmrId: parentId,
+      components: { Child },
+      setup() {
+        const ok = ref(true)
+        return { ok, target }
+      },
+      render: compileToFunction(
+        `<teleport :to="target"><template v-if="ok"><Child/><span>sibling</span></template></teleport>`,
+      ),
+    }).create()
+    createRecord(parentId, Parent as any)
+
+    mount(root)
+    expect(target.textContent).toBe(`childsibling`)
+
+    reload(childId, {
+      __vapor: true,
+      __hmrId: childId,
+      setup() {
+        const msg = ref('child changed')
+        return { msg }
+      },
+      render: compileToFunction(`<div>{{ msg }}</div>`),
+    })
+    expect(target.textContent).toBe(`child changedsibling`)
+
+    reload(parentId, {
+      __vapor: true,
+      __hmrId: parentId,
+      components: { Child },
+      setup() {
+        const ok = ref(true)
+        return { ok, target }
+      },
+      render: compileToFunction(
+        `<teleport :to="target"><template v-if="ok"><Child/><span>sibling</span></template></teleport>`,
+      ),
+    })
+
+    await nextTick()
+    expect(target.textContent).toBe(`child changedsibling`)
+  })
+
   // Vapor router-view has no render function (setup-only).
   // When HMR rerender is triggered, the setup function is re-executed.
   // Ensure provide() warning is suppressed.