--- /dev/null
+import { createRouterMatcher } from '../../src/matcher'
+import { MatcherLocationNormalized } from '../../src/types'
+
+const currentLocation = { path: '/' } as MatcherLocationNormalized
+// @ts-ignore
+const component: RouteComponent = null
+
+describe('normalizeRouteRecord', () => {
+ it('can add records', () => {
+ const matcher = createRouterMatcher([], {})
+ matcher.addRoute({ path: '/', component, name: 'home' })
+ expect(matcher.resolve({ path: '/' }, currentLocation)).toMatchObject({
+ name: 'home',
+ })
+ })
+
+ describe('addRoute returned function', () => {
+ it('remove records', () => {
+ const matcher = createRouterMatcher([], {})
+ const remove = matcher.addRoute({ path: '/', component, name: 'home' })
+ remove()
+ expect(() => {
+ matcher.resolve({ path: '/' }, currentLocation)
+ }).toThrow()
+ })
+
+ it.todo('remove aliases')
+ it.todo('remove children')
+ it.todo('remove aliases children')
+ })
+
+ it('can remove records by name', () => {
+ const matcher = createRouterMatcher([], {})
+ matcher.addRoute({ path: '/', component, name: 'home' })
+ matcher.removeRoute('home')
+ // TODO: this sholud probably return an empty `matched` instead. It needs extra refactoring
+ expect(() => {
+ matcher.resolve({ path: '/' }, currentLocation)
+ }).toThrow()
+ })
+
+ it('removes children', () => {
+ const matcher = createRouterMatcher([], {})
+ matcher.addRoute({
+ path: '/',
+ component,
+ name: 'home',
+ children: [
+ // absolute path so it can work out
+ { path: '/about', component },
+ ],
+ })
+
+ matcher.removeRoute('home')
+ expect(() => {
+ matcher.resolve({ path: '/about' }, currentLocation)
+ }).toThrow()
+ })
+
+ it.todo('removes alias by name')
+ it.todo('removes children by name')
+ it.todo('removes children alias by name')
+})
const ChildA = { path: 'a', name: 'child-a', components }
const ChildB = { path: 'b', name: 'child-b', components }
const ChildC = { path: 'c', name: 'child-c', components }
+ const ChildD = { path: '/absolute', name: 'absolute', components }
const ChildWithParam = { path: ':p', name: 'child-params', components }
const NestedChildWithParam = {
...ChildWithParam,
}
)
})
+
+ it('resolves absolute path children', () => {
+ const Foo = {
+ path: '/foo',
+ name: 'Foo',
+ components,
+ children: [ChildA, ChildD],
+ }
+ assertRecordMatch(
+ Foo,
+ { path: '/absolute' },
+ {
+ name: 'absolute',
+ path: '/absolute',
+ params: {},
+ matched: [Foo, ChildD],
+ }
+ )
+ })
})
})
})
RouteRecord,
MatcherLocation,
MatcherLocationNormalized,
+ ListenerRemover,
} from '../types'
import { NoRouteMatchError } from '../errors'
import { createRouteRecordMatcher, RouteRecordMatcher } from './path-matcher'
} from './path-parser-ranker'
interface RouterMatcher {
- addRoute: (record: RouteRecord, parent?: RouteRecordMatcher) => void
- removeRoute: (name: Required<RouteRecord>['name']) => void
+ addRoute: (
+ record: RouteRecord,
+ parent?: RouteRecordMatcher
+ ) => ListenerRemover
+ removeRoute: {
+ (matcher: RouteRecordMatcher): void
+ (name: Required<RouteRecord>['name']): void
+ }
// TODO:
// getRoutes: () => RouteRecordMatcher
// hasRoute: (name: Required<RouteRecord>['name']) => boolean
function addRoute(
record: Readonly<RouteRecord>,
parent?: RouteRecordMatcher
- ): void {
+ ) {
const mainNormalizedRecord = normalizeRouteRecord(record)
const options: PathParserOptions = { ...globalOptions, ...record.options }
// TODO: can probably be removed now that we have our own parser and we handle this correctly
}
}
+ let addedMatchers: RouteRecordMatcher[] = []
+
for (const normalizedRecord of normalizedRecords) {
let { path } = normalizedRecord
// build up the path for nested routes if the child isn't an absolute route
}
insertMatcher(matcher)
+ addedMatchers.push(matcher)
+ }
+
+ return () => {
+ // TODO: not the good method because it should work when passing a string too
+ addedMatchers.forEach(removeRoute)
}
}
function removeRoute(matcherRef: string | RouteRecordMatcher) {
if (typeof matcherRef === 'string') {
- const matcher = matcherMap.get(name)
+ const matcher = matcherMap.get(matcherRef)
if (matcher) {
- matcherMap.delete(name)
+ matcherMap.delete(matcherRef)
matchers.splice(matchers.indexOf(matcher), 1)
matcher.children.forEach(removeRoute)
}