apex-code-coverage-transformer 2.13.4 → 2.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -0
- package/README.md +276 -9
- package/lib/handlers/BaseHandler.d.ts +51 -0
- package/lib/handlers/BaseHandler.js +63 -0
- package/lib/handlers/BaseHandler.js.map +1 -0
- package/lib/handlers/HandlerRegistry.d.ts +90 -0
- package/lib/handlers/HandlerRegistry.js +103 -0
- package/lib/handlers/HandlerRegistry.js.map +1 -0
- package/lib/handlers/clover.d.ts +16 -2
- package/lib/handlers/clover.js +35 -16
- package/lib/handlers/clover.js.map +1 -1
- package/lib/handlers/cobertura.d.ts +11 -2
- package/lib/handlers/cobertura.js +23 -11
- package/lib/handlers/cobertura.js.map +1 -1
- package/lib/handlers/getHandler.d.ts +24 -0
- package/lib/handlers/getHandler.js +27 -19
- package/lib/handlers/getHandler.js.map +1 -1
- package/lib/handlers/istanbulJson.d.ts +18 -2
- package/lib/handlers/istanbulJson.js +28 -1
- package/lib/handlers/istanbulJson.js.map +1 -1
- package/lib/handlers/jacoco.d.ts +18 -2
- package/lib/handlers/jacoco.js +27 -1
- package/lib/handlers/jacoco.js.map +1 -1
- package/lib/handlers/jsonSummary.d.ts +49 -0
- package/lib/handlers/jsonSummary.js +103 -0
- package/lib/handlers/jsonSummary.js.map +1 -0
- package/lib/handlers/lcov.d.ts +17 -2
- package/lib/handlers/lcov.js +29 -9
- package/lib/handlers/lcov.js.map +1 -1
- package/lib/handlers/opencover.d.ts +71 -0
- package/lib/handlers/opencover.js +165 -0
- package/lib/handlers/opencover.js.map +1 -0
- package/lib/handlers/simplecov.d.ts +50 -0
- package/lib/handlers/simplecov.js +83 -0
- package/lib/handlers/simplecov.js.map +1 -0
- package/lib/handlers/sonar.d.ts +10 -2
- package/lib/handlers/sonar.js +20 -2
- package/lib/handlers/sonar.js.map +1 -1
- package/lib/transformers/reportGenerator.d.ts +2 -2
- package/lib/transformers/reportGenerator.js +7 -8
- package/lib/transformers/reportGenerator.js.map +1 -1
- package/lib/utils/constants.d.ts +5 -0
- package/lib/utils/constants.js +8 -1
- package/lib/utils/constants.js.map +1 -1
- package/lib/utils/types.d.ts +78 -1
- package/oclif.manifest.json +8 -5
- package/package.json +1 -1
package/lib/handlers/lcov.d.ts
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import { LcovCoverageObject } from '../utils/types.js';
|
|
2
|
+
import { BaseHandler } from './BaseHandler.js';
|
|
3
|
+
/**
|
|
4
|
+
* Handler for generating LCOV coverage reports.
|
|
5
|
+
*
|
|
6
|
+
* LCOV is a widely-used format for code coverage reporting,
|
|
7
|
+
* particularly common in JavaScript/Node.js projects.
|
|
8
|
+
*
|
|
9
|
+
* Compatible with:
|
|
10
|
+
* - Codecov
|
|
11
|
+
* - Coveralls
|
|
12
|
+
* - GitHub Actions
|
|
13
|
+
* - LCOV analysis tools
|
|
14
|
+
*
|
|
15
|
+
* @see http://ltp.sourceforge.net/coverage/lcov.php
|
|
16
|
+
*/
|
|
17
|
+
export declare class LcovCoverageHandler extends BaseHandler {
|
|
3
18
|
private readonly coverageObj;
|
|
4
19
|
constructor();
|
|
5
20
|
processFile(filePath: string, fileName: string, lines: Record<string, number>): void;
|
package/lib/handlers/lcov.js
CHANGED
|
@@ -1,21 +1,33 @@
|
|
|
1
1
|
'use strict';
|
|
2
|
-
|
|
2
|
+
import { BaseHandler } from './BaseHandler.js';
|
|
3
|
+
import { HandlerRegistry } from './HandlerRegistry.js';
|
|
4
|
+
/**
|
|
5
|
+
* Handler for generating LCOV coverage reports.
|
|
6
|
+
*
|
|
7
|
+
* LCOV is a widely-used format for code coverage reporting,
|
|
8
|
+
* particularly common in JavaScript/Node.js projects.
|
|
9
|
+
*
|
|
10
|
+
* Compatible with:
|
|
11
|
+
* - Codecov
|
|
12
|
+
* - Coveralls
|
|
13
|
+
* - GitHub Actions
|
|
14
|
+
* - LCOV analysis tools
|
|
15
|
+
*
|
|
16
|
+
* @see http://ltp.sourceforge.net/coverage/lcov.php
|
|
17
|
+
*/
|
|
18
|
+
export class LcovCoverageHandler extends BaseHandler {
|
|
3
19
|
coverageObj;
|
|
4
20
|
constructor() {
|
|
21
|
+
super();
|
|
5
22
|
this.coverageObj = { files: [] };
|
|
6
23
|
}
|
|
7
24
|
processFile(filePath, fileName, lines) {
|
|
8
|
-
const
|
|
9
|
-
.filter((lineNumber) => lines[lineNumber] === 0)
|
|
10
|
-
.map(Number);
|
|
11
|
-
const coveredLines = Object.keys(lines)
|
|
12
|
-
.filter((lineNumber) => lines[lineNumber] === 1)
|
|
13
|
-
.map(Number);
|
|
25
|
+
const { totalLines, coveredLines } = this.calculateCoverage(lines);
|
|
14
26
|
const lcovFile = {
|
|
15
27
|
sourceFile: filePath,
|
|
16
28
|
lines: [],
|
|
17
|
-
totalLines
|
|
18
|
-
coveredLines
|
|
29
|
+
totalLines,
|
|
30
|
+
coveredLines,
|
|
19
31
|
};
|
|
20
32
|
for (const [lineNumber, isCovered] of Object.entries(lines)) {
|
|
21
33
|
lcovFile.lines.push({
|
|
@@ -32,4 +44,12 @@ export class LcovCoverageHandler {
|
|
|
32
44
|
return this.coverageObj;
|
|
33
45
|
}
|
|
34
46
|
}
|
|
47
|
+
// Self-register this handler
|
|
48
|
+
HandlerRegistry.register({
|
|
49
|
+
name: 'lcovonly',
|
|
50
|
+
description: 'LCOV format for JavaScript and C/C++ coverage',
|
|
51
|
+
fileExtension: '.info',
|
|
52
|
+
handler: () => new LcovCoverageHandler(),
|
|
53
|
+
compatibleWith: ['Codecov', 'Coveralls', 'GitHub Actions'],
|
|
54
|
+
});
|
|
35
55
|
//# sourceMappingURL=lcov.js.map
|
package/lib/handlers/lcov.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lcov.js","sourceRoot":"","sources":["../../src/handlers/lcov.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"lcov.js","sourceRoot":"","sources":["../../src/handlers/lcov.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAGb,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAEvD;;;;;;;;;;;;;GAaG;AACH,MAAM,OAAO,mBAAoB,SAAQ,WAAW;IACjC,WAAW,CAAqB;IAEjD;QACE,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,WAAW,GAAG,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;IACnC,CAAC;IAEM,WAAW,CAAC,QAAgB,EAAE,QAAgB,EAAE,KAA6B;QAClF,MAAM,EAAE,UAAU,EAAE,YAAY,EAAE,GAAG,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC;QAEnE,MAAM,QAAQ,GAAa;YACzB,UAAU,EAAE,QAAQ;YACpB,KAAK,EAAE,EAAE;YACT,UAAU;YACV,YAAY;SACb,CAAC;QAEF,KAAK,MAAM,CAAC,UAAU,EAAE,SAAS,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YAC5D,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC;gBAClB,UAAU,EAAE,MAAM,CAAC,UAAU,CAAC;gBAC9B,QAAQ,EAAE,SAAS,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;aAClC,CAAC,CAAC;QACL,CAAC;QAED,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACxC,CAAC;IAEM,QAAQ;QACb,IAAI,OAAO,IAAI,IAAI,CAAC,WAAW,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE,CAAC;YACzE,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC;QAClF,CAAC;QACD,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;CACF;AAED,6BAA6B;AAC7B,eAAe,CAAC,QAAQ,CAAC;IACvB,IAAI,EAAE,UAAU;IAChB,WAAW,EAAE,+CAA+C;IAC5D,aAAa,EAAE,OAAO;IACtB,OAAO,EAAE,GAAG,EAAE,CAAC,IAAI,mBAAmB,EAAE;IACxC,cAAc,EAAE,CAAC,SAAS,EAAE,WAAW,EAAE,gBAAgB,CAAC;CAC3D,CAAC,CAAC"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { OpenCoverCoverageObject } from '../utils/types.js';
|
|
2
|
+
import { BaseHandler } from './BaseHandler.js';
|
|
3
|
+
/**
|
|
4
|
+
* Handler for generating OpenCover XML coverage reports.
|
|
5
|
+
*
|
|
6
|
+
* OpenCover is a code coverage tool for .NET, but its XML format
|
|
7
|
+
* is also accepted by Azure DevOps, Visual Studio, and other tools.
|
|
8
|
+
*
|
|
9
|
+
* **Format Origin**: OpenCover (.NET coverage tool)
|
|
10
|
+
*
|
|
11
|
+
* @see https://github.com/OpenCover/opencover
|
|
12
|
+
* @see https://github.com/OpenCover/opencover/wiki/Reports
|
|
13
|
+
*
|
|
14
|
+
* **Apex-Specific Adaptations**:
|
|
15
|
+
* - Salesforce Apex only provides line-level coverage data
|
|
16
|
+
* - Each Apex class is represented as an OpenCover "Module"
|
|
17
|
+
* - Line coverage is mapped to "SequencePoints" (executable code locations)
|
|
18
|
+
* - Branch coverage is always 0 (Apex doesn't provide branch/decision coverage)
|
|
19
|
+
* - Column information (`@sc`, `@ec`) defaults to 0 (not available in Apex)
|
|
20
|
+
*
|
|
21
|
+
* **Limitations**:
|
|
22
|
+
* - No branch/decision coverage - OpenCover supports this, Apex does not
|
|
23
|
+
* - No method-level coverage granularity - treating entire class as one method
|
|
24
|
+
* - No cyclomatic complexity metrics
|
|
25
|
+
* - No column-level positioning data
|
|
26
|
+
*
|
|
27
|
+
* **Structure Mapping**:
|
|
28
|
+
* - Apex Class → OpenCover Module/Class
|
|
29
|
+
* - Apex Class → OpenCover Method (single method per class)
|
|
30
|
+
* - Apex Lines → OpenCover SequencePoints
|
|
31
|
+
*
|
|
32
|
+
* Compatible with:
|
|
33
|
+
* - Azure DevOps
|
|
34
|
+
* - Visual Studio
|
|
35
|
+
* - Codecov
|
|
36
|
+
* - JetBrains tools (ReSharper, Rider)
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* ```xml
|
|
40
|
+
* <CoverageSession>
|
|
41
|
+
* <Summary numSequencePoints="100" visitedSequencePoints="75" />
|
|
42
|
+
* <Modules>
|
|
43
|
+
* <Module>
|
|
44
|
+
* <Files>
|
|
45
|
+
* <File uid="1" fullPath="path/to/file.cls" />
|
|
46
|
+
* </Files>
|
|
47
|
+
* <Classes>
|
|
48
|
+
* <Class fullName="ClassName">
|
|
49
|
+
* <Methods>
|
|
50
|
+
* <Method name="MethodName">
|
|
51
|
+
* <SequencePoints>
|
|
52
|
+
* <SequencePoint vc="1" sl="1" />
|
|
53
|
+
* </SequencePoints>
|
|
54
|
+
* </Method>
|
|
55
|
+
* </Methods>
|
|
56
|
+
* </Class>
|
|
57
|
+
* </Classes>
|
|
58
|
+
* </Module>
|
|
59
|
+
* </Modules>
|
|
60
|
+
* </CoverageSession>
|
|
61
|
+
* ```
|
|
62
|
+
*/
|
|
63
|
+
export declare class OpenCoverCoverageHandler extends BaseHandler {
|
|
64
|
+
private readonly coverageObj;
|
|
65
|
+
private readonly module;
|
|
66
|
+
private fileIdCounter;
|
|
67
|
+
private filePathToId;
|
|
68
|
+
constructor();
|
|
69
|
+
processFile(filePath: string, fileName: string, lines: Record<string, number>): void;
|
|
70
|
+
finalize(): OpenCoverCoverageObject;
|
|
71
|
+
}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
import { BaseHandler } from './BaseHandler.js';
|
|
3
|
+
import { HandlerRegistry } from './HandlerRegistry.js';
|
|
4
|
+
/**
|
|
5
|
+
* Handler for generating OpenCover XML coverage reports.
|
|
6
|
+
*
|
|
7
|
+
* OpenCover is a code coverage tool for .NET, but its XML format
|
|
8
|
+
* is also accepted by Azure DevOps, Visual Studio, and other tools.
|
|
9
|
+
*
|
|
10
|
+
* **Format Origin**: OpenCover (.NET coverage tool)
|
|
11
|
+
*
|
|
12
|
+
* @see https://github.com/OpenCover/opencover
|
|
13
|
+
* @see https://github.com/OpenCover/opencover/wiki/Reports
|
|
14
|
+
*
|
|
15
|
+
* **Apex-Specific Adaptations**:
|
|
16
|
+
* - Salesforce Apex only provides line-level coverage data
|
|
17
|
+
* - Each Apex class is represented as an OpenCover "Module"
|
|
18
|
+
* - Line coverage is mapped to "SequencePoints" (executable code locations)
|
|
19
|
+
* - Branch coverage is always 0 (Apex doesn't provide branch/decision coverage)
|
|
20
|
+
* - Column information (`@sc`, `@ec`) defaults to 0 (not available in Apex)
|
|
21
|
+
*
|
|
22
|
+
* **Limitations**:
|
|
23
|
+
* - No branch/decision coverage - OpenCover supports this, Apex does not
|
|
24
|
+
* - No method-level coverage granularity - treating entire class as one method
|
|
25
|
+
* - No cyclomatic complexity metrics
|
|
26
|
+
* - No column-level positioning data
|
|
27
|
+
*
|
|
28
|
+
* **Structure Mapping**:
|
|
29
|
+
* - Apex Class → OpenCover Module/Class
|
|
30
|
+
* - Apex Class → OpenCover Method (single method per class)
|
|
31
|
+
* - Apex Lines → OpenCover SequencePoints
|
|
32
|
+
*
|
|
33
|
+
* Compatible with:
|
|
34
|
+
* - Azure DevOps
|
|
35
|
+
* - Visual Studio
|
|
36
|
+
* - Codecov
|
|
37
|
+
* - JetBrains tools (ReSharper, Rider)
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* ```xml
|
|
41
|
+
* <CoverageSession>
|
|
42
|
+
* <Summary numSequencePoints="100" visitedSequencePoints="75" />
|
|
43
|
+
* <Modules>
|
|
44
|
+
* <Module>
|
|
45
|
+
* <Files>
|
|
46
|
+
* <File uid="1" fullPath="path/to/file.cls" />
|
|
47
|
+
* </Files>
|
|
48
|
+
* <Classes>
|
|
49
|
+
* <Class fullName="ClassName">
|
|
50
|
+
* <Methods>
|
|
51
|
+
* <Method name="MethodName">
|
|
52
|
+
* <SequencePoints>
|
|
53
|
+
* <SequencePoint vc="1" sl="1" />
|
|
54
|
+
* </SequencePoints>
|
|
55
|
+
* </Method>
|
|
56
|
+
* </Methods>
|
|
57
|
+
* </Class>
|
|
58
|
+
* </Classes>
|
|
59
|
+
* </Module>
|
|
60
|
+
* </Modules>
|
|
61
|
+
* </CoverageSession>
|
|
62
|
+
* ```
|
|
63
|
+
*/
|
|
64
|
+
export class OpenCoverCoverageHandler extends BaseHandler {
|
|
65
|
+
coverageObj;
|
|
66
|
+
module;
|
|
67
|
+
fileIdCounter = 1;
|
|
68
|
+
filePathToId = new Map();
|
|
69
|
+
constructor() {
|
|
70
|
+
super();
|
|
71
|
+
this.module = {
|
|
72
|
+
'@hash': 'apex-module',
|
|
73
|
+
Files: { File: [] },
|
|
74
|
+
Classes: { Class: [] },
|
|
75
|
+
};
|
|
76
|
+
this.coverageObj = {
|
|
77
|
+
CoverageSession: {
|
|
78
|
+
Summary: {
|
|
79
|
+
'@numSequencePoints': 0,
|
|
80
|
+
'@visitedSequencePoints': 0,
|
|
81
|
+
'@numBranchPoints': 0,
|
|
82
|
+
'@visitedBranchPoints': 0,
|
|
83
|
+
'@sequenceCoverage': 0,
|
|
84
|
+
'@branchCoverage': 0,
|
|
85
|
+
},
|
|
86
|
+
Modules: {
|
|
87
|
+
Module: [this.module],
|
|
88
|
+
},
|
|
89
|
+
},
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
processFile(filePath, fileName, lines) {
|
|
93
|
+
// Register file if not already registered
|
|
94
|
+
if (!this.filePathToId.has(filePath)) {
|
|
95
|
+
const fileId = this.fileIdCounter++;
|
|
96
|
+
this.filePathToId.set(filePath, fileId);
|
|
97
|
+
const fileObj = {
|
|
98
|
+
'@uid': fileId,
|
|
99
|
+
'@fullPath': filePath,
|
|
100
|
+
};
|
|
101
|
+
this.module.Files.File.push(fileObj);
|
|
102
|
+
}
|
|
103
|
+
const { totalLines, coveredLines } = this.calculateCoverage(lines);
|
|
104
|
+
// Create sequence points for each line
|
|
105
|
+
// In OpenCover, a SequencePoint represents an executable statement location
|
|
106
|
+
// We map each Apex line to a SequencePoint
|
|
107
|
+
const sequencePoints = [];
|
|
108
|
+
for (const [lineNumber, hits] of Object.entries(lines)) {
|
|
109
|
+
sequencePoints.push({
|
|
110
|
+
'@vc': hits, // visit count (number of times this line was executed)
|
|
111
|
+
'@sl': Number(lineNumber), // start line
|
|
112
|
+
'@sc': 0, // start column (not available in Apex coverage data)
|
|
113
|
+
'@el': Number(lineNumber), // end line (same as start for line-level coverage)
|
|
114
|
+
'@ec': 0, // end column (not available in Apex coverage data)
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
// Create a method for this file
|
|
118
|
+
// NOTE: Apex classes are treated as a single method since we don't have
|
|
119
|
+
// method-level coverage granularity from Salesforce
|
|
120
|
+
const method = {
|
|
121
|
+
'@name': fileName,
|
|
122
|
+
'@isConstructor': false,
|
|
123
|
+
'@isStatic': false,
|
|
124
|
+
SequencePoints: {
|
|
125
|
+
SequencePoint: sequencePoints,
|
|
126
|
+
},
|
|
127
|
+
};
|
|
128
|
+
// Create a class for this file
|
|
129
|
+
const classObj = {
|
|
130
|
+
'@fullName': fileName,
|
|
131
|
+
Methods: {
|
|
132
|
+
Method: [method],
|
|
133
|
+
},
|
|
134
|
+
};
|
|
135
|
+
this.module.Classes.Class.push(classObj);
|
|
136
|
+
// Update summary statistics
|
|
137
|
+
this.coverageObj.CoverageSession.Summary['@numSequencePoints'] += totalLines;
|
|
138
|
+
this.coverageObj.CoverageSession.Summary['@visitedSequencePoints'] += coveredLines;
|
|
139
|
+
}
|
|
140
|
+
finalize() {
|
|
141
|
+
const summary = this.coverageObj.CoverageSession.Summary;
|
|
142
|
+
// Calculate sequence coverage percentage
|
|
143
|
+
if (summary['@numSequencePoints'] > 0) {
|
|
144
|
+
const coverage = (summary['@visitedSequencePoints'] / summary['@numSequencePoints']) * 100;
|
|
145
|
+
summary['@sequenceCoverage'] = Number(coverage.toFixed(2));
|
|
146
|
+
}
|
|
147
|
+
// Branch coverage is always 0 for Apex (no branch/decision coverage data available)
|
|
148
|
+
// In .NET environments, this would track if/else branches, switch cases, etc.
|
|
149
|
+
summary['@branchCoverage'] = 0;
|
|
150
|
+
// Sort classes by name for consistent output
|
|
151
|
+
this.module.Classes.Class.sort((a, b) => a['@fullName'].localeCompare(b['@fullName']));
|
|
152
|
+
// Sort files by path for consistent output
|
|
153
|
+
this.module.Files.File.sort((a, b) => a['@fullPath'].localeCompare(b['@fullPath']));
|
|
154
|
+
return this.coverageObj;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
// Self-register this handler
|
|
158
|
+
HandlerRegistry.register({
|
|
159
|
+
name: 'opencover',
|
|
160
|
+
description: 'OpenCover XML format for .NET and Azure DevOps',
|
|
161
|
+
fileExtension: '.xml',
|
|
162
|
+
handler: () => new OpenCoverCoverageHandler(),
|
|
163
|
+
compatibleWith: ['Azure DevOps', 'Visual Studio', 'Codecov', 'JetBrains Tools'],
|
|
164
|
+
});
|
|
165
|
+
//# sourceMappingURL=opencover.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"opencover.js","sourceRoot":"","sources":["../../src/handlers/opencover.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { SimpleCovCoverageObject } from '../utils/types.js';
|
|
2
|
+
import { BaseHandler } from './BaseHandler.js';
|
|
3
|
+
/**
|
|
4
|
+
* Handler for generating SimpleCov JSON coverage reports.
|
|
5
|
+
*
|
|
6
|
+
* SimpleCov is a popular Ruby code coverage tool. This format is also
|
|
7
|
+
* accepted by Codecov and other coverage aggregation tools.
|
|
8
|
+
*
|
|
9
|
+
* **Format Origin**: SimpleCov (Ruby coverage tool)
|
|
10
|
+
*
|
|
11
|
+
* @see https://github.com/simplecov-ruby/simplecov
|
|
12
|
+
* @see https://github.com/vicentllongo/simplecov-json
|
|
13
|
+
* @see https://docs.codecov.com/docs/codecov-uploader
|
|
14
|
+
*
|
|
15
|
+
* **Format Structure**:
|
|
16
|
+
* The format uses an array of hit counts per line, with null for non-executable lines.
|
|
17
|
+
* Array indices are 0-based (index 0 = line 1, index 1 = line 2, etc.)
|
|
18
|
+
*
|
|
19
|
+
* **Apex-Specific Adaptations**:
|
|
20
|
+
* - Only lines present in Apex coverage data are tracked
|
|
21
|
+
* - Lines not in coverage data are marked as `null` (non-executable)
|
|
22
|
+
* - This works well with Apex since Salesforce only reports executable lines
|
|
23
|
+
*
|
|
24
|
+
* **Advantages for Apex**:
|
|
25
|
+
* - Simple, compact format
|
|
26
|
+
* - Direct mapping from Apex line coverage to SimpleCov format
|
|
27
|
+
* - Well-supported by Codecov and similar platforms
|
|
28
|
+
*
|
|
29
|
+
* Compatible with:
|
|
30
|
+
* - Codecov
|
|
31
|
+
* - SimpleCov analyzers
|
|
32
|
+
* - Ruby coverage tools
|
|
33
|
+
* - Custom parsers
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ```json
|
|
37
|
+
* {
|
|
38
|
+
* "coverage": {
|
|
39
|
+
* "path/to/file.cls": [1, 1, 0, 1, null, 1]
|
|
40
|
+
* },
|
|
41
|
+
* "timestamp": 1234567890
|
|
42
|
+
* }
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
45
|
+
export declare class SimpleCovCoverageHandler extends BaseHandler {
|
|
46
|
+
private readonly coverageObj;
|
|
47
|
+
constructor();
|
|
48
|
+
processFile(filePath: string, _fileName: string, lines: Record<string, number>): void;
|
|
49
|
+
finalize(): SimpleCovCoverageObject;
|
|
50
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
import { BaseHandler } from './BaseHandler.js';
|
|
3
|
+
import { HandlerRegistry } from './HandlerRegistry.js';
|
|
4
|
+
/**
|
|
5
|
+
* Handler for generating SimpleCov JSON coverage reports.
|
|
6
|
+
*
|
|
7
|
+
* SimpleCov is a popular Ruby code coverage tool. This format is also
|
|
8
|
+
* accepted by Codecov and other coverage aggregation tools.
|
|
9
|
+
*
|
|
10
|
+
* **Format Origin**: SimpleCov (Ruby coverage tool)
|
|
11
|
+
*
|
|
12
|
+
* @see https://github.com/simplecov-ruby/simplecov
|
|
13
|
+
* @see https://github.com/vicentllongo/simplecov-json
|
|
14
|
+
* @see https://docs.codecov.com/docs/codecov-uploader
|
|
15
|
+
*
|
|
16
|
+
* **Format Structure**:
|
|
17
|
+
* The format uses an array of hit counts per line, with null for non-executable lines.
|
|
18
|
+
* Array indices are 0-based (index 0 = line 1, index 1 = line 2, etc.)
|
|
19
|
+
*
|
|
20
|
+
* **Apex-Specific Adaptations**:
|
|
21
|
+
* - Only lines present in Apex coverage data are tracked
|
|
22
|
+
* - Lines not in coverage data are marked as `null` (non-executable)
|
|
23
|
+
* - This works well with Apex since Salesforce only reports executable lines
|
|
24
|
+
*
|
|
25
|
+
* **Advantages for Apex**:
|
|
26
|
+
* - Simple, compact format
|
|
27
|
+
* - Direct mapping from Apex line coverage to SimpleCov format
|
|
28
|
+
* - Well-supported by Codecov and similar platforms
|
|
29
|
+
*
|
|
30
|
+
* Compatible with:
|
|
31
|
+
* - Codecov
|
|
32
|
+
* - SimpleCov analyzers
|
|
33
|
+
* - Ruby coverage tools
|
|
34
|
+
* - Custom parsers
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* ```json
|
|
38
|
+
* {
|
|
39
|
+
* "coverage": {
|
|
40
|
+
* "path/to/file.cls": [1, 1, 0, 1, null, 1]
|
|
41
|
+
* },
|
|
42
|
+
* "timestamp": 1234567890
|
|
43
|
+
* }
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
export class SimpleCovCoverageHandler extends BaseHandler {
|
|
47
|
+
coverageObj;
|
|
48
|
+
constructor() {
|
|
49
|
+
super();
|
|
50
|
+
this.coverageObj = {
|
|
51
|
+
coverage: {},
|
|
52
|
+
timestamp: Math.floor(Date.now() / 1000),
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
processFile(filePath, _fileName, lines) {
|
|
56
|
+
// Find the maximum line number to determine array size
|
|
57
|
+
const lineNumbers = Object.keys(lines).map(Number);
|
|
58
|
+
const maxLine = Math.max(...lineNumbers);
|
|
59
|
+
// Create array with nulls for non-executable lines
|
|
60
|
+
// SimpleCov uses null to indicate lines that are not executable/trackable
|
|
61
|
+
const lineArray = new Array(maxLine).fill(null);
|
|
62
|
+
// Fill in the coverage data
|
|
63
|
+
// SimpleCov arrays are 0-indexed, but line numbers are 1-indexed
|
|
64
|
+
// So line 1 goes into array index 0, line 2 into index 1, etc.
|
|
65
|
+
for (const [lineNumber, hits] of Object.entries(lines)) {
|
|
66
|
+
const lineIdx = Number(lineNumber) - 1; // Convert to 0-index
|
|
67
|
+
lineArray[lineIdx] = hits; // Store hit count (0 = uncovered, >0 = covered)
|
|
68
|
+
}
|
|
69
|
+
this.coverageObj.coverage[filePath] = lineArray;
|
|
70
|
+
}
|
|
71
|
+
finalize() {
|
|
72
|
+
return this.coverageObj;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
// Self-register this handler
|
|
76
|
+
HandlerRegistry.register({
|
|
77
|
+
name: 'simplecov',
|
|
78
|
+
description: 'SimpleCov JSON format compatible with Ruby coverage tools',
|
|
79
|
+
fileExtension: '.json',
|
|
80
|
+
handler: () => new SimpleCovCoverageHandler(),
|
|
81
|
+
compatibleWith: ['Codecov', 'SimpleCov', 'Ruby Tools'],
|
|
82
|
+
});
|
|
83
|
+
//# sourceMappingURL=simplecov.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"simplecov.js","sourceRoot":"","sources":["../../src/handlers/simplecov.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAGb,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAEvD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AACH,MAAM,OAAO,wBAAyB,SAAQ,WAAW;IACtC,WAAW,CAA0B;IAEtD;QACE,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,WAAW,GAAG;YACjB,QAAQ,EAAE,EAAE;YACZ,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;SACzC,CAAC;IACJ,CAAC;IAEM,WAAW,CAAC,QAAgB,EAAE,SAAiB,EAAE,KAA6B;QACnF,uDAAuD;QACvD,MAAM,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACnD,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,WAAW,CAAC,CAAC;QAEzC,mDAAmD;QACnD,0EAA0E;QAC1E,MAAM,SAAS,GAAyB,IAAI,KAAK,CAAgB,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAErF,4BAA4B;QAC5B,iEAAiE;QACjE,+DAA+D;QAC/D,KAAK,MAAM,CAAC,UAAU,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YACvD,MAAM,OAAO,GAAG,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,qBAAqB;YAC7D,SAAS,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC,gDAAgD;QAC7E,CAAC;QAED,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,SAAS,CAAC;IAClD,CAAC;IAEM,QAAQ;QACb,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;CACF;AAED,6BAA6B;AAC7B,eAAe,CAAC,QAAQ,CAAC;IACvB,IAAI,EAAE,WAAW;IACjB,WAAW,EAAE,2DAA2D;IACxE,aAAa,EAAE,OAAO;IACtB,OAAO,EAAE,GAAG,EAAE,CAAC,IAAI,wBAAwB,EAAE;IAC7C,cAAc,EAAE,CAAC,SAAS,EAAE,WAAW,EAAE,YAAY,CAAC;CACvD,CAAC,CAAC"}
|
package/lib/handlers/sonar.d.ts
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
|
-
import { SonarCoverageObject
|
|
2
|
-
|
|
1
|
+
import { SonarCoverageObject } from '../utils/types.js';
|
|
2
|
+
import { BaseHandler } from './BaseHandler.js';
|
|
3
|
+
/**
|
|
4
|
+
* Handler for generating SonarQube Generic Coverage reports.
|
|
5
|
+
*
|
|
6
|
+
* This is the default format and is compatible with SonarQube and SonarCloud.
|
|
7
|
+
*
|
|
8
|
+
* @see https://docs.sonarqube.org/latest/analysis/generic-test/
|
|
9
|
+
*/
|
|
10
|
+
export declare class SonarCoverageHandler extends BaseHandler {
|
|
3
11
|
private readonly coverageObj;
|
|
4
12
|
constructor();
|
|
5
13
|
processFile(filePath: string, _fileName: string, lines: Record<string, number>): void;
|
package/lib/handlers/sonar.js
CHANGED
|
@@ -1,7 +1,17 @@
|
|
|
1
1
|
'use strict';
|
|
2
|
-
|
|
2
|
+
import { BaseHandler } from './BaseHandler.js';
|
|
3
|
+
import { HandlerRegistry } from './HandlerRegistry.js';
|
|
4
|
+
/**
|
|
5
|
+
* Handler for generating SonarQube Generic Coverage reports.
|
|
6
|
+
*
|
|
7
|
+
* This is the default format and is compatible with SonarQube and SonarCloud.
|
|
8
|
+
*
|
|
9
|
+
* @see https://docs.sonarqube.org/latest/analysis/generic-test/
|
|
10
|
+
*/
|
|
11
|
+
export class SonarCoverageHandler extends BaseHandler {
|
|
3
12
|
coverageObj;
|
|
4
13
|
constructor() {
|
|
14
|
+
super();
|
|
5
15
|
this.coverageObj = { coverage: { '@version': '1', file: [] } };
|
|
6
16
|
}
|
|
7
17
|
processFile(filePath, _fileName, lines) {
|
|
@@ -20,9 +30,17 @@ export class SonarCoverageHandler {
|
|
|
20
30
|
}
|
|
21
31
|
finalize() {
|
|
22
32
|
if (this.coverageObj.coverage?.file) {
|
|
23
|
-
this.coverageObj.coverage.file
|
|
33
|
+
this.coverageObj.coverage.file = this.sortByPath(this.coverageObj.coverage.file);
|
|
24
34
|
}
|
|
25
35
|
return this.coverageObj;
|
|
26
36
|
}
|
|
27
37
|
}
|
|
38
|
+
// Self-register this handler
|
|
39
|
+
HandlerRegistry.register({
|
|
40
|
+
name: 'sonar',
|
|
41
|
+
description: 'SonarQube Generic Coverage format',
|
|
42
|
+
fileExtension: '.xml',
|
|
43
|
+
handler: () => new SonarCoverageHandler(),
|
|
44
|
+
compatibleWith: ['SonarQube', 'SonarCloud'],
|
|
45
|
+
});
|
|
28
46
|
//# sourceMappingURL=sonar.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sonar.js","sourceRoot":"","sources":["../../src/handlers/sonar.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"sonar.js","sourceRoot":"","sources":["../../src/handlers/sonar.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAGb,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAEvD;;;;;;GAMG;AACH,MAAM,OAAO,oBAAqB,SAAQ,WAAW;IAClC,WAAW,CAAsB;IAElD;QACE,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,WAAW,GAAG,EAAE,QAAQ,EAAE,EAAE,UAAU,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,CAAC;IACjE,CAAC;IAEM,WAAW,CAAC,QAAgB,EAAE,SAAiB,EAAE,KAA6B;QACnF,MAAM,OAAO,GAAe;YAC1B,OAAO,EAAE,QAAQ;YACjB,WAAW,EAAE,EAAE;SAChB,CAAC;QACF,KAAK,MAAM,CAAC,gBAAgB,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YAC9D,MAAM,OAAO,GAAG,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC;YAC/C,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC;gBACvB,aAAa,EAAE,MAAM,CAAC,gBAAgB,CAAC;gBACvC,UAAU,EAAE,OAAO;aACpB,CAAC,CAAC;QACL,CAAC;QAED,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC/C,CAAC;IAEM,QAAQ;QACb,IAAI,IAAI,CAAC,WAAW,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC;YACpC,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QACnF,CAAC;QACD,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;CACF;AAED,6BAA6B;AAC7B,eAAe,CAAC,QAAQ,CAAC;IACvB,IAAI,EAAE,OAAO;IACb,WAAW,EAAE,mCAAmC;IAChD,aAAa,EAAE,MAAM;IACrB,OAAO,EAAE,GAAG,EAAE,CAAC,IAAI,oBAAoB,EAAE;IACzC,cAAc,EAAE,CAAC,WAAW,EAAE,YAAY,CAAC;CAC5C,CAAC,CAAC"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { SonarCoverageObject, CoberturaCoverageObject, CloverCoverageObject, LcovCoverageObject, JaCoCoCoverageObject, IstanbulCoverageObject } from '../utils/types.js';
|
|
2
|
-
export declare function generateAndWriteReport(outputPath: string, coverageObj: SonarCoverageObject | CoberturaCoverageObject | CloverCoverageObject | LcovCoverageObject | JaCoCoCoverageObject | IstanbulCoverageObject, format: string, formatAmount: number): Promise<string>;
|
|
1
|
+
import { SonarCoverageObject, CoberturaCoverageObject, CloverCoverageObject, LcovCoverageObject, JaCoCoCoverageObject, IstanbulCoverageObject, JsonSummaryCoverageObject, SimpleCovCoverageObject, OpenCoverCoverageObject } from '../utils/types.js';
|
|
2
|
+
export declare function generateAndWriteReport(outputPath: string, coverageObj: SonarCoverageObject | CoberturaCoverageObject | CloverCoverageObject | LcovCoverageObject | JaCoCoCoverageObject | IstanbulCoverageObject | JsonSummaryCoverageObject | SimpleCovCoverageObject | OpenCoverCoverageObject, format: string, formatAmount: number): Promise<string>;
|
|
3
3
|
export declare function getExtensionForFormat(format: string): string;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { writeFile } from 'node:fs/promises';
|
|
2
2
|
import { extname, basename, dirname, join } from 'node:path';
|
|
3
3
|
import { create } from 'xmlbuilder2';
|
|
4
|
+
import { HandlerRegistry } from '../handlers/HandlerRegistry.js';
|
|
4
5
|
export async function generateAndWriteReport(outputPath, coverageObj, format, formatAmount) {
|
|
5
6
|
const content = generateReportContent(coverageObj, format);
|
|
6
|
-
const extension =
|
|
7
|
+
const extension = HandlerRegistry.getExtension(format);
|
|
7
8
|
const base = basename(outputPath, extname(outputPath)); // e.g., 'coverage'
|
|
8
9
|
const dir = dirname(outputPath);
|
|
9
10
|
const suffix = formatAmount > 1 ? `-${format}` : '';
|
|
@@ -15,10 +16,10 @@ function generateReportContent(coverageObj, format) {
|
|
|
15
16
|
if (format === 'lcovonly' && isLcovCoverageObject(coverageObj)) {
|
|
16
17
|
return generateLcov(coverageObj);
|
|
17
18
|
}
|
|
18
|
-
if (format === 'json') {
|
|
19
|
+
if (format === 'json' || format === 'json-summary' || format === 'simplecov') {
|
|
19
20
|
return JSON.stringify(coverageObj, null, 2);
|
|
20
21
|
}
|
|
21
|
-
const isHeadless = ['cobertura', 'clover', 'jacoco'].includes(format);
|
|
22
|
+
const isHeadless = ['cobertura', 'clover', 'jacoco', 'opencover'].includes(format);
|
|
22
23
|
const xml = create(coverageObj).end({ prettyPrint: true, indent: ' ', headless: isHeadless });
|
|
23
24
|
return prependXmlHeader(xml, format);
|
|
24
25
|
}
|
|
@@ -49,16 +50,14 @@ function prependXmlHeader(xml, format) {
|
|
|
49
50
|
return `<?xml version="1.0" encoding="UTF-8"?>\n${xml}`;
|
|
50
51
|
case 'jacoco':
|
|
51
52
|
return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n<!DOCTYPE report PUBLIC "-//JACOCO//DTD Report 1.0//EN" "report.dtd">\n${xml}`;
|
|
53
|
+
case 'opencover':
|
|
54
|
+
return `<?xml version="1.0" encoding="utf-8"?>\n${xml}`;
|
|
52
55
|
default:
|
|
53
56
|
return xml;
|
|
54
57
|
}
|
|
55
58
|
}
|
|
56
59
|
export function getExtensionForFormat(format) {
|
|
57
|
-
|
|
58
|
-
return '.info';
|
|
59
|
-
if (format === 'json')
|
|
60
|
-
return '.json';
|
|
61
|
-
return '.xml';
|
|
60
|
+
return HandlerRegistry.getExtension(format);
|
|
62
61
|
}
|
|
63
62
|
function isLcovCoverageObject(obj) {
|
|
64
63
|
return typeof obj === 'object' && obj !== null && 'files' in obj;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reportGenerator.js","sourceRoot":"","sources":["../../src/transformers/reportGenerator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC7D,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"reportGenerator.js","sourceRoot":"","sources":["../../src/transformers/reportGenerator.ts"],"names":[],"mappings":"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"}
|
package/lib/utils/constants.d.ts
CHANGED
package/lib/utils/constants.js
CHANGED
|
@@ -1,2 +1,9 @@
|
|
|
1
|
-
|
|
1
|
+
import { HandlerRegistry } from '../handlers/HandlerRegistry.js';
|
|
2
|
+
// Import all handlers to ensure they're registered
|
|
3
|
+
import '../handlers/getHandler.js';
|
|
4
|
+
/**
|
|
5
|
+
* Get available coverage format options.
|
|
6
|
+
* This dynamically retrieves all registered formats from the HandlerRegistry.
|
|
7
|
+
*/
|
|
8
|
+
export const formatOptions = HandlerRegistry.getAvailableFormats();
|
|
2
9
|
//# sourceMappingURL=constants.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/utils/constants.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/utils/constants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AAEjE,mDAAmD;AACnD,OAAO,2BAA2B,CAAC;AAEnC;;;GAGG;AACH,MAAM,CAAC,MAAM,aAAa,GAAa,eAAe,CAAC,mBAAmB,EAAE,CAAC"}
|