diff --git a/lib/router.js b/lib/router.js index eb51758..9e21686 100644 --- a/lib/router.js +++ b/lib/router.js @@ -146,39 +146,50 @@ Route.prototype.match = function (url, options) { */ Route.prototype.makePath = function (params, query) { var routePath = this.config.path; - var compiler; var err; - var url; - var strQuery; + var i; + var len; if (Array.isArray(routePath)) { - routePath = routePath[0]; - } - - if (typeof routePath === 'string') { - compiler = cachedCompilers[routePath] || pathToRegexp.compile(routePath); - cachedCompilers[routePath] = compiler; - - try { - url = compiler(params); - if (query) { - strQuery = this._queryLib.stringify(query); - if (strQuery) { - url += '?' + strQuery; - } + for (i = 0, len = routePath.length; i < len; i++) { + try { + return this._makePath(routePath[i], params, query); + } catch (pathErr) { + err = pathErr; } - return url; - } catch (e) { - err = e; } } else { - err = new TypeError('route path must be a string:' + routePath); + try { + return this._makePath(routePath, params, query) + } catch (pathErr) { + err = pathErr; + } } debug('Route.makePath failed, e = ', err); return null; }; +Route.prototype._makePath = function(routePath, params, query) { + var compiler; + var url; + var strQuery; + if (typeof routePath === 'string') { + compiler = cachedCompilers[routePath] || pathToRegexp.compile(routePath); + cachedCompilers[routePath] = compiler; + url = compiler(params); + if (query) { + strQuery = this._queryLib.stringify(query); + if (strQuery) { + url += '?' + strQuery; + } + } + return url; + } else { + throw new TypeError('route path must be a string:' + routePath); + } +} + /** * A Router class that provides route matching and route generation functionalities. * @class Router diff --git a/tests/unit/lib/router.js b/tests/unit/lib/router.js index 2de0892..154c2f9 100644 --- a/tests/unit/lib/router.js +++ b/tests/unit/lib/router.js @@ -69,6 +69,12 @@ var routesObject = { method: 'GET', page: 'arrayPathNameCollision' }, + array_path_with_different_props: { + path: [ + '/array/path/with/different/props/foo/:foo', + '/array/path/with/different/props/bar/:bar' + ] + }, invalid_path: { path: 123 }, @@ -82,6 +88,8 @@ var routesArray = Object.keys(routesObject).map(function (routeName) { }); }); var encodingConsistencyPath = '/path/with/some/json_value/%7B%22keyword%22%3A%22foo%22%7D'; +var arrayPathWithDifferentPropsFoo = '/array/path/with/different/props/foo/foo'; +var arrayPathWithDifferentPropsBar = '/array/path/with/different/props/bar/bar'; describe('Router', function () { [routesObject, routesArray].forEach(function (routes, key) { @@ -292,6 +300,12 @@ describe('Router', function () { var route = router.getRoute(encodingConsistencyPath); expect(route.params.json).to.equal('{"keyword":"foo"}'); }); + it('route with array path with different props', function () { + var routeFoo = router.getRoute(arrayPathWithDifferentPropsFoo); + expect(routeFoo.params.foo).to.equal('foo'); + var routeBar = router.getRoute(arrayPathWithDifferentPropsBar); + expect(routeBar.params.bar).to.equal('bar'); + }); it('should handle a hash fragment with a question-mark', function () { var route = router.getRoute('/finance/news/test.html#?', {method: 'get'}); expect(route.name).to.equal('article'); @@ -409,6 +423,18 @@ describe('Router', function () { }); expect(path).to.equal(encodingConsistencyPath); }); + it('array path with different props', function () { + var pathFoo = router.makePath('array_path_with_different_props', { + foo: 'foo' + }); + expect(pathFoo).to.equal(arrayPathWithDifferentPropsFoo); + var pathBar = router.makePath('array_path_with_different_props', { + bar: 'bar' + }); + expect(pathBar).to.equal(arrayPathWithDifferentPropsBar); + var pathInvalid = router.makePath('array_path_with_different_props', {}); + expect(pathInvalid).to.equal(null); + }); }); it('should throw if route name is not defined', function () {