Skip to content

Commit 05844e4

Browse files
committed
test: add tests
1 parent 0a8322b commit 05844e4

File tree

2 files changed

+130
-0
lines changed

2 files changed

+130
-0
lines changed

packages/runtime-vapor/__tests__/_utils.ts

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@ import { createVaporApp } from '../src'
22
import type { App } from '@vue/runtime-dom'
33
import type { VaporComponent, VaporComponentInstance } from '../src/component'
44
import type { RawProps } from '../src/componentProps'
5+
import { compileScript, parse } from '@vue/compiler-sfc'
6+
import * as runtimeVapor from '../src'
7+
import * as runtimeDom from '@vue/runtime-dom'
8+
import * as VueServerRenderer from '@vue/server-renderer'
59

610
export interface RenderContext {
711
component: VaporComponent
@@ -82,3 +86,50 @@ export function makeRender<C = VaporComponent>(
8286

8387
return define
8488
}
89+
90+
export { runtimeDom, runtimeVapor, VueServerRenderer }
91+
export function compile(
92+
sfc: string,
93+
data: runtimeDom.Ref<any>,
94+
components: Record<string, any> = {},
95+
{
96+
vapor = true,
97+
ssr = false,
98+
}: {
99+
vapor?: boolean | undefined
100+
ssr?: boolean | undefined
101+
} = {},
102+
): any {
103+
if (!sfc.includes(`<script`)) {
104+
sfc =
105+
`<script vapor>const data = _data; const components = _components;</script>` +
106+
sfc
107+
}
108+
const descriptor = parse(sfc).descriptor
109+
110+
const script = compileScript(descriptor, {
111+
id: 'x',
112+
isProd: true,
113+
inlineTemplate: true,
114+
genDefaultAs: '__sfc__',
115+
vapor,
116+
templateOptions: {
117+
ssr,
118+
},
119+
})
120+
121+
const code =
122+
script.content
123+
.replace(/\bimport {/g, 'const {')
124+
.replace(/ as _/g, ': _')
125+
.replace(/} from ['"]vue['"]/g, `} = Vue`)
126+
.replace(/} from "vue\/server-renderer"/g, '} = VueServerRenderer') +
127+
'\nreturn __sfc__'
128+
129+
return new Function('Vue', 'VueServerRenderer', '_data', '_components', code)(
130+
{ ...runtimeDom, ...runtimeVapor },
131+
VueServerRenderer,
132+
data,
133+
components,
134+
)
135+
}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
import { nextTick } from 'vue'
2+
import { compile, runtimeDom, runtimeVapor } from '../_utils'
3+
4+
describe.todo('VaporSuspense', () => {})
5+
6+
describe('vapor / vdom interop', () => {
7+
async function testSuspense(
8+
code: string,
9+
components: Record<string, { code: string; vapor: boolean }> = {},
10+
data: any = {},
11+
{ vapor = false } = {},
12+
) {
13+
const clientComponents: any = {}
14+
for (const key in components) {
15+
const comp = components[key]
16+
let code = comp.code
17+
const isVaporComp = !!comp.vapor
18+
clientComponents[key] = compile(code, data, clientComponents, {
19+
vapor: isVaporComp,
20+
})
21+
}
22+
23+
const clientComp = compile(code, data, clientComponents, {
24+
vapor,
25+
})
26+
27+
const app = (vapor ? runtimeVapor.createVaporApp : runtimeDom.createApp)(
28+
clientComp,
29+
)
30+
app.use(runtimeVapor.vaporInteropPlugin)
31+
32+
const container = document.createElement('div')
33+
document.body.appendChild(container)
34+
app.mount(container)
35+
return { container }
36+
}
37+
38+
function asyncWrapper(code: string) {
39+
return {
40+
code: `
41+
<script vapor>
42+
const data = _data;
43+
const p = new Promise(r => setTimeout(r, 5))
44+
data.deps.push(p.then(() => Promise.resolve()))
45+
await p
46+
</script>
47+
${code}
48+
`,
49+
vapor: true,
50+
}
51+
}
52+
53+
test('vdom suspense: render vapor components', async () => {
54+
const data = { deps: [] }
55+
const { container } = await testSuspense(
56+
`<script setup>
57+
const components = _components;
58+
</script>
59+
<template>
60+
<Suspense>
61+
<components.VaporChild/>
62+
<template #fallback>
63+
<span>loading</span>
64+
</template>
65+
</Suspense>
66+
</template>`,
67+
{
68+
VaporChild: asyncWrapper(`<template><div>hi</div></template>`),
69+
},
70+
data,
71+
)
72+
73+
expect(container.innerHTML).toBe(`<span>loading</span>`)
74+
expect(data.deps.length).toBe(1)
75+
await Promise.all(data.deps)
76+
await nextTick()
77+
expect(container.innerHTML).toBe(`<div>hi</div>`)
78+
})
79+
})

0 commit comments

Comments
 (0)