Files
MoviePilot-Frontend/tests/support/render.ts
2026-07-17 06:53:56 +08:00

60 lines
1.8 KiB
TypeScript

import i18n from '@/plugins/i18n'
import vuetify from '@/plugins/vuetify'
import { createTestingPinia } from '@pinia/testing'
import { render } from '@testing-library/vue'
import { setActivePinia } from 'pinia'
import { defineComponent, h, type Component } from 'vue'
import { createMemoryHistory, createRouter, type RouteLocationRaw, type RouteMeta } from 'vue-router'
import { vi } from 'vitest'
type TestingLibraryRenderOptions = NonNullable<Parameters<typeof render>[1]>
export interface RenderWithProvidersOptions extends Omit<TestingLibraryRenderOptions, 'global'> {
global?: TestingLibraryRenderOptions['global']
initialRoute?: RouteLocationRaw
initialRouteMeta?: RouteMeta
initialState?: Record<string, Record<string, unknown>>
stubActions?: boolean
}
const EmptyRoute = defineComponent({
name: 'EmptyTestRoute',
setup: () => () => h('div'),
})
/** 使用独立 Router、Pinia 和生产 UI 插件渲染业务组件。 */
export async function renderWithProviders(component: Component, options: RenderWithProvidersOptions = {}) {
const {
global: globalOptions,
initialRoute = '/',
initialRouteMeta = {},
initialState = {},
stubActions = true,
...renderOptions
} = options
const router = createRouter({
history: createMemoryHistory(),
routes: [{ path: '/:pathMatch(.*)*', component: EmptyRoute, meta: initialRouteMeta }],
})
await router.push(initialRoute)
i18n.global.locale.value = 'zh-CN'
const pinia = createTestingPinia({
createSpy: vi.fn,
initialState,
stubActions,
})
setActivePinia(pinia)
const result = render(component, {
...renderOptions,
global: {
...globalOptions,
plugins: [vuetify, i18n, pinia, router, ...(globalOptions?.plugins ?? [])],
},
})
await router.isReady()
return { ...result, pinia, router }
}