]> git.ipfire.org Git - thirdparty/vuejs/router.git/commitdiff
test: remove duplicated cases for replace
authorEduardo San Martin Morote <posva13@gmail.com>
Fri, 27 Mar 2020 14:52:22 +0000 (15:52 +0100)
committerEduardo San Martin Morote <posva13@gmail.com>
Fri, 27 Mar 2020 14:52:22 +0000 (15:52 +0100)
__tests__/guards/component-beforeRouteEnter.spec.ts
__tests__/guards/component-beforeRouteLeave.spec.ts
__tests__/guards/component-beforeRouteUpdate.spec.ts
__tests__/guards/global-after.spec.ts
__tests__/guards/global-beforeEach.spec.ts
__tests__/guards/route-beforeEnter.spec.ts
__tests__/router.spec.ts
__tests__/utils.ts
src/router.ts

index 5f4f48bb2b8d40338c8c082c536f698aaa9f8c32..9dba291068437d567f9250753829f0f9ddfd079c 100644 (file)
@@ -1,6 +1,6 @@
 import { RouterOptions, createRouter as newRouter } from '../../src/router'
 import fakePromise from 'faked-promise'
-import { NAVIGATION_TYPES, createDom, noGuard } from '../utils'
+import { createDom, noGuard } from '../utils'
 import { RouteRecord, NavigationGuard } from '../../src/types'
 import { createWebHistory } from '../../src'
 
@@ -121,129 +121,125 @@ describe('beforeRouteEnter', () => {
     createDom()
   })
 
-  NAVIGATION_TYPES.forEach(navigationMethod => {
-    describe(navigationMethod, () => {
-      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()
-        })
-        await router[navigationMethod]('/guard/valid')
-        expect(beforeRouteEnter).toHaveBeenCalledTimes(1)
-      })
+  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()
+    })
+    await router.push('/guard/valid')
+    expect(beforeRouteEnter).toHaveBeenCalledTimes(1)
+  })
 
-      it('calls beforeRouteEnter guards on navigation for nested views', async () => {
-        const router = createRouter({ routes })
-        await router[navigationMethod]('/nested/nested/foo')
-        expect(nested.parent).toHaveBeenCalledTimes(1)
-        expect(nested.nestedNested).toHaveBeenCalledTimes(1)
-        expect(nested.nestedNestedFoo).toHaveBeenCalledTimes(1)
-        expect(nested.nestedAbs).not.toHaveBeenCalled()
-        expect(nested.nestedA).not.toHaveBeenCalled()
-      })
+  it('calls beforeRouteEnter guards on navigation for nested views', async () => {
+    const router = createRouter({ routes })
+    await router.push('/nested/nested/foo')
+    expect(nested.parent).toHaveBeenCalledTimes(1)
+    expect(nested.nestedNested).toHaveBeenCalledTimes(1)
+    expect(nested.nestedNestedFoo).toHaveBeenCalledTimes(1)
+    expect(nested.nestedAbs).not.toHaveBeenCalled()
+    expect(nested.nestedA).not.toHaveBeenCalled()
+  })
 
-      it('calls beforeRouteEnter guards on navigation for nested views', async () => {
-        const router = createRouter({ routes })
-        await router[navigationMethod]('/nested/nested/foo')
-        expect(nested.parent).toHaveBeenCalledTimes(1)
-        expect(nested.nestedNested).toHaveBeenCalledTimes(1)
-        expect(nested.nestedNestedFoo).toHaveBeenCalledTimes(1)
-      })
+  it('calls beforeRouteEnter guards on navigation for nested views', async () => {
+    const router = createRouter({ routes })
+    await router.push('/nested/nested/foo')
+    expect(nested.parent).toHaveBeenCalledTimes(1)
+    expect(nested.nestedNested).toHaveBeenCalledTimes(1)
+    expect(nested.nestedNestedFoo).toHaveBeenCalledTimes(1)
+  })
 
-      it('calls beforeRouteEnter guards on non-entered nested routes', async () => {
-        const router = createRouter({ routes })
-        await router.push('/nested/nested')
-        resetMocks()
-        await router[navigationMethod]('/nested/nested/foo')
-        expect(nested.parent).not.toHaveBeenCalled()
-        expect(nested.nestedNested).not.toHaveBeenCalled()
-        expect(nested.nestedNestedFoo).toHaveBeenCalledTimes(1)
-      })
+  it('calls beforeRouteEnter guards on non-entered nested routes', async () => {
+    const router = createRouter({ routes })
+    await router.push('/nested/nested')
+    resetMocks()
+    await router.push('/nested/nested/foo')
+    expect(nested.parent).not.toHaveBeenCalled()
+    expect(nested.nestedNested).not.toHaveBeenCalled()
+    expect(nested.nestedNestedFoo).toHaveBeenCalledTimes(1)
+  })
 
-      it('does not call beforeRouteEnter guards on param change', async () => {
-        const router = createRouter({ routes })
-        await router.push('/nested/nested/param/1')
-        resetMocks()
-        await router[navigationMethod]('/nested/nested/param/2')
-        expect(nested.parent).not.toHaveBeenCalled()
-        expect(nested.nestedNested).not.toHaveBeenCalled()
-        expect(nested.nestedNestedParam).not.toHaveBeenCalled()
-      })
+  it('does not call beforeRouteEnter guards on param change', async () => {
+    const router = createRouter({ routes })
+    await router.push('/nested/nested/param/1')
+    resetMocks()
+    await router.push('/nested/nested/param/2')
+    expect(nested.parent).not.toHaveBeenCalled()
+    expect(nested.nestedNested).not.toHaveBeenCalled()
+    expect(nested.nestedNestedParam).not.toHaveBeenCalled()
+  })
 
-      it('calls beforeRouteEnter guards on navigation for named views', async () => {
-        const router = createRouter({ routes })
-        named.default.mockImplementationOnce(noGuard)
-        named.other.mockImplementationOnce(noGuard)
-        await router[navigationMethod]('/named')
-        expect(named.default).toHaveBeenCalledTimes(1)
-        expect(named.other).toHaveBeenCalledTimes(1)
-        expect(router.currentRoute.value.fullPath).toBe('/named')
-      })
+  it('calls beforeRouteEnter guards on navigation for named views', async () => {
+    const router = createRouter({ routes })
+    named.default.mockImplementationOnce(noGuard)
+    named.other.mockImplementationOnce(noGuard)
+    await router.push('/named')
+    expect(named.default).toHaveBeenCalledTimes(1)
+    expect(named.other).toHaveBeenCalledTimes(1)
+    expect(router.currentRoute.value.fullPath).toBe('/named')
+  })
 
-      it('aborts navigation if one of the named views aborts', async () => {
-        const router = createRouter({ routes })
-        named.default.mockImplementationOnce((to, from, next) => {
-          next(false)
-        })
-        named.other.mockImplementationOnce(noGuard)
-        await router[navigationMethod]('/named').catch(err => {}) // catch abort
-        expect(named.default).toHaveBeenCalledTimes(1)
-        expect(router.currentRoute.value.fullPath).not.toBe('/named')
-      })
+  it('aborts navigation if one of the named views aborts', async () => {
+    const router = createRouter({ routes })
+    named.default.mockImplementationOnce((to, from, next) => {
+      next(false)
+    })
+    named.other.mockImplementationOnce(noGuard)
+    await router.push('/named').catch(err => {}) // catch abort
+    expect(named.default).toHaveBeenCalledTimes(1)
+    expect(router.currentRoute.value.fullPath).not.toBe('/named')
+  })
 
-      it('does not call beforeRouteEnter if we were already on the page', async () => {
-        const router = createRouter({ routes })
-        beforeRouteEnter.mockImplementation(noGuard)
-        await router.push('/guard/one')
-        expect(beforeRouteEnter).toHaveBeenCalledTimes(1)
-        await router[navigationMethod]('/guard/one')
-        expect(beforeRouteEnter).toHaveBeenCalledTimes(1)
-      })
+  it('does not call beforeRouteEnter if we were already on the page', async () => {
+    const router = createRouter({ routes })
+    beforeRouteEnter.mockImplementation(noGuard)
+    await router.push('/guard/one')
+    expect(beforeRouteEnter).toHaveBeenCalledTimes(1)
+    await router.push('/guard/one')
+    expect(beforeRouteEnter).toHaveBeenCalledTimes(1)
+  })
+
+  it('waits before navigating', async () => {
+    const [promise, resolve] = fakePromise()
+    const router = createRouter({ routes })
+    beforeRouteEnter.mockImplementationOnce(async (to, from, next) => {
+      await promise
+      next()
+    })
+    const p = router.push('/foo')
+    expect(router.currentRoute.value.fullPath).toBe('/')
+    resolve()
+    await p
+    expect(router.currentRoute.value.fullPath).toBe('/foo')
+  })
 
-      it('waits before navigating', async () => {
-        const [promise, resolve] = fakePromise()
-        const router = createRouter({ routes })
-        beforeRouteEnter.mockImplementationOnce(async (to, from, next) => {
-          await promise
-          next()
-        })
-        const p = router[navigationMethod]('/foo')
-        expect(router.currentRoute.value.fullPath).toBe('/')
-        resolve()
-        await p
+  // TODO:
+  it.skip('calls next callback', async done => {
+    const router = createRouter({ routes })
+    beforeRouteEnter.mockImplementationOnce((to, from, next) => {
+      next(vm => {
         expect(router.currentRoute.value.fullPath).toBe('/foo')
+        expect(vm).toBeTruthy()
+        done()
       })
+    })
 
-      // TODO:
-      it.skip('calls next callback', async done => {
-        const router = createRouter({ routes })
-        beforeRouteEnter.mockImplementationOnce((to, from, next) => {
-          next(vm => {
-            expect(router.currentRoute.value.fullPath).toBe('/foo')
-            expect(vm).toBeTruthy()
-            done()
-          })
-        })
-
-        await router.push('/')
-        await router.push('/guard/2')
-      })
+    await router.push('/')
+    await router.push('/guard/2')
+  })
 
-      it.skip('calls next callback after waiting', async done => {
-        const [promise, resolve] = fakePromise()
-        const router = createRouter({ routes })
-        beforeRouteEnter.mockImplementationOnce(async (to, from, next) => {
-          await promise
-          next(vm => {
-            expect(router.currentRoute.value.fullPath).toBe('/foo')
-            expect(vm).toBeTruthy()
-            done()
-          })
-        })
-        router[navigationMethod]('/foo')
-        resolve()
+  it.skip('calls next callback after waiting', async done => {
+    const [promise, resolve] = fakePromise()
+    const router = createRouter({ routes })
+    beforeRouteEnter.mockImplementationOnce(async (to, from, next) => {
+      await promise
+      next(vm => {
+        expect(router.currentRoute.value.fullPath).toBe('/foo')
+        expect(vm).toBeTruthy()
+        done()
       })
     })
+    router.push('/foo')
+    resolve()
   })
 })
index f88676792c727d203fd2fa360430e1a9d75def86..9a5ce6494bfca7f83e4e8a536653cfeeda09e5c5 100644 (file)
@@ -1,5 +1,5 @@
 import { RouterOptions, createRouter as newRouter } from '../../src/router'
-import { NAVIGATION_TYPES, createDom, noGuard } from '../utils'
+import { createDom, noGuard } from '../utils'
 import { RouteRecord } from '../../src/types'
 import { createWebHistory } from '../../src'
 
@@ -103,87 +103,83 @@ describe('beforeRouteLeave', () => {
     createDom()
   })
 
-  NAVIGATION_TYPES.forEach(navigationMethod => {
-    describe(navigationMethod, () => {
-      it('calls beforeRouteLeave guard on navigation', async () => {
-        const router = createRouter({ routes })
-        beforeRouteLeave.mockImplementationOnce((to, from, next) => {
-          if (to.path === 'foo') next(false)
-          else next()
-        })
-        await router.push('/guard')
-        expect(beforeRouteLeave).not.toHaveBeenCalled()
-
-        await router[navigationMethod]('/foo')
-        expect(beforeRouteLeave).toHaveBeenCalledTimes(1)
-      })
+  it('calls beforeRouteLeave guard on navigation', async () => {
+    const router = createRouter({ routes })
+    beforeRouteLeave.mockImplementationOnce((to, from, next) => {
+      if (to.path === 'foo') next(false)
+      else next()
+    })
+    await router.push('/guard')
+    expect(beforeRouteLeave).not.toHaveBeenCalled()
 
-      it('calls beforeRouteLeave guard on navigation between children', async () => {
-        const router = createRouter({ routes })
-        await router.push({ name: 'nested-path' })
-        resetMocks()
-        await router[navigationMethod]({ name: 'nested-path-b' })
-        expect(nested.nestedEmpty).not.toHaveBeenCalled()
-        expect(nested.nestedAbs).not.toHaveBeenCalled()
-        expect(nested.nestedB).not.toHaveBeenCalled()
-        expect(nested.nestedNestedFoo).not.toHaveBeenCalled()
-        expect(nested.parent).not.toHaveBeenCalled()
-        expect(nested.nestedNested).not.toHaveBeenCalled()
-        expect(nested.nestedA).toHaveBeenCalledTimes(1)
-        expect(nested.nestedA).toHaveBeenCalledWith(
-          expect.objectContaining({
-            name: 'nested-path-b',
-            fullPath: '/nested/b',
-          }),
-          expect.objectContaining({
-            name: 'nested-path',
-            fullPath: '/nested/a',
-          }),
-          expect.any(Function)
-        )
-      })
+    await router.push('/foo')
+    expect(beforeRouteLeave).toHaveBeenCalledTimes(1)
+  })
 
-      it('calls beforeRouteLeave guard on navigation between children in order', async () => {
-        const router = createRouter({ routes })
-        await router.push({ name: 'nested-nested-foo' })
-        resetMocks()
-        let count = 0
-        nested.nestedNestedFoo.mockImplementation((to, from, next) => {
-          expect(count++).toBe(0)
-          next()
-        })
-        nested.nestedNested.mockImplementation((to, from, next) => {
-          expect(count++).toBe(1)
-          next()
-        })
-        nested.parent.mockImplementation((to, from, next) => {
-          expect(count++).toBe(2)
-          next()
-        })
+  it('calls beforeRouteLeave guard on navigation between children', async () => {
+    const router = createRouter({ routes })
+    await router.push({ name: 'nested-path' })
+    resetMocks()
+    await router.push({ name: 'nested-path-b' })
+    expect(nested.nestedEmpty).not.toHaveBeenCalled()
+    expect(nested.nestedAbs).not.toHaveBeenCalled()
+    expect(nested.nestedB).not.toHaveBeenCalled()
+    expect(nested.nestedNestedFoo).not.toHaveBeenCalled()
+    expect(nested.parent).not.toHaveBeenCalled()
+    expect(nested.nestedNested).not.toHaveBeenCalled()
+    expect(nested.nestedA).toHaveBeenCalledTimes(1)
+    expect(nested.nestedA).toHaveBeenCalledWith(
+      expect.objectContaining({
+        name: 'nested-path-b',
+        fullPath: '/nested/b',
+      }),
+      expect.objectContaining({
+        name: 'nested-path',
+        fullPath: '/nested/a',
+      }),
+      expect.any(Function)
+    )
+  })
 
-        await router[navigationMethod]('/')
-        expect(nested.parent).toHaveBeenCalledTimes(1)
-        expect(nested.nestedNested).toHaveBeenCalledTimes(1)
-        expect(nested.nestedNestedFoo).toHaveBeenCalledTimes(1)
-      })
+  it('calls beforeRouteLeave guard on navigation between children in order', async () => {
+    const router = createRouter({ routes })
+    await router.push({ name: 'nested-nested-foo' })
+    resetMocks()
+    let count = 0
+    nested.nestedNestedFoo.mockImplementation((to, from, next) => {
+      expect(count++).toBe(0)
+      next()
+    })
+    nested.nestedNested.mockImplementation((to, from, next) => {
+      expect(count++).toBe(1)
+      next()
+    })
+    nested.parent.mockImplementation((to, from, next) => {
+      expect(count++).toBe(2)
+      next()
+    })
 
-      it('can cancel navigation', async () => {
-        const router = createRouter({ routes })
-        beforeRouteLeave.mockImplementationOnce(async (to, from, next) => {
-          next(false)
-        })
-        await router.push('/guard')
-        const p = router[navigationMethod]('/')
-        const currentRoute = router.currentRoute.value
-        expect(currentRoute.fullPath).toBe('/guard')
-        await p.catch(err => {}) // catch the navigation abortion
-        expect(currentRoute.fullPath).toBe('/guard')
-      })
+    await router.push('/')
+    expect(nested.parent).toHaveBeenCalledTimes(1)
+    expect(nested.nestedNested).toHaveBeenCalledTimes(1)
+    expect(nested.nestedNestedFoo).toHaveBeenCalledTimes(1)
+  })
 
-      it.todo('invokes with the component context')
-      it.todo('invokes with the component context with named views')
-      it.todo('invokes with the component context with nested views')
-      it.todo('invokes with the component context with nested named views')
+  it('can cancel navigation', async () => {
+    const router = createRouter({ routes })
+    beforeRouteLeave.mockImplementationOnce(async (to, from, next) => {
+      next(false)
     })
+    await router.push('/guard')
+    const p = router.push('/')
+    const currentRoute = router.currentRoute.value
+    expect(currentRoute.fullPath).toBe('/guard')
+    await p.catch(err => {}) // catch the navigation abortion
+    expect(currentRoute.fullPath).toBe('/guard')
   })
+
+  it.todo('invokes with the component context')
+  it.todo('invokes with the component context with named views')
+  it.todo('invokes with the component context with nested views')
+  it.todo('invokes with the component context with nested named views')
 })
index f832179c23f5ce698a5974f4d30bd38953d60184..6250b8fa2b5ecaf9679f236ae13c7f55f43377bd 100644 (file)
@@ -1,5 +1,5 @@
 import fakePromise from 'faked-promise'
-import { NAVIGATION_TYPES, createDom, noGuard } from '../utils'
+import { createDom, noGuard } from '../utils'
 import { createRouter as newRouter, createWebHistory } from '../../src'
 import { RouteRecord } from '../../src/types'
 
@@ -39,37 +39,33 @@ describe('beforeRouteUpdate', () => {
     createDom()
   })
 
-  NAVIGATION_TYPES.forEach(navigationMethod => {
-    describe(navigationMethod, () => {
-      it('calls beforeRouteUpdate guards when changing params', async () => {
-        const router = createRouter({ routes })
-        beforeRouteUpdate.mockImplementationOnce(noGuard)
-        await router[navigationMethod]('/guard/valid')
-        // not called on initial navigation
-        expect(beforeRouteUpdate).not.toHaveBeenCalled()
-        await router[navigationMethod]('/guard/other')
-        expect(beforeRouteUpdate).toHaveBeenCalledTimes(1)
-      })
-
-      it('waits before navigating', async () => {
-        const [promise, resolve] = fakePromise()
-        const router = createRouter({ routes })
-        beforeRouteUpdate.mockImplementationOnce(async (to, from, next) => {
-          await promise
-          next()
-        })
-        await router[navigationMethod]('/guard/one')
-        const p = router[navigationMethod]('/guard/foo')
-        expect(router.currentRoute.value.fullPath).toBe('/guard/one')
-        resolve()
-        await p
-        expect(router.currentRoute.value.fullPath).toBe('/guard/foo')
-      })
+  it('calls beforeRouteUpdate guards when changing params', async () => {
+    const router = createRouter({ routes })
+    beforeRouteUpdate.mockImplementationOnce(noGuard)
+    await router.push('/guard/valid')
+    // not called on initial navigation
+    expect(beforeRouteUpdate).not.toHaveBeenCalled()
+    await router.push('/guard/other')
+    expect(beforeRouteUpdate).toHaveBeenCalledTimes(1)
+  })
 
-      it.todo('invokes with the component context')
-      it.todo('invokes with the component context with named views')
-      it.todo('invokes with the component context with nested views')
-      it.todo('invokes with the component context with nested named views')
+  it('waits before navigating', async () => {
+    const [promise, resolve] = fakePromise()
+    const router = createRouter({ routes })
+    beforeRouteUpdate.mockImplementationOnce(async (to, from, next) => {
+      await promise
+      next()
     })
+    await router.push('/guard/one')
+    const p = router.push('/guard/foo')
+    expect(router.currentRoute.value.fullPath).toBe('/guard/one')
+    resolve()
+    await p
+    expect(router.currentRoute.value.fullPath).toBe('/guard/foo')
   })
+
+  it.todo('invokes with the component context')
+  it.todo('invokes with the component context with named views')
+  it.todo('invokes with the component context with nested views')
+  it.todo('invokes with the component context with nested named views')
 })
index 3b6a2039487b694ea39b51f006805e5ddf316eab..a7e55c90ee24c07da4be7c4b48801e1989497382 100644 (file)
@@ -1,4 +1,4 @@
-import { NAVIGATION_TYPES, createDom } from '../utils'
+import { createDom } from '../utils'
 import { createWebHistory, createRouter as newRouter } from '../../src'
 
 function createRouter(
@@ -35,58 +35,54 @@ describe('router.afterEach', () => {
     createDom()
   })
 
-  NAVIGATION_TYPES.forEach(navigationMethod => {
-    describe(navigationMethod, () => {
-      it('calls afterEach guards on push', async () => {
-        const spy = jest.fn()
-        const router = createRouter({ routes })
-        router.afterEach(spy)
-        await router[navigationMethod]('/foo')
-        expect(spy).toHaveBeenCalledTimes(1)
-        expect(spy).toHaveBeenCalledWith(
-          expect.objectContaining({ fullPath: '/foo' }),
-          expect.objectContaining({ fullPath: '/' })
-        )
-      })
+  it('calls afterEach guards on push', async () => {
+    const spy = jest.fn()
+    const router = createRouter({ routes })
+    router.afterEach(spy)
+    await router.push('/foo')
+    expect(spy).toHaveBeenCalledTimes(1)
+    expect(spy).toHaveBeenCalledWith(
+      expect.objectContaining({ fullPath: '/foo' }),
+      expect.objectContaining({ fullPath: '/' })
+    )
+  })
 
-      it('can be removed', async () => {
-        const spy = jest.fn()
-        const router = createRouter({ routes })
-        const remove = router.afterEach(spy)
-        remove()
-        await router[navigationMethod]('/foo')
-        expect(spy).not.toHaveBeenCalled()
-      })
+  it('can be removed', async () => {
+    const spy = jest.fn()
+    const router = createRouter({ routes })
+    const remove = router.afterEach(spy)
+    remove()
+    await router.push('/foo')
+    expect(spy).not.toHaveBeenCalled()
+  })
 
-      it('calls afterEach guards on push', async () => {
-        const spy = jest.fn()
-        const router = createRouter({ routes })
-        await router.push('/nested')
-        router.afterEach(spy)
-        await router[navigationMethod]('/nested/home')
-        expect(spy).toHaveBeenCalledTimes(1)
-        expect(spy).toHaveBeenLastCalledWith(
-          expect.objectContaining({ name: 'nested-home' }),
-          expect.objectContaining({ name: 'nested-default' })
-        )
-        await router[navigationMethod]('/nested')
-        expect(spy).toHaveBeenLastCalledWith(
-          expect.objectContaining({ name: 'nested-default' }),
-          expect.objectContaining({ name: 'nested-home' })
-        )
-        expect(spy).toHaveBeenCalledTimes(2)
-      })
+  it('calls afterEach guards on push', async () => {
+    const spy = jest.fn()
+    const router = createRouter({ routes })
+    await router.push('/nested')
+    router.afterEach(spy)
+    await router.push('/nested/home')
+    expect(spy).toHaveBeenCalledTimes(1)
+    expect(spy).toHaveBeenLastCalledWith(
+      expect.objectContaining({ name: 'nested-home' }),
+      expect.objectContaining({ name: 'nested-default' })
+    )
+    await router.push('/nested')
+    expect(spy).toHaveBeenLastCalledWith(
+      expect.objectContaining({ name: 'nested-default' }),
+      expect.objectContaining({ name: 'nested-home' })
+    )
+    expect(spy).toHaveBeenCalledTimes(2)
+  })
 
-      it('does not call afterEach if navigation is cancelled', async () => {
-        const spy = jest.fn()
-        const router = createRouter({ routes })
-        router.afterEach(spy)
-        router.beforeEach((to, from, next) => {
-          next(false) // cancel the navigation
-        })
-        await router[navigationMethod]('/foo').catch(err => {}) // ignore the error
-        expect(spy).not.toHaveBeenCalled()
-      })
+  it('does not call afterEach if navigation is cancelled', async () => {
+    const spy = jest.fn()
+    const router = createRouter({ routes })
+    router.afterEach(spy)
+    router.beforeEach((to, from, next) => {
+      next(false) // cancel the navigation
     })
+    await router.push('/foo').catch(err => {}) // ignore the error
+    expect(spy).not.toHaveBeenCalled()
   })
 })
index 58df9ed39d54305e59fece26456aacef4b55f222..8ab1421a7ccbdb2ce76ba098afc650f5a54b2b48 100644 (file)
@@ -1,6 +1,6 @@
 import { RouterOptions } from '../../src/router'
 import fakePromise from 'faked-promise'
-import { NAVIGATION_TYPES, createDom, tick, noGuard } from '../utils'
+import { createDom, tick, noGuard } from '../utils'
 import { RouteRecord, RouteLocation } from '../../src/types'
 import { createWebHistory, createRouter as newRouter } from '../../src'
 
@@ -37,201 +37,197 @@ describe('router.beforeEach', () => {
     createDom()
   })
 
-  NAVIGATION_TYPES.forEach(navigationMethod => {
-    describe(navigationMethod, () => {
-      it('calls beforeEach guards on navigation', async () => {
-        const spy = jest.fn()
-        const router = createRouter({ routes })
-        router.beforeEach(spy)
-        spy.mockImplementationOnce(noGuard)
-        await router[navigationMethod]('/foo')
-        expect(spy).toHaveBeenCalledTimes(1)
-      })
-
-      it('can be removed', async () => {
-        const spy = jest.fn()
-        const router = createRouter({ routes })
-        const remove = router.beforeEach(spy)
-        remove()
-        spy.mockImplementationOnce(noGuard)
-        await router[navigationMethod]('/foo')
-        expect(spy).not.toHaveBeenCalled()
-      })
-
-      it('does not call beforeEach guard if we were already on the page', async () => {
-        const spy = jest.fn()
-        const router = createRouter({ routes })
-        await router.push('/foo')
-        router.beforeEach(spy)
-        spy.mockImplementationOnce(noGuard)
-        await router[navigationMethod]('/foo')
-        expect(spy).not.toHaveBeenCalled()
-      })
-
-      it('calls beforeEach guards on navigation between children routes', async () => {
-        const spy = jest.fn()
-        const router = createRouter({ routes })
-        await router.push('/nested')
-        router.beforeEach(spy)
-        spy.mockImplementation(noGuard)
-        await router[navigationMethod]('/nested/home')
-        expect(spy).toHaveBeenCalledTimes(1)
-        expect(spy).toHaveBeenLastCalledWith(
-          expect.objectContaining({ name: 'nested-home' }),
-          expect.objectContaining({ name: 'nested-default' }),
-          expect.any(Function)
-        )
-        await router[navigationMethod]('/nested')
-        expect(spy).toHaveBeenLastCalledWith(
-          expect.objectContaining({ name: 'nested-default' }),
-          expect.objectContaining({ name: 'nested-home' }),
-          expect.any(Function)
-        )
-        expect(spy).toHaveBeenCalledTimes(2)
-      })
-
-      it('can redirect to a different location', async () => {
-        const spy = jest.fn()
-        const router = createRouter({ routes })
-        await router.push('/foo')
-        spy.mockImplementation((to, from, next) => {
-          // only allow going to /other
-          if (to.fullPath !== '/other') next('/other')
-          else next()
-        })
-        router.beforeEach(spy)
-        expect(spy).not.toHaveBeenCalled()
-        await router[navigationMethod]('/')
-        expect(spy).toHaveBeenCalledTimes(2)
-        // called before redirect
-        expect(spy).toHaveBeenNthCalledWith(
-          1,
-          expect.objectContaining({ path: '/' }),
-          expect.objectContaining({ path: '/foo' }),
-          expect.any(Function)
-        )
-        expect(spy).toHaveBeenNthCalledWith(
-          2,
-          expect.objectContaining({ path: '/other' }),
-          expect.objectContaining({ path: '/foo' }),
-          expect.any(Function)
-        )
-        expect(router.currentRoute.value.fullPath).toBe('/other')
-      })
-
-      async function assertRedirect(redirectFn: (i: string) => RouteLocation) {
-        const spy = jest.fn()
-        const router = createRouter({ routes })
-        await router.push('/')
-        spy.mockImplementation((to, from, next) => {
-          // only allow going to /other
-          const i = Number(to.params.i)
-          if (i >= 3) next()
-          else next(redirectFn(String(i + 1)))
-        })
-        router.beforeEach(spy)
-        expect(spy).not.toHaveBeenCalled()
-        await router[navigationMethod]('/n/0')
-        expect(spy).toHaveBeenCalledTimes(4)
-        expect(router.currentRoute.value.fullPath).toBe('/n/3')
-      }
-
-      it('can redirect multiple times with string redirect', async () => {
-        await assertRedirect(i => '/n/' + i)
-      })
-
-      it('can redirect multiple times with path object', async () => {
-        await assertRedirect(i => ({ path: '/n/' + i }))
-      })
-
-      it('can redirect multiple times with named route', async () => {
-        await assertRedirect(i => ({ name: 'n', params: { i } }))
-      })
-
-      it('is called when changing params', async () => {
-        const spy = jest.fn()
-        const router = createRouter({ routes: [...routes] })
-        await router.push('/n/2')
-        spy.mockImplementation(noGuard)
-        router.beforeEach(spy)
-        spy.mockImplementationOnce(noGuard)
-        await router[navigationMethod]('/n/1')
-        expect(spy).toHaveBeenCalledTimes(1)
-      })
-
-      it('is not called with same params', async () => {
-        const spy = jest.fn()
-        const router = createRouter({ routes: [...routes] })
-        await router.push('/n/2')
-        spy.mockImplementation(noGuard)
-        router.beforeEach(spy)
-        spy.mockImplementationOnce(noGuard)
-        await router[navigationMethod]('/n/2')
-        expect(spy).not.toHaveBeenCalled()
-      })
-
-      it('waits before navigating', async () => {
-        const [promise, resolve] = fakePromise()
-        const router = createRouter({ routes })
-        router.beforeEach(async (to, from, next) => {
-          await promise
-          next()
-        })
-        const p = router[navigationMethod]('/foo')
-        expect(router.currentRoute.value.fullPath).toBe('/')
-        resolve()
-        await p
-        expect(router.currentRoute.value.fullPath).toBe('/foo')
-      })
-
-      it('waits in the right order', async () => {
-        const [p1, r1] = fakePromise()
-        const [p2, r2] = fakePromise()
-        const router = createRouter({ routes })
-        const guard1 = jest.fn()
-        let order = 0
-        guard1.mockImplementationOnce(async (to, from, next) => {
-          expect(order++).toBe(0)
-          await p1
-          next()
-        })
-        router.beforeEach(guard1)
-        const guard2 = jest.fn()
-        guard2.mockImplementationOnce(async (to, from, next) => {
-          expect(order++).toBe(1)
-          await p2
-          next()
-        })
-        router.beforeEach(guard2)
-        let navigation = router[navigationMethod]('/foo')
-        expect(router.currentRoute.value.fullPath).toBe('/')
-        expect(guard1).not.toHaveBeenCalled()
-        expect(guard2).not.toHaveBeenCalled()
-        r1() // resolve the first guard
-        await tick() // wait a tick
-        await tick() // mocha requires an extra tick here
-        expect(guard1).toHaveBeenCalled()
-        // we haven't resolved the second gurad yet
-        expect(router.currentRoute.value.fullPath).toBe('/')
-        r2()
-        await navigation
-        expect(guard2).toHaveBeenCalled()
-        expect(router.currentRoute.value.fullPath).toBe('/foo')
-      })
-
-      it('adds meta information', async () => {
-        const spy = jest.fn()
-        const router = createRouter({ routes })
-        router.beforeEach(spy)
-        spy.mockImplementationOnce(noGuard)
-        await router[navigationMethod]('/n/2')
-        expect(spy).toHaveBeenCalledTimes(1)
-        expect(spy).toHaveBeenCalledWith(
-          expect.objectContaining({ meta: { requiresLogin: true } }),
-          expect.objectContaining({ meta: {} }),
-          expect.any(Function)
-        )
-      })
+  it('calls beforeEach guards on navigation', async () => {
+    const spy = jest.fn()
+    const router = createRouter({ routes })
+    router.beforeEach(spy)
+    spy.mockImplementationOnce(noGuard)
+    await router.push('/foo')
+    expect(spy).toHaveBeenCalledTimes(1)
+  })
+
+  it('can be removed', async () => {
+    const spy = jest.fn()
+    const router = createRouter({ routes })
+    const remove = router.beforeEach(spy)
+    remove()
+    spy.mockImplementationOnce(noGuard)
+    await router.push('/foo')
+    expect(spy).not.toHaveBeenCalled()
+  })
+
+  it('does not call beforeEach guard if we were already on the page', async () => {
+    const spy = jest.fn()
+    const router = createRouter({ routes })
+    await router.push('/foo')
+    router.beforeEach(spy)
+    spy.mockImplementationOnce(noGuard)
+    await router.push('/foo')
+    expect(spy).not.toHaveBeenCalled()
+  })
+
+  it('calls beforeEach guards on navigation between children routes', async () => {
+    const spy = jest.fn()
+    const router = createRouter({ routes })
+    await router.push('/nested')
+    router.beforeEach(spy)
+    spy.mockImplementation(noGuard)
+    await router.push('/nested/home')
+    expect(spy).toHaveBeenCalledTimes(1)
+    expect(spy).toHaveBeenLastCalledWith(
+      expect.objectContaining({ name: 'nested-home' }),
+      expect.objectContaining({ name: 'nested-default' }),
+      expect.any(Function)
+    )
+    await router.push('/nested')
+    expect(spy).toHaveBeenLastCalledWith(
+      expect.objectContaining({ name: 'nested-default' }),
+      expect.objectContaining({ name: 'nested-home' }),
+      expect.any(Function)
+    )
+    expect(spy).toHaveBeenCalledTimes(2)
+  })
+
+  it('can redirect to a different location', async () => {
+    const spy = jest.fn()
+    const router = createRouter({ routes })
+    await router.push('/foo')
+    spy.mockImplementation((to, from, next) => {
+      // only allow going to /other
+      if (to.fullPath !== '/other') next('/other')
+      else next()
+    })
+    router.beforeEach(spy)
+    expect(spy).not.toHaveBeenCalled()
+    await router.push('/')
+    expect(spy).toHaveBeenCalledTimes(2)
+    // called before redirect
+    expect(spy).toHaveBeenNthCalledWith(
+      1,
+      expect.objectContaining({ path: '/' }),
+      expect.objectContaining({ path: '/foo' }),
+      expect.any(Function)
+    )
+    expect(spy).toHaveBeenNthCalledWith(
+      2,
+      expect.objectContaining({ path: '/other' }),
+      expect.objectContaining({ path: '/foo' }),
+      expect.any(Function)
+    )
+    expect(router.currentRoute.value.fullPath).toBe('/other')
+  })
+
+  async function assertRedirect(redirectFn: (i: string) => RouteLocation) {
+    const spy = jest.fn()
+    const router = createRouter({ routes })
+    await router.push('/')
+    spy.mockImplementation((to, from, next) => {
+      // only allow going to /other
+      const i = Number(to.params.i)
+      if (i >= 3) next()
+      else next(redirectFn(String(i + 1)))
+    })
+    router.beforeEach(spy)
+    expect(spy).not.toHaveBeenCalled()
+    await router.push('/n/0')
+    expect(spy).toHaveBeenCalledTimes(4)
+    expect(router.currentRoute.value.fullPath).toBe('/n/3')
+  }
+
+  it('can redirect multiple times with string redirect', async () => {
+    await assertRedirect(i => '/n/' + i)
+  })
+
+  it('can redirect multiple times with path object', async () => {
+    await assertRedirect(i => ({ path: '/n/' + i }))
+  })
+
+  it('can redirect multiple times with named route', async () => {
+    await assertRedirect(i => ({ name: 'n', params: { i } }))
+  })
+
+  it('is called when changing params', async () => {
+    const spy = jest.fn()
+    const router = createRouter({ routes: [...routes] })
+    await router.push('/n/2')
+    spy.mockImplementation(noGuard)
+    router.beforeEach(spy)
+    spy.mockImplementationOnce(noGuard)
+    await router.push('/n/1')
+    expect(spy).toHaveBeenCalledTimes(1)
+  })
+
+  it('is not called with same params', async () => {
+    const spy = jest.fn()
+    const router = createRouter({ routes: [...routes] })
+    await router.push('/n/2')
+    spy.mockImplementation(noGuard)
+    router.beforeEach(spy)
+    spy.mockImplementationOnce(noGuard)
+    await router.push('/n/2')
+    expect(spy).not.toHaveBeenCalled()
+  })
+
+  it('waits before navigating', async () => {
+    const [promise, resolve] = fakePromise()
+    const router = createRouter({ routes })
+    router.beforeEach(async (to, from, next) => {
+      await promise
+      next()
+    })
+    const p = router.push('/foo')
+    expect(router.currentRoute.value.fullPath).toBe('/')
+    resolve()
+    await p
+    expect(router.currentRoute.value.fullPath).toBe('/foo')
+  })
+
+  it('waits in the right order', async () => {
+    const [p1, r1] = fakePromise()
+    const [p2, r2] = fakePromise()
+    const router = createRouter({ routes })
+    const guard1 = jest.fn()
+    let order = 0
+    guard1.mockImplementationOnce(async (to, from, next) => {
+      expect(order++).toBe(0)
+      await p1
+      next()
     })
+    router.beforeEach(guard1)
+    const guard2 = jest.fn()
+    guard2.mockImplementationOnce(async (to, from, next) => {
+      expect(order++).toBe(1)
+      await p2
+      next()
+    })
+    router.beforeEach(guard2)
+    let navigation = router.push('/foo')
+    expect(router.currentRoute.value.fullPath).toBe('/')
+    expect(guard1).not.toHaveBeenCalled()
+    expect(guard2).not.toHaveBeenCalled()
+    r1() // resolve the first guard
+    await tick() // wait a tick
+    await tick() // mocha requires an extra tick here
+    expect(guard1).toHaveBeenCalled()
+    // we haven't resolved the second gurad yet
+    expect(router.currentRoute.value.fullPath).toBe('/')
+    r2()
+    await navigation
+    expect(guard2).toHaveBeenCalled()
+    expect(router.currentRoute.value.fullPath).toBe('/foo')
+  })
+
+  it('adds meta information', async () => {
+    const spy = jest.fn()
+    const router = createRouter({ routes })
+    router.beforeEach(spy)
+    spy.mockImplementationOnce(noGuard)
+    await router.push('/n/2')
+    expect(spy).toHaveBeenCalledTimes(1)
+    expect(spy).toHaveBeenCalledWith(
+      expect.objectContaining({ meta: { requiresLogin: true } }),
+      expect.objectContaining({ meta: {} }),
+      expect.any(Function)
+    )
   })
 })
index 58ed89185ef35f3211815c38ff43dbc53443ffdf..a69c8396033fbffbb9940cde3afcdf0ed21733fc 100644 (file)
@@ -1,6 +1,6 @@
 import { RouterOptions, createRouter as newRouter } from '../../src/router'
 import fakePromise from 'faked-promise'
-import { NAVIGATION_TYPES, createDom, noGuard, tick } from '../utils'
+import { createDom, noGuard, tick } from '../utils'
 import { RouteRecord } from '../../src/types'
 import { createWebHistory } from '../../src'
 
@@ -106,102 +106,98 @@ describe('beforeEnter', () => {
     createDom()
   })
 
-  NAVIGATION_TYPES.forEach(navigationMethod => {
-    describe(navigationMethod, () => {
-      it('calls beforeEnter guards on navigation', async () => {
-        const router = createRouter({ routes })
-        beforeEnter.mockImplementationOnce(noGuard)
-        await router[navigationMethod]('/guard/valid')
-        expect(beforeEnter).toHaveBeenCalledTimes(1)
-      })
+  it('calls beforeEnter guards on navigation', async () => {
+    const router = createRouter({ routes })
+    beforeEnter.mockImplementationOnce(noGuard)
+    await router.push('/guard/valid')
+    expect(beforeEnter).toHaveBeenCalledTimes(1)
+  })
 
-      it('supports an array of beforeEnter', async () => {
-        const router = createRouter({ routes })
-        await router[navigationMethod]('/multiple')
-        expect(beforeEnters[0]).toHaveBeenCalledTimes(1)
-        expect(beforeEnters[1]).toHaveBeenCalledTimes(1)
-        expect(beforeEnters[0]).toHaveBeenCalledWith(
-          expect.objectContaining({ path: '/multiple' }),
-          expect.objectContaining({ path: '/' }),
-          expect.any(Function)
-        )
-      })
+  it('supports an array of beforeEnter', async () => {
+    const router = createRouter({ routes })
+    await router.push('/multiple')
+    expect(beforeEnters[0]).toHaveBeenCalledTimes(1)
+    expect(beforeEnters[1]).toHaveBeenCalledTimes(1)
+    expect(beforeEnters[0]).toHaveBeenCalledWith(
+      expect.objectContaining({ path: '/multiple' }),
+      expect.objectContaining({ path: '/' }),
+      expect.any(Function)
+    )
+  })
 
-      it('call beforeEnter in nested views', async () => {
-        const router = createRouter({ routes })
-        await router.push('/nested/a')
-        resetMocks()
-        await router[navigationMethod]('/nested/nested/foo')
-        expect(nested.parent).not.toHaveBeenCalled()
-        expect(nested.nestedA).not.toHaveBeenCalled()
-        expect(nested.nestedNested).toHaveBeenCalledTimes(1)
-        expect(nested.nestedNestedFoo).toHaveBeenCalledTimes(1)
-        expect(nested.nestedNested).toHaveBeenCalledWith(
-          expect.objectContaining({ path: '/nested/nested/foo' }),
-          expect.objectContaining({ path: '/nested/a' }),
-          expect.any(Function)
-        )
-        expect(nested.nestedNestedFoo).toHaveBeenCalledWith(
-          expect.objectContaining({ path: '/nested/nested/foo' }),
-          expect.objectContaining({ path: '/nested/a' }),
-          expect.any(Function)
-        )
-      })
+  it('call beforeEnter in nested views', async () => {
+    const router = createRouter({ routes })
+    await router.push('/nested/a')
+    resetMocks()
+    await router.push('/nested/nested/foo')
+    expect(nested.parent).not.toHaveBeenCalled()
+    expect(nested.nestedA).not.toHaveBeenCalled()
+    expect(nested.nestedNested).toHaveBeenCalledTimes(1)
+    expect(nested.nestedNestedFoo).toHaveBeenCalledTimes(1)
+    expect(nested.nestedNested).toHaveBeenCalledWith(
+      expect.objectContaining({ path: '/nested/nested/foo' }),
+      expect.objectContaining({ path: '/nested/a' }),
+      expect.any(Function)
+    )
+    expect(nested.nestedNestedFoo).toHaveBeenCalledWith(
+      expect.objectContaining({ path: '/nested/nested/foo' }),
+      expect.objectContaining({ path: '/nested/a' }),
+      expect.any(Function)
+    )
+  })
 
-      it('calls beforeEnter different records, same component', async () => {
-        const router = createRouter({ routes })
-        beforeEnter.mockImplementationOnce(noGuard)
-        await router.push('/')
-        expect(beforeEnter).not.toHaveBeenCalled()
-        await router[navigationMethod]('/home')
-        expect(beforeEnter).toHaveBeenCalledTimes(1)
-      })
+  it('calls beforeEnter different records, same component', async () => {
+    const router = createRouter({ routes })
+    beforeEnter.mockImplementationOnce(noGuard)
+    await router.push('/')
+    expect(beforeEnter).not.toHaveBeenCalled()
+    await router.push('/home')
+    expect(beforeEnter).toHaveBeenCalledTimes(1)
+  })
 
-      it('does not call beforeEnter guard if we were already on the page', async () => {
-        const router = createRouter({ routes })
-        beforeEnter.mockImplementation(noGuard)
-        await router.push('/guard/one')
-        expect(beforeEnter).toHaveBeenCalledTimes(1)
-        await router[navigationMethod]('/guard/one')
-        expect(beforeEnter).toHaveBeenCalledTimes(1)
-      })
+  it('does not call beforeEnter guard if we were already on the page', async () => {
+    const router = createRouter({ routes })
+    beforeEnter.mockImplementation(noGuard)
+    await router.push('/guard/one')
+    expect(beforeEnter).toHaveBeenCalledTimes(1)
+    await router.push('/guard/one')
+    expect(beforeEnter).toHaveBeenCalledTimes(1)
+  })
 
-      it('waits before navigating', async () => {
-        const [promise, resolve] = fakePromise()
-        const router = createRouter({ routes })
-        beforeEnter.mockImplementationOnce(async (to, from, next) => {
-          await promise
-          next()
-        })
-        const p = router[navigationMethod]('/foo')
-        expect(router.currentRoute.value.fullPath).toBe('/')
-        resolve()
-        await p
-        expect(router.currentRoute.value.fullPath).toBe('/foo')
-      })
+  it('waits before navigating', async () => {
+    const [promise, resolve] = fakePromise()
+    const router = createRouter({ routes })
+    beforeEnter.mockImplementationOnce(async (to, from, next) => {
+      await promise
+      next()
+    })
+    const p = router.push('/foo')
+    expect(router.currentRoute.value.fullPath).toBe('/')
+    resolve()
+    await p
+    expect(router.currentRoute.value.fullPath).toBe('/foo')
+  })
 
-      it('waits before navigating in an array of beforeEnter', async () => {
-        const [p1, r1] = fakePromise()
-        const [p2, r2] = fakePromise()
-        const router = createRouter({ routes })
-        beforeEnters[0].mockImplementationOnce(async (to, from, next) => {
-          await p1
-          next()
-        })
-        beforeEnters[1].mockImplementationOnce(async (to, from, next) => {
-          await p2
-          next()
-        })
-        const p = router[navigationMethod]('/multiple')
-        expect(router.currentRoute.value.fullPath).toBe('/')
-        expect(beforeEnters[1]).not.toHaveBeenCalled()
-        r1()
-        await p1
-        await tick()
-        r2()
-        await p
-        expect(router.currentRoute.value.fullPath).toBe('/multiple')
-      })
+  it('waits before navigating in an array of beforeEnter', async () => {
+    const [p1, r1] = fakePromise()
+    const [p2, r2] = fakePromise()
+    const router = createRouter({ routes })
+    beforeEnters[0].mockImplementationOnce(async (to, from, next) => {
+      await p1
+      next()
+    })
+    beforeEnters[1].mockImplementationOnce(async (to, from, next) => {
+      await p2
+      next()
     })
+    const p = router.push('/multiple')
+    expect(router.currentRoute.value.fullPath).toBe('/')
+    expect(beforeEnters[1]).not.toHaveBeenCalled()
+    r1()
+    await p1
+    await tick()
+    r2()
+    await p
+    expect(router.currentRoute.value.fullPath).toBe('/multiple')
   })
 })
index 73db654689c306a042ab9579a0dbf6da615a7564..6617fa6775bb0f3a866d9a95e3a3be5366bc7f8a 100644 (file)
@@ -149,6 +149,38 @@ describe('Router', () => {
     )
   })
 
+  it('can replaces current location with a string location', async () => {
+    const { router, history } = await newRouter()
+    jest.spyOn(history, 'replace')
+    await router.replace('/foo')
+    expect(history.replace).toHaveBeenCalledTimes(1)
+    expect(history.replace).toHaveBeenCalledWith(
+      expect.objectContaining({
+        fullPath: '/foo',
+        path: '/foo',
+        query: {},
+        hash: '',
+      }),
+      undefined
+    )
+  })
+
+  it('can replaces current location with an object location', async () => {
+    const { router, history } = await newRouter()
+    jest.spyOn(history, 'replace')
+    await router.replace({ path: '/foo' })
+    expect(history.replace).toHaveBeenCalledTimes(1)
+    expect(history.replace).toHaveBeenCalledWith(
+      expect.objectContaining({
+        fullPath: '/foo',
+        path: '/foo',
+        query: {},
+        hash: '',
+      }),
+      undefined
+    )
+  })
+
   it('navigates if the location does not exist', async () => {
     const { router } = await newRouter()
     const spy = jest.fn((to, from, next) => next())
index f9023308e5a4bf3b1865f93ca85bdb64e0ccd028..061201654b580c9afc09a59fc2dd86c56f48c1e9 100644 (file)
@@ -21,9 +21,6 @@ export async function ticks(n: number) {
   }
 }
 
-export type NAVIGATION_METHOD = 'push' | 'replace'
-export const NAVIGATION_TYPES: NAVIGATION_METHOD[] = ['push', 'replace']
-
 export interface RouteRecordViewLoose
   extends Pick<
     RouteRecordMultipleViews,
index 89907ee1a73ae12c67401d479d603a7a22bbb264..22182c09a1a50b98028d2701db9d370ad6c1cf28 100644 (file)
@@ -213,6 +213,11 @@ export function createRouter({
     return pushWithRedirect(to, undefined)
   }
 
+  function replace(to: RouteLocation | RouteLocationNormalized) {
+    const location = typeof to === 'string' ? { path: to } : to
+    return push({ ...location, replace: true })
+  }
+
   async function pushWithRedirect(
     to: RouteLocation | RouteLocationNormalized,
     redirectedFrom: RouteLocationNormalized | undefined
@@ -266,11 +271,6 @@ export function createRouter({
     return currentRoute.value
   }
 
-  function replace(to: RouteLocation | RouteLocationNormalized) {
-    const location = typeof to === 'string' ? { path: to } : to
-    return push({ ...location, replace: true })
-  }
-
   async function navigate(
     to: RouteLocationNormalized,
     from: RouteLocationNormalizedResolved