From c08ae009da09f3bd7ff88318d0f78b1a4a01853a Mon Sep 17 00:00:00 2001 From: Pavel Lang Date: Thu, 20 Oct 2016 20:34:04 +0200 Subject: [PATCH] Provide all URL parameters to each route (#57) --- src/matchPath.js | 6 +++++- src/matchRoute.js | 9 +++++---- test/resolve.spec.js | 47 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 57 insertions(+), 5 deletions(-) diff --git a/src/matchPath.js b/src/matchPath.js index c498f48..8164164 100644 --- a/src/matchPath.js +++ b/src/matchPath.js @@ -23,7 +23,7 @@ function decodeParam(val) { } } -function matchPathBase(end, routePath, urlPath) { +function matchPathBase(end, routePath, urlPath, parentParams) { const key = `${routePath}|${end}`; let regexp = cache.get(key); @@ -40,6 +40,10 @@ function matchPathBase(end, routePath, urlPath) { } const params = Object.create(null); + if (parentParams) { + Object.assign(params, parentParams); + } + const path = m[0]; for (let i = 1; i < m.length; i += 1) { diff --git a/src/matchRoute.js b/src/matchRoute.js index c3cc411..1e32671 100644 --- a/src/matchRoute.js +++ b/src/matchRoute.js @@ -9,11 +9,11 @@ import { matchPath, matchBasePath } from './matchPath'; -function* matchRoute(route, baseUrl, path) { +function* matchRoute(route, baseUrl, path, parentParams) { let match; if (!route.children) { - match = matchPath(route.path, path); + match = matchPath(route.path, path, parentParams); if (match) { yield { @@ -27,7 +27,7 @@ function* matchRoute(route, baseUrl, path) { } if (route.children) { - match = matchBasePath(route.path, path); + match = matchBasePath(route.path, path, parentParams); if (match) { yield { route, @@ -42,7 +42,8 @@ function* matchRoute(route, baseUrl, path) { yield* matchRoute( childRoute, baseUrl + (match.path === '/' ? '' : match.path), - newPath.startsWith('/') ? newPath : `/${newPath}` + newPath.startsWith('/') ? newPath : `/${newPath}`, + match.params ); } } diff --git a/test/resolve.spec.js b/test/resolve.spec.js index f659bc5..ea7edfe 100644 --- a/test/resolve.spec.js +++ b/test/resolve.spec.js @@ -88,6 +88,53 @@ describe('resolve(routes, { path, ...context })', () => { expect(action.args[0][0]).to.have.deep.property('params.two', 'b'); }); + it('should provide all URL parameters to each route', async () => { + const action = sinon.spy(); + const routes = [ + { + path: '/:one', + children: [ + { + path: '/:two', + action, + }, + ], + action, + }, + ]; + await resolve(routes, { path: '/a/b' }); + expect(action.calledTwice).to.be.true; + expect(action.args[0][0]).to.have.deep.property('params.one', 'a'); + expect(action.args[1][0]).to.have.deep.property('params.one', 'a'); + expect(action.args[1][0]).to.have.deep.property('params.two', 'b'); + }); + + it('should override URL parameters with same name in child route', async () => { + const action = sinon.spy(); + const routes = [ + { + path: '/:one', + children: [ + { + path: '/:one', + action, + }, + { + path: '/:two', + action, + }, + ], + action, + }, + ]; + await resolve(routes, { path: '/a/b' }); + expect(action.calledThrice).to.be.true; + expect(action.args[0][0]).to.have.deep.property('params.one', 'a'); + expect(action.args[1][0]).to.have.deep.property('params.one', 'b'); + expect(action.args[2][0]).to.have.deep.property('params.one', 'a'); + expect(action.args[2][0]).to.have.deep.property('params.two', 'b'); + }); + it('should support next() across multiple routes', async () => { const log = []; const routes = [