apex-code-coverage-transformer 1.6.2 → 1.6.4
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 +3 -37
- package/lib/commands/apex-code-coverage/transformer/transform.js +8 -16
- package/lib/commands/apex-code-coverage/transformer/transform.js.map +1 -1
- package/lib/helpers/convertToGenericCoverageReport.js +3 -19
- package/lib/helpers/convertToGenericCoverageReport.js.map +1 -1
- package/lib/helpers/findFilePath.js +6 -6
- package/lib/helpers/findFilePath.js.map +1 -1
- package/lib/helpers/getPackageDirectories.js +4 -4
- package/lib/helpers/getPackageDirectories.js.map +1 -1
- package/lib/helpers/getTotalLines.d.ts +1 -1
- package/lib/helpers/getTotalLines.js +3 -3
- package/lib/helpers/getTotalLines.js.map +1 -1
- package/lib/helpers/setCoveredLines.d.ts +1 -0
- package/lib/helpers/setCoveredLines.js +25 -0
- package/lib/helpers/setCoveredLines.js.map +1 -0
- package/lib/helpers/types.d.ts +5 -0
- package/oclif.manifest.json +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
The `apex-code-coverage-transformer` is a simple Salesforce CLI plugin to transform the Apex Code Coverage JSON file into Generic Test Coverage Format (XML). This format is accepted by static code analysis tools like SonarQube.
|
|
6
6
|
|
|
7
|
-
This plugin supports code coverage metrics created for Apex Classes
|
|
7
|
+
This plugin supports code coverage metrics created for Apex Classes and Apex Triggers. This also supports multiple package directories as listed in your project's `sfdx-project.json` configuration, assuming unique file-names are used in your package directories.
|
|
8
8
|
|
|
9
9
|
To create the code coverage JSON during a Salesforce CLI deployment/validation, append `--coverage-formatters json --results-dir coverage` to the `sf project deploy` command:
|
|
10
10
|
|
|
@@ -68,7 +68,6 @@ If none of the files listed in the coverage JSON were found in a package directo
|
|
|
68
68
|
```
|
|
69
69
|
Warning: The file name AccountTrigger was not found in any package directory.
|
|
70
70
|
Warning: The file name AccountProfile was not found in any package directory.
|
|
71
|
-
Warning: The file name Get_Info was not found in any package directory.
|
|
72
71
|
Error (1): None of the files listed in the coverage JSON were processed.
|
|
73
72
|
```
|
|
74
73
|
|
|
@@ -86,12 +85,12 @@ Error (1): ENOENT: no such file or directory: {packageDirPath}
|
|
|
86
85
|
|
|
87
86
|
## Example
|
|
88
87
|
|
|
89
|
-
This [code coverage JSON file](https://raw.githubusercontent.com/mcarvin8/apex-code-coverage-transformer/main/coverage_no_file_exts.json) created by the Salesforce CLI will be transformed into:
|
|
88
|
+
This [code coverage JSON file](https://raw.githubusercontent.com/mcarvin8/apex-code-coverage-transformer/main/test/coverage_no_file_exts.json) created by the Salesforce CLI will be transformed into:
|
|
90
89
|
|
|
91
90
|
```xml
|
|
92
91
|
<?xml version="1.0"?>
|
|
93
92
|
<coverage version="1">
|
|
94
|
-
<file path="
|
|
93
|
+
<file path="packaged\triggers\AccountTrigger.trigger">
|
|
95
94
|
<lineToCover lineNumber="52" covered="false"/>
|
|
96
95
|
<lineToCover lineNumber="53" covered="false"/>
|
|
97
96
|
<lineToCover lineNumber="59" covered="false"/>
|
|
@@ -157,38 +156,5 @@ This [code coverage JSON file](https://raw.githubusercontent.com/mcarvin8/apex-c
|
|
|
157
156
|
<lineToCover lineNumber="9" covered="true"/>
|
|
158
157
|
<lineToCover lineNumber="10" covered="true"/>
|
|
159
158
|
</file>
|
|
160
|
-
<file path="packaged\flows\Get_Info.flow-meta.xml">
|
|
161
|
-
<lineToCover lineNumber="52" covered="false"/>
|
|
162
|
-
<lineToCover lineNumber="53" covered="false"/>
|
|
163
|
-
<lineToCover lineNumber="59" covered="false"/>
|
|
164
|
-
<lineToCover lineNumber="60" covered="false"/>
|
|
165
|
-
<lineToCover lineNumber="54" covered="true"/>
|
|
166
|
-
<lineToCover lineNumber="55" covered="true"/>
|
|
167
|
-
<lineToCover lineNumber="56" covered="true"/>
|
|
168
|
-
<lineToCover lineNumber="57" covered="true"/>
|
|
169
|
-
<lineToCover lineNumber="58" covered="true"/>
|
|
170
|
-
<lineToCover lineNumber="61" covered="true"/>
|
|
171
|
-
<lineToCover lineNumber="62" covered="true"/>
|
|
172
|
-
<lineToCover lineNumber="63" covered="true"/>
|
|
173
|
-
<lineToCover lineNumber="64" covered="true"/>
|
|
174
|
-
<lineToCover lineNumber="65" covered="true"/>
|
|
175
|
-
<lineToCover lineNumber="66" covered="true"/>
|
|
176
|
-
<lineToCover lineNumber="67" covered="true"/>
|
|
177
|
-
<lineToCover lineNumber="68" covered="true"/>
|
|
178
|
-
<lineToCover lineNumber="69" covered="true"/>
|
|
179
|
-
<lineToCover lineNumber="70" covered="true"/>
|
|
180
|
-
<lineToCover lineNumber="71" covered="true"/>
|
|
181
|
-
<lineToCover lineNumber="72" covered="true"/>
|
|
182
|
-
<lineToCover lineNumber="73" covered="true"/>
|
|
183
|
-
<lineToCover lineNumber="74" covered="true"/>
|
|
184
|
-
<lineToCover lineNumber="75" covered="true"/>
|
|
185
|
-
<lineToCover lineNumber="76" covered="true"/>
|
|
186
|
-
<lineToCover lineNumber="77" covered="true"/>
|
|
187
|
-
<lineToCover lineNumber="78" covered="true"/>
|
|
188
|
-
<lineToCover lineNumber="79" covered="true"/>
|
|
189
|
-
<lineToCover lineNumber="80" covered="true"/>
|
|
190
|
-
<lineToCover lineNumber="81" covered="true"/>
|
|
191
|
-
<lineToCover lineNumber="82" covered="true"/>
|
|
192
|
-
</file>
|
|
193
159
|
</coverage>
|
|
194
160
|
```
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
|
-
import
|
|
3
|
-
import
|
|
2
|
+
import { resolve } from 'node:path';
|
|
3
|
+
import { writeFile, readFile } from 'node:fs/promises';
|
|
4
4
|
import { SfCommand, Flags } from '@salesforce/sf-plugins-core';
|
|
5
5
|
import { Messages } from '@salesforce/core';
|
|
6
6
|
import { convertToGenericCoverageReport } from '../../../helpers/convertToGenericCoverageReport.js';
|
|
@@ -37,10 +37,10 @@ export default class TransformerTransform extends SfCommand {
|
|
|
37
37
|
let jsonFilePath = flags['coverage-json'];
|
|
38
38
|
let xmlFilePath = flags['xml'];
|
|
39
39
|
let sfdxConfigFile = flags['sfdx-configuration'];
|
|
40
|
-
jsonFilePath =
|
|
41
|
-
xmlFilePath =
|
|
42
|
-
sfdxConfigFile =
|
|
43
|
-
const jsonData =
|
|
40
|
+
jsonFilePath = resolve(jsonFilePath);
|
|
41
|
+
xmlFilePath = resolve(xmlFilePath);
|
|
42
|
+
sfdxConfigFile = resolve(sfdxConfigFile);
|
|
43
|
+
const jsonData = await readFile(jsonFilePath, 'utf-8');
|
|
44
44
|
const coverageData = JSON.parse(jsonData);
|
|
45
45
|
const { xml: xmlData, warnings, filesProcessed, } = await convertToGenericCoverageReport(coverageData, sfdxConfigFile);
|
|
46
46
|
// Print warnings if any
|
|
@@ -52,16 +52,8 @@ export default class TransformerTransform extends SfCommand {
|
|
|
52
52
|
if (filesProcessed === 0) {
|
|
53
53
|
this.error('None of the files listed in the coverage JSON were processed.');
|
|
54
54
|
}
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
fs.writeFileSync(xmlFilePath, xmlData);
|
|
58
|
-
this.log(`The XML data has been written to ${xmlFilePath}`);
|
|
59
|
-
}
|
|
60
|
-
catch (error) {
|
|
61
|
-
if (error instanceof Error) {
|
|
62
|
-
this.error(`Error writing XML data to file: ${error.message}`);
|
|
63
|
-
}
|
|
64
|
-
}
|
|
55
|
+
await writeFile(xmlFilePath, xmlData);
|
|
56
|
+
this.log(`The XML data has been written to ${xmlFilePath}`);
|
|
65
57
|
return { path: xmlFilePath };
|
|
66
58
|
}
|
|
67
59
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transform.js","sourceRoot":"","sources":["../../../../src/commands/apex-code-coverage/transformer/transform.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,
|
|
1
|
+
{"version":3,"file":"transform.js","sourceRoot":"","sources":["../../../../src/commands/apex-code-coverage/transformer/transform.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
|
-
import { getTotalLines } from './getTotalLines.js';
|
|
3
2
|
import { findFilePath } from './findFilePath.js';
|
|
3
|
+
import { setCoveredLines } from './setCoveredLines.js';
|
|
4
4
|
export async function convertToGenericCoverageReport(data, dxConfigFile) {
|
|
5
5
|
let xml = '<?xml version="1.0"?>\n<coverage version="1">\n';
|
|
6
6
|
const warnings = [];
|
|
@@ -22,28 +22,12 @@ export async function convertToGenericCoverageReport(data, dxConfigFile) {
|
|
|
22
22
|
const coveredLines = Object.keys(fileInfo.s)
|
|
23
23
|
.filter((lineNumber) => fileInfo.s[lineNumber] === 1)
|
|
24
24
|
.map(Number);
|
|
25
|
-
const randomLines = [];
|
|
26
|
-
const totalLines = getTotalLines(filePath);
|
|
27
25
|
xml += `\t<file path="${filePath}">\n`;
|
|
28
26
|
for (const uncoveredLine of uncoveredLines) {
|
|
29
27
|
xml += `\t\t<lineToCover lineNumber="${uncoveredLine}" covered="false"/>\n`;
|
|
30
28
|
}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
for (let randomLineNumber = 1; randomLineNumber <= totalLines; randomLineNumber++) {
|
|
34
|
-
if (!uncoveredLines.includes(randomLineNumber) &&
|
|
35
|
-
!coveredLines.includes(randomLineNumber) &&
|
|
36
|
-
!randomLines.includes(randomLineNumber)) {
|
|
37
|
-
xml += `\t\t<lineToCover lineNumber="${randomLineNumber}" covered="true"/>\n`;
|
|
38
|
-
randomLines.push(randomLineNumber);
|
|
39
|
-
break;
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
else {
|
|
44
|
-
xml += `\t\t<lineToCover lineNumber="${coveredLine}" covered="true"/>\n`;
|
|
45
|
-
}
|
|
46
|
-
}
|
|
29
|
+
// this function is only needed until Salesforce fixes the API to correctly return covered lines
|
|
30
|
+
xml += await setCoveredLines(coveredLines, uncoveredLines, filePath);
|
|
47
31
|
filesProcessed++;
|
|
48
32
|
xml += '\t</file>\n';
|
|
49
33
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"convertToGenericCoverageReport.js","sourceRoot":"","sources":["../../src/helpers/convertToGenericCoverageReport.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAIb,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"convertToGenericCoverageReport.js","sourceRoot":"","sources":["../../src/helpers/convertToGenericCoverageReport.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAIb,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAEvD,MAAM,CAAC,KAAK,UAAU,8BAA8B,CAClD,IAAkB,EAClB,YAAoB;IAEpB,IAAI,GAAG,GAAG,iDAAiD,CAAC;IAC5D,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,IAAI,cAAc,GAAW,CAAC,CAAC;IAE/B,KAAK,MAAM,QAAQ,IAAI,IAAI,EAAE,CAAC;QAC5B,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,QAAQ,CAAC;YAAE,SAAS;QAC7C,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC;QAChC,MAAM,iBAAiB,GAAG,QAAQ,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;QAC1D,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC,iBAAiB,EAAE,YAAY,CAAC,CAAC;QACrE,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;YAC3B,QAAQ,CAAC,IAAI,CAAC,iBAAiB,iBAAiB,0CAA0C,CAAC,CAAC;YAC5F,SAAS;QACX,CAAC;QACD,mDAAmD;QACnD,MAAM,cAAc,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;aAC3C,MAAM,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;aACpD,GAAG,CAAC,MAAM,CAAC,CAAC;QACf,MAAM,YAAY,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;aACzC,MAAM,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;aACpD,GAAG,CAAC,MAAM,CAAC,CAAC;QAEf,GAAG,IAAI,iBAAiB,QAAQ,MAAM,CAAC;QAEvC,KAAK,MAAM,aAAa,IAAI,cAAc,EAAE,CAAC;YAC3C,GAAG,IAAI,gCAAgC,aAAa,uBAAuB,CAAC;QAC9E,CAAC;QAED,gGAAgG;QAChG,GAAG,IAAI,MAAM,eAAe,CAAC,YAAY,EAAE,cAAc,EAAE,QAAQ,CAAC,CAAC;QACrE,cAAc,EAAE,CAAC;QACjB,GAAG,IAAI,aAAa,CAAC;IACvB,CAAC;IACD,GAAG,IAAI,aAAa,CAAC;IACrB,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,cAAc,EAAE,CAAC;AAC3C,CAAC"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
/* eslint-disable no-await-in-loop */
|
|
3
|
-
import
|
|
4
|
-
import
|
|
3
|
+
import { readdir, stat } from 'node:fs/promises';
|
|
4
|
+
import { join } from 'node:path';
|
|
5
5
|
import { getPackageDirectories } from './getPackageDirectories.js';
|
|
6
6
|
export async function findFilePath(fileName, dxConfigFile) {
|
|
7
7
|
const packageDirectories = await getPackageDirectories(dxConfigFile);
|
|
@@ -15,10 +15,10 @@ export async function findFilePath(fileName, dxConfigFile) {
|
|
|
15
15
|
return filePath;
|
|
16
16
|
}
|
|
17
17
|
async function searchRecursively(fileName, dxDirectory) {
|
|
18
|
-
const files = await
|
|
18
|
+
const files = await readdir(dxDirectory);
|
|
19
19
|
for (const file of files) {
|
|
20
|
-
const filePath =
|
|
21
|
-
const stats = await
|
|
20
|
+
const filePath = join(dxDirectory, file);
|
|
21
|
+
const stats = await stat(filePath);
|
|
22
22
|
if (stats.isDirectory()) {
|
|
23
23
|
const result = await searchRecursively(fileName, filePath);
|
|
24
24
|
if (result) {
|
|
@@ -40,7 +40,7 @@ async function findFilePathinDirectory(fileName, dxDirectory) {
|
|
|
40
40
|
}
|
|
41
41
|
else {
|
|
42
42
|
// If file extension is not defined, test each extension option
|
|
43
|
-
const fileExts = ['cls', 'trigger'
|
|
43
|
+
const fileExts = ['cls', 'trigger'];
|
|
44
44
|
for (const ext of fileExts) {
|
|
45
45
|
relativeFilePath = await searchRecursively(`${fileName}.${ext}`, dxDirectory);
|
|
46
46
|
if (relativeFilePath !== undefined) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"findFilePath.js","sourceRoot":"","sources":["../../src/helpers/findFilePath.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AACb,qCAAqC;AAErC,OAAO,
|
|
1
|
+
{"version":3,"file":"findFilePath.js","sourceRoot":"","sources":["../../src/helpers/findFilePath.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AACb,qCAAqC;AAErC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AAEnE,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,QAAgB,EAAE,YAAoB;IACvE,MAAM,kBAAkB,GAAG,MAAM,qBAAqB,CAAC,YAAY,CAAC,CAAC;IAErE,IAAI,QAA4B,CAAC;IACjC,KAAK,MAAM,SAAS,IAAI,kBAAkB,EAAE,CAAC;QAC3C,QAAQ,GAAG,MAAM,uBAAuB,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;QAC9D,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;YAC3B,MAAM;QACR,CAAC;IACH,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,KAAK,UAAU,iBAAiB,CAAC,QAAgB,EAAE,WAAmB;IACpE,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,WAAW,CAAC,CAAC;IACzC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;QACzC,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,CAAC;QACnC,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;YACxB,MAAM,MAAM,GAAG,MAAM,iBAAiB,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;YAC3D,IAAI,MAAM,EAAE,CAAC;gBACX,OAAO,MAAM,CAAC;YAChB,CAAC;QACH,CAAC;aAAM,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC7B,OAAO,QAAQ,CAAC;QAClB,CAAC;IACH,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,KAAK,UAAU,uBAAuB,CAAC,QAAgB,EAAE,WAAmB;IAC1E,MAAM,aAAa,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC7D,IAAI,gBAAoC,CAAC;IAEzC,IAAI,aAAa,EAAE,CAAC;QAClB,uEAAuE;QACvE,gBAAgB,GAAG,MAAM,iBAAiB,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;IACpE,CAAC;SAAM,CAAC;QACN,+DAA+D;QAC/D,MAAM,QAAQ,GAAa,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;QAC9C,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;YAC3B,gBAAgB,GAAG,MAAM,iBAAiB,CAAC,GAAG,QAAQ,IAAI,GAAG,EAAE,EAAE,WAAW,CAAC,CAAC;YAC9E,IAAI,gBAAgB,KAAK,SAAS,EAAE,CAAC;gBACnC,MAAM;YACR,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,gBAAgB,CAAC;AAC1B,CAAC"}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
/* eslint-disable no-await-in-loop */
|
|
3
|
-
import
|
|
4
|
-
import
|
|
3
|
+
import { existsSync } from 'node:fs';
|
|
4
|
+
import { readFile } from 'node:fs/promises';
|
|
5
5
|
export async function getPackageDirectories(dxConfigFile) {
|
|
6
|
-
if (!
|
|
6
|
+
if (!existsSync(dxConfigFile)) {
|
|
7
7
|
throw Error(`Salesforce DX Config File does not exist in this path: ${dxConfigFile}`);
|
|
8
8
|
}
|
|
9
|
-
const sfdxProjectRaw = await
|
|
9
|
+
const sfdxProjectRaw = await readFile(dxConfigFile, 'utf-8');
|
|
10
10
|
const sfdxProject = JSON.parse(sfdxProjectRaw);
|
|
11
11
|
const packageDirectories = sfdxProject.packageDirectories.map((directory) => directory.path);
|
|
12
12
|
return packageDirectories;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getPackageDirectories.js","sourceRoot":"","sources":["../../src/helpers/getPackageDirectories.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AACb,qCAAqC;AAErC,OAAO,
|
|
1
|
+
{"version":3,"file":"getPackageDirectories.js","sourceRoot":"","sources":["../../src/helpers/getPackageDirectories.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AACb,qCAAqC;AAErC,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAG5C,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,YAAoB;IAC9D,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QAC9B,MAAM,KAAK,CAAC,0DAA0D,YAAY,EAAE,CAAC,CAAC;IACxF,CAAC;IAED,MAAM,cAAc,GAAW,MAAM,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;IACrE,MAAM,WAAW,GAAgB,IAAI,CAAC,KAAK,CAAC,cAAc,CAAgB,CAAC;IAC3E,MAAM,kBAAkB,GAAG,WAAW,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IAC7F,OAAO,kBAAkB,CAAC;AAC5B,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare function getTotalLines(filePath: string): number
|
|
1
|
+
export declare function getTotalLines(filePath: string): Promise<number>;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
|
-
import
|
|
3
|
-
export function getTotalLines(filePath) {
|
|
4
|
-
const fileContent =
|
|
2
|
+
import { readFile } from 'node:fs/promises';
|
|
3
|
+
export async function getTotalLines(filePath) {
|
|
4
|
+
const fileContent = await readFile(filePath, 'utf8');
|
|
5
5
|
return fileContent.split(/\r\n|\r|\n/).length;
|
|
6
6
|
}
|
|
7
7
|
//# sourceMappingURL=getTotalLines.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getTotalLines.js","sourceRoot":"","sources":["../../src/helpers/getTotalLines.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"getTotalLines.js","sourceRoot":"","sources":["../../src/helpers/getTotalLines.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,QAAgB;IAClD,MAAM,WAAW,GAAG,MAAM,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IACrD,OAAO,WAAW,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC;AAChD,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function setCoveredLines(coveredLines: number[], uncoveredLines: number[], filePath: string): Promise<string>;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
import { getTotalLines } from './getTotalLines.js';
|
|
3
|
+
export async function setCoveredLines(coveredLines, uncoveredLines, filePath) {
|
|
4
|
+
let formattedCoveredLines = '';
|
|
5
|
+
const randomLines = [];
|
|
6
|
+
const totalLines = await getTotalLines(filePath);
|
|
7
|
+
for (const coveredLine of coveredLines) {
|
|
8
|
+
if (coveredLine > totalLines) {
|
|
9
|
+
for (let randomLineNumber = 1; randomLineNumber <= totalLines; randomLineNumber++) {
|
|
10
|
+
if (!uncoveredLines.includes(randomLineNumber) &&
|
|
11
|
+
!coveredLines.includes(randomLineNumber) &&
|
|
12
|
+
!randomLines.includes(randomLineNumber)) {
|
|
13
|
+
formattedCoveredLines += `\t\t<lineToCover lineNumber="${randomLineNumber}" covered="true"/>\n`;
|
|
14
|
+
randomLines.push(randomLineNumber);
|
|
15
|
+
break;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
formattedCoveredLines += `\t\t<lineToCover lineNumber="${coveredLine}" covered="true"/>\n`;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return formattedCoveredLines;
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=setCoveredLines.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setCoveredLines.js","sourceRoot":"","sources":["../../src/helpers/setCoveredLines.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEnD,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,YAAsB,EACtB,cAAwB,EACxB,QAAgB;IAEhB,IAAI,qBAAqB,GAAW,EAAE,CAAC;IACvC,MAAM,WAAW,GAAa,EAAE,CAAC;IACjC,MAAM,UAAU,GAAG,MAAM,aAAa,CAAC,QAAQ,CAAC,CAAC;IACjD,KAAK,MAAM,WAAW,IAAI,YAAY,EAAE,CAAC;QACvC,IAAI,WAAW,GAAG,UAAU,EAAE,CAAC;YAC7B,KAAK,IAAI,gBAAgB,GAAG,CAAC,EAAE,gBAAgB,IAAI,UAAU,EAAE,gBAAgB,EAAE,EAAE,CAAC;gBAClF,IACE,CAAC,cAAc,CAAC,QAAQ,CAAC,gBAAgB,CAAC;oBAC1C,CAAC,YAAY,CAAC,QAAQ,CAAC,gBAAgB,CAAC;oBACxC,CAAC,WAAW,CAAC,QAAQ,CAAC,gBAAgB,CAAC,EACvC,CAAC;oBACD,qBAAqB,IAAI,gCAAgC,gBAAgB,sBAAsB,CAAC;oBAChG,WAAW,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;oBACnC,MAAM;gBACR,CAAC;YACH,CAAC;QACH,CAAC;aAAM,CAAC;YACN,qBAAqB,IAAI,gCAAgC,WAAW,sBAAsB,CAAC;QAC7F,CAAC;IACH,CAAC;IACD,OAAO,qBAAqB,CAAC;AAC/B,CAAC"}
|
package/lib/helpers/types.d.ts
CHANGED
package/oclif.manifest.json
CHANGED
package/package.json
CHANGED