@codechecks/type-coverage-watcher
Version:
Track missing type coverage in TypeScript projects to ensure type safety
91 lines (90 loc) • 3.76 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const client_1 = require("@codechecks/client");
const type_coverage_core_1 = require("type-coverage-core");
const lodash_1 = require("lodash");
const formatters_1 = require("./formatters");
async function typeCoverageWatcher(_options = {}) {
const options = normalizeOptions(_options);
const _typeCoverage = await type_coverage_core_1.lint(options.tsconfigPath, {
debug: false,
ignoreCatch: _options.ignoreCatch,
ignoreFiles: _options.ignoreFiles,
strict: _options.strict,
});
const typeCoverage = normalizeTypeCoverage(_typeCoverage);
await client_1.codechecks.saveValue(options.artifactName, typeCoverage);
if (!client_1.codechecks.isPr()) {
return;
}
const baseTypeCoverage = await client_1.codechecks.getValue(options.artifactName);
const report = getReport(typeCoverage, baseTypeCoverage, options);
await client_1.codechecks.report(report);
}
exports.typeCoverageWatcher = typeCoverageWatcher;
exports.default = typeCoverageWatcher;
function getReport(headTypeCoverageArtifact, baseTypeCoverageArtifact, options) {
const headTypeCoverage = (headTypeCoverageArtifact.typedSymbols / headTypeCoverageArtifact.totalSymbols) * 100;
const baseTypeCoverage = baseTypeCoverageArtifact
? (baseTypeCoverageArtifact.typedSymbols / baseTypeCoverageArtifact.totalSymbols) * 100
: 0;
const coverageDiff = headTypeCoverage - baseTypeCoverage;
const newUntypedSymbols = findNew(headTypeCoverageArtifact.allUntypedSymbols, baseTypeCoverageArtifact ? baseTypeCoverageArtifact.allUntypedSymbols : []);
const shortDescription = formatters_1.formatShortDescription({
coverageDiffPerc: coverageDiff,
atLeast: options.atLeast,
headTypeCoveragePerc: headTypeCoverage,
newUntypedSymbols: newUntypedSymbols.length,
});
let longDescription = `New untyped symbols: ${newUntypedSymbols.length}`;
if (newUntypedSymbols.length > 0) {
longDescription += `
| File | line:character | Symbol |
|:-----:|:-----:|:-----:|
${newUntypedSymbols
.slice(0, 100)
.map(s => `| ${s.filename} | ${s.line}:${s.character} | ${s.symbol} |`)
.join("\n")}`;
}
const status = options.atLeast === undefined || headTypeCoverage > options.atLeast ? "success" : "failure";
return {
name: options.name,
status,
shortDescription,
longDescription,
};
}
function findNew(headSymbols, baseSymbols) {
const baseSymbolsByFilename = lodash_1.groupBy(baseSymbols, s => s.filename);
const newSymbols = [];
for (const headSymbol of headSymbols) {
// we assess if symbols are the same only by looking at filename and symbol name (we ignore line and character)
const baseSymbolMatch = (baseSymbolsByFilename[headSymbol.filename] || []).filter(s => s.symbol === headSymbol.symbol).length > 0;
if (!baseSymbolMatch) {
newSymbols.push(headSymbol);
}
}
return newSymbols;
}
function normalizeTypeCoverage(rawTypeCoverage) {
return {
typedSymbols: rawTypeCoverage.correctCount,
totalSymbols: rawTypeCoverage.totalCount,
allUntypedSymbols: rawTypeCoverage.anys.map(a => ({
filename: a.file,
line: a.line,
character: a.character,
symbol: a.text,
})),
};
}
function normalizeOptions(options = {}) {
const name = options.name || "Type Coverage";
return {
name,
tsconfigPath: options.name || "tsconfig.json",
artifactName: `type-coverage:${name}`,
atLeast: options.atLeast,
};
}
//# sourceMappingURL=index.js.map