From: Eduardo San Martin Morote Date: Sat, 14 Mar 2020 22:40:19 +0000 (+0100) Subject: feat(matcher): remove aliases alongside the original record X-Git-Tag: v4.0.0-alpha.4~67 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=26b71b285b743ab8af94b9297fa7037872ae0de6;p=thirdparty%2Fvuejs%2Frouter.git feat(matcher): remove aliases alongside the original record --- diff --git a/__tests__/matcher/addingRemoving.spec.ts b/__tests__/matcher/addingRemoving.spec.ts index b377d35a..d6341cf1 100644 --- a/__tests__/matcher/addingRemoving.spec.ts +++ b/__tests__/matcher/addingRemoving.spec.ts @@ -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([], {}) @@ -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) + }) }) diff --git a/src/matcher/index.ts b/src/matcher/index.ts index 621eb226..1246aa92 100644 --- a/src/matcher/index.ts +++ b/src/matcher/index.ts @@ -13,6 +13,8 @@ import { PathParserOptions, } from './path-parser-ranker' +let noop = () => {} + interface RouterMatcher { addRoute: ( record: RouteRecord, @@ -72,6 +74,7 @@ export function createRouterMatcher( } let matcher: RouteRecordMatcher + let originalMatcher: RouteRecordMatcher | undefined for (const normalizedRecord of normalizedRecords) { let { path } = normalizedRecord @@ -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( @@ -105,20 +118,22 @@ 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) @@ -126,6 +141,7 @@ export function createRouterMatcher( matchers.splice(index, 1) if (matcherRef.record.name) matcherMap.delete(matcherRef.record.name) matcherRef.children.forEach(removeRoute) + matcherRef.alias.forEach(removeRoute) } } } diff --git a/src/matcher/path-matcher.ts b/src/matcher/path-matcher.ts index 0d315e28..34c5f47a 100644 --- a/src/matcher/path-matcher.ts +++ b/src/matcher/path-matcher.ts @@ -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( @@ -25,6 +27,7 @@ export function createRouteRecordMatcher( parent, // these needs to be populated by the parent children: [], + alias: [], } if (parent) {