Skip to content

Commit d88146d

Browse files
committed
fix: enhance ignore path handling with improved code aggregation and new tests
1 parent 6db8f27 commit d88146d

2 files changed

Lines changed: 138 additions & 3 deletions

File tree

packages/extension/server/src/ignorePath.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,22 @@ export async function getIgnorePatterns(
2626
}
2727

2828
export function getIgnoredCodes(path: string, ignorePatterns: IgnoredPaths[]): string[] | undefined {
29+
let matched = false;
30+
const codes = new Set<string>();
2931
for (const ignorePattern of ignorePatterns) {
3032
if (ignorePattern.regex.test(path)) {
31-
return ignorePattern.codes;
33+
matched = true;
34+
// An empty array means ignore all diagnostics for this path.
35+
if (ignorePattern.codes.length === 0) {
36+
return [];
37+
}
38+
ignorePattern.codes.forEach((code) => codes.add(code));
3239
}
3340
}
34-
return undefined;
41+
return matched ? [...codes] : undefined;
3542
}
3643

37-
function pathToRegex(workspace: string, path: string): RegExp {
44+
export function pathToRegex(workspace: string, path: string): RegExp {
3845
path = path.replace(/^\./, "").replace(/^\//, "");
3946
const absPath = workspace + "/" + path;
4047
let pattern = absPath.replace(/[-/\\^$*+?.()|[\]{}]/g, "\\$&"); // Escape special characters
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
import { expect } from "chai";
2+
import {
3+
IgnoredPaths,
4+
getIgnoredCodes,
5+
pathToRegex,
6+
} from "../ignorePath";
7+
8+
const workspace = "file:///workspace";
9+
10+
function makePatterns(
11+
entries: { [path: string]: string[] },
12+
): IgnoredPaths[] {
13+
return Object.keys(entries).map((path) => ({
14+
regex: pathToRegex(workspace, path),
15+
codes: entries[path],
16+
}));
17+
}
18+
19+
describe("Test ignorePath pathToRegex", () => {
20+
it("Matches a single specific file", () => {
21+
const regex = pathToRegex(workspace, "external/test.cnfg");
22+
expect(regex.test(`${workspace}/external/test.cnfg`)).to.equal(true);
23+
expect(regex.test(`${workspace}/external/other.cnfg`)).to.equal(false);
24+
});
25+
26+
it("Wildcard matches files and nested subfolders", () => {
27+
const regex = pathToRegex(workspace, "external/*");
28+
expect(regex.test(`${workspace}/external/test.cnfg`)).to.equal(true);
29+
expect(regex.test(`${workspace}/external/sub/deep/test.cnfg`)).to.equal(
30+
true,
31+
);
32+
expect(regex.test(`${workspace}/other/test.cnfg`)).to.equal(false);
33+
});
34+
35+
it("Single '*' matches every file", () => {
36+
const regex = pathToRegex(workspace, "*");
37+
expect(regex.test(`${workspace}/anything.cnfg`)).to.equal(true);
38+
expect(regex.test(`${workspace}/deep/nested/file.cnfg`)).to.equal(true);
39+
});
40+
41+
it("Strips leading ./ and /", () => {
42+
const regexDot = pathToRegex(workspace, "./external/*");
43+
const regexSlash = pathToRegex(workspace, "/external/*");
44+
expect(regexDot.test(`${workspace}/external/test.cnfg`)).to.equal(true);
45+
expect(regexSlash.test(`${workspace}/external/test.cnfg`)).to.equal(
46+
true,
47+
);
48+
});
49+
50+
it("'?' matches a single character", () => {
51+
const regex = pathToRegex(workspace, "external/test?.cnfg");
52+
expect(regex.test(`${workspace}/external/test1.cnfg`)).to.equal(true);
53+
expect(regex.test(`${workspace}/external/test12.cnfg`)).to.equal(false);
54+
});
55+
});
56+
57+
describe("Test ignorePath getIgnoredCodes", () => {
58+
it("Returns undefined when no pattern matches", () => {
59+
const patterns = makePatterns({ "external/*": [] });
60+
const codes = getIgnoredCodes(`${workspace}/src/test.cnfg`, patterns);
61+
expect(codes).to.equal(undefined);
62+
});
63+
64+
it("Returns empty array (ignore all) for empty codes", () => {
65+
const patterns = makePatterns({ "external/*": [] });
66+
const codes = getIgnoredCodes(
67+
`${workspace}/external/test.cnfg`,
68+
patterns,
69+
);
70+
expect(codes).to.deep.equal([]);
71+
});
72+
73+
it("Returns the specific codes for a matching path", () => {
74+
const patterns = makePatterns({ "external/*": ["W101", "W502"] });
75+
const codes = getIgnoredCodes(
76+
`${workspace}/external/test.cnfg`,
77+
patterns,
78+
);
79+
expect(codes).to.deep.equal(["W101", "W502"]);
80+
});
81+
82+
it("Aggregates codes from all matching patterns", () => {
83+
const patterns = makePatterns({
84+
"*": ["W101", "W502", "E206"],
85+
"external/*": ["E301"],
86+
});
87+
const codes = getIgnoredCodes(
88+
`${workspace}/external/test.cnfg`,
89+
patterns,
90+
);
91+
expect(codes).to.have.members(["W101", "W502", "E206", "E301"]);
92+
expect(codes).to.have.lengthOf(4);
93+
});
94+
95+
it("Deduplicates codes shared across matching patterns", () => {
96+
const patterns = makePatterns({
97+
"*": ["W101", "W502"],
98+
"external/*": ["W101", "E301"],
99+
});
100+
const codes = getIgnoredCodes(
101+
`${workspace}/external/test.cnfg`,
102+
patterns,
103+
);
104+
expect(codes).to.have.members(["W101", "W502", "E301"]);
105+
expect(codes).to.have.lengthOf(3);
106+
});
107+
108+
it("Global '*' does not shadow a more specific ignore-all pattern", () => {
109+
const patterns = makePatterns({
110+
"*": ["W101", "W502", "E206"],
111+
"external/*": [],
112+
});
113+
const codes = getIgnoredCodes(
114+
`${workspace}/external/test.cnfg`,
115+
patterns,
116+
);
117+
expect(codes).to.deep.equal([]);
118+
});
119+
120+
it("Applies only global codes to files outside specific folders", () => {
121+
const patterns = makePatterns({
122+
"*": ["W101", "W502", "E206"],
123+
"external/*": [],
124+
});
125+
const codes = getIgnoredCodes(`${workspace}/src/test.cnfg`, patterns);
126+
expect(codes).to.deep.equal(["W101", "W502", "E206"]);
127+
});
128+
});

0 commit comments

Comments
 (0)