]> git.ipfire.org Git - thirdparty/vuejs/router.git/commitdiff
test: matcher.removeRoute
authorEduardo San Martin Morote <posva13@gmail.com>
Fri, 7 Feb 2020 14:07:24 +0000 (15:07 +0100)
committerEduardo San Martin Morote <posva13@gmail.com>
Fri, 7 Feb 2020 14:07:24 +0000 (15:07 +0100)
__tests__/matcher/addingRemoving.spec.ts [new file with mode: 0644]
__tests__/matcher/resolve.spec.ts
src/matcher/index.ts

diff --git a/__tests__/matcher/addingRemoving.spec.ts b/__tests__/matcher/addingRemoving.spec.ts
new file mode 100644 (file)
index 0000000..0300021
--- /dev/null
@@ -0,0 +1,63 @@
+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')
+})
index 0de5afe6127b6611c21c4532ca5eaa07806942a8..8c2139f2f8f2e928b76814effd488b894bfa2569 100644 (file)
@@ -586,6 +586,7 @@ describe('Router Matcher', () => {
       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,
@@ -820,6 +821,25 @@ describe('Router Matcher', () => {
           }
         )
       })
+
+      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],
+          }
+        )
+      })
     })
   })
 })
index 134b599a616a2d4b15bc4f496c56e1e4638affbe..6ade595d8f432b6b25fcfce7ec5ea8d5ea9b5a22 100644 (file)
@@ -2,6 +2,7 @@ import {
   RouteRecord,
   MatcherLocation,
   MatcherLocationNormalized,
+  ListenerRemover,
 } from '../types'
 import { NoRouteMatchError } from '../errors'
 import { createRouteRecordMatcher, RouteRecordMatcher } from './path-matcher'
@@ -13,8 +14,14 @@ import {
 } 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
@@ -40,7 +47,7 @@ export function createRouterMatcher(
   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
@@ -60,6 +67,8 @@ export function createRouterMatcher(
       }
     }
 
+    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
@@ -81,14 +90,20 @@ export function createRouterMatcher(
       }
 
       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)
       }