163 lines
4.1 KiB
JavaScript
163 lines
4.1 KiB
JavaScript
import { vi } from 'vitest'
|
|
|
|
/**
|
|
* Create a mock Vue Router instance
|
|
* @param {object} options - Router options
|
|
* @returns {object} Mock router
|
|
*/
|
|
export function createMockRouter(options = {}) {
|
|
const {
|
|
currentRoute = { path: '/', name: 'home', params: {}, query: {}, meta: {} },
|
|
routes = []
|
|
} = options
|
|
|
|
const router = {
|
|
currentRoute: {
|
|
value: currentRoute
|
|
},
|
|
options: {
|
|
routes
|
|
},
|
|
push: vi.fn(() => Promise.resolve()),
|
|
replace: vi.fn(() => Promise.resolve()),
|
|
go: vi.fn(),
|
|
back: vi.fn(),
|
|
forward: vi.fn(),
|
|
beforeEach: vi.fn((guard) => {
|
|
router._beforeEachGuards.push(guard)
|
|
return () => {
|
|
const index = router._beforeEachGuards.indexOf(guard)
|
|
if (index > -1) router._beforeEachGuards.splice(index, 1)
|
|
}
|
|
}),
|
|
afterEach: vi.fn((hook) => {
|
|
router._afterEachHooks.push(hook)
|
|
return () => {
|
|
const index = router._afterEachHooks.indexOf(hook)
|
|
if (index > -1) router._afterEachHooks.splice(index, 1)
|
|
}
|
|
}),
|
|
beforeResolve: vi.fn(),
|
|
hasRoute: vi.fn((name) => routes.some(r => r.name === name)),
|
|
getRoutes: vi.fn(() => routes),
|
|
resolve: vi.fn((to) => ({
|
|
path: typeof to === 'string' ? to : to.path || '/',
|
|
name: typeof to === 'object' ? to.name : undefined,
|
|
params: typeof to === 'object' ? to.params || {} : {},
|
|
query: typeof to === 'object' ? to.query || {} : {},
|
|
meta: {},
|
|
matched: [],
|
|
redirectedFrom: undefined,
|
|
href: typeof to === 'string' ? to : to.path || '/'
|
|
})),
|
|
addRoute: vi.fn(),
|
|
removeRoute: vi.fn(),
|
|
isReady: vi.fn(() => Promise.resolve()),
|
|
install: vi.fn(),
|
|
|
|
// Internal tracking
|
|
_beforeEachGuards: [],
|
|
_afterEachHooks: []
|
|
}
|
|
|
|
return router
|
|
}
|
|
|
|
/**
|
|
* Create a mock route object
|
|
* @param {object} options - Route options
|
|
* @returns {object} Mock route
|
|
*/
|
|
export function createMockRoute(options = {}) {
|
|
const {
|
|
path = '/',
|
|
name = 'default',
|
|
params = {},
|
|
query = {},
|
|
meta = {},
|
|
hash = '',
|
|
fullPath = null,
|
|
matched = [],
|
|
redirectedFrom = undefined
|
|
} = options
|
|
|
|
return {
|
|
path,
|
|
name,
|
|
params,
|
|
query,
|
|
meta,
|
|
hash,
|
|
fullPath: fullPath || path + (Object.keys(query).length ? '?' + new URLSearchParams(query).toString() : '') + hash,
|
|
matched,
|
|
redirectedFrom
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Simulate navigation with guards
|
|
* @param {object} router - Mock router instance
|
|
* @param {object} to - Target route
|
|
* @param {object} from - Source route
|
|
* @returns {Promise} Navigation result
|
|
*/
|
|
export async function simulateNavigation(router, to, from = { path: '/' }) {
|
|
const toRoute = typeof to === 'string' ? { path: to } : to
|
|
const fromRoute = typeof from === 'string' ? { path: from } : from
|
|
|
|
let nextCalled = false
|
|
let nextArg = undefined
|
|
|
|
const next = vi.fn((arg) => {
|
|
nextCalled = true
|
|
nextArg = arg
|
|
})
|
|
|
|
// Run through beforeEach guards
|
|
for (const guard of router._beforeEachGuards) {
|
|
await guard(toRoute, fromRoute, next)
|
|
|
|
if (nextCalled) {
|
|
if (nextArg === false) {
|
|
return { success: false, redirect: null }
|
|
}
|
|
if (nextArg && typeof nextArg === 'object') {
|
|
return { success: false, redirect: nextArg }
|
|
}
|
|
if (typeof nextArg === 'string') {
|
|
return { success: false, redirect: { path: nextArg } }
|
|
}
|
|
}
|
|
nextCalled = false
|
|
nextArg = undefined
|
|
}
|
|
|
|
// Update current route
|
|
router.currentRoute.value = { ...router.currentRoute.value, ...toRoute }
|
|
|
|
// Run afterEach hooks
|
|
for (const hook of router._afterEachHooks) {
|
|
hook(toRoute, fromRoute)
|
|
}
|
|
|
|
return { success: true, redirect: null }
|
|
}
|
|
|
|
/**
|
|
* Create a mock useRoute composable return value
|
|
* @param {object} options - Route options
|
|
* @returns {object} Mock useRoute return
|
|
*/
|
|
export function createMockUseRoute(options = {}) {
|
|
return createMockRoute(options)
|
|
}
|
|
|
|
/**
|
|
* Create a mock useRouter composable return value
|
|
* @param {object} options - Router options
|
|
* @returns {object} Mock useRouter return
|
|
*/
|
|
export function createMockUseRouter(options = {}) {
|
|
return createMockRouter(options)
|
|
}
|