chore(web): enhance frontend tests (#29869)

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
This commit is contained in:
yyh
2025-12-18 17:47:13 +08:00
committed by GitHub
parent 82220a645c
commit c12f0d16bb
9 changed files with 434 additions and 549 deletions

View File

@@ -70,6 +70,13 @@ jobs:
node <<'NODE' >> "$GITHUB_STEP_SUMMARY"
const fs = require('fs');
const path = require('path');
let libCoverage = null;
try {
libCoverage = require('istanbul-lib-coverage');
} catch (error) {
libCoverage = null;
}
const summaryPath = path.join('coverage', 'coverage-summary.json');
const finalPath = path.join('coverage', 'coverage-final.json');
@@ -91,6 +98,54 @@ jobs:
? JSON.parse(fs.readFileSync(finalPath, 'utf8'))
: null;
const getLineCoverageFromStatements = (statementMap, statementHits) => {
const lineHits = {};
if (!statementMap || !statementHits) {
return lineHits;
}
Object.entries(statementMap).forEach(([key, statement]) => {
const line = statement?.start?.line;
if (!line) {
return;
}
const hits = statementHits[key] ?? 0;
const previous = lineHits[line];
lineHits[line] = previous === undefined ? hits : Math.max(previous, hits);
});
return lineHits;
};
const getFileCoverage = (entry) => (
libCoverage ? libCoverage.createFileCoverage(entry) : null
);
const getLineHits = (entry, fileCoverage) => {
const lineHits = entry.l ?? {};
if (Object.keys(lineHits).length > 0) {
return lineHits;
}
if (fileCoverage) {
return fileCoverage.getLineCoverage();
}
return getLineCoverageFromStatements(entry.statementMap ?? {}, entry.s ?? {});
};
const getUncoveredLines = (entry, fileCoverage, lineHits) => {
if (lineHits && Object.keys(lineHits).length > 0) {
return Object.entries(lineHits)
.filter(([, count]) => count === 0)
.map(([line]) => Number(line))
.sort((a, b) => a - b);
}
if (fileCoverage) {
return fileCoverage.getUncoveredLines();
}
return [];
};
const totals = {
lines: { covered: 0, total: 0 },
statements: { covered: 0, total: 0 },
@@ -106,7 +161,7 @@ jobs:
totals[key].covered = totalEntry[key].covered ?? 0;
totals[key].total = totalEntry[key].total ?? 0;
}
});
});
Object.entries(summary)
.filter(([file]) => file !== 'total')
@@ -122,7 +177,8 @@ jobs:
});
} else if (coverage) {
Object.entries(coverage).forEach(([file, entry]) => {
const lineHits = entry.l ?? {};
const fileCoverage = getFileCoverage(entry);
const lineHits = getLineHits(entry, fileCoverage);
const statementHits = entry.s ?? {};
const branchHits = entry.b ?? {};
const functionHits = entry.f ?? {};
@@ -228,7 +284,8 @@ jobs:
};
const tableRows = Object.entries(coverage)
.map(([file, entry]) => {
const lineHits = entry.l ?? {};
const fileCoverage = getFileCoverage(entry);
const lineHits = getLineHits(entry, fileCoverage);
const statementHits = entry.s ?? {};
const branchHits = entry.b ?? {};
const functionHits = entry.f ?? {};
@@ -254,10 +311,7 @@ jobs:
tableTotals.functions.total += functionTotal;
tableTotals.functions.covered += functionCovered;
const uncoveredLines = Object.entries(lineHits)
.filter(([, count]) => count === 0)
.map(([line]) => Number(line))
.sort((a, b) => a - b);
const uncoveredLines = getUncoveredLines(entry, fileCoverage, lineHits);
const filePath = entry.path ?? file;
const relativePath = path.isAbsolute(filePath)
@@ -294,46 +348,20 @@ jobs:
};
const rowsForOutput = [allFilesRow, ...tableRows];
const columnWidths = Object.fromEntries(
columns.map(({ key, header }) => [key, header.length]),
);
rowsForOutput.forEach((row) => {
columns.forEach(({ key }) => {
const value = String(row[key] ?? '');
columnWidths[key] = Math.max(columnWidths[key], value.length);
});
});
const formatRow = (row) => columns
.map(({ key, align }) => {
const value = String(row[key] ?? '');
const width = columnWidths[key];
return align === 'right' ? value.padStart(width) : value.padEnd(width);
})
.join(' | ');
const headerRow = columns
.map(({ header, key, align }) => {
const width = columnWidths[key];
return align === 'right' ? header.padStart(width) : header.padEnd(width);
})
.join(' | ');
const dividerRow = columns
.map(({ key }) => '-'.repeat(columnWidths[key]))
.join('|');
const formatRow = (row) => `| ${columns
.map(({ key }) => String(row[key] ?? ''))
.join(' | ')} |`;
const headerRow = `| ${columns.map(({ header }) => header).join(' | ')} |`;
const dividerRow = `| ${columns
.map(({ align }) => (align === 'right' ? '---:' : ':---'))
.join(' | ')} |`;
console.log('');
console.log('<details><summary>Jest coverage table</summary>');
console.log('');
console.log('```');
console.log(dividerRow);
console.log(headerRow);
console.log(dividerRow);
rowsForOutput.forEach((row) => console.log(formatRow(row)));
console.log(dividerRow);
console.log('```');
console.log('</details>');
}
NODE