import { Teleport, createApp, h } from 'vue' import { renderToString } from '../src/renderToString' import { renderToSimpleStream } from '../src/renderToStream' import type { SSRContext } from '../src/render' import { ssrRenderTeleport } from '../src/helpers/ssrRenderTeleport' describe('ssrRenderTeleport', () => { test('teleport rendering (compiled)', async () => { const ctx: SSRContext = {} const html = await renderToString( createApp({ data() { return { msg: 'hello' } }, ssrRender(_ctx, _push, _parent) { ssrRenderTeleport( _push, _push => { _push(`
content
`) }, '#target', false, _parent, ) }, }), ctx, ) expect(html).toBe('') expect(ctx.teleports!['#target']).toBe( `
content
`, ) }) test('teleport rendering (compiled + disabled)', async () => { const ctx: SSRContext = {} const html = await renderToString( createApp({ data() { return { msg: 'hello' } }, ssrRender(_ctx, _push, _parent) { ssrRenderTeleport( _push, _push => { _push(`
content
`) }, '#target', true, _parent, ) }, }), ctx, ) expect(html).toBe( '
content
', ) expect(ctx.teleports!['#target']).toBe( ``, ) }) test('teleport rendering (vnode)', async () => { const ctx: SSRContext = {} const html = await renderToString( h( Teleport, { to: `#target`, }, h('span', 'hello'), ), ctx, ) expect(html).toBe('') expect(ctx.teleports!['#target']).toBe( 'hello', ) }) test('teleport rendering (vnode + disabled)', async () => { const ctx: SSRContext = {} const html = await renderToString( h( Teleport, { to: `#target`, disabled: true, }, h('span', 'hello'), ), ctx, ) expect(html).toBe( 'hello', ) expect(ctx.teleports!['#target']).toBe( ``, ) }) test('multiple teleports with same target', async () => { const ctx: SSRContext = {} const html = await renderToString( h('div', [ h( Teleport, { to: `#target`, }, h('span', 'hello'), ), h(Teleport, { to: `#target` }, 'world'), ]), ctx, ) expect(html).toBe( '
', ) expect(ctx.teleports!['#target']).toBe( 'hello' + 'world', ) }) test('teleport inside async component', async () => { const ctx: SSRContext = {} const asyncComponent = { template: '
content
', async setup() {}, } const html = await renderToString( h({ template: '', components: { asyncComponent }, }), ctx, ) expect(html).toBe('') expect(ctx.teleports!['#target']).toBe( `
content
`, ) }) test('teleport inside async component (stream)', async () => { const ctx: SSRContext = {} const asyncComponent = { template: '
content
', async setup() {}, } let html = '' let resolve: any const p = new Promise(r => (resolve = r)) renderToSimpleStream( h({ template: '', components: { asyncComponent }, }), ctx, { push(chunk) { if (chunk === null) { resolve() } else { html += chunk } }, destroy(err) { throw err }, }, ) await p expect(html).toBe('') expect(ctx.teleports!['#target']).toBe( `
content
`, ) }) })