304 lines
7.8 KiB
TypeScript
304 lines
7.8 KiB
TypeScript
import { compile, pathToRegexp } from "path-to-regexp"
|
|
import { describe, expect, test } from "vitest"
|
|
|
|
import {
|
|
MissingOptionalParamError,
|
|
MissingRequiredParamError,
|
|
parseFullPathParams,
|
|
parseRegexpPathParams,
|
|
regexpPathToPath,
|
|
transformUriPath,
|
|
} from "./path-parser"
|
|
|
|
describe("test `transformUriPath()`", () => {
|
|
test("normal path", () => {
|
|
expect(transformUriPath("/issues/all")).toMatchInlineSnapshot(`"/issues/all"`)
|
|
})
|
|
|
|
test("has tailing optional params", () => {
|
|
const path = transformUriPath("/issues/:id?")
|
|
expect(path).toMatchInlineSnapshot(`"/issues{/:id}"`)
|
|
expect(compile(path)({})).toMatchInlineSnapshot(`"/issues"`)
|
|
const regexp = pathToRegexp(path)
|
|
expect(regexp.keys).toMatchInlineSnapshot(`
|
|
[
|
|
{
|
|
"name": "id",
|
|
"type": "param",
|
|
},
|
|
]
|
|
`)
|
|
})
|
|
|
|
test("has tailing optional params and with value", () => {
|
|
const path = transformUriPath("/issues/:id?")
|
|
|
|
expect(
|
|
compile(path)({
|
|
id: "1111111",
|
|
}),
|
|
).toMatchInlineSnapshot(`"/issues/1111111"`)
|
|
const regexp = pathToRegexp(path)
|
|
expect(regexp.keys).toMatchInlineSnapshot(`
|
|
[
|
|
{
|
|
"name": "id",
|
|
"type": "param",
|
|
},
|
|
]
|
|
`)
|
|
})
|
|
|
|
test("catch all path", () => {
|
|
const path = transformUriPath("/:path{.+}?")
|
|
expect(path).toMatchInlineSnapshot(`"{/*path}"`)
|
|
expect(
|
|
compile(path)({
|
|
path: ["a", "b", "c"],
|
|
}),
|
|
).toMatchInlineSnapshot(`"/a/b/c"`)
|
|
})
|
|
|
|
test("catch all path with leading route", () => {
|
|
const path = transformUriPath("/issues/:path{.+}?")
|
|
expect(path).toMatchInlineSnapshot(`"/issues{/*path}"`)
|
|
expect(
|
|
compile(path)({
|
|
path: ["a", "b", "c"],
|
|
}),
|
|
).toMatchInlineSnapshot(`"/issues/a/b/c"`)
|
|
})
|
|
|
|
test("catch all path but value is query search string", () => {
|
|
const path = transformUriPath("/issues/:path{.+}?")
|
|
expect(path).toMatchInlineSnapshot(`"/issues{/*path}"`)
|
|
expect(
|
|
compile(path)({
|
|
path: ["a=1&b=2"],
|
|
}),
|
|
).toMatchInlineSnapshot(`"/issues/a%3D1%26b%3D2"`)
|
|
})
|
|
|
|
test("catch all route via `*`", () => {
|
|
expect(transformUriPath("/issues/*")).toMatchInlineSnapshot(`"/issues{/:__catchAll__}"`)
|
|
expect(transformUriPath("*")).toMatchInlineSnapshot(`"{/:__catchAll__}"`)
|
|
})
|
|
})
|
|
|
|
describe("test `regexpPathToPath()`", () => {
|
|
test("normal path", () => {
|
|
expect(regexpPathToPath("/issues/all", {})).toMatchInlineSnapshot(`"/issues/all"`)
|
|
})
|
|
test("path with optional params", () => {
|
|
expect(regexpPathToPath("/issues/:id?", {})).toMatchInlineSnapshot(`"/issues"`)
|
|
expect(regexpPathToPath("/issues/:id?", { id: "1" })).toMatchInlineSnapshot(`"/issues/1"`)
|
|
})
|
|
|
|
test("path with many optional params", () => {
|
|
expect(
|
|
regexpPathToPath("/issue/:user/:repo/:state?/:labels?", {
|
|
user: "rssnext",
|
|
repo: "follow",
|
|
}),
|
|
).toMatchInlineSnapshot(`"/issue/rssnext/follow"`)
|
|
})
|
|
|
|
test("path with many optional params, but when using the optional parameter(s) after the optional parameter(s), the previous optional parameter(s) is/are not filled in.", () => {
|
|
expect(() =>
|
|
regexpPathToPath("/issue/:user/:repo/:state?/:labels?", {
|
|
user: "rssnext",
|
|
repo: "follow",
|
|
labels: "rss",
|
|
}),
|
|
).toThrowError(MissingOptionalParamError)
|
|
})
|
|
test("path with many optional params, but when using the optional parameter(s) after the optional parameter(s), the previous optional parameter(s) is/are not filled in.", () => {
|
|
expect(() =>
|
|
regexpPathToPath("/ranking/:rid?/:day?/:arc_type?/:disableEmbed?", {
|
|
day: "1",
|
|
}),
|
|
).toThrowError(MissingOptionalParamError)
|
|
})
|
|
|
|
test("missing required param", () => {
|
|
expect(() => regexpPathToPath("/issue/:user/:repo/:state?/:labels?", {})).toThrow(
|
|
MissingRequiredParamError,
|
|
)
|
|
})
|
|
|
|
test("path with many optional params and all inputted", () => {
|
|
expect(
|
|
regexpPathToPath("/issue/:user/:repo/:state?/:labels?", {
|
|
user: "rssnext",
|
|
repo: "follow",
|
|
state: "open",
|
|
labels: "rss",
|
|
}),
|
|
).toMatchInlineSnapshot(`"/issue/rssnext/follow/open/rss"`)
|
|
})
|
|
|
|
test("omit empty string and nil value", () => {
|
|
expect(
|
|
regexpPathToPath(
|
|
"/issue/:user/:repo/:state?/:labels?",
|
|
{
|
|
user: "rssnext",
|
|
repo: "follow",
|
|
state: "open",
|
|
labels: "",
|
|
},
|
|
{
|
|
omitNilAndEmptyString: true,
|
|
},
|
|
),
|
|
).toMatchInlineSnapshot(`"/issue/rssnext/follow/open"`)
|
|
})
|
|
|
|
test("omit empty string and nil value will throw", () => {
|
|
expect(() =>
|
|
regexpPathToPath(
|
|
"/issue/:user/:repo/:state?/:labels?",
|
|
{
|
|
user: "rssnext",
|
|
repo: "follow",
|
|
state: "",
|
|
labels: "l",
|
|
},
|
|
{
|
|
omitNilAndEmptyString: true,
|
|
},
|
|
),
|
|
).toThrow(MissingOptionalParamError)
|
|
})
|
|
|
|
test("omit empty string and nil value will throw (default behavior)", () => {
|
|
expect(() =>
|
|
regexpPathToPath("/issue/:user/:repo/:state?/:labels?", {
|
|
user: "rssnext",
|
|
repo: "follow",
|
|
state: "",
|
|
labels: "l",
|
|
}),
|
|
).toThrow(MissingOptionalParamError)
|
|
})
|
|
|
|
test("empty string will pass", () => {
|
|
expect(
|
|
regexpPathToPath(
|
|
"/issue/:user/:repo/:state?/:labels?",
|
|
{
|
|
user: "rssnext",
|
|
repo: "follow",
|
|
state: "",
|
|
labels: "l",
|
|
},
|
|
{ omitNilAndEmptyString: false },
|
|
),
|
|
).toMatchInlineSnapshot(`"/issue/rssnext/follow//l"`)
|
|
})
|
|
})
|
|
|
|
describe("test `parseRegexpPathParams()`", () => {
|
|
test("normal path", () => {
|
|
expect(parseRegexpPathParams("/issues/all")).toMatchInlineSnapshot(`
|
|
[]
|
|
`)
|
|
})
|
|
|
|
test("path with optional params", () => {
|
|
expect(parseRegexpPathParams("/issues/:id?")).toMatchInlineSnapshot(`
|
|
[
|
|
{
|
|
"isCatchAll": false,
|
|
"name": "id",
|
|
"optional": true,
|
|
},
|
|
]
|
|
`)
|
|
})
|
|
|
|
test("path with many optional params", () => {
|
|
expect(parseRegexpPathParams("/issue/:user/:repo/:state?/:labels?")).toMatchInlineSnapshot(`
|
|
[
|
|
{
|
|
"isCatchAll": false,
|
|
"name": "user",
|
|
"optional": false,
|
|
},
|
|
{
|
|
"isCatchAll": false,
|
|
"name": "repo",
|
|
"optional": false,
|
|
},
|
|
{
|
|
"isCatchAll": false,
|
|
"name": "state",
|
|
"optional": true,
|
|
},
|
|
{
|
|
"isCatchAll": false,
|
|
"name": "labels",
|
|
"optional": true,
|
|
},
|
|
]
|
|
`)
|
|
})
|
|
|
|
test("catch all path", () => {
|
|
expect(parseRegexpPathParams("/:path{.+}?")).toMatchInlineSnapshot(`
|
|
[
|
|
{
|
|
"isCatchAll": true,
|
|
"name": "path",
|
|
"optional": true,
|
|
},
|
|
]
|
|
`)
|
|
})
|
|
|
|
test("with excludeNames", () => {
|
|
expect(
|
|
parseRegexpPathParams("/issue/:user/:repo/:state?/:labels?/:routeParams?", {
|
|
excludeNames: ["state", "routeParams"],
|
|
}),
|
|
).toMatchInlineSnapshot(`
|
|
[
|
|
{
|
|
"isCatchAll": false,
|
|
"name": "user",
|
|
"optional": false,
|
|
},
|
|
{
|
|
"isCatchAll": false,
|
|
"name": "repo",
|
|
"optional": false,
|
|
},
|
|
{
|
|
"isCatchAll": false,
|
|
"name": "labels",
|
|
"optional": true,
|
|
},
|
|
]
|
|
`)
|
|
})
|
|
})
|
|
|
|
describe("test `parseFullPathParams()`", () => {
|
|
test("case 1", () => {
|
|
expect(parseFullPathParams("/user/123344", "/user/:id")).toMatchInlineSnapshot(`
|
|
{
|
|
"id": "123344",
|
|
}
|
|
`)
|
|
})
|
|
test("case 2", () => {
|
|
expect(parseFullPathParams("/build/wangqiru/ttrss", "/build/:user/:name"))
|
|
.toMatchInlineSnapshot(`
|
|
{
|
|
"name": "ttrss",
|
|
"user": "wangqiru",
|
|
}
|
|
`)
|
|
})
|
|
})
|