apex-code-coverage-transformer 1.0.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/README.md +48 -0
- package/lib/commands/apex-code-coverage/transformer/transform.d.ts +15 -0
- package/lib/commands/apex-code-coverage/transformer/transform.js +78 -0
- package/lib/commands/apex-code-coverage/transformer/transform.js.map +1 -0
- package/lib/helpers/types.d.ts +20 -0
- package/lib/helpers/types.js +3 -0
- package/lib/helpers/types.js.map +1 -0
- package/lib/index.d.ts +2 -0
- package/lib/index.js +2 -0
- package/lib/index.js.map +1 -0
- package/messages/transformer.transform.md +23 -0
- package/oclif.lock +12084 -0
- package/oclif.manifest.json +70 -0
- package/package.json +186 -0
package/README.md
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Apex Code Coverage Transformer
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/apex-code-coverage-transformer) [](https://npmjs.org/package/apex-code-coverage-transformer) [](https://raw.githubusercontent.com/salesforcecli/apex-code-coverage-transformer/main/LICENSE.txt)
|
|
4
|
+
|
|
5
|
+
The `apex-code-coverage-transformer` is a simple plugin to transform the JSON file for Apex Code Coverage into Generic Test Coverage Format (XML). This format is accepted by static code analysis tools like SonarQube.
|
|
6
|
+
|
|
7
|
+
Here is how you can create the JSON file with the Salesforce CLI:
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
sf project deploy validate -x manifest/package.xml -l RunSpecifiedTests -t {testclasses} --verbose --coverage-formatters json --results-dir coverage
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
This will create a coverage JSON in this relative path - `coverage/coverage/coverage.json`
|
|
14
|
+
|
|
15
|
+
This JSON isn't accepted by SonarQube automatically and needs to be converted using this plugin.
|
|
16
|
+
|
|
17
|
+
## Install
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
sf plugins install apex-code-coverage-transformer@x.y.z
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Commands
|
|
24
|
+
|
|
25
|
+
The `apex-code-coverage-transformer` has 1 command:
|
|
26
|
+
|
|
27
|
+
- `sf apex-code-coverage transformer transform`
|
|
28
|
+
|
|
29
|
+
## `sf apex-code-coverage transformer transform`
|
|
30
|
+
|
|
31
|
+
```
|
|
32
|
+
USAGE
|
|
33
|
+
$ sf apex-code-coverage transformer transform -j <value> -x <value> -d <value> [--json]
|
|
34
|
+
|
|
35
|
+
FLAGS
|
|
36
|
+
-j, --json=<value> The path to the JSON file created by the Salesforce CLI for code coverage.
|
|
37
|
+
-x, --xml=<value> [default: coverage.xml] Output path for the XML file created by this plugin
|
|
38
|
+
-d, --dx-directory=<value> [default: force-app/main/default] The root directory containing your Salesforce metadata.
|
|
39
|
+
|
|
40
|
+
GLOBAL FLAGS
|
|
41
|
+
--json Format output as json.
|
|
42
|
+
|
|
43
|
+
DESCRIPTION
|
|
44
|
+
This plugin will convert the JSON file created by the Salesforce CLI during Apex deployments into the Generic Test Coverage Format.
|
|
45
|
+
|
|
46
|
+
EXAMPLES
|
|
47
|
+
$ apex-code-coverage transformer transform -j "test.json" -x "coverage.xml" -d "force-app/main/default"
|
|
48
|
+
```
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { SfCommand } from '@salesforce/sf-plugins-core';
|
|
2
|
+
export type TransformerTransformResult = {
|
|
3
|
+
path: string;
|
|
4
|
+
};
|
|
5
|
+
export default class TransformerTransform extends SfCommand<TransformerTransformResult> {
|
|
6
|
+
static readonly summary: string;
|
|
7
|
+
static readonly description: string;
|
|
8
|
+
static readonly examples: string[];
|
|
9
|
+
static readonly flags: {
|
|
10
|
+
'dx-directory': import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
11
|
+
json: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
12
|
+
xml: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
13
|
+
};
|
|
14
|
+
run(): Promise<TransformerTransformResult>;
|
|
15
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
import * as fs from 'node:fs';
|
|
3
|
+
import { SfCommand, Flags } from '@salesforce/sf-plugins-core';
|
|
4
|
+
import { Messages } from '@salesforce/core';
|
|
5
|
+
Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
|
|
6
|
+
const messages = Messages.loadMessages('apex-code-coverage-transformer', 'transformer.transform');
|
|
7
|
+
export default class TransformerTransform extends SfCommand {
|
|
8
|
+
static summary = messages.getMessage('summary');
|
|
9
|
+
static description = messages.getMessage('description');
|
|
10
|
+
static examples = messages.getMessages('examples');
|
|
11
|
+
static flags = {
|
|
12
|
+
'dx-directory': Flags.directory({
|
|
13
|
+
summary: messages.getMessage('flags.dx-directory.summary'),
|
|
14
|
+
char: 'd',
|
|
15
|
+
required: true,
|
|
16
|
+
exists: true,
|
|
17
|
+
default: 'force-app/main/default',
|
|
18
|
+
}),
|
|
19
|
+
'json': Flags.string({
|
|
20
|
+
summary: messages.getMessage('flags.json.summary'),
|
|
21
|
+
char: 'j',
|
|
22
|
+
required: true,
|
|
23
|
+
exists: true,
|
|
24
|
+
}),
|
|
25
|
+
'xml': Flags.string({
|
|
26
|
+
summary: messages.getMessage('flags.xml.summary'),
|
|
27
|
+
char: 'x',
|
|
28
|
+
required: true,
|
|
29
|
+
exists: true,
|
|
30
|
+
default: 'coverage.xml',
|
|
31
|
+
}),
|
|
32
|
+
};
|
|
33
|
+
async run() {
|
|
34
|
+
const { flags } = await this.parse(TransformerTransform);
|
|
35
|
+
const jsonFilePath = flags['json'];
|
|
36
|
+
const xmlFilePath = flags['xml'];
|
|
37
|
+
const dxDirectory = flags['dx-directory'];
|
|
38
|
+
const jsonData = fs.readFileSync(jsonFilePath, 'utf-8');
|
|
39
|
+
const coverageData = JSON.parse(jsonData);
|
|
40
|
+
const xmlData = convertToGenericTestReport(coverageData, dxDirectory);
|
|
41
|
+
// Write the XML data to the XML file
|
|
42
|
+
try {
|
|
43
|
+
fs.writeFileSync(xmlFilePath, xmlData);
|
|
44
|
+
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
|
|
45
|
+
this.log(`The XML data has been written to ${xmlFilePath}`);
|
|
46
|
+
}
|
|
47
|
+
catch (error) {
|
|
48
|
+
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
|
|
49
|
+
this.error(`Error writing XML data to file: ${error}`);
|
|
50
|
+
}
|
|
51
|
+
return { path: xmlFilePath };
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
function convertToGenericTestReport(data, dxDirectory) {
|
|
55
|
+
let xml = '<?xml version="1.0"?>\n<coverage version="1">\n';
|
|
56
|
+
for (const className in data) {
|
|
57
|
+
if (Object.prototype.hasOwnProperty.call(data, className)) {
|
|
58
|
+
const classInfo = data[className];
|
|
59
|
+
const formattedClassName = className.replace('no-map/', '');
|
|
60
|
+
const classPath = `${dxDirectory}/classes/${formattedClassName}.cls`;
|
|
61
|
+
xml += `\t<file path="${classPath}">\n`;
|
|
62
|
+
for (const lineNumber in classInfo.s) {
|
|
63
|
+
if (Object.prototype.hasOwnProperty.call(classInfo.s, lineNumber)) {
|
|
64
|
+
const count = classInfo.s[lineNumber];
|
|
65
|
+
const covered = count > 0 ? 'true' : 'false';
|
|
66
|
+
// only add uncovered lines
|
|
67
|
+
if (covered === 'false') {
|
|
68
|
+
xml += `\t\t<lineToCover lineNumber="${lineNumber}" covered="${covered}"/>\n`;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
xml += '\t</file>\n';
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
xml += '</coverage>';
|
|
76
|
+
return xml;
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=transform.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transform.js","sourceRoot":"","sources":["../../../../src/commands/apex-code-coverage/transformer/transform.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export interface CoverageData {
|
|
2
|
+
[className: string]: {
|
|
3
|
+
fnMap: Record<string, unknown>;
|
|
4
|
+
branchMap: Record<string, unknown>;
|
|
5
|
+
path: string;
|
|
6
|
+
f: Record<string, unknown>;
|
|
7
|
+
b: Record<string, unknown>;
|
|
8
|
+
s: Record<string, number>;
|
|
9
|
+
statementMap: Record<string, {
|
|
10
|
+
start: {
|
|
11
|
+
line: number;
|
|
12
|
+
column: number;
|
|
13
|
+
};
|
|
14
|
+
end: {
|
|
15
|
+
line: number;
|
|
16
|
+
column: number;
|
|
17
|
+
};
|
|
18
|
+
}>;
|
|
19
|
+
};
|
|
20
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/helpers/types.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC"}
|
package/lib/index.d.ts
ADDED
package/lib/index.js
ADDED
package/lib/index.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,eAAe,EAAE,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# summary
|
|
2
|
+
|
|
3
|
+
Transforms the Code Coverage JSON into the Generic Test Data Format (XML).
|
|
4
|
+
|
|
5
|
+
# description
|
|
6
|
+
|
|
7
|
+
This plugin will convert the JSON file created by the Salesforce CLI during Apex deployments
|
|
8
|
+
|
|
9
|
+
# examples
|
|
10
|
+
|
|
11
|
+
- `sf apex-code-coverage transformer transform --json "path-to-cli-coverage.json"`
|
|
12
|
+
|
|
13
|
+
# flags.dx-directory.summary
|
|
14
|
+
|
|
15
|
+
Directory containing Salesforce metadata (default: `force-app/main/default`).
|
|
16
|
+
|
|
17
|
+
# flags.json.summary
|
|
18
|
+
|
|
19
|
+
Path to the JSON file created by the Salesforce CLI deployment command.
|
|
20
|
+
|
|
21
|
+
# flags.xml.summary
|
|
22
|
+
|
|
23
|
+
XML file created by this plugin (default: `coverage.xml`).
|