From b0eab007be29c18e695a06f7aec33a6695d5c0b5 Mon Sep 17 00:00:00 2001 From: Blake Embrey Date: Thu, 29 Aug 2024 16:03:27 -0700 Subject: [PATCH] Get tests passing --- src/cases.spec.ts | 984 ++++++---------------------------------------- src/index.spec.ts | 8 - src/index.ts | 34 +- 3 files changed, 133 insertions(+), 893 deletions(-) diff --git a/src/cases.spec.ts b/src/cases.spec.ts index bc491f9..b45d596 100644 --- a/src/cases.spec.ts +++ b/src/cases.spec.ts @@ -199,7 +199,7 @@ export const MATCH_TESTS: MatchTestSet[] = [ { input: "/test/route", expected: false }, { input: "/test/", - expected: false, + expected: { path: "/test/", params: {} }, }, ], }, @@ -214,7 +214,7 @@ export const MATCH_TESTS: MatchTestSet[] = [ { input: "/test", expected: false }, { input: "/test//", - expected: false, + expected: { path: "/test//", params: {} }, }, ], }, @@ -227,7 +227,7 @@ export const MATCH_TESTS: MatchTestSet[] = [ }, { input: "/route/", - expected: false, + expected: { path: "/route/", params: { test: "route" } }, }, { input: "/route.json", @@ -238,7 +238,10 @@ export const MATCH_TESTS: MatchTestSet[] = [ }, { input: "/route.json/", - expected: false, + expected: { + path: "/route.json/", + params: { test: "route.json" }, + }, }, { input: "/route/test", @@ -313,7 +316,7 @@ export const MATCH_TESTS: MatchTestSet[] = [ }, { input: "/test/", - expected: { path: "/test", params: {} }, + expected: { path: "/test/", params: {} }, }, { input: "/test////", @@ -349,7 +352,7 @@ export const MATCH_TESTS: MatchTestSet[] = [ }, { input: "/test//", - expected: { path: "/test/", params: {} }, + expected: { path: "/test//", params: {} }, }, { input: "/test/route", @@ -373,7 +376,7 @@ export const MATCH_TESTS: MatchTestSet[] = [ }, { input: "/route/", - expected: { path: "/route", params: { test: "route" } }, + expected: { path: "/route/", params: { test: "route" } }, }, { input: "/route.json", @@ -385,7 +388,7 @@ export const MATCH_TESTS: MatchTestSet[] = [ { input: "/route.json/", expected: { - path: "/route.json", + path: "/route.json/", params: { test: "route.json" }, }, }, @@ -449,7 +452,7 @@ export const MATCH_TESTS: MatchTestSet[] = [ }, { input: "/", - expected: { path: "", params: {} }, + expected: { path: "/", params: {} }, }, { input: "route", @@ -470,326 +473,91 @@ export const MATCH_TESTS: MatchTestSet[] = [ * Optional. */ { - path: "{/:test}?", + path: "{/route}", tests: [ - { - input: "/route", - expected: { path: "/route", params: { test: "route" } }, - }, { input: "", expected: { path: "", params: {} }, }, { input: "/", - expected: false, - }, - ], - }, - { - path: "{/:test}?/bar", - tests: [ - { - input: "/bar", - expected: { path: "/bar", params: {} }, - }, - { - input: "/foo/bar", - expected: { path: "/foo/bar", params: { test: "foo" } }, + expected: { path: "/", params: {} }, }, { - input: "/foo/bar/", + input: "/foo", expected: false, }, - ], - }, - { - path: "{/:test}?-bar", - tests: [ { - input: "-bar", - expected: { path: "-bar", params: {} }, - }, - { - input: "/foo-bar", - expected: { path: "/foo-bar", params: { test: "foo" } }, - }, - { - input: "/foo-bar/", - expected: false, + input: "/route", + expected: { path: "/route", params: {} }, }, ], }, { - path: "/{:test}?-bar", + path: "{/:test}", tests: [ { - input: "/-bar", - expected: { path: "/-bar", params: {} }, + input: "/route", + expected: { path: "/route", params: { test: "route" } }, }, { - input: "/foo-bar", - expected: { path: "/foo-bar", params: { test: "foo" } }, + input: "", + expected: { path: "", params: {} }, }, { - input: "/foo-bar/", - expected: false, + input: "/", + expected: { path: "/", params: {} }, }, ], }, - - /** - * Zero or more times. - */ { - path: "{/:test}*", + path: "{/:test}/bar", tests: [ { - input: "/", - expected: false, - }, - { - input: "//", - expected: false, + input: "/bar", + expected: { path: "/bar", params: {} }, }, { - input: "/route", - expected: { path: "/route", params: { test: ["route"] } }, + input: "/foo/bar", + expected: { path: "/foo/bar", params: { test: "foo" } }, }, { - input: "/some/basic/route", - expected: { - path: "/some/basic/route", - params: { test: ["some", "basic", "route"] }, - }, + input: "/foo/bar/", + expected: { path: "/foo/bar/", params: { test: "foo" } }, }, ], }, { - path: "{/:test}*-bar", + path: "{/:test}-bar", tests: [ { input: "-bar", expected: { path: "-bar", params: {} }, }, - { - input: "/-bar", - expected: false, - }, { input: "/foo-bar", - expected: { path: "/foo-bar", params: { test: ["foo"] } }, - }, - { - input: "/foo/baz-bar", - expected: { - path: "/foo/baz-bar", - params: { test: ["foo", "baz"] }, - }, - }, - ], - }, - - /** - * One or more times. - */ - { - path: "{/:test}+", - tests: [ - { - input: "/", - expected: false, - }, - { - input: "//", - expected: false, - }, - { - input: "/route", - expected: { path: "/route", params: { test: ["route"] } }, + expected: { path: "/foo-bar", params: { test: "foo" } }, }, { - input: "/some/basic/route", - expected: { - path: "/some/basic/route", - params: { test: ["some", "basic", "route"] }, - }, + input: "/foo-bar/", + expected: { path: "/foo-bar/", params: { test: "foo" } }, }, ], }, { - path: "{/:test}+-bar", + path: "/{:test}-bar", tests: [ - { - input: "-bar", - expected: false, - }, { input: "/-bar", - expected: false, + expected: { path: "/-bar", params: {} }, }, { input: "/foo-bar", - expected: { path: "/foo-bar", params: { test: ["foo"] } }, - }, - { - input: "/foo/baz-bar", - expected: { - path: "/foo/baz-bar", - params: { test: ["foo", "baz"] }, - }, - }, - ], - }, - - /** - * Custom parameters. - */ - { - path: String.raw`/:test(\d+)`, - tests: [ - { - input: "/123", - expected: { path: "/123", params: { test: "123" } }, - }, - { - input: "/abc", - expected: false, - }, - { - input: "/123/abc", - expected: false, - }, - ], - }, - { - path: String.raw`/:test(\d+)-bar`, - tests: [ - { - input: "-bar", - expected: false, - }, - { - input: "/-bar", - expected: false, - }, - { - input: "/abc-bar", - expected: false, - }, - { - input: "/123-bar", - expected: { path: "/123-bar", params: { test: "123" } }, - }, - { - input: "/123/456-bar", - expected: false, - }, - ], - }, - { - path: "/:test(.*)", - tests: [ - { - input: "/", - expected: { path: "/", params: { test: "" } }, - }, - { - input: "/route", - expected: { path: "/route", params: { test: "route" } }, - }, - { - input: "/route/123", - expected: { - path: "/route/123", - params: { test: "route/123" }, - }, - }, - { - input: "/;,:@&=/+$-_.!/~*()", - expected: { - path: "/;,:@&=/+$-_.!/~*()", - params: { test: ";,:@&=/+$-_.!/~*()" }, - }, - }, - ], - }, - { - path: "/:test([a-z]+)", - tests: [ - { - input: "/abc", - expected: { path: "/abc", params: { test: "abc" } }, - }, - { - input: "/123", - expected: false, - }, - { - input: "/abc/123", - expected: false, - }, - ], - }, - { - path: "/:test(this|that)", - tests: [ - { - input: "/this", - expected: { path: "/this", params: { test: "this" } }, - }, - { - input: "/that", - expected: { path: "/that", params: { test: "that" } }, - }, - { - input: "/foo", - expected: false, - }, - ], - }, - { - path: "{/:test(abc|xyz)}*", - tests: [ - { - input: "/", - expected: false, - }, - { - input: "/abc", - expected: { path: "/abc", params: { test: ["abc"] } }, - }, - { - input: "/abc/abc", - expected: { - path: "/abc/abc", - params: { test: ["abc", "abc"] }, - }, - }, - { - input: "/xyz/xyz", - expected: { - path: "/xyz/xyz", - params: { test: ["xyz", "xyz"] }, - }, - }, - { - input: "/abc/xyz", - expected: { - path: "/abc/xyz", - params: { test: ["abc", "xyz"] }, - }, - }, - { - input: "/abc/xyz/abc/xyz", - expected: { - path: "/abc/xyz/abc/xyz", - params: { test: ["abc", "xyz", "abc", "xyz"] }, - }, + expected: { path: "/foo-bar", params: { test: "foo" } }, }, { - input: "/xyzxyz", - expected: false, + input: "/foo-bar/", + expected: { path: "/foo-bar/", params: { test: "foo" } }, }, ], }, @@ -823,12 +591,12 @@ export const MATCH_TESTS: MatchTestSet[] = [ }, { input: "route/", - expected: false, + expected: { path: "route/", params: { test: "route" } }, }, ], }, { - path: "{:test}?", + path: "{:test}", tests: [ { input: "test", @@ -840,30 +608,6 @@ export const MATCH_TESTS: MatchTestSet[] = [ }, ], }, - { - path: "{:test/}+", - tests: [ - { - input: "route/", - expected: { path: "route/", params: { test: ["route"] } }, - }, - { - input: "/route", - expected: false, - }, - { - input: "", - expected: false, - }, - { - input: "foo/bar/", - expected: { - path: "foo/bar/", - params: { test: ["foo", "bar"] }, - }, - }, - ], - }, /** * Formats. @@ -898,111 +642,7 @@ export const MATCH_TESTS: MatchTestSet[] = [ }, { input: "/route.json.json", - expected: false, - }, - ], - }, - { - path: "/:test([^/]+).json", - tests: [ - { - input: "/route.json.json", - expected: { - path: "/route.json.json", - params: { test: "route.json" }, - }, - }, - ], - }, - - /** - * Format params. - */ - { - path: "/test.:format(\\w+)", - tests: [ - { - input: "/test.html", - expected: { path: "/test.html", params: { format: "html" } }, - }, - { - input: "/test", - expected: false, - }, - ], - }, - { - path: "/test.:format(\\w+).:format(\\w+)", - tests: [ - { - input: "/test.html.json", - expected: { - path: "/test.html.json", - params: { format: "json" }, - }, - }, - { - input: "/test.html", - expected: false, - }, - ], - }, - { - path: "/test{.:format(\\w+)}?", - tests: [ - { - input: "/test", - expected: { path: "/test", params: { format: undefined } }, - }, - { - input: "/test.html", - expected: { path: "/test.html", params: { format: "html" } }, - }, - ], - }, - { - path: "/test{.:format(\\w+)}+", - tests: [ - { - input: "/test", - expected: false, - }, - { - input: "/test.html", - expected: { - path: "/test.html", - params: { format: ["html"] }, - }, - }, - { - input: "/test.html.json", - expected: { - path: "/test.html.json", - params: { format: ["html", "json"] }, - }, - }, - ], - }, - { - path: "/test{.:format}+", - tests: [ - { - input: "/test", - expected: false, - }, - { - input: "/test.html", - expected: { - path: "/test.html", - params: { format: ["html"] }, - }, - }, - { - input: "/test.hbs.html", - expected: { - path: "/test.hbs.html", - params: { format: ["hbs", "html"] }, - }, + expected: { path: "/route.json.json", params: { test: "route.json" } }, }, ], }, @@ -1034,7 +674,7 @@ export const MATCH_TESTS: MatchTestSet[] = [ ], }, { - path: "/:test{.:format}?", + path: "/:test{.:format}", tests: [ { input: "/route", @@ -1073,90 +713,6 @@ export const MATCH_TESTS: MatchTestSet[] = [ ], }, - /** - * Unnamed params. - */ - { - path: "/(\\d+)", - tests: [ - { - input: "/123", - expected: { path: "/123", params: { "0": "123" } }, - }, - { - input: "/abc", - expected: false, - }, - { - input: "/123/abc", - expected: false, - }, - ], - }, - { - path: "{/(\\d+)}?", - tests: [ - { - input: "/", - expected: false, - }, - { - input: "/123", - expected: { path: "/123", params: { "0": "123" } }, - }, - ], - }, - { - path: "/route\\(\\\\(\\d+\\\\)\\)", - tests: [ - { - input: "/route(\\123\\)", - expected: { - path: "/route(\\123\\)", - params: { "0": "123\\" }, - }, - }, - { - input: "/route(\\123)", - expected: false, - }, - ], - }, - { - path: "{/route}?", - tests: [ - { - input: "", - expected: { path: "", params: {} }, - }, - { - input: "/", - expected: false, - }, - { - input: "/foo", - expected: false, - }, - { - input: "/route", - expected: { path: "/route", params: {} }, - }, - ], - }, - { - path: "{/(.*)}", - tests: [ - { - input: "/", - expected: { path: "/", params: { "0": "" } }, - }, - { - input: "/login", - expected: { path: "/login", params: { "0": "login" } }, - }, - ], - }, - /** * Escaped characters. */ @@ -1174,7 +730,7 @@ export const MATCH_TESTS: MatchTestSet[] = [ ], }, { - path: "/.\\+\\*\\?\\{\\}=^\\!\\:$[]\\|", + path: "/.\\+\\*\\?\\{\\}=^\\!\\:$\\[\\]\\|", tests: [ { input: "/.+*?{}=^!:$[]|", @@ -1182,39 +738,6 @@ export const MATCH_TESTS: MatchTestSet[] = [ }, ], }, - { - path: "/test/{:uid(u\\d+)}?{:cid(c\\d+)}?", - tests: [ - { - input: "/test/u123", - expected: { path: "/test/u123", params: { uid: "u123" } }, - }, - { - input: "/test/c123", - expected: { path: "/test/c123", params: { cid: "c123" } }, - }, - ], - }, - - /** - * Unnamed group prefix. - */ - { - path: "/{apple-}?icon-:res(\\d+).png", - tests: [ - { - input: "/icon-240.png", - expected: { path: "/icon-240.png", params: { res: "240" } }, - }, - { - input: "/apple-icon-240.png", - expected: { - path: "/apple-icon-240.png", - params: { res: "240" }, - }, - }, - ], - }, /** * Random examples. @@ -1244,32 +767,6 @@ export const MATCH_TESTS: MatchTestSet[] = [ }, ], }, - { - path: "/:remote([\\w\\-\\.]+)/:user([\\w-]+)", - tests: [ - { - input: "/endpoint/user", - expected: { - path: "/endpoint/user", - params: { remote: "endpoint", user: "user" }, - }, - }, - { - input: "/endpoint/user-name", - expected: { - path: "/endpoint/user-name", - params: { remote: "endpoint", user: "user-name" }, - }, - }, - { - input: "/foo.bar/user-name", - expected: { - path: "/foo.bar/user-name", - params: { remote: "foo.bar", user: "user-name" }, - }, - }, - ], - }, { path: "/:foo\\?", tests: [ @@ -1284,24 +781,7 @@ export const MATCH_TESTS: MatchTestSet[] = [ ], }, { - path: "{/:foo}+bar", - tests: [ - { - input: "/foobar", - expected: { path: "/foobar", params: { foo: ["foo"] } }, - }, - { - input: "/foo/bar", - expected: false, - }, - { - input: "/foo/barbar", - expected: false, - }, - ], - }, - { - path: "/{:pre}?baz", + path: "/{:pre}baz", tests: [ { input: "/foobaz", @@ -1330,7 +810,7 @@ export const MATCH_TESTS: MatchTestSet[] = [ ], }, { - path: "/:foo\\({:bar}?\\)", + path: "/:foo\\({:bar}\\)", tests: [ { input: "/hello(world)", @@ -1349,27 +829,7 @@ export const MATCH_TESTS: MatchTestSet[] = [ ], }, { - path: "/:postType(video|audio|text){(\\+.+)}?", - tests: [ - { - input: "/video", - expected: { path: "/video", params: { postType: "video" } }, - }, - { - input: "/video+test", - expected: { - path: "/video+test", - params: { 0: "+test", postType: "video" }, - }, - }, - { - input: "/video+", - expected: false, - }, - ], - }, - { - path: "{/:foo}?{/:bar}?-ext", + path: "{/:foo}{/:bar}-ext", tests: [ { input: "/-ext", @@ -1400,7 +860,7 @@ export const MATCH_TESTS: MatchTestSet[] = [ ], }, { - path: "/:required{/:optional}?-ext", + path: "/:required{/:optional}-ext", tests: [ { input: "/foo-ext", @@ -1517,7 +977,7 @@ export const MATCH_TESTS: MatchTestSet[] = [ ], }, { - path: "mail{.:domain}?.com", + path: "mail{.:domain}.com", options: { delimiter: ".", }, @@ -1580,7 +1040,7 @@ export const MATCH_TESTS: MatchTestSet[] = [ * Prefixes. */ { - path: "{$:foo}{$:bar}?", + path: "$:foo{$:bar}", tests: [ { input: "$x", @@ -1593,20 +1053,7 @@ export const MATCH_TESTS: MatchTestSet[] = [ ], }, { - path: "{$:foo}+", - tests: [ - { - input: "$x", - expected: { path: "$x", params: { foo: ["x"] } }, - }, - { - input: "$x$y", - expected: { path: "$x$y", params: { foo: ["x", "y"] } }, - }, - ], - }, - { - path: "name{/:attr1}?{-:attr2}?{-:attr3}?", + path: "name{/:attr1}{-:attr2}{-:attr3}", tests: [ { input: "name", @@ -1650,108 +1097,12 @@ export const MATCH_TESTS: MatchTestSet[] = [ }, ], }, - { - path: "name{/:attrs;-}*", - tests: [ - { - input: "name", - expected: { path: "name", params: {} }, - }, - { - input: "name/1", - expected: { - path: "name/1", - params: { attrs: ["1"] }, - }, - }, - { - input: "name/1-2", - expected: { - path: "name/1-2", - params: { attrs: ["1", "2"] }, - }, - }, - { - input: "name/1-2-3", - expected: { - path: "name/1-2-3", - params: { attrs: ["1", "2", "3"] }, - }, - }, - { - input: "name/foo-bar/route", - expected: false, - }, - { - input: "name/test/route", - expected: false, - }, - ], - }, - - /** - * Nested parentheses. - */ - { - path: "/:test(\\d+(?:\\.\\d+)?)", - tests: [ - { - input: "/123", - expected: { path: "/123", params: { test: "123" } }, - }, - { - input: "/abc", - expected: false, - }, - { - input: "/123/abc", - expected: false, - }, - { - input: "/123.123", - expected: { path: "/123.123", params: { test: "123.123" } }, - }, - { - input: "/123.abc", - expected: false, - }, - ], - }, - { - path: "/:test((?!login)[^/]+)", - tests: [ - { - input: "/route", - expected: { path: "/route", params: { test: "route" } }, - }, - { - input: "/login", - expected: false, - }, - ], - }, /** * https://github.com/pillarjs/path-to-regexp/issues/206 */ { - path: "/user{(s)}?/:user", - tests: [ - { - input: "/user/123", - expected: { path: "/user/123", params: { user: "123" } }, - }, - { - input: "/users/123", - expected: { - path: "/users/123", - params: { 0: "s", user: "123" }, - }, - }, - ], - }, - { - path: "/user{s}?/:user", + path: "/user{s}/:user", tests: [ { input: "/user/123", @@ -1765,187 +1116,93 @@ export const MATCH_TESTS: MatchTestSet[] = [ }, /** - * https://github.com/pillarjs/path-to-regexp/pull/270 - */ - { - path: "/files{/:path}*{.:ext}*", - tests: [ - { - input: "/files/hello/world.txt", - expected: { - path: "/files/hello/world.txt", - params: { path: ["hello", "world"], ext: ["txt"] }, - }, - }, - { - input: "/files/hello/world.txt.png", - expected: { - path: "/files/hello/world.txt.png", - params: { path: ["hello", "world"], ext: ["txt", "png"] }, - }, - }, - { - input: "/files/my/photo.jpg/gif", - expected: false, - }, - ], - }, - { - path: "/files{/:path}*{.:ext}?", - tests: [ - { - input: "/files/hello/world.txt", - expected: { - path: "/files/hello/world.txt", - params: { path: ["hello", "world"], ext: "txt" }, - }, - }, - { - input: "/files/my/photo.jpg/gif", - expected: false, - }, - ], - }, - { - path: "#/*", - tests: [ - { - input: "#/", - expected: { path: "#/", params: {} }, - }, - ], - }, - { - path: "/foo{/:bar}*", - tests: [ - { - input: "/foo/test1/test2", - expected: { - path: "/foo/test1/test2", - params: { bar: ["test1", "test2"] }, - }, - }, - ], - }, - { - path: "/entity/:id/*", - tests: [ - { - input: "/entity/foo", - expected: false, - }, - { - input: "/entity/foo/", - expected: { path: "/entity/foo/", params: { id: "foo" } }, - }, - ], - }, - { - path: "/test/*", - tests: [ - { - input: "/test", - expected: false, - }, - { - input: "/test/", - expected: { path: "/test/", params: {} }, - }, - { - input: "/test/route", - expected: { path: "/test/route", params: { "0": ["route"] } }, - }, - { - input: "/test/route/nested", - expected: { - path: "/test/route/nested", - params: { "0": ["route", "nested"] }, - }, - }, - ], - }, - - /** - * Asterisk wildcard. + * Wildcard. */ { - path: "/*", + path: "/*path", tests: [ { input: "/", - expected: { path: "/", params: { "0": undefined } }, + expected: false, }, { input: "/route", - expected: { path: "/route", params: { "0": ["route"] } }, + expected: { path: "/route", params: { path: ["route"] } }, }, { input: "/route/nested", expected: { path: "/route/nested", - params: { "0": ["route", "nested"] }, + params: { path: ["route", "nested"] }, }, }, ], }, { - path: "*", + path: "*path", tests: [ { input: "/", - expected: { path: "/", params: { "0": ["", ""] } }, + expected: { path: "/", params: { path: ["", ""] } }, }, { input: "/test", - expected: { path: "/test", params: { "0": ["", "test"] } }, + expected: { path: "/test", params: { path: ["", "test"] } }, }, ], }, { - path: "*", + path: "*path", options: { decode: false }, tests: [ { input: "/", - expected: { path: "/", params: { "0": "/" } }, + expected: { path: "/", params: { path: "/" } }, }, { input: "/test", - expected: { path: "/test", params: { "0": "/test" } }, + expected: { path: "/test", params: { path: "/test" } }, }, ], }, { - path: "/*.:ext", + path: "/*path.:ext", tests: [ { input: "/test.html", expected: { path: "/test.html", - params: { "0": ["test"], ext: "html" }, + params: { path: ["test"], ext: "html" }, }, }, { input: "/test.html/nested", expected: false, }, + { + input: "/test.html/nested.json", + expected: { + path: "/test.html/nested.json", + params: { path: ["test.html", "nested"], ext: "json" }, + }, + }, ], }, { - path: "/*{.:ext}?", + path: "/*path{.:ext}", tests: [ { input: "/test.html", expected: { path: "/test.html", - params: { "0": ["test.html"], ext: undefined }, + params: { path: ["test"], ext: "html" }, }, }, { input: "/test.html/nested", expected: { params: { - "0": ["test.html", "nested"], + path: ["test.html", "nested"], }, path: "/test.html/nested", }, @@ -1953,22 +1210,17 @@ export const MATCH_TESTS: MatchTestSet[] = [ ], }, { - path: "/*{.:ext}*", + path: "/entity/:id/*path", tests: [ { - input: "/test.html", - expected: { - path: "/test.html", - params: { "0": ["test.html"], ext: undefined }, - }, + input: "/entity/foo", + expected: false, }, { - input: "/test.html/nested", + input: "/entity/foo/path", expected: { - params: { - "0": ["test.html", "nested"], - }, - path: "/test.html/nested", + path: "/entity/foo/path", + params: { id: "foo", path: ["path"] }, }, }, ], @@ -1978,7 +1230,7 @@ export const MATCH_TESTS: MatchTestSet[] = [ * Longer prefix. */ { - path: "/:foo{/test/:bar}?", + path: "/:foo{/test/:bar}", tests: [ { input: "/route", @@ -1994,31 +1246,11 @@ export const MATCH_TESTS: MatchTestSet[] = [ ], }, - /** - * Prefix and suffix as separator. - */ - { - path: "/{<:foo>}+", - tests: [ - { - input: "/", - expected: { path: "/", params: { foo: ["test"] } }, - }, - { - input: "/", - expected: { - path: "/", - params: { foo: ["test", "again"] }, - }, - }, - ], - }, - /** * Backtracking tests. */ { - path: "{:foo/}?{:bar.}?", + path: "{:foo/}{:bar.}", tests: [ { input: "", @@ -2038,7 +1270,7 @@ export const MATCH_TESTS: MatchTestSet[] = [ ], }, { - path: "/abc{abc:foo}?", + path: "/abc{abc:foo}", tests: [ { input: "/abc", @@ -2066,19 +1298,28 @@ export const MATCH_TESTS: MatchTestSet[] = [ ], }, { - path: "/:foo{abc:bar}?", + path: "/:foo{abc:bar}", tests: [ { input: "/abc", - expected: false, + expected: { + params: { foo: "abc" }, + path: "/abc", + }, }, { input: "/abcabc", - expected: false, + expected: { + params: { foo: "abcabc" }, + path: "/abcabc", + }, }, { input: "/abcabc123", - expected: false, + expected: { + params: { foo: "abcabc123" }, + path: "/abcabc123", + }, }, { input: "/acb", @@ -2088,10 +1329,17 @@ export const MATCH_TESTS: MatchTestSet[] = [ }, }, { - input: "/acbabc123", + input: "/123", + expected: { + path: "/123", + params: { foo: "123" }, + }, + }, + { + input: "/123abcabc", expected: { - path: "/acbabc123", - params: { foo: "acb", bar: "123" }, + path: "/123abcabc", + params: { foo: "123", bar: "abc" }, }, }, ], @@ -2111,18 +1359,12 @@ export const MATCH_TESTS: MatchTestSet[] = [ input: "/abcabc123", expected: false, }, - ], - }, - { - path: "/:foo(.*){.:ext}?", - tests: [ - { - input: "/abc", - expected: { path: "/abc", params: { foo: "abc" } }, - }, { - input: "/abc.txt", - expected: { path: "/abc.txt", params: { foo: "abc.txt" } }, + input: "/123abcabc", + expected: { + path: "/123abcabc", + params: { foo: "123", bar: "abc" }, + }, }, ], }, diff --git a/src/index.spec.ts b/src/index.spec.ts index 014c0f5..2399bcb 100644 --- a/src/index.spec.ts +++ b/src/index.spec.ts @@ -56,14 +56,6 @@ describe("path-to-regexp", () => { }).toThrow(new TypeError("Missing parameters: b")); }); - it("should throw when all group children are invalid", () => { - const toPath = compile("/a/{:a,:b,:c}"); - - expect(() => { - toPath(); - }).toThrow(new TypeError("Missing parameters: a, b, c")); - }); - it("should throw when expecting a repeated value", () => { const toPath = compile("/*foo"); diff --git a/src/index.ts b/src/index.ts index f1e4c7a..bfce158 100644 --- a/src/index.ts +++ b/src/index.ts @@ -363,7 +363,7 @@ function tokensToFunction( ); return (data: ParamData) => { - const result: string[] = []; + const result: string[] = [""]; for (const encoder of encoders) { const [value, ...extras] = encoder(data); @@ -462,23 +462,19 @@ function $match

( const { decode = decodeURIComponent, end = true, trailing = true } = options; const flags = toFlags(options); const regexps: string[] = []; - const decoders: Array = []; + const decoders: Array = []; for (const { tokens, delimiter } of data) { const sources: string[] = []; for (const seq of flatten(tokens, 0, [])) { - const [regexp, keys] = sequenceToRegExp( - seq, - decode || NOOP_VALUE, - delimiter, - ); + const [regexp, keys] = sequenceToRegExp(seq, decode, delimiter); sources.push(regexp); decoders.push(...keys); } let pattern = `^(?:${sources.join("|")})`; - if (trailing) pattern += `(?:${escape(delimiter)})?`; + if (trailing) pattern += `(?:${escape(delimiter)}$)?`; pattern += end ? "$" : `(?=${escape(delimiter)}|$)`; regexps.push(pattern); @@ -552,14 +548,14 @@ function* flatten( */ function sequenceToRegExp( tokens: Sequence[], - decode: Decode, + decode: Decode | false, delimiter: string, -): [string, Array] { +): [string, Array] { const patterns = Array(tokens.length); let i = tokens.length; let backtrack = ""; let isLastSegmentParam = true; - const decoders: Array = []; + const decoders: Array = []; while (i--) { const token = tokens[i]; @@ -583,9 +579,11 @@ function sequenceToRegExp( ? `(.+)` : `(${negate(delimiter, isLastSegmentParam ? "" : backtrack)}+)`; decoders.unshift( - token.type === "wildcard" - ? new MatchWildcard(token.name, decode, delimiter) - : new MatchParam(token.name, decode), + decode === false + ? new MatchNoop(token.name) + : token.type === "wildcard" + ? new MatchWildcard(token.name, decode, delimiter) + : new MatchParam(token.name, decode), ); backtrack = ""; isLastSegmentParam = false; @@ -613,6 +611,14 @@ function negate(...args: string[]) { return `(?:(?!${values.map(escape).join("|")}).)`; } +class MatchNoop { + constructor(public name: string) {} + + decode(value: string) { + return value; + } +} + class MatchParam { constructor( public name: string,