import { ref, shallowRef } from '@vue/reactivity' import { nextTick, resolveDynamicComponent } from '@vue/runtime-dom' import { createComponentWithFallback, createDynamicComponent, defineVaporComponent, renderEffect, setHtml, setInsertionState, template, } from '../src' import { makeRender } from './_utils' const define = makeRender() describe('api: createDynamicComponent', () => { const A = () => document.createTextNode('AAA') const B = () => document.createTextNode('BBB') test('direct value', async () => { const val = shallowRef(A) const { html } = define({ setup() { return createDynamicComponent(() => val.value) }, }).render() expect(html()).toBe('AAA') val.value = B await nextTick() expect(html()).toBe('BBB') // fallback val.value = 'foo' await nextTick() expect(html()).toBe('') }) test('global registration', async () => { const val = shallowRef('foo') const { app, html, mount } = define({ setup() { return createDynamicComponent(() => val.value) }, }).create() app.component('foo', A) app.component('bar', B) mount() expect(html()).toBe('AAA') val.value = 'bar' await nextTick() expect(html()).toBe('BBB') // fallback val.value = 'baz' await nextTick() expect(html()).toBe('') }) test('render fallback with insertionState', async () => { const { html, mount } = define({ setup() { const html = ref('hi') const n1 = template('
', true)() as any setInsertionState(n1) const n0 = createComponentWithFallback( resolveDynamicComponent('button') as any, ) as any renderEffect(() => setHtml(n0, html.value)) return n1 }, }).create() mount() expect(html()).toBe('
') }) test('switch dynamic component children', async () => { const CompA = defineVaporComponent({ setup() { return template('
A
')() }, }) const CompB = defineVaporComponent({ setup() { return template('
B
')() }, }) const current = shallowRef(CompA) const { html } = define({ setup() { const t1 = template('
') const n2 = t1() as any setInsertionState(n2) createDynamicComponent(() => current.value) return n2 }, }).render() expect(html()).toBe('
A
') current.value = CompB await nextTick() expect(html()).toBe('
B
') }) })