it('next("/location") triggers afterEach', async () => {
await testNavigation(
- ((to, from, next) => {
- if (to.path === '/location') next()
- else next('/location')
+ ((to, from) => {
+ if (to.path === '/location') return
+ else return '/location'
}) as NavigationGuard,
undefined
)
it('triggers afterEach if a new navigation happens', async () => {
const { router } = createRouter()
const [promise, resolve] = fakePromise()
- router.beforeEach((to, from, next) => {
+ router.beforeEach(async (to, from) => {
// let it hang otherwise
- if (to.path === '/') next()
- else promise.then(() => next())
+ if (to.path === '/') return
+ else {
+ await promise
+ return
+ }
})
let from = router.currentRoute.value
it('next("/location") triggers afterEach with history.back', async () => {
await testHistoryNavigation(
- ((to, from, next) => {
- if (to.path === '/location') next()
- else next('/location')
+ ((to, from) => {
+ if (to.path === '/location') return
+ else return '/location'
}) as NavigationGuard,
undefined
)
const spy = vi.fn()
const router = createRouter({ routes })
await router.push('/foo')
- spy.mockImplementation((to, from, next) => {
+ spy.mockImplementation((to, from) => {
// only allow going to /other
- if (to.fullPath !== '/other') next('/other')
- else next()
+ if (to.fullPath !== '/other') return '/other'
+ else return
})
router.beforeEach(spy)
expect(spy).not.toHaveBeenCalled()
const spy = vi.fn()
const router = createRouter({ routes })
await router.push('/')
- spy.mockImplementation((to, from, next) => {
+ spy.mockImplementation((to, from) => {
// only allow going to /other
const i = Number(to.params.i)
- if (i >= 3) next()
- else next(redirectFn(String(i + 1)))
+ if (i >= 3) return
+ else return redirectFn(String(i + 1))
})
router.beforeEach(spy)
expect(spy).not.toHaveBeenCalled()
it('waits before navigating', async () => {
const [promise, resolve] = fakePromise()
const router = createRouter({ routes })
- router.beforeEach(async (to, from, next) => {
+ router.beforeEach(async (to, from) => {
await promise
- next()
+ return
})
const p = router.push('/foo')
expect(router.currentRoute.value.fullPath).toBe('/')
const router = createRouter({ routes })
const guard1 = vi.fn()
let order = 0
- guard1.mockImplementationOnce(async (to, from, next) => {
+ guard1.mockImplementationOnce(async (to, from) => {
expect(order++).toBe(0)
await p1
- next()
+ return
})
router.beforeEach(guard1)
const guard2 = vi.fn()
- guard2.mockImplementationOnce(async (to, from, next) => {
+ guard2.mockImplementationOnce(async (to, from) => {
expect(order++).toBe(1)
await p2
- next()
+ return
})
router.beforeEach(guard2)
let navigation = router.push('/foo')
it('waits before navigating', async () => {
const [promise, resolve] = fakePromise()
const router = createRouter({ routes })
- beforeEnter.mockImplementationOnce(async (to, from, next) => {
+ beforeEnter.mockImplementationOnce(async (to, from) => {
await promise
- next()
+ return
})
const p = router.push('/foo')
expect(router.currentRoute.value.fullPath).toBe('/')
const [p1, r1] = fakePromise()
const [p2, r2] = fakePromise()
const router = createRouter({ routes })
- beforeEnters[0].mockImplementationOnce(async (to, from, next) => {
+ beforeEnters[0].mockImplementationOnce(async (to, from) => {
await p1
- next()
+ return
})
- beforeEnters[1].mockImplementationOnce(async (to, from, next) => {
+ beforeEnters[1].mockImplementationOnce(async (to, from) => {
await p2
- next()
+ return
})
const p = router.push('/multiple')
expect(router.currentRoute.value.fullPath).toBe('/')
it('calls beforeRouteEnter guards on navigation', async () => {
const router = createRouter({ routes })
- beforeRouteEnter.mockImplementationOnce((to, from, next) => {
- if (to.params.n !== 'valid') return next(false)
- next()
+ beforeRouteEnter.mockImplementationOnce((to, from) => {
+ if (to.params.n !== 'valid') return false
+ return
})
await router.push('/guard/valid')
expect(beforeRouteEnter).toHaveBeenCalledTimes(1)
it('aborts navigation if one of the named views aborts', async () => {
const router = createRouter({ routes })
- named.default.mockImplementationOnce((to, from, next) => {
- next(false)
+ named.default.mockImplementationOnce((to, from) => {
+ return false
})
named.other.mockImplementationOnce(noGuard)
await router.push('/named').catch(err => {}) // catch abort
it('waits before navigating', async () => {
const [promise, resolve] = fakePromise()
const router = createRouter({ routes })
- beforeRouteEnter.mockImplementationOnce(async (to, from, next) => {
+ beforeRouteEnter.mockImplementationOnce(async (to, from) => {
await promise
- next()
+ return
})
const p = router.push('/foo')
expect(router.currentRoute.value.fullPath).toBe('/')
it('calls beforeRouteLeave guard on navigation', async () => {
const router = createRouter({ routes })
- beforeRouteLeave.mockImplementationOnce((to, from, next) => {
- if (to.path === 'foo') next(false)
- else next()
+ beforeRouteLeave.mockImplementationOnce((to, from) => {
+ if (to.path === 'foo') return false
+ else return
})
await router.push('/guard')
expect(beforeRouteLeave).not.toHaveBeenCalled()
it('does not call beforeRouteLeave guard if the view is not mounted', async () => {
const router = createRouter({ routes })
- beforeRouteLeave.mockImplementationOnce((to, from, next) => {
- next()
+ beforeRouteLeave.mockImplementationOnce((to, from) => {
+ return
})
await router.push('/guard')
expect(beforeRouteLeave).not.toHaveBeenCalled()
await router.push({ name: 'nested-nested-foo' })
resetMocks()
let count = 0
- nested.nestedNestedFoo.mockImplementation((to, from, next) => {
+ nested.nestedNestedFoo.mockImplementation((to, from) => {
expect(count++).toBe(0)
- next()
+ return
})
- nested.nestedNested.mockImplementation((to, from, next) => {
+ nested.nestedNested.mockImplementation((to, from) => {
expect(count++).toBe(1)
- next()
+ return
})
- nested.parent.mockImplementation((to, from, next) => {
+ nested.parent.mockImplementation((to, from) => {
expect(count++).toBe(2)
- next()
+ return
})
// simulate a mounted route component
it('can cancel navigation', async () => {
const router = createRouter({ routes })
- beforeRouteLeave.mockImplementationOnce(async (to, from, next) => {
- next(false)
+ beforeRouteLeave.mockImplementationOnce(async (to, from) => {
+ return false
})
await router.push('/guard')
const p = router.push('/')
it('waits before navigating', async () => {
const [promise, resolve] = fakePromise()
const router = createRouter({ routes })
- beforeRouteUpdate.mockImplementationOnce(async (to, from, next) => {
+ beforeRouteUpdate.mockImplementationOnce(async (to, from) => {
await promise
- next()
+ return
})
await router.push('/guard/one')
const p = router.push('/guard/foo')
beforeEach(() => {
beforeRouteEnter.mockReset()
- beforeRouteEnter.mockImplementation((to, from, next) => {
- next()
+ beforeRouteEnter.mockImplementation((to, from) => {
+ return
})
})
{
path: '/home-before',
component,
- beforeEnter: (to, from, next) => {
- next('/')
+ beforeEnter: (to, from) => {
+ return '/'
},
},
{ path: '/bar', component },
it('avoid fetching async component if navigation is cancelled through beforeEnter', async () => {
const { component, resolve } = createLazyComponent()
- const spy = vi.fn((to, from, next) => next(false))
+ const spy = vi.fn((to, from) => false)
const { router } = newRouter({
routes: [
{
],
})
- const spy = vi.fn((to, from, next) => next(false))
+ const spy = vi.fn((to, from) => false)
router.beforeEach(spy)
it('invokes beforeRouteEnter after lazy loading the component', async () => {
const { promise, resolve } = createLazyComponent()
- const spy = vi.fn((to, from, next) => next())
+ const spy = vi.fn((to, from) => {})
const component = vi.fn(() =>
promise.then(() => ({ beforeRouteEnter: spy }))
)
it('beforeRouteLeave works on a lazy loaded component', async () => {
const { promise, resolve } = createLazyComponent()
- const spy = vi.fn((to, from, next) => next())
+ const spy = vi.fn((to, from) => {})
const component = vi.fn(() =>
promise.then(() => ({ beforeRouteLeave: spy }))
)
it('beforeRouteUpdate works on a lazy loaded component', async () => {
const { promise, resolve } = createLazyComponent()
- const spy = vi.fn((to, from, next) => next())
+ const spy = vi.fn((to, from) => {})
const component = vi.fn(() =>
promise.then(() => ({ beforeRouteUpdate: spy }))
)
it('does not listen to url changes before being ready', async () => {
const { router, history } = newRouter()
- const spy = vi.fn((to, from, next) => {
- next()
+ const spy = vi.fn((to, from) => {
+ return
})
router.beforeEach(spy)
{
path: '/home-before',
component: components.Home,
- beforeEnter: (to, from, next) => {
- next('/')
+ beforeEnter: (to, from) => {
+ return '/'
},
},
{ path: '/search', component: components.Home },
it('navigates if the location does not exist', async () => {
const { router } = await newRouter({ routes: [routes[0]] })
- const spy = vi.fn((to, from, next) => next())
+ const spy = vi.fn((to, from) => {})
router.beforeEach(spy)
await router.push('/idontexist')
expect(spy).toHaveBeenCalledTimes(1)
describe('alias', () => {
it('does not navigate to alias if already on original record', async () => {
const { router } = await newRouter()
- const spy = vi.fn((to, from, next) => next())
+ const spy = vi.fn((to, from) => {})
await router.push('/basic')
router.beforeEach(spy)
await router.push('/basic-alias')
it('does not navigate to alias with children if already on original record', async () => {
const { router } = await newRouter()
- const spy = vi.fn((to, from, next) => next())
+ const spy = vi.fn((to, from) => {})
await router.push('/aliases')
router.beforeEach(spy)
await router.push('/aliases1')
it('does not navigate to child alias if already on original record', async () => {
const { router } = await newRouter()
- const spy = vi.fn((to, from, next) => next())
+ const spy = vi.fn((to, from) => {})
await router.push('/aliases/one')
router.beforeEach(spy)
await router.push('/aliases1/one')
const [p1, r1] = fakePromise()
const history = createMemoryHistory()
const router = createRouter({ history, routes })
- router.beforeEach(async (to, from, next) => {
- if (to.name !== 'Param') return next()
+ router.beforeEach(async (to, from) => {
+ if (to.name !== 'Param') return
// the first navigation gets passed target
if (to.params.p === 'a') {
await p1
- target ? next(target) : next()
+ return target || undefined
} else {
// the second one just passes
- next()
+ return
}
})
const from = router.currentRoute.value
await router.push('/p/a')
await router.push('/p/b')
- router.beforeEach(async (to, from, next) => {
- if (to.name !== 'Param') return next()
+ router.beforeEach(async (to, from) => {
+ if (to.name !== 'Param') return
if (to.fullPath === '/foo') {
await p1
- next()
+ return
} else if (from.fullPath === '/p/b') {
await p2
// @ts-ignore: same as function above
- next(target)
+ return target
} else {
- next()
+ return
}
})
it('only triggers guards once with a redirect option', async () => {
const history = createMemoryHistory()
const router = createRouter({ history, routes })
- const spy = vi.fn((to, from, next) => next())
+ const spy = vi.fn((to, from) => {})
router.beforeEach(spy)
await router.push('/to-foo')
expect(spy).toHaveBeenCalledTimes(1)
name: 'dynamic parent',
end: false,
strict: true,
- beforeEnter(to, from, next) {
+ beforeEnter(to, from) {
if (!removeRoute) {
removeRoute = router.addRoute('dynamic parent', {
path: 'child',
name: 'dynamic child',
component: components.Foo,
})
- next(to.fullPath)
- } else next()
+ return to.fullPath
+ } else return
},
})
const homeOnlyRoutes = [experimentalRoutes.find(r => r.name === 'home')!]
const resolver = createFixedResolver(homeOnlyRoutes)
const { router } = await newRouter({ resolver })
- const spy = vi.fn((to, from, next) => next())
+ const spy = vi.fn((_to, _from) => {})
router.beforeEach(spy)
await router.push('/idontexist')
expect(spy).toHaveBeenCalledTimes(1)
const history = createMemoryHistory()
const resolver = createFixedResolver(experimentalRoutes)
const router = experimental_createRouter({ history, resolver })
- router.beforeEach(async (to, from, next) => {
- if (to.name !== 'Param') return next()
+ router.beforeEach(async (to, from) => {
+ if (to.name !== 'Param') return
// the first navigation gets passed target
if (to.params.p === 'a') {
await p1
- target ? next(target) : next()
+ return target || undefined
} else {
// the second one just passes
- next()
+ return
}
})
const from = router.currentRoute.value
await router.push('/p/a')
await router.push('/p/b')
- router.beforeEach(async (to, from, next) => {
- if (to.name !== 'Param' && to.name !== 'Foo') return next()
+ router.beforeEach(async (to, from) => {
+ if (to.name !== 'Param' && to.name !== 'Foo') return
if (to.fullPath === '/foo') {
await p1
- next()
+ return
} else if (from.fullPath === '/p/b') {
await p2
// @ts-ignore: same as function above
- next(target)
+ return target
} else {
- next()
+ return
}
})
})
})
- describe('Dynamic Routing', () => {
+ describe.todo('Dynamic Routing', () => {
it.skip('resolves new added routes', async () => {})
it.skip('checks if a route exists', async () => {})