Skip to content

Commit

Permalink
feat(matcher): remove aliases alongside the original record
Browse files Browse the repository at this point in the history
  • Loading branch information
posva committed Mar 14, 2020
1 parent 72bbb7f commit 26b71b2
Show file tree
Hide file tree
Showing 3 changed files with 178 additions and 9 deletions.
158 changes: 154 additions & 4 deletions __tests__/matcher/addingRemoving.spec.ts
Expand Up @@ -60,8 +60,70 @@ describe('normalizeRouteRecord', () => {
})
})

it.todo('remove aliases')
it.todo('remove aliases children')
it('remove aliases', () => {
const matcher = createRouterMatcher([], {})
const remove = matcher.addRoute({
path: '/',
component,
name: 'home',
alias: ['/home', '/start'],
})
remove()
expect(matcher.resolve({ path: '/' }, currentLocation)).toMatchObject({
path: '/',
name: undefined,
matched: [],
})
expect(matcher.resolve({ path: '/home' }, currentLocation)).toMatchObject(
{
path: '/home',
name: undefined,
matched: [],
}
)
expect(
matcher.resolve({ path: '/start' }, currentLocation)
).toMatchObject({
path: '/start',
name: undefined,
matched: [],
})
})

it('remove aliases children', () => {
const matcher = createRouterMatcher([], {})
const remove = matcher.addRoute({
path: '/',
component,
name: 'home',
alias: ['/home', '/start'],
children: [
{
path: 'one',
alias: ['o, o2'],
component,
children: [{ path: 'two', alias: ['t', 't2'], component }],
},
],
})
remove()
;[
'/',
'/start',
'/home',
'/one/two',
'/start/one/two',
'/home/o/two',
'/home/one/t2',
'/o2/t',
].forEach(path => {
expect(matcher.resolve({ path }, currentLocation)).toMatchObject({
path,
name: undefined,
matched: [],
})
})
})

it('remove children when removing the parent', () => {
const matcher = createRouterMatcher([], {})
Expand Down Expand Up @@ -176,7 +238,95 @@ describe('normalizeRouteRecord', () => {
expect(matcher.getRecordMatcher('child')).toBe(undefined)
})

it.todo('removes alias by name')
it('removes alias (and original) by name', () => {
const matcher = createRouterMatcher([], {})
matcher.addRoute({
path: '/',
alias: '/start',
component,
name: 'home',
})

matcher.removeRoute('home')

expect(matcher.resolve({ path: '/start' }, currentLocation)).toMatchObject({
name: undefined,
matched: [],
})
})

it('removes all children alias when removing parent by name', () => {
const matcher = createRouterMatcher([], {})
matcher.addRoute({
path: '/',
alias: ['/start', '/home'],
component,
name: 'home',
children: [
{
path: 'one',
alias: ['o', 'o2'],
component,
children: [{ path: 'two', alias: ['t', 't2'], component }],
},
],
})

matcher.removeRoute('home')
;[
'/',
'/start',
'/home',
'/one/two',
'/start/one/two',
'/home/o/two',
'/home/one/t2',
'/o2/t',
].forEach(path => {
expect(matcher.resolve({ path }, currentLocation)).toMatchObject({
path,
name: undefined,
matched: [],
})
})
})

it('removes children alias (and original) by name', () => {
const matcher = createRouterMatcher([], {})
matcher.addRoute({
path: '/',
alias: '/start',
component,
name: 'home',
children: [{ path: 'about', alias: 'two', name: 'child', component }],
})

matcher.removeRoute('child')

expect(matcher.resolve({ path: '/about' }, currentLocation)).toMatchObject({
name: undefined,
matched: [],
})

expect(matcher.resolve({ path: '/two' }, currentLocation)).toMatchObject({
name: undefined,
matched: [],
})

it.todo('removes children alias by name')
expect(
matcher.resolve({ path: '/start/about' }, currentLocation)
).toMatchObject({
name: undefined,
matched: [],
})

expect(
matcher.resolve({ path: '/start/two' }, currentLocation)
).toMatchObject({
name: undefined,
matched: [],
})

expect(matcher.getRecordMatcher('child')).toBe(undefined)
})
})
26 changes: 21 additions & 5 deletions src/matcher/index.ts
Expand Up @@ -13,6 +13,8 @@ import {
PathParserOptions,
} from './path-parser-ranker'

let noop = () => {}

interface RouterMatcher {
addRoute: (
record: RouteRecord,
Expand Down Expand Up @@ -72,6 +74,7 @@ export function createRouterMatcher(
}

let matcher: RouteRecordMatcher
let originalMatcher: RouteRecordMatcher | undefined

for (const normalizedRecord of normalizedRecords) {
let { path } = normalizedRecord
Expand All @@ -89,6 +92,16 @@ export function createRouterMatcher(
// create the object before hand so it can be passed to children
matcher = createRouteRecordMatcher(normalizedRecord, parent, options)

// if we are an alias we must tell the original record that we exist
// so we can be removed
if (originalRecord) {
originalRecord.alias.push(matcher)
} else {
// otherwise, the first record is the original and others are aliases
originalMatcher = originalMatcher || matcher
if (originalMatcher !== matcher) originalMatcher.alias.push(matcher)
}

let children = mainNormalizedRecord.children
for (let i = 0; i < children.length; i++) {
addRoute(
Expand All @@ -105,27 +118,30 @@ export function createRouterMatcher(
insertMatcher(matcher)
}

return () => {
// since other matchers are aliases, they should should be removed by any of the matchers
removeRoute(matcher)
}
return originalMatcher
? () => {
// since other matchers are aliases, they should be removed by the original matcher
removeRoute(originalMatcher!)
}
: noop
}

function removeRoute(matcherRef: string | RouteRecordMatcher) {
// TODO: remove aliases (needs to keep them in the RouteRecordMatcher first)
if (typeof matcherRef === 'string') {
const matcher = matcherMap.get(matcherRef)
if (matcher) {
matcherMap.delete(matcherRef)
matchers.splice(matchers.indexOf(matcher), 1)
matcher.children.forEach(removeRoute)
matcher.alias.forEach(removeRoute)
}
} else {
let index = matchers.indexOf(matcherRef)
if (index > -1) {
matchers.splice(index, 1)
if (matcherRef.record.name) matcherMap.delete(matcherRef.record.name)
matcherRef.children.forEach(removeRoute)
matcherRef.alias.forEach(removeRoute)
}
}
}
Expand Down
3 changes: 3 additions & 0 deletions src/matcher/path-matcher.ts
Expand Up @@ -10,6 +10,8 @@ export interface RouteRecordMatcher extends PathParser {
record: RouteRecordNormalized
parent: RouteRecordMatcher | undefined
children: RouteRecordMatcher[]
// aliases that must be removed when removing this record
alias: RouteRecordMatcher[]
}

export function createRouteRecordMatcher(
Expand All @@ -25,6 +27,7 @@ export function createRouteRecordMatcher(
parent,
// these needs to be populated by the parent
children: [],
alias: [],
}

if (parent) {
Expand Down

0 comments on commit 26b71b2

Please sign in to comment.