UNPKG

codecheck-type-coverage

Version:

Track missing type coverage in TypeScript projects to ensure type safety

85 lines (84 loc) 3.36 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const client_1 = require("@codechecks/client"); const type_coverage_1 = require("type-coverage"); const lodash_1 = require("lodash"); const ARTIFACT_KEY = "type-coverage"; const defaultOptions = { tsconfigPath: "tsconfig.json", }; async function typeCoverageWatcher(_options) { const options = Object.assign({}, defaultOptions, _options); const _typeCoverage = await type_coverage_1.lint(options.tsconfigPath, true, false); const typeCoverage = normalizeTypeCoverage(_typeCoverage); await client_1.codeChecks.saveValue(ARTIFACT_KEY, typeCoverage); if (!client_1.codeChecks.isPr()) { return; } const baseTypeCoverage = await client_1.codeChecks.getValue(ARTIFACT_KEY); const report = getReport(typeCoverage, baseTypeCoverage); await client_1.codeChecks.report(report); } exports.typeCoverageWatcher = typeCoverageWatcher; function getReport(headTypeCoverageArtifact, baseTypeCoverageArtifact) { const headTypeCoverage = (headTypeCoverageArtifact.typedSymbols / headTypeCoverageArtifact.totalSymbols) * 100; const baseTypeCoverage = baseTypeCoverageArtifact ? (baseTypeCoverageArtifact.typedSymbols / baseTypeCoverageArtifact.totalSymbols) * 100 : 0; const coverageDiff = headTypeCoverage - baseTypeCoverage; const shortDescription = `Change: ${renderSign(coverageDiff)}${perc(coverageDiff)} Total: ${perc(headTypeCoverage)}`; const newUntypedSymbols = findNew(headTypeCoverageArtifact.allUntypedSymbols, baseTypeCoverageArtifact ? baseTypeCoverageArtifact.allUntypedSymbols : []); 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")}`; } return { name: "Type Coverage", status: "success", 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 perc(n) { return n.toFixed(2) + "%"; } 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 renderSign(value) { if (value > 0) { return "+"; } else { // we dont' render signs for negative (it's part of a number xD) or 0 return ""; } } //# sourceMappingURL=index.js.map