apex-code-coverage-transformer 1.3.1 → 1.4.1-beta.1
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/lib/commands/apex-code-coverage/transformer/transform.js +3 -46
- package/lib/commands/apex-code-coverage/transformer/transform.js.map +1 -1
- package/lib/helpers/convertToGenericCoverageReport.d.ts +2 -0
- package/lib/helpers/convertToGenericCoverageReport.js +24 -0
- package/lib/helpers/convertToGenericCoverageReport.js.map +1 -0
- package/lib/helpers/findFilePath.d.ts +1 -0
- package/lib/helpers/findFilePath.js +52 -0
- package/lib/helpers/findFilePath.js.map +1 -0
- package/oclif.manifest.json +1 -1
- package/package.json +1 -1
|
@@ -3,6 +3,7 @@ import * as fs from 'node:fs';
|
|
|
3
3
|
import * as path from 'node:path';
|
|
4
4
|
import { SfCommand, Flags } from '@salesforce/sf-plugins-core';
|
|
5
5
|
import { Messages } from '@salesforce/core';
|
|
6
|
+
import { convertToGenericCoverageReport } from '../../../helpers/convertToGenericCoverageReport.js';
|
|
6
7
|
Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
|
|
7
8
|
const messages = Messages.loadMessages('apex-code-coverage-transformer', 'transformer.transform');
|
|
8
9
|
export default class TransformerTransform extends SfCommand {
|
|
@@ -23,7 +24,7 @@ export default class TransformerTransform extends SfCommand {
|
|
|
23
24
|
required: true,
|
|
24
25
|
exists: true,
|
|
25
26
|
}),
|
|
26
|
-
|
|
27
|
+
xml: Flags.file({
|
|
27
28
|
summary: messages.getMessage('flags.xml.summary'),
|
|
28
29
|
char: 'x',
|
|
29
30
|
required: true,
|
|
@@ -44,7 +45,7 @@ export default class TransformerTransform extends SfCommand {
|
|
|
44
45
|
}
|
|
45
46
|
const jsonData = fs.readFileSync(jsonFilePath, 'utf-8');
|
|
46
47
|
const coverageData = JSON.parse(jsonData);
|
|
47
|
-
const xmlData =
|
|
48
|
+
const xmlData = convertToGenericCoverageReport(coverageData, dxDirectory);
|
|
48
49
|
// Write the XML data to the XML file
|
|
49
50
|
try {
|
|
50
51
|
fs.writeFileSync(xmlFilePath, xmlData);
|
|
@@ -58,48 +59,4 @@ export default class TransformerTransform extends SfCommand {
|
|
|
58
59
|
return { path: xmlFilePath };
|
|
59
60
|
}
|
|
60
61
|
}
|
|
61
|
-
function findFilePath(className, dxDirectory) {
|
|
62
|
-
const relativeClassPath = `${dxDirectory}/classes/${className}.cls`;
|
|
63
|
-
const relativeTriggerPath = `${dxDirectory}/triggers/${className}.trigger`;
|
|
64
|
-
const relativeFlowPath = `${dxDirectory}/flows/${className}.flow-meta.xml`;
|
|
65
|
-
const absoluteClassPath = path.resolve(relativeClassPath);
|
|
66
|
-
const absoluteTriggerPath = path.resolve(relativeTriggerPath);
|
|
67
|
-
const absoluteFlowPath = path.resolve(relativeFlowPath);
|
|
68
|
-
if (fs.existsSync(absoluteClassPath)) {
|
|
69
|
-
return relativeClassPath;
|
|
70
|
-
}
|
|
71
|
-
else if (fs.existsSync(absoluteTriggerPath)) {
|
|
72
|
-
return relativeTriggerPath;
|
|
73
|
-
}
|
|
74
|
-
else if (fs.existsSync(absoluteFlowPath)) {
|
|
75
|
-
return relativeFlowPath;
|
|
76
|
-
}
|
|
77
|
-
else {
|
|
78
|
-
throw Error(`The file name ${className} was not found in the classes, triggers, or flows directory.`);
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
function convertToGenericTestReport(data, dxDirectory) {
|
|
82
|
-
let xml = '<?xml version="1.0"?>\n<coverage version="1">\n';
|
|
83
|
-
for (const className in data) {
|
|
84
|
-
if (Object.prototype.hasOwnProperty.call(data, className)) {
|
|
85
|
-
const classInfo = data[className];
|
|
86
|
-
const formattedClassName = className.replace('no-map/', '');
|
|
87
|
-
const filePath = findFilePath(formattedClassName, dxDirectory);
|
|
88
|
-
xml += `\t<file path="${filePath}">\n`;
|
|
89
|
-
for (const lineNumber in classInfo.s) {
|
|
90
|
-
if (Object.prototype.hasOwnProperty.call(classInfo.s, lineNumber)) {
|
|
91
|
-
const count = classInfo.s[lineNumber];
|
|
92
|
-
const covered = count > 0 ? 'true' : 'false';
|
|
93
|
-
// only add uncovered lines
|
|
94
|
-
if (covered === 'false') {
|
|
95
|
-
xml += `\t\t<lineToCover lineNumber="${lineNumber}" covered="${covered}"/>\n`;
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
xml += '\t</file>\n';
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
xml += '</coverage>';
|
|
103
|
-
return xml;
|
|
104
|
-
}
|
|
105
62
|
//# sourceMappingURL=transform.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transform.js","sourceRoot":"","sources":["../../../../src/commands/apex-code-coverage/transformer/transform.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AACb,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAElC,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;
|
|
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,24 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
import { findFilePath } from './findFilePath.js';
|
|
3
|
+
export function convertToGenericCoverageReport(data, dxDirectory) {
|
|
4
|
+
let xml = '<?xml version="1.0"?>\n<coverage version="1">\n';
|
|
5
|
+
for (const className in data) {
|
|
6
|
+
if (Object.hasOwn(data, className)) {
|
|
7
|
+
const classInfo = data[className];
|
|
8
|
+
const formattedClassName = className.replace('no-map/', '');
|
|
9
|
+
const filePath = findFilePath(formattedClassName, dxDirectory);
|
|
10
|
+
xml += `\t<file path="${filePath}">\n`;
|
|
11
|
+
for (const lineNumber in classInfo.s) {
|
|
12
|
+
if (Object.hasOwn(classInfo.s, lineNumber)) {
|
|
13
|
+
const count = classInfo.s[lineNumber];
|
|
14
|
+
const covered = count > 0 ? 'true' : 'false';
|
|
15
|
+
xml += `\t\t<lineToCover lineNumber="${lineNumber}" covered="${covered}"/>\n`;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
xml += '\t</file>\n';
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
xml += '</coverage>';
|
|
22
|
+
return xml;
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=convertToGenericCoverageReport.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"convertToGenericCoverageReport.js","sourceRoot":"","sources":["../../src/helpers/convertToGenericCoverageReport.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEjD,MAAM,UAAU,8BAA8B,CAAC,IAAkB,EAAE,WAAmB;IACpF,IAAI,GAAG,GAAG,iDAAiD,CAAC;IAE5D,KAAK,MAAM,SAAS,IAAI,IAAI,EAAE,CAAC;QAC7B,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,SAAS,CAAC,EAAE,CAAC;YACnC,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC;YAClC,MAAM,kBAAkB,GAAG,SAAS,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;YAC5D,MAAM,QAAQ,GAAG,YAAY,CAAC,kBAAkB,EAAE,WAAW,CAAC,CAAC;YAC/D,GAAG,IAAI,iBAAiB,QAAQ,MAAM,CAAC;YAEvC,KAAK,MAAM,UAAU,IAAI,SAAS,CAAC,CAAC,EAAE,CAAC;gBACrC,IAAI,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,EAAE,UAAU,CAAC,EAAE,CAAC;oBAC3C,MAAM,KAAK,GAAG,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;oBACtC,MAAM,OAAO,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC;oBAC7C,GAAG,IAAI,gCAAgC,UAAU,cAAc,OAAO,OAAO,CAAC;gBAChF,CAAC;YACH,CAAC;YACD,GAAG,IAAI,aAAa,CAAC;QACvB,CAAC;IACH,CAAC;IACD,GAAG,IAAI,aAAa,CAAC;IACrB,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function findFilePath(fileName: string, dxDirectory: string): string | null;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
import * as fs from 'node:fs';
|
|
3
|
+
import * as path from 'node:path';
|
|
4
|
+
export function findFilePath(fileName, dxDirectory) {
|
|
5
|
+
const fileExtension = fileName.split('.').slice(1).join('.');
|
|
6
|
+
let relativeClassPath = '';
|
|
7
|
+
let relativeTriggerPath = '';
|
|
8
|
+
let relativeFlowPath = '';
|
|
9
|
+
let absoluteClassPath = '';
|
|
10
|
+
let absoluteTriggerPath = '';
|
|
11
|
+
let absoluteFlowPath = '';
|
|
12
|
+
// if file extension is found, use that to determine paths
|
|
13
|
+
if (fileExtension === 'cls') {
|
|
14
|
+
relativeClassPath = `${dxDirectory}/classes/${fileName}`;
|
|
15
|
+
absoluteClassPath = path.resolve(relativeClassPath);
|
|
16
|
+
if (fs.existsSync(absoluteClassPath)) {
|
|
17
|
+
return relativeClassPath;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
else if (fileExtension === 'trigger') {
|
|
21
|
+
relativeTriggerPath = `${dxDirectory}/triggers/${fileName}`;
|
|
22
|
+
absoluteTriggerPath = path.resolve(relativeTriggerPath);
|
|
23
|
+
if (fs.existsSync(absoluteTriggerPath)) {
|
|
24
|
+
return relativeTriggerPath;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
else if (fileExtension === 'flow-meta.xml') {
|
|
28
|
+
relativeFlowPath = `${dxDirectory}/flows/${fileName}`;
|
|
29
|
+
absoluteFlowPath = path.resolve(relativeFlowPath);
|
|
30
|
+
if (fs.existsSync(absoluteFlowPath)) {
|
|
31
|
+
return relativeFlowPath;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
// if file extension is not found, add file extensions manually and test paths
|
|
35
|
+
relativeClassPath = `${dxDirectory}/classes/${fileName}.cls`;
|
|
36
|
+
relativeTriggerPath = `${dxDirectory}/triggers/${fileName}.trigger`;
|
|
37
|
+
relativeFlowPath = `${dxDirectory}/flows/${fileName}.flow-meta.xml`;
|
|
38
|
+
absoluteClassPath = path.resolve(relativeClassPath);
|
|
39
|
+
absoluteTriggerPath = path.resolve(relativeTriggerPath);
|
|
40
|
+
absoluteFlowPath = path.resolve(relativeFlowPath);
|
|
41
|
+
if (fs.existsSync(absoluteClassPath)) {
|
|
42
|
+
return relativeClassPath;
|
|
43
|
+
}
|
|
44
|
+
else if (fs.existsSync(absoluteTriggerPath)) {
|
|
45
|
+
return relativeTriggerPath;
|
|
46
|
+
}
|
|
47
|
+
else if (fs.existsSync(absoluteFlowPath)) {
|
|
48
|
+
return relativeFlowPath;
|
|
49
|
+
}
|
|
50
|
+
throw Error(`The file name ${fileName} was not found in the classes, triggers, or flows directory.`);
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=findFilePath.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"findFilePath.js","sourceRoot":"","sources":["../../src/helpers/findFilePath.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AACb,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAElC,MAAM,UAAU,YAAY,CAAC,QAAgB,EAAE,WAAmB;IAChE,MAAM,aAAa,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC7D,IAAI,iBAAiB,GAAG,EAAE,CAAC;IAC3B,IAAI,mBAAmB,GAAG,EAAE,CAAC;IAC7B,IAAI,gBAAgB,GAAG,EAAE,CAAC;IAC1B,IAAI,iBAAiB,GAAG,EAAE,CAAC;IAC3B,IAAI,mBAAmB,GAAG,EAAE,CAAC;IAC7B,IAAI,gBAAgB,GAAG,EAAE,CAAC;IAE1B,0DAA0D;IAC1D,IAAI,aAAa,KAAK,KAAK,EAAE,CAAC;QAC5B,iBAAiB,GAAG,GAAG,WAAW,YAAY,QAAQ,EAAE,CAAC;QACzD,iBAAiB,GAAG,IAAI,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;QACpD,IAAI,EAAE,CAAC,UAAU,CAAC,iBAAiB,CAAC,EAAE,CAAC;YACrC,OAAO,iBAAiB,CAAC;QAC3B,CAAC;IACH,CAAC;SAAM,IAAI,aAAa,KAAK,SAAS,EAAE,CAAC;QACvC,mBAAmB,GAAG,GAAG,WAAW,aAAa,QAAQ,EAAE,CAAC;QAC5D,mBAAmB,GAAG,IAAI,CAAC,OAAO,CAAC,mBAAmB,CAAC,CAAC;QACxD,IAAI,EAAE,CAAC,UAAU,CAAC,mBAAmB,CAAC,EAAE,CAAC;YACvC,OAAO,mBAAmB,CAAC;QAC7B,CAAC;IACH,CAAC;SAAM,IAAI,aAAa,KAAK,eAAe,EAAE,CAAC;QAC7C,gBAAgB,GAAG,GAAG,WAAW,UAAU,QAAQ,EAAE,CAAC;QACtD,gBAAgB,GAAG,IAAI,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC;QAClD,IAAI,EAAE,CAAC,UAAU,CAAC,gBAAgB,CAAC,EAAE,CAAC;YACpC,OAAO,gBAAgB,CAAC;QAC1B,CAAC;IACH,CAAC;IAED,8EAA8E;IAC9E,iBAAiB,GAAG,GAAG,WAAW,YAAY,QAAQ,MAAM,CAAC;IAC7D,mBAAmB,GAAG,GAAG,WAAW,aAAa,QAAQ,UAAU,CAAC;IACpE,gBAAgB,GAAG,GAAG,WAAW,UAAU,QAAQ,gBAAgB,CAAC;IACpE,iBAAiB,GAAG,IAAI,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;IACpD,mBAAmB,GAAG,IAAI,CAAC,OAAO,CAAC,mBAAmB,CAAC,CAAC;IACxD,gBAAgB,GAAG,IAAI,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAClD,IAAI,EAAE,CAAC,UAAU,CAAC,iBAAiB,CAAC,EAAE,CAAC;QACrC,OAAO,iBAAiB,CAAC;IAC3B,CAAC;SAAM,IAAI,EAAE,CAAC,UAAU,CAAC,mBAAmB,CAAC,EAAE,CAAC;QAC9C,OAAO,mBAAmB,CAAC;IAC7B,CAAC;SAAM,IAAI,EAAE,CAAC,UAAU,CAAC,gBAAgB,CAAC,EAAE,CAAC;QAC3C,OAAO,gBAAgB,CAAC;IAC1B,CAAC;IACD,MAAM,KAAK,CAAC,iBAAiB,QAAQ,8DAA8D,CAAC,CAAC;AACvG,CAAC"}
|
package/oclif.manifest.json
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "apex-code-coverage-transformer",
|
|
3
3
|
"description": "Transforms the Apex Code Coverage JSON into the Generic Test Data Report.",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.4.1-beta.1",
|
|
5
5
|
"dependencies": {
|
|
6
6
|
"@oclif/core": "^3.18.1",
|
|
7
7
|
"@salesforce/core": "^6.4.7",
|