Skip to content

Commit 8e85585

Browse files
authored
Show multiple errors at once (#2)
Signed-off-by: Matthew Peveler <[email protected]>
1 parent c5e7a88 commit 8e85585

File tree

4 files changed

+95
-53
lines changed

4 files changed

+95
-53
lines changed

dist/index.js

Lines changed: 13 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/index.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/validate.ts

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -41,55 +41,67 @@ export function checkTitle(fullTitle: string): true {
4141
}
4242
}
4343

44-
if (!/^\[[a-zA-Z/]+(?::[a-zA-Z]+)?\] /.test(title)) {
44+
if (!/^\[[a-zA-Z0-9\\/]+(?::[a-zA-Z0-9\\/]+)?\] /.test(title)) {
4545
throw new Error(
4646
`Invalid title format, must start with ${
4747
hasSysadminTag ? sysadminTag : ""
4848
}[<TYPE>:<MODULE>] and have space before description.`
4949
);
5050
}
5151

52+
const errors = [];
53+
5254
const [
5355
_,
5456
type,
5557
module,
5658
message,
57-
] = /^\[([a-zA-Z/]+)(?::([a-zA-Z]+))?\] (.*)/.exec(title) as RegExpMatchArray;
59+
] = /^\[([a-zA-Z0-9\\/]+)(?::([a-zA-Z0-9\\/]+))?\] (.*)/.exec(
60+
title
61+
) as RegExpMatchArray;
5862

5963
const isDependency = type === "Dependency" || type === "DevDependency";
6064
const minMessageLength = 2;
6165
const maxMessageLength = isDependency ? 70 : 40;
6266

6367
if (!allowedTypes.includes(type)) {
64-
throw new Error(
68+
errors.push(
6569
`Invalid type, expected one of ${allowedTypes.join(", ")}. Got ${type}.`
6670
);
6771
}
6872

6973
if (isDependency) {
7074
if (module !== undefined) {
71-
throw new Error(
75+
errors.push(
7276
`No allowed module for ${type}, expected [${type}]. Got [${type}:${module}].`
7377
);
7478
}
7579
} else if (!allowedModules.includes(module)) {
76-
throw new Error(
80+
errors.push(
7781
`Invalid module, expected one of ${allowedModules.join(
7882
", "
7983
)}. Got ${module}.`
8084
);
8185
}
8286

8387
if (message.length < minMessageLength) {
84-
throw new Error(
88+
errors.push(
8589
`Too short a message, expected at least ${minMessageLength} characters, got ${message.length} characters.`
8690
);
8791
}
8892
if (message.length > maxMessageLength) {
89-
throw new Error(
93+
errors.push(
9094
`Too long a message, expected at most ${maxMessageLength} characters, got ${message.length} characters.`
9195
);
9296
}
9397

98+
if (errors.length > 0) {
99+
throw new Error(
100+
`Errors detected in title:\n${errors
101+
.map((str) => ` - ${str}`)
102+
.join("\n")}`
103+
);
104+
}
105+
94106
return true;
95107
}

test/validate.spec.ts

Lines changed: 62 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -24,48 +24,72 @@ describe("validate", () => {
2424
});
2525

2626
describe("throws", () => {
27-
[
28-
[
29-
"[UI//UX:API] xxxx",
30-
"Invalid type, expected one of Bugfix, Feature, Refactor, Testing, Documentation, VPAT, UI/UX, Dependency, DevDependency. Got UI//UX.",
31-
],
32-
[
33-
"[UI\\/UX:API] xxxx",
34-
"Invalid title format, must start with [<TYPE>:<MODULE>] and have space before description.",
35-
],
36-
[
37-
"[Refactor:RainbowGrades]",
38-
"Invalid title format, must start with [<TYPE>:<MODULE>] and have space before description.",
39-
],
40-
[
41-
"[BugFix:TAGrading] xxxx",
42-
"Invalid type, expected one of Bugfix, Feature, Refactor, Testing, Documentation, VPAT, UI/UX, Dependency, DevDependency. Got BugFix.",
43-
],
44-
[
45-
"[Dependency:Autograding] xxxx",
46-
"No allowed module for Dependency, expected [Dependency]. Got [Dependency:Autograding].",
47-
],
48-
[
49-
"[SYSADMINACTION][Refactor:Autograding] xxxx",
50-
"Invalid title format, must start with [<TYPE>:<MODULE>] and have space before description.",
51-
],
27+
describe("error parsing", () => {
5228
[
53-
"[DevDependency:Autograding] xxxx",
54-
"No allowed module for DevDependency, expected [DevDependency]. Got [DevDependency:Autograding].",
55-
],
56-
[
57-
"[Bugfix:Submission] a",
58-
"Too short a message, expected at least 2 characters, got 1 characters.",
59-
],
29+
[
30+
"[Refactor:RainbowGrades]",
31+
"Invalid title format, must start with [<TYPE>:<MODULE>] and have space before description.",
32+
],
33+
[
34+
"[SYSADMINACTION][Refactor:Autograding] xxxx",
35+
"Invalid title format, must start with [<TYPE>:<MODULE>] and have space before description.",
36+
],
37+
].forEach(([value, expectedException]) => {
38+
it(`checkTitle should throw: ${value}`, () => {
39+
expect(() => checkTitle(value)).to.throw(expectedException);
40+
});
41+
});
42+
});
43+
44+
describe("specific format errors", () => {
6045
[
61-
"[Bugfix:Submission] 01234567890123456789012345678901234567890",
62-
"Too long a message, expected at most 40 characters, got 41 characters.",
63-
],
64-
].forEach(([value, expectedException]) => {
65-
it(`checkTitle should throw: ${value}`, () => {
66-
expect(() => checkTitle(value)).to.throw(expectedException);
46+
[
47+
"[UI//UX:API] xxxx",
48+
"Invalid type, expected one of Bugfix, Feature, Refactor, Testing, Documentation, VPAT, UI/UX, Dependency, DevDependency. Got UI//UX.",
49+
],
50+
[
51+
"[UI\\/UX:API] xxxx",
52+
"Invalid type, expected one of Bugfix, Feature, Refactor, Testing, Documentation, VPAT, UI/UX, Dependency, DevDependency. Got UI\\/UX.",
53+
],
54+
[
55+
"[BugFix:TAGrading] xxxx",
56+
"Invalid type, expected one of Bugfix, Feature, Refactor, Testing, Documentation, VPAT, UI/UX, Dependency, DevDependency. Got BugFix.",
57+
],
58+
[
59+
"[Dependency:Autograding] xxxx",
60+
"No allowed module for Dependency, expected [Dependency]. Got [Dependency:Autograding].",
61+
],
62+
[
63+
"[DevDependency:Autograding] xxxx",
64+
"No allowed module for DevDependency, expected [DevDependency]. Got [DevDependency:Autograding].",
65+
],
66+
[
67+
"[Bugfix:Submission] a",
68+
"Too short a message, expected at least 2 characters, got 1 characters.",
69+
],
70+
[
71+
"[Bugfix:Submission] 01234567890123456789012345678901234567890",
72+
"Too long a message, expected at most 40 characters, got 41 characters.",
73+
],
74+
].forEach(([value, expectedException]) => {
75+
it(`checkTitle should throw: ${value}`, () => {
76+
expect(() => checkTitle(value)).to.throw(
77+
`Errors detected in title:\n - ${expectedException}`
78+
);
79+
});
6780
});
6881
});
82+
83+
it("should show multiple format errors at once", () => {
84+
expect(() =>
85+
checkTitle(
86+
"[Fake:Error] this message is much too long and it should be shortened"
87+
)
88+
).to.throw(`Errors detected in title:
89+
- Invalid type, expected one of Bugfix, Feature, Refactor, Testing, Documentation, VPAT, UI/UX, Dependency, DevDependency. Got Fake.
90+
- Invalid module, expected one of Submission, Autograding, Forum, Notifications, TAGrading, InstructorUI, SubminiPolls, HelpQueue, CourseMaterials, Plagiarism, RainbowGrades, System, Developer, API. Got Error.
91+
- Too long a message, expected at most 40 characters, got 56 characters.`);
92+
});
6993
});
7094
});
7195
});

0 commit comments

Comments
 (0)