UNPKG

typecov

Version:

Track type coverage in TypeScript projects to ensure type safety

93 lines (92 loc) 3.92 kB
"use strict"; 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