UNPKG

@feedzai/feedzai-config

Version:
152 lines (132 loc) 4.41 kB
var _ = require("lodash"); const logger = require("pino")({ prettyPrint: { colorize: true }, translateTime: true }); const lcovparse = require("lcov-parse"); const hasYarn = require("has-yarn"); const { METRIC_GROUPS, executeCommand } = require("@feedzai/analyzer-utilities"); const BaseMetric = require("@feedzai/analyzer-utilities/Base.metric"); /** * CoverageMetric * * This class implements the coverage metric * * @author Henrique Dias (henrique.dias@feedzai.com) * * @extends BaseMetric */ class CoverageMetric extends BaseMetric { /** * Used to specify details about this metric. * @returns {object} */ info() { return { name: "Coverage", group: METRIC_GROUPS.RANDOM }; } schema() { return { "statements": { "type": "float" }, "branch": { "type": "float" } } } /** * Decides whether the metric can be ran in current repository or not. * @returns {boolean} */ async verify() { if (_.isObject(this.getPackage().scripts) && _.isString(this.getPackage().scripts.build) && this.getPackage().scripts.build.includes("rollup")) { return false; } return _.isString(this.getAllDependencies().jest); } /** * This function is reponsible to calculate the code coverage * The way it works it's straightforward, at first it parses the lcov.info file generated by jest * After parsing the file, sums all the metrics for each file and returns the result * @returns {object} */ parseLcov() { return new Promise((resolve, reject) => { lcovparse(`${this.getRepoFolder()}/coverage/lcov.info`, function (err, data) { if (_.isNull(err) && _.isArray(data)) { // process the data here let totalBranchs = 0, coveredBranches = 0; let totalFunctions = 0, coveredFunctions = 0; for (let i = 0; i < data.length; i++) { const n = data[i]; totalBranchs += n.branches.found; coveredBranches += n.branches.hit; totalFunctions += n.functions.found; coveredFunctions += n.functions.hit; } resolve({ coveredstatements: coveredFunctions, statements: totalFunctions, coveredconditionals: coveredBranches, conditionals: totalBranchs }); } reject(err); }); }); } /** * Used to execute the coverage command and parse the results. * @returns {Object} */ async runCoverageAndParseResult() { let command; if (hasYarn(this.getRepoFolder())) { // eslint-disable-next-line quotes command = 'yarn test --coverage --coverageDirectory="coverage" '; } else { // eslint-disable-next-line quotes command = 'npm run test -- --coverage --coverageDirectory="coverage" '; } const result = await executeCommand(this.getRepoFolder(), command); if (!result) { // eslint-disable-next-line quotes logger.error('Error executing npm run test --coverage --coverageDirectory="coverage"'); return null; } return this.parseLcov().then((res) => { if (_.isObject(res)) { return res; } return null; }).catch(() => { return null; }); } /** * Returns the calculated metric. * @returns {Object} */ async execute() { return await this.runCoverageAndParseResult().then((metrics) => { if (!_.isObject(metrics)) { return undefined; } return { result: { statements: Math.round((metrics.coveredstatements / metrics.statements) * 100), branch: Math.round((metrics.coveredconditionals / metrics.conditionals) * 100) } }; }); } } module.exports = CoverageMetric;