Skip to content

Commit 01ef37e

Browse files
Copilotneilime
andcommitted
Refactor AUTO_PATTERNS to be provided by parsers via getAutoPatterns()
Co-authored-by: neilime <314088+neilime@users.noreply.github.com>
1 parent 1bbe89d commit 01ef37e

13 files changed

Lines changed: 354 additions & 55 deletions

actions/parse-ci-reports/src/ReportPathResolver.js

Lines changed: 19 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,7 @@
1-
const AUTO_MODE_ALL = "all";
2-
const AUTO_MODE_TEST = "test";
3-
const AUTO_MODE_COVERAGE = "coverage";
4-
const AUTO_MODE_LINT = "lint";
1+
import { ParserFactory } from "./parsers/ParserFactory.js";
2+
import { ReportCategory } from "./parsers/BaseParser.js";
53

6-
/**
7-
* Auto-detection patterns for common report files
8-
*/
9-
const AUTO_PATTERNS = {
10-
[AUTO_MODE_TEST]: [
11-
"**/junit*.xml",
12-
"**/test-results/**/*.xml",
13-
"**/test-reports/**/*.xml",
14-
"**/*test*.xml",
15-
"**/*.tap",
16-
],
17-
[AUTO_MODE_COVERAGE]: [
18-
"**/coverage/lcov.info",
19-
"**/coverage/cobertura-coverage.xml",
20-
"**/coverage.xml",
21-
"**/lcov.info",
22-
"**/cobertura.xml",
23-
],
24-
[AUTO_MODE_LINT]: [
25-
"**/eslint-report.json",
26-
"**/eslint.json",
27-
"**/checkstyle-result.xml",
28-
"**/checkstyle.xml",
29-
"**/prettier-check.log",
30-
"**/prettier-check.txt",
31-
"**/prettier-report.log",
32-
"**/prettier-report.txt",
33-
"**/astro-check.log",
34-
"**/astro-check.txt",
35-
"**/astro-check-report.log",
36-
"**/astro-check-report.txt",
37-
],
38-
};
4+
const AUTO_MODE_ALL = "all";
395

406
/**
417
* Component responsible for resolving report file paths
@@ -44,6 +10,15 @@ export class ReportPathResolver {
4410
constructor(fileSystemService, logger) {
4511
this.fileSystemService = fileSystemService;
4612
this.logger = logger;
13+
this.parserFactory = new ParserFactory(fileSystemService);
14+
}
15+
16+
/**
17+
* Get the auto patterns map from parsers
18+
* @returns {Object} Object with category keys and pattern arrays
19+
*/
20+
getAutoPatterns() {
21+
return this.parserFactory.getAutoPatternsMap();
4722
}
4823

4924
/**
@@ -57,6 +32,7 @@ export class ReportPathResolver {
5732
.map((p) => p.trim())
5833
.filter((p) => p.length > 0);
5934

35+
const autoPatterns = this.getAutoPatterns();
6036
const patternList = new Set();
6137
for (const segment of segments) {
6238
const isAuto = segment.startsWith("auto:");
@@ -74,14 +50,14 @@ export class ReportPathResolver {
7450
this.logger.info(`Auto-detection mode: ${normalizedMode}`);
7551

7652
if (normalizedMode === AUTO_MODE_ALL) {
77-
for (const pattern of Object.values(AUTO_PATTERNS).flat()) {
53+
for (const pattern of Object.values(autoPatterns).flat()) {
7854
patternList.add(pattern);
7955
}
8056
continue;
8157
}
8258

83-
if (AUTO_PATTERNS[normalizedMode] !== undefined) {
84-
for (const pattern of AUTO_PATTERNS[normalizedMode]) {
59+
if (autoPatterns[normalizedMode] !== undefined) {
60+
for (const pattern of autoPatterns[normalizedMode]) {
8561
patternList.add(pattern);
8662
}
8763
continue;
@@ -122,3 +98,6 @@ export class ReportPathResolver {
12298
return Array.from(files);
12399
}
124100
}
101+
102+
// Export ReportCategory for convenience
103+
export { ReportCategory };

actions/parse-ci-reports/src/ReportPathResolver.test.js

Lines changed: 92 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -77,24 +77,53 @@ describe("ReportPathResolver", () => {
7777
assert.deepStrictEqual(files, ["resolved:match-a", "resolved:match-b"]);
7878
});
7979

80-
it("merges multiple auto modes in declaration order", () => {
80+
it("returns test and coverage patterns for auto:test and auto:coverage", () => {
8181
const logger = createLoggerStub();
8282
const resolver = new ReportPathResolver({}, logger);
8383

8484
const patterns = resolver.resolvePatterns("auto:test, auto:coverage");
8585

86-
assert.deepStrictEqual(patterns, [
86+
// Verify test patterns are included (from JUnitParser and TAPParser)
87+
const testPatterns = [
8788
"**/junit*.xml",
8889
"**/test-results/**/*.xml",
8990
"**/test-reports/**/*.xml",
9091
"**/*test*.xml",
9192
"**/*.tap",
93+
];
94+
for (const pattern of testPatterns) {
95+
assert.ok(
96+
patterns.includes(pattern),
97+
`Missing test pattern: ${pattern}`,
98+
);
99+
}
100+
101+
// Verify coverage patterns are included (from LCOVParser and CoberturaParser)
102+
const coveragePatterns = [
92103
"**/coverage/lcov.info",
104+
"**/lcov.info",
93105
"**/coverage/cobertura-coverage.xml",
94106
"**/coverage.xml",
95-
"**/lcov.info",
96107
"**/cobertura.xml",
97-
]);
108+
];
109+
for (const pattern of coveragePatterns) {
110+
assert.ok(
111+
patterns.includes(pattern),
112+
`Missing coverage pattern: ${pattern}`,
113+
);
114+
}
115+
116+
// Verify no lint patterns are included
117+
const lintPatterns = ["**/eslint-report.json", "**/checkstyle.xml"];
118+
for (const pattern of lintPatterns) {
119+
assert.ok(
120+
!patterns.includes(pattern),
121+
`Should not include lint pattern: ${pattern}`,
122+
);
123+
}
124+
125+
// Verify total count matches expected (5 test + 5 coverage)
126+
assert.strictEqual(patterns.length, 10);
98127
});
99128

100129
it("deduplicates overlapping auto modes", () => {
@@ -103,7 +132,8 @@ describe("ReportPathResolver", () => {
103132

104133
const patterns = resolver.resolvePatterns("auto:lint,auto:all");
105134

106-
assert.deepStrictEqual(patterns, [
135+
// All lint patterns should be included
136+
const lintPatterns = [
107137
"**/eslint-report.json",
108138
"**/eslint.json",
109139
"**/checkstyle-result.xml",
@@ -116,17 +146,72 @@ describe("ReportPathResolver", () => {
116146
"**/astro-check.txt",
117147
"**/astro-check-report.log",
118148
"**/astro-check-report.txt",
149+
];
150+
for (const pattern of lintPatterns) {
151+
assert.ok(
152+
patterns.includes(pattern),
153+
`Missing lint pattern: ${pattern}`,
154+
);
155+
}
156+
157+
// All test patterns should be included
158+
const testPatterns = [
119159
"**/junit*.xml",
120160
"**/test-results/**/*.xml",
121161
"**/test-reports/**/*.xml",
122162
"**/*test*.xml",
123163
"**/*.tap",
164+
];
165+
for (const pattern of testPatterns) {
166+
assert.ok(
167+
patterns.includes(pattern),
168+
`Missing test pattern: ${pattern}`,
169+
);
170+
}
171+
172+
// All coverage patterns should be included
173+
const coveragePatterns = [
124174
"**/coverage/lcov.info",
175+
"**/lcov.info",
125176
"**/coverage/cobertura-coverage.xml",
126177
"**/coverage.xml",
127-
"**/lcov.info",
128178
"**/cobertura.xml",
129-
]);
179+
];
180+
for (const pattern of coveragePatterns) {
181+
assert.ok(
182+
patterns.includes(pattern),
183+
`Missing coverage pattern: ${pattern}`,
184+
);
185+
}
186+
187+
// Verify deduplication - total should be 12 lint + 5 test + 5 coverage = 22
188+
assert.strictEqual(patterns.length, 22);
189+
});
190+
191+
it("gets patterns from parsers via getAutoPatterns", () => {
192+
const logger = createLoggerStub();
193+
const resolver = new ReportPathResolver({}, logger);
194+
195+
const autoPatterns = resolver.getAutoPatterns();
196+
197+
// Verify structure
198+
assert.ok(autoPatterns.test, "Should have test patterns");
199+
assert.ok(autoPatterns.coverage, "Should have coverage patterns");
200+
assert.ok(autoPatterns.lint, "Should have lint patterns");
201+
202+
// Verify test patterns come from JUnitParser and TAPParser
203+
assert.ok(autoPatterns.test.includes("**/junit*.xml"));
204+
assert.ok(autoPatterns.test.includes("**/*.tap"));
205+
206+
// Verify coverage patterns come from LCOVParser and CoberturaParser
207+
assert.ok(autoPatterns.coverage.includes("**/coverage/lcov.info"));
208+
assert.ok(autoPatterns.coverage.includes("**/cobertura.xml"));
209+
210+
// Verify lint patterns come from ESLintParser, CheckStyleParser, PrettierParser, AstroCheckParser
211+
assert.ok(autoPatterns.lint.includes("**/eslint-report.json"));
212+
assert.ok(autoPatterns.lint.includes("**/checkstyle.xml"));
213+
assert.ok(autoPatterns.lint.includes("**/prettier-check.log"));
214+
assert.ok(autoPatterns.lint.includes("**/astro-check.log"));
130215
});
131216

132217
it("excludes node_modules files from glob patterns", async () => {

actions/parse-ci-reports/src/parsers/AstroCheckParser.js

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { BaseParser } from "./BaseParser.js";
1+
import { BaseParser, ReportCategory } from "./BaseParser.js";
22
import { ReportData, LintIssue } from "../models/ReportData.js";
33

44
const LOCATION_PATTERN = /:(\d+):(\d+)\s+-\s+(error|warning|hint)\s+/i;
@@ -21,6 +21,19 @@ export class AstroCheckParser extends BaseParser {
2121
return 8;
2222
}
2323

24+
getCategory() {
25+
return ReportCategory.LINT;
26+
}
27+
28+
getAutoPatterns() {
29+
return [
30+
"**/astro-check.log",
31+
"**/astro-check.txt",
32+
"**/astro-check-report.log",
33+
"**/astro-check-report.txt",
34+
];
35+
}
36+
2437
parse(content) {
2538
const reportData = new ReportData();
2639
reportData.reportType = "lint";

actions/parse-ci-reports/src/parsers/BaseParser.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
1+
/**
2+
* Report category constants
3+
*/
4+
export const ReportCategory = {
5+
TEST: "test",
6+
COVERAGE: "coverage",
7+
LINT: "lint",
8+
};
9+
110
/**
211
* Base class for all report parsers
312
* Follows the Strategy pattern for different report formats
@@ -32,4 +41,20 @@ export class BaseParser {
3241
getPriority() {
3342
return 0;
3443
}
44+
45+
/**
46+
* Get the category of reports this parser handles
47+
* @returns {string} Report category (test, coverage, or lint)
48+
*/
49+
getCategory() {
50+
throw new Error("getCategory() must be implemented by subclass");
51+
}
52+
53+
/**
54+
* Get the glob patterns for auto-detecting files this parser can handle
55+
* @returns {string[]} Array of glob patterns
56+
*/
57+
getAutoPatterns() {
58+
return [];
59+
}
3560
}

actions/parse-ci-reports/src/parsers/CheckStyleParser.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { XMLParser } from "fast-xml-parser";
2-
import { BaseParser } from "./BaseParser.js";
2+
import { BaseParser, ReportCategory } from "./BaseParser.js";
33
import { ReportData, LintIssue } from "../models/ReportData.js";
44

55
/**
@@ -28,6 +28,14 @@ export class CheckStyleParser extends BaseParser {
2828
return 8;
2929
}
3030

31+
getCategory() {
32+
return ReportCategory.LINT;
33+
}
34+
35+
getAutoPatterns() {
36+
return ["**/checkstyle-result.xml", "**/checkstyle.xml"];
37+
}
38+
3139
parse(content) {
3240
const reportData = new ReportData();
3341
reportData.reportType = "lint";

actions/parse-ci-reports/src/parsers/CoberturaParser.js

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { XMLParser } from "fast-xml-parser";
2-
import { BaseParser } from "./BaseParser.js";
2+
import { BaseParser, ReportCategory } from "./BaseParser.js";
33
import { ReportData, Coverage } from "../models/ReportData.js";
44

55
/**
@@ -28,6 +28,18 @@ export class CoberturaParser extends BaseParser {
2828
return 9;
2929
}
3030

31+
getCategory() {
32+
return ReportCategory.COVERAGE;
33+
}
34+
35+
getAutoPatterns() {
36+
return [
37+
"**/coverage/cobertura-coverage.xml",
38+
"**/coverage.xml",
39+
"**/cobertura.xml",
40+
];
41+
}
42+
3143
parse(content) {
3244
const reportData = new ReportData();
3345
reportData.reportType = "coverage";

actions/parse-ci-reports/src/parsers/ESLintParser.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { BaseParser } from "./BaseParser.js";
1+
import { BaseParser, ReportCategory } from "./BaseParser.js";
22
import { ReportData, LintIssue } from "../models/ReportData.js";
33

44
/**
@@ -25,6 +25,14 @@ export class ESLintParser extends BaseParser {
2525
return 10;
2626
}
2727

28+
getCategory() {
29+
return ReportCategory.LINT;
30+
}
31+
32+
getAutoPatterns() {
33+
return ["**/eslint-report.json", "**/eslint.json"];
34+
}
35+
2836
parse(content) {
2937
const reportData = new ReportData();
3038
reportData.reportType = "lint";

actions/parse-ci-reports/src/parsers/JUnitParser.js

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { XMLParser } from "fast-xml-parser";
2-
import { BaseParser } from "./BaseParser.js";
2+
import { BaseParser, ReportCategory } from "./BaseParser.js";
33
import { ReportData, TestResult } from "../models/ReportData.js";
44

55
/**
@@ -27,6 +27,19 @@ export class JUnitParser extends BaseParser {
2727
return 10;
2828
}
2929

30+
getCategory() {
31+
return ReportCategory.TEST;
32+
}
33+
34+
getAutoPatterns() {
35+
return [
36+
"**/junit*.xml",
37+
"**/test-results/**/*.xml",
38+
"**/test-reports/**/*.xml",
39+
"**/*test*.xml",
40+
];
41+
}
42+
3043
parse(content) {
3144
const reportData = new ReportData();
3245
reportData.reportType = "test";

0 commit comments

Comments
 (0)