import { components } from '../utils'
import { normalizeRouteRecord } from '../../src/matcher'
import { RouteRecordNormalized } from 'src/matcher/types'
+import { mockWarn } from 'jest-mock-warn'
const beforeRouteEnter = jest.fn()
const from = START_LOCATION_NORMALIZED
const NoGuard: RouteRecordRaw = { path: '/', component: components.Home }
+const InvalidRoute: RouteRecordRaw = {
+ path: '/',
+ // @ts-ignore: intended error
+ component: null,
+}
+const WrongLazyRoute: RouteRecordRaw = {
+ path: '/',
+ // @ts-ignore: intended error
+ component: Promise.resolve(components.Home),
+}
const SingleGuard: RouteRecordRaw = {
path: '/',
component: { ...components.Home, beforeRouteEnter },
}
describe('extractComponentsGuards', () => {
+ mockWarn()
+
it('extracts guards from one single component', async () => {
await checkGuards([SingleGuard], 1)
})
await checkGuards([SingleGuard, SingleGuard], 2)
await checkGuards([SingleGuardNamed, SingleGuardNamed], 4)
})
+
+ it('throws if component is null', async () => {
+ // @ts-ignore
+ await expect(checkGuards([InvalidRoute], 2)).rejects.toHaveProperty(
+ 'message',
+ expect.stringMatching('Invalid route component')
+ )
+ expect('is not a valid component').toHaveBeenWarned()
+ })
+
+ it('warns wrong lazy component', async () => {
+ await checkGuards([WrongLazyRoute], 0, 1)
+ expect('Promise instead of a function').toHaveBeenWarned()
+ })
})
NavigationRedirectError,
} from './errors'
import { ComponentOptions, onUnmounted, onActivated, onDeactivated } from 'vue'
-import { inject, getCurrentInstance, warn } from 'vue'
+import { inject, getCurrentInstance } from 'vue'
import { matchedRouteKey } from './injectionSymbols'
import { RouteRecordNormalized } from './matcher/types'
import { isESModule } from './utils'
+import { warn } from './warning'
function registerGuard(list: NavigationGuard[], guard: NavigationGuard) {
const removeFromList = () => {
for (const record of matched) {
for (const name in record.components) {
let rawComponent = record.components[name]
- // warn if user wrote import('/component.vue') instead of () => import('./component.vue')
- if (__DEV__ && 'then' in rawComponent) {
- warn(
- `Component "${name}" in record with path "${record.path}" is a Promise instead of a function that returns a Promise. Did you write "import('./MyPage.vue')" instead of "() => import('./MyPage.vue')"? This will break in production if not fixed.`
- )
- let promise = rawComponent
- rawComponent = () => promise
+ if (__DEV__) {
+ if (
+ !rawComponent ||
+ (typeof rawComponent !== 'object' &&
+ typeof rawComponent !== 'function')
+ ) {
+ warn(
+ `Component "${name}" in record with path "${record.path}" is not` +
+ ` a valid component. Received "${String(rawComponent)}".`
+ )
+ // throw to ensure we stop here but warn to ensure the message isn't
+ // missed by the user
+ throw new Error('Invalid route component')
+ } else if ('then' in rawComponent) {
+ // warn if user wrote import('/component.vue') instead of () =>
+ // import('./component.vue')
+ warn(
+ `Component "${name}" in record with path "${record.path}" is a ` +
+ `Promise instead of a function that returns a Promise. Did you ` +
+ `write "import('./MyPage.vue')" instead of ` +
+ `"() => import('./MyPage.vue')" ? This will break in ` +
+ `production if not fixed.`
+ )
+ let promise = rawComponent
+ rawComponent = () => promise
+ }
}
// skip update and leave guards if the route component is not mounted