text,
enterValue,
html,
- value,
transitionStart,
waitForElement,
nextFrame,
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',
<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'
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() {
<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">
+++ /dev/null
-<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>
+++ /dev/null
-<script setup lang="ts"></script>
-
-<template>
- <div>foo</div>
-</template>
import {
+ KeepAlive,
createVNode,
defineComponent,
h,
nextTick,
+ onActivated,
+ onBeforeMount,
+ onDeactivated,
+ onMounted,
+ onUnmounted,
ref,
renderSlot,
toDisplayString,
applyVShow,
child,
createComponent,
+ defineVaporAsyncComponent,
defineVaporComponent,
renderEffect,
setText,
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])
+ })
+ })
})