From 66cacedf8c045505a07341f15a4b89dffede52c6 Mon Sep 17 00:00:00 2001 From: dzyhenry Date: Sat, 29 Sep 2018 16:59:30 +0800 Subject: [PATCH] add backtrace feature for splat matching --- index.js | 20 +++++++++++++++++++- test/index.js | 26 ++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/index.js b/index.js index 46a4c07..dd97527 100644 --- a/index.js +++ b/index.js @@ -17,11 +17,13 @@ function get(pathname) { var pathSegments = pathname.split('/'); var hash = this._hash; + var parentNode = hash; var splat = null; var params = {}; var variablePaths; + var i = 0; - for (var i = 0; i < pathSegments.length; i++) { + for (; i < pathSegments.length; i++) { var segment = pathSegments[i]; if (!segment && !hash.isSplat) { @@ -32,14 +34,17 @@ function get(pathname) { ) { hash = hash.proto; } else if (hash.staticPaths.hasOwnProperty(segment)) { + parentNode = hash; hash = hash.staticPaths[segment]; } else if ((variablePaths = hash.variablePaths)) { if (variablePaths.isSplat) { splat = pathSegments.slice(i).join('/'); + parentNode = hash; hash = variablePaths; break; } else { params[variablePaths.segment] = segment; + parentNode = hash; hash = variablePaths; } } else { @@ -48,6 +53,19 @@ function get(pathname) { } } + // backtrace + while (hash === null && parentNode && i >= 0) { + var parentVp = parentNode.variablePaths; + i -= 1; + if (parentVp && parentVp.isSplat) { + splat = pathSegments.slice(i).join('/'); + hash = parentVp; + break; + } else { + parentNode = parentNode.parent; + } + } + // Match the empty splat if (hash && hash.handler === null && diff --git a/test/index.js b/test/index.js index 67d3a5a..7f6328c 100644 --- a/test/index.js +++ b/test/index.js @@ -23,6 +23,32 @@ test('http hash inserts root', function (assert) { assert.end(); }); +test('http hash test priority of /a/b/c and /a/b/*', function (assert) { + // Arrange + function routeHandlerABC() {} + function routeHandlerABStar() {} + + var hash = HttpHash(); + + // Act + hash.set('/a/b/c', routeHandlerABC); + hash.set('/a/b/*', routeHandlerABStar); + + // get + var res1 = hash.get('/a/b/c'); + var res2 = hash.get('/a/b/c/d'); + var res3 = hash.get('/a/b/e'); + var res4 = hash.get('/a/b'); + var res5 = hash.get('/a/c'); + // Assert + assert.strictEqual(res1.handler, routeHandlerABC); + assert.strictEqual(res2.handler, routeHandlerABStar); + assert.strictEqual(res3.handler, routeHandlerABStar); + assert.strictEqual(res4.handler, routeHandlerABStar); + assert.strictEqual(res5.handler, null); + assert.end(); +}); + test('http hash inserts fixed route', function (assert) { // Arrange function routeHandler() {}