typecov
Version:
Track type coverage in TypeScript projects to ensure type safety
93 lines (92 loc) • 3.92 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 typecov(_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.typecov = typecov;
exports.default = typecov;
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 status = options.atLeast === undefined || headTypeCoverage >= options.atLeast ? "success" : "failure";
const shortDescription = formatters_1.formatShortDescription({
coverageDiffPerc: coverageDiff,
headTypeCoveragePerc: headTypeCoverage,
newUntypedSymbols: newUntypedSymbols.length,
baseReportExisted: !!baseTypeCoverageArtifact,
});
let longDescription = `### Current type coverage: ${formatters_1.perc(headTypeCoverage)}
${formatters_1.getDescriptionAboutThreshold(options, status)}
### 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")}`;
}
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 ? `TypeCov (${options.name})` : "TypeCov";
return {
name,
tsconfigPath: options.tsconfigPath || "tsconfig.json",
artifactName: `typecov/${options.name || "default"}`,
atLeast: options.atLeast,
};
}
//# sourceMappingURL=index.js.map