Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit a6bdf40

Browse files
Improved error messages and stack size (#363)
1 parent c6d7244 commit a6bdf40

File tree

4 files changed

+294
-167
lines changed

4 files changed

+294
-167
lines changed

‎package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@
5353
"size-limit": [
5454
{
5555
"path": "dist/index.js",
56-
"limit": "2.2 kB"
56+
"limit": "2 kB"
5757
}
5858
],
5959
"ts-scripts": {

‎src/cases.spec.ts

Lines changed: 88 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
type CompileOptions,
77
type ParamData,
88
TokenData,
9+
Path,
910
} from "./index.js";
1011

1112
export interface ParserTestSet {
@@ -21,7 +22,7 @@ export interface StringifyTestSet {
2122
}
2223

2324
export interface CompileTestSet {
24-
path: string;
25+
path: Path;
2526
options?: CompileOptions & ParseOptions;
2627
tests: Array<{
2728
input: ParamData | undefined;
@@ -30,7 +31,7 @@ export interface CompileTestSet {
3031
}
3132

3233
export interface MatchTestSet {
33-
path: string;
34+
path: Path|Path[];
3435
options?: MatchOptions & ParseOptions;
3536
tests: Array<{
3637
input: string;
@@ -41,64 +42,99 @@ export interface MatchTestSet {
4142
export const PARSER_TESTS: ParserTestSet[] = [
4243
{
4344
path: "/",
44-
expected: new TokenData([{ type: "text", value: "/" }]),
45+
expected: new TokenData([{ type: "text", value: "/" }],"/"),
4546
},
4647
{
4748
path: "/:test",
48-
expected: new TokenData([
49-
{ type: "text", value: "/" },
50-
{ type: "param", name: "test" },
51-
]),
49+
expected: new TokenData(
50+
[
51+
{ type: "text", value: "/" },
52+
{ type: "param", name: "test" },
53+
],
54+
"/:test",
55+
),
56+
},
57+
{
58+
path: "/:a:b",
59+
expected: new TokenData(
60+
[
61+
{ type: "text", value: "/" },
62+
{ type: "param", name: "a" },
63+
{ type: "param", name: "b" },
64+
],
65+
"/:a:b",
66+
),
5267
},
5368
{
5469
path: '/:"0"',
55-
expected: new TokenData([
56-
{ type: "text", value: "/" },
57-
{ type: "param", name: "0" },
58-
]),
70+
expected: new TokenData(
71+
[
72+
{ type: "text", value: "/" },
73+
{ type: "param", name: "0" },
74+
],
75+
'/:"0"',
76+
),
5977
},
6078
{
6179
path: "/:_",
62-
expected: new TokenData([
63-
{ type: "text", value: "/" },
64-
{ type: "param", name: "_" },
65-
]),
80+
expected: new TokenData(
81+
[
82+
{ type: "text", value: "/" },
83+
{ type: "param", name: "_" },
84+
],
85+
"/:_",
86+
),
6687
},
6788
{
6889
path: "/:café",
69-
expected: new TokenData([
70-
{ type: "text", value: "/" },
71-
{ type: "param", name: "café" },
72-
]),
90+
expected: new TokenData(
91+
[
92+
{ type: "text", value: "/" },
93+
{ type: "param", name: "café" },
94+
],
95+
"/:café",
96+
),
7397
},
7498
{
7599
path: '/:"123"',
76-
expected: new TokenData([
77-
{ type: "text", value: "/" },
78-
{ type: "param", name: "123" },
79-
]),
100+
expected: new TokenData(
101+
[
102+
{ type: "text", value: "/" },
103+
{ type: "param", name: "123" },
104+
],
105+
'/:"123"',
106+
),
80107
},
81108
{
82109
path: '/:"1\\"\2円\\"3"',
83-
expected: new TokenData([
84-
{ type: "text", value: "/" },
85-
{ type: "param", name: '1"2"3' },
86-
]),
110+
expected: new TokenData(
111+
[
112+
{ type: "text", value: "/" },
113+
{ type: "param", name: '1"2"3' },
114+
],
115+
'/:"1\\"\2円\\"3"',
116+
),
87117
},
88118
{
89119
path: "/*path",
90-
expected: new TokenData([
91-
{ type: "text", value: "/" },
92-
{ type: "wildcard", name: "path" },
93-
]),
120+
expected: new TokenData(
121+
[
122+
{ type: "text", value: "/" },
123+
{ type: "wildcard", name: "path" },
124+
],
125+
"/*path",
126+
),
94127
},
95128
{
96129
path: '/:"test"stuff',
97-
expected: new TokenData([
98-
{ type: "text", value: "/" },
99-
{ type: "param", name: "test" },
100-
{ type: "text", value: "stuff" },
101-
]),
130+
expected: new TokenData(
131+
[
132+
{ type: "text", value: "/" },
133+
{ type: "param", name: "test" },
134+
{ type: "text", value: "stuff" },
135+
],
136+
'/:"test"stuff',
137+
),
102138
},
103139
];
104140

@@ -1609,4 +1645,20 @@ export const MATCH_TESTS: MatchTestSet[] = [
16091645
},
16101646
],
16111647
},
1648+
1649+
/**
1650+
* Array input is normalized.
1651+
*/
1652+
{
1653+
path: ["/:foo/:bar", "/:foo/:baz"],
1654+
tests: [
1655+
{
1656+
input: "/hello/world",
1657+
expected: {
1658+
path: "/hello/world",
1659+
params: { foo: "hello", bar: "world" },
1660+
},
1661+
},
1662+
],
1663+
},
16121664
];

‎src/index.spec.ts

Lines changed: 71 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
import { describe, it, expect } from "vitest";
2-
import { parse, compile, match, stringify } from "./index.js";
2+
import {
3+
parse,
4+
compile,
5+
match,
6+
stringify,
7+
pathToRegexp,
8+
TokenData,
9+
} from "./index.js";
310
import {
411
PARSER_TESTS,
512
COMPILE_TESTS,
@@ -15,38 +22,39 @@ describe("path-to-regexp", () => {
1522
it("should throw on unbalanced group", () => {
1623
expect(() => parse("/{:foo,")).toThrow(
1724
new TypeError(
18-
"Unexpected END at 7, expected }: https://git.new/pathToRegexpError",
25+
"Unexpected END at index 7, expected }: /{:foo,; visit https://git.new/pathToRegexpError for info",
1926
),
2027
);
2128
});
29+
2230
it("should throw on nested unbalanced group", () => {
2331
expect(() => parse("/{:foo/{x,y}")).toThrow(
2432
new TypeError(
25-
"Unexpected END at 12, expected }: https://git.new/pathToRegexpError",
33+
"Unexpected END at index 12, expected }: /{:foo/{x,y}; visit https://git.new/pathToRegexpError for info",
2634
),
2735
);
2836
});
2937

3038
it("should throw on missing param name", () => {
3139
expect(() => parse("/:/")).toThrow(
3240
new TypeError(
33-
"Missing parameter name at 2: https://git.new/pathToRegexpError",
41+
"Missing parameter name at index 2: /:/; visit https://git.new/pathToRegexpError for info",
3442
),
3543
);
3644
});
3745

3846
it("should throw on missing wildcard name", () => {
3947
expect(() => parse("/*/")).toThrow(
4048
new TypeError(
41-
"Missing parameter name at 2: https://git.new/pathToRegexpError",
49+
"Missing parameter name at index 2: /*/; visit https://git.new/pathToRegexpError for info",
4250
),
4351
);
4452
});
4553

4654
it("should throw on unterminated quote", () => {
4755
expect(() => parse('/:"foo')).toThrow(
4856
new TypeError(
49-
"Unterminated quote at 2: https://git.new/pathToRegexpError",
57+
'Unterminated quote at index 2: /:"foo; visit https://git.new/pathToRegexpError for info',
5058
),
5159
);
5260
});
@@ -94,6 +102,63 @@ describe("path-to-regexp", () => {
94102
});
95103
});
96104

105+
describe("pathToRegexp errors", () => {
106+
it("should throw when missing text between params", () => {
107+
expect(() => pathToRegexp("/:foo:bar")).toThrow(
108+
new TypeError(
109+
'Missing text before "bar": /:foo:bar; visit https://git.new/pathToRegexpError for info',
110+
),
111+
);
112+
});
113+
114+
it("should throw when missing text between params using TokenData", () => {
115+
expect(() =>
116+
pathToRegexp(
117+
new TokenData([
118+
{ type: "param", name: "a" },
119+
{ type: "param", name: "b" },
120+
]),
121+
),
122+
).toThrow(
123+
new TypeError(
124+
'Missing text before "b"; visit https://git.new/pathToRegexpError for info',
125+
),
126+
);
127+
});
128+
129+
it("should throw with `originalPath` when missing text between params using TokenData", () => {
130+
expect(() =>
131+
pathToRegexp(
132+
new TokenData(
133+
[
134+
{ type: "param", name: "a" },
135+
{ type: "param", name: "b" },
136+
],
137+
"/[a][b]",
138+
),
139+
),
140+
).toThrow(
141+
new TypeError(
142+
'Missing text before "b": /[a][b]; visit https://git.new/pathToRegexpError for info',
143+
),
144+
);
145+
});
146+
147+
it("should contain the error line", () => {
148+
expect.hasAssertions();
149+
150+
try {
151+
pathToRegexp("/:");
152+
} catch (error) {
153+
const stack = (error as Error).stack
154+
?.split("\n")
155+
.slice(0, 5)
156+
.join("\n");
157+
expect(stack).toContain("index.spec.ts");
158+
}
159+
});
160+
});
161+
97162
describe.each(PARSER_TESTS)(
98163
"parse $path with $options",
99164
({ path, options, expected }) => {

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /