]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
refactor(tests): port async component and keepalive tests
authordaiwei <daiwei521@126.com>
Thu, 23 Oct 2025 06:14:25 +0000 (14:14 +0800)
committeredison <daiwei521@126.com>
Thu, 23 Oct 2025 06:21:28 +0000 (14:21 +0800)
packages-private/vapor-e2e-test/__tests__/vdomInterop.spec.ts
packages-private/vapor-e2e-test/interop/App.vue
packages-private/vapor-e2e-test/interop/components/SimpleVaporComp.vue [deleted file]
packages-private/vapor-e2e-test/interop/components/VdomFoo.vue [deleted file]
packages/runtime-vapor/__tests__/vdomInterop.spec.ts

index df190fe8e15dd2c7c74bc05859476d6d4a752ac3..3f90814cb4b0d49ce42126b050fa36ff63d36f75 100644 (file)
@@ -11,7 +11,6 @@ const {
   text,
   enterValue,
   html,
-  value,
   transitionStart,
   waitForElement,
   nextFrame,
@@ -98,81 +97,6 @@ describe('vdom / vapor interop', () => {
     E2E_TIMEOUT,
   )
 
-  describe('async component', () => {
-    const container = '.async-component-interop'
-    test(
-      'with-vdom-inner-component',
-      async () => {
-        const testContainer = `${container} .with-vdom-component`
-        expect(await html(testContainer)).toBe('<span>loading...</span>')
-
-        await timeout(duration)
-        expect(await html(testContainer)).toBe('<div>foo</div>')
-      },
-      E2E_TIMEOUT,
-    )
-  })
-
-  describe('keepalive', () => {
-    test(
-      'render vapor component',
-      async () => {
-        const testSelector = '.render-vapor-component'
-        const btnShow = `${testSelector} .btn-show`
-        const btnToggle = `${testSelector} .btn-toggle`
-        const container = `${testSelector} > div`
-        const inputSelector = `${testSelector} input`
-
-        let calls = await page().evaluate(() => {
-          return (window as any).getCalls()
-        })
-        expect(calls).toStrictEqual(['mounted', 'activated'])
-
-        expect(await html(container)).toBe('<input type="text">')
-        expect(await value(inputSelector)).toBe('vapor')
-
-        // change input value
-        await enterValue(inputSelector, 'changed')
-        expect(await value(inputSelector)).toBe('changed')
-
-        // deactivate
-        await click(btnToggle)
-        expect(await html(container)).toBe('<!---->')
-        calls = await page().evaluate(() => {
-          return (window as any).getCalls()
-        })
-        expect(calls).toStrictEqual(['deactivated'])
-
-        // activate
-        await click(btnToggle)
-        expect(await html(container)).toBe('<input type="text">')
-        expect(await value(inputSelector)).toBe('changed')
-        calls = await page().evaluate(() => {
-          return (window as any).getCalls()
-        })
-        expect(calls).toStrictEqual(['activated'])
-
-        // unmount keepalive
-        await click(btnShow)
-        expect(await html(container)).toBe('<!---->')
-        calls = await page().evaluate(() => {
-          return (window as any).getCalls()
-        })
-        expect(calls).toStrictEqual(['deactivated', 'unmounted'])
-
-        // mount keepalive
-        await click(btnShow)
-        expect(await html(container)).toBe('<input type="text">')
-        expect(await value(inputSelector)).toBe('vapor')
-        calls = await page().evaluate(() => {
-          return (window as any).getCalls()
-        })
-        expect(calls).toStrictEqual(['mounted', 'activated'])
-      },
-      E2E_TIMEOUT,
-    )
-  })
-
   describe('vdom transition', () => {
     test(
       'render vapor component',
index 30e99a2e5e372bea1c165a48179c02afacc5f6c0..b0c9b778a7e3975c34d9e6bc5ee03eb622efe60c 100644 (file)
@@ -1,8 +1,6 @@
 <script setup lang="ts">
-import { ref, defineVaporAsyncComponent, h, shallowRef } from 'vue'
+import { ref, shallowRef } from 'vue'
 import VaporComp from './components/VaporComp.vue'
-import VdomFoo from './components/VdomFoo.vue'
-import SimpleVaporComp from './components/SimpleVaporComp.vue'
 import VaporCompA from '../transition/components/VaporCompA.vue'
 import VdomComp from '../transition/components/VdomComp.vue'
 import VaporSlot from '../transition/components/VaporSlot.vue'
@@ -10,27 +8,6 @@ import VaporSlot from '../transition/components/VaporSlot.vue'
 const msg = ref('hello')
 const passSlot = ref(true)
 
-const duration = typeof process !== 'undefined' && process.env.CI ? 200 : 50
-
-const AsyncVDomFoo = defineVaporAsyncComponent({
-  loader: () => {
-    return new Promise(r => {
-      setTimeout(() => {
-        r(VdomFoo as any)
-      }, duration)
-    })
-  },
-  loadingComponent: () => h('span', 'loading...'),
-})
-;(window as any).calls = []
-;(window as any).getCalls = () => {
-  const ret = (window as any).calls.slice()
-  ;(window as any).calls = []
-  return ret
-}
-
-const show = ref(true)
-const toggle = ref(true)
 const toggleVapor = ref(true)
 const interopComponent = shallowRef(VdomComp)
 function toggleInteropComponent() {
@@ -55,25 +32,6 @@ const enterClick = () => items.value.push('d', 'e')
 
     <template #test v-if="passSlot">A test slot</template>
   </VaporComp>
-
-  <!-- async component  -->
-  <div class="async-component-interop">
-    <div class="with-vdom-component">
-      <AsyncVDomFoo />
-    </div>
-  </div>
-  <!-- async component end -->
-  <!-- keepalive -->
-  <div class="render-vapor-component">
-    <button class="btn-show" @click="show = !show">show</button>
-    <button class="btn-toggle" @click="toggle = !toggle">toggle</button>
-    <div>
-      <KeepAlive v-if="show">
-        <SimpleVaporComp v-if="toggle" />
-      </KeepAlive>
-    </div>
-  </div>
-  <!-- keepalive end -->
   <!-- transition interop -->
   <div>
     <div class="trans-vapor">
diff --git a/packages-private/vapor-e2e-test/interop/components/SimpleVaporComp.vue b/packages-private/vapor-e2e-test/interop/components/SimpleVaporComp.vue
deleted file mode 100644 (file)
index 7f8dc48..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-<script vapor>
-import { onActivated, onDeactivated, onMounted, onUnmounted, ref } from 'vue'
-const msg = ref('vapor')
-
-onMounted(() => {
-  window.calls.push('mounted')
-})
-onActivated(() => {
-  window.calls.push('activated')
-})
-onDeactivated(() => {
-  window.calls.push('deactivated')
-})
-onUnmounted(() => {
-  window.calls.push('unmounted')
-})
-</script>
-<template>
-  <input type="text" v-model="msg" />
-</template>
diff --git a/packages-private/vapor-e2e-test/interop/components/VdomFoo.vue b/packages-private/vapor-e2e-test/interop/components/VdomFoo.vue
deleted file mode 100644 (file)
index ee13cfb..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-<script setup lang="ts"></script>
-
-<template>
-  <div>foo</div>
-</template>
index dd25f06aab8bcaeaa5a1b163f3b9f043050c1cd0..a9baea6ab2d986de7757638a7d89e2aeb94b8750 100644 (file)
@@ -1,8 +1,14 @@
 import {
+  KeepAlive,
   createVNode,
   defineComponent,
   h,
   nextTick,
+  onActivated,
+  onBeforeMount,
+  onDeactivated,
+  onMounted,
+  onUnmounted,
   ref,
   renderSlot,
   toDisplayString,
@@ -14,6 +20,7 @@ import {
   applyVShow,
   child,
   createComponent,
+  defineVaporAsyncComponent,
   defineVaporComponent,
   renderEffect,
   setText,
@@ -275,4 +282,140 @@ describe('vdomInterop', () => {
       expect(fn).toHaveBeenCalledTimes(1)
     })
   })
+
+  describe('async component', () => {
+    const duration = 5
+    test('render vapor async component', async () => {
+      const VdomChild = {
+        setup() {
+          return () => h('div', 'foo')
+        },
+      }
+      const VaporAsyncChild = defineVaporAsyncComponent({
+        loader: () => {
+          return new Promise(r => {
+            setTimeout(() => {
+              r(VdomChild as any)
+            }, duration)
+          })
+        },
+        loadingComponent: () => h('span', 'loading...'),
+      })
+
+      const { html } = define({
+        setup() {
+          return () => h(VaporAsyncChild as any)
+        },
+      }).render()
+
+      expect(html()).toBe('<span>loading...</span><!--async component-->')
+
+      await new Promise(r => setTimeout(r, duration))
+      await nextTick()
+      expect(html()).toBe('<div>foo</div><!--async component-->')
+    })
+  })
+
+  describe('keepalive', () => {
+    function assertHookCalls(
+      hooks: {
+        beforeMount: any
+        mounted: any
+        activated: any
+        deactivated: any
+        unmounted: any
+      },
+      callCounts: number[],
+    ) {
+      expect([
+        hooks.beforeMount.mock.calls.length,
+        hooks.mounted.mock.calls.length,
+        hooks.activated.mock.calls.length,
+        hooks.deactivated.mock.calls.length,
+        hooks.unmounted.mock.calls.length,
+      ]).toEqual(callCounts)
+    }
+
+    let hooks: any
+    beforeEach(() => {
+      hooks = {
+        beforeMount: vi.fn(),
+        mounted: vi.fn(),
+        activated: vi.fn(),
+        deactivated: vi.fn(),
+        unmounted: vi.fn(),
+      }
+    })
+
+    test('render vapor component', async () => {
+      const VaporChild = defineVaporComponent({
+        setup() {
+          const msg = ref('vapor')
+          onBeforeMount(() => hooks.beforeMount())
+          onMounted(() => hooks.mounted())
+          onActivated(() => hooks.activated())
+          onDeactivated(() => hooks.deactivated())
+          onUnmounted(() => hooks.unmounted())
+
+          const n0 = template('<input type="text">', true)() as any
+          applyTextModel(
+            n0,
+            () => msg.value,
+            _value => (msg.value = _value),
+          )
+          return n0
+        },
+      })
+
+      const show = ref(true)
+      const toggle = ref(true)
+      const { html, host } = define({
+        setup() {
+          return () =>
+            show.value
+              ? h(KeepAlive, null, {
+                  default: () => (toggle.value ? h(VaporChild as any) : null),
+                })
+              : null
+        },
+      }).render()
+
+      expect(html()).toBe('<input type="text">')
+      let inputEl = host.firstChild as HTMLInputElement
+      expect(inputEl.value).toBe('vapor')
+      assertHookCalls(hooks, [1, 1, 1, 0, 0])
+
+      // change input value
+      inputEl.value = 'changed'
+      inputEl.dispatchEvent(new Event('input'))
+      await nextTick()
+
+      // deactivate
+      toggle.value = false
+      await nextTick()
+      expect(html()).toBe('<!---->')
+      assertHookCalls(hooks, [1, 1, 1, 1, 0])
+
+      // activate
+      toggle.value = true
+      await nextTick()
+      expect(html()).toBe('<input type="text">')
+      inputEl = host.firstChild as HTMLInputElement
+      expect(inputEl.value).toBe('changed')
+      assertHookCalls(hooks, [1, 1, 2, 1, 0])
+
+      // unmount keepalive
+      show.value = false
+      await nextTick()
+      expect(html()).toBe('<!---->')
+      assertHookCalls(hooks, [1, 1, 2, 2, 1])
+
+      // mount keepalive
+      show.value = true
+      await nextTick()
+      inputEl = host.firstChild as HTMLInputElement
+      expect(inputEl.value).toBe('vapor')
+      assertHookCalls(hooks, [2, 2, 3, 2, 1])
+    })
+  })
 })