]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
test: add tests
authordaiwei <daiwei521@126.com>
Tue, 20 May 2025 03:47:31 +0000 (11:47 +0800)
committerdaiwei <daiwei521@126.com>
Tue, 20 May 2025 03:47:31 +0000 (11:47 +0800)
packages/runtime-vapor/__tests__/_utils.ts
packages/runtime-vapor/__tests__/components/Suspense.spec.ts [new file with mode: 0644]

index 0ed645544784c82eb4de0dda1fbc17a8ed4eb512..729d42de78c27ea602b9cdbbb72a988b9b92f224 100644 (file)
@@ -2,6 +2,10 @@ import { createVaporApp } from '../src'
 import type { App } from '@vue/runtime-dom'
 import type { VaporComponent, VaporComponentInstance } from '../src/component'
 import type { RawProps } from '../src/componentProps'
+import { compileScript, parse } from '@vue/compiler-sfc'
+import * as runtimeVapor from '../src'
+import * as runtimeDom from '@vue/runtime-dom'
+import * as VueServerRenderer from '@vue/server-renderer'
 
 export interface RenderContext {
   component: VaporComponent
@@ -82,3 +86,50 @@ export function makeRender<C = VaporComponent>(
 
   return define
 }
+
+export { runtimeDom, runtimeVapor, VueServerRenderer }
+export function compile(
+  sfc: string,
+  data: runtimeDom.Ref<any>,
+  components: Record<string, any> = {},
+  {
+    vapor = true,
+    ssr = false,
+  }: {
+    vapor?: boolean | undefined
+    ssr?: boolean | undefined
+  } = {},
+): any {
+  if (!sfc.includes(`<script`)) {
+    sfc =
+      `<script vapor>const data = _data; const components = _components;</script>` +
+      sfc
+  }
+  const descriptor = parse(sfc).descriptor
+
+  const script = compileScript(descriptor, {
+    id: 'x',
+    isProd: true,
+    inlineTemplate: true,
+    genDefaultAs: '__sfc__',
+    vapor,
+    templateOptions: {
+      ssr,
+    },
+  })
+
+  const code =
+    script.content
+      .replace(/\bimport {/g, 'const {')
+      .replace(/ as _/g, ': _')
+      .replace(/} from ['"]vue['"]/g, `} = Vue`)
+      .replace(/} from "vue\/server-renderer"/g, '} = VueServerRenderer') +
+    '\nreturn __sfc__'
+
+  return new Function('Vue', 'VueServerRenderer', '_data', '_components', code)(
+    { ...runtimeDom, ...runtimeVapor },
+    VueServerRenderer,
+    data,
+    components,
+  )
+}
diff --git a/packages/runtime-vapor/__tests__/components/Suspense.spec.ts b/packages/runtime-vapor/__tests__/components/Suspense.spec.ts
new file mode 100644 (file)
index 0000000..6bec5b8
--- /dev/null
@@ -0,0 +1,79 @@
+import { nextTick } from 'vue'
+import { compile, runtimeDom, runtimeVapor } from '../_utils'
+
+describe.todo('VaporSuspense', () => {})
+
+describe('vapor / vdom interop', () => {
+  async function testSuspense(
+    code: string,
+    components: Record<string, { code: string; vapor: boolean }> = {},
+    data: any = {},
+    { vapor = false } = {},
+  ) {
+    const clientComponents: any = {}
+    for (const key in components) {
+      const comp = components[key]
+      let code = comp.code
+      const isVaporComp = !!comp.vapor
+      clientComponents[key] = compile(code, data, clientComponents, {
+        vapor: isVaporComp,
+      })
+    }
+
+    const clientComp = compile(code, data, clientComponents, {
+      vapor,
+    })
+
+    const app = (vapor ? runtimeVapor.createVaporApp : runtimeDom.createApp)(
+      clientComp,
+    )
+    app.use(runtimeVapor.vaporInteropPlugin)
+
+    const container = document.createElement('div')
+    document.body.appendChild(container)
+    app.mount(container)
+    return { container }
+  }
+
+  function asyncWrapper(code: string) {
+    return {
+      code: `
+    <script vapor>
+      const data = _data;
+      const p = new Promise(r => setTimeout(r, 5))
+      data.deps.push(p.then(() => Promise.resolve()))
+      await p
+    </script>
+    ${code}
+    `,
+      vapor: true,
+    }
+  }
+
+  test('vdom suspense: render vapor components', async () => {
+    const data = { deps: [] }
+    const { container } = await testSuspense(
+      `<script setup>
+        const components = _components;
+      </script>
+      <template>
+        <Suspense>
+          <components.VaporChild/>
+          <template #fallback>
+            <span>loading</span>
+          </template>
+        </Suspense>
+      </template>`,
+      {
+        VaporChild: asyncWrapper(`<template><div>hi</div></template>`),
+      },
+      data,
+    )
+
+    expect(container.innerHTML).toBe(`<span>loading</span>`)
+    expect(data.deps.length).toBe(1)
+    await Promise.all(data.deps)
+    await nextTick()
+    expect(container.innerHTML).toBe(`<div>hi</div>`)
+  })
+})