UNPKG

apex-code-coverage-transformer

Version:

Transform Salesforce Apex code coverage JSONs into other formats accepted by SonarQube, GitHub, GitLab, Azure, Bitbucket, etc.

118 lines 4.04 kB
'use strict'; import { BaseHandler } from './BaseHandler.js'; import { HandlerRegistry } from './HandlerRegistry.js'; /** * Handler for generating JaCoCo XML coverage reports. * * JaCoCo is the standard code coverage library for Java projects. * The format is also accepted by Codecov and other coverage tools. * * Compatible with: * - Codecov * - Jenkins * - Maven * - Gradle * - IntelliJ IDEA * * @see https://www.jacoco.org/ */ export class JaCoCoCoverageHandler extends BaseHandler { coverageObj; packageMap; constructor() { super(); this.coverageObj = { report: { '@name': 'JaCoCo', package: [], counter: [], }, }; this.packageMap = {}; // Stores packages by directory } processFile(filePath, fileName, lines) { const pathParts = filePath.split('/'); const fileNamewithExt = pathParts.pop(); const packageName = pathParts.join('/'); const packageObj = this.getOrCreatePackage(packageName); // Ensure source file only contains the filename, not the full path const sourceFileObj = { '@name': fileNamewithExt, line: [], counter: [], }; let coveredLines = 0; let totalLines = 0; for (const [lineNumber, isCovered] of Object.entries(lines)) { totalLines++; if (isCovered === 1) coveredLines++; const lineObj = { '@nr': Number(lineNumber), '@mi': isCovered === 0 ? 1 : 0, '@ci': isCovered === 1 ? 1 : 0, '@mb': 0, '@cb': 0, }; sourceFileObj.line.push(lineObj); } // Add line coverage counter for the source file sourceFileObj.counter.push({ '@type': 'LINE', '@missed': totalLines - coveredLines, '@covered': coveredLines, }); packageObj.sourcefile.push(sourceFileObj); } finalize() { let overallCovered = 0; let overallMissed = 0; // Sort packages by name for consistent output const sortedPackages = Object.keys(this.packageMap).sort(); for (const packageName of sortedPackages) { const packageObj = this.packageMap[packageName]; packageObj.sourcefile.sort((a, b) => a['@name'].localeCompare(b['@name'])); let packageCovered = 0; let packageMissed = 0; for (const sf of packageObj.sourcefile) { packageCovered += sf.counter[0]['@covered']; packageMissed += sf.counter[0]['@missed']; } packageObj.counter.push({ '@type': 'LINE', '@missed': packageMissed, '@covered': packageCovered, }); overallCovered += packageCovered; overallMissed += packageMissed; } // Rebuild the package array in sorted order this.coverageObj.report.package = sortedPackages.map((name) => this.packageMap[name]); this.coverageObj.report.counter.push({ '@type': 'LINE', '@missed': overallMissed, '@covered': overallCovered, }); return this.coverageObj; } getOrCreatePackage(packageName) { if (!this.packageMap[packageName]) { this.packageMap[packageName] = { '@name': packageName, sourcefile: [], counter: [], }; this.coverageObj.report.package.push(this.packageMap[packageName]); } return this.packageMap[packageName]; } } // Self-register this handler HandlerRegistry.register({ name: 'jacoco', description: 'JaCoCo XML format for Java projects', fileExtension: '.xml', handler: () => new JaCoCoCoverageHandler(), compatibleWith: ['Codecov', 'Jenkins', 'Maven', 'Gradle'], }); //# sourceMappingURL=jacoco.js.map