Skip to content

Commit

Permalink
fix!: remove covered line adjustment in deploy coverage reports
Browse files Browse the repository at this point in the history
  • Loading branch information
mcarvin8 committed Dec 19, 2024
1 parent 89d562a commit e0a3b86
Show file tree
Hide file tree
Showing 10 changed files with 78 additions and 291 deletions.
2 changes: 0 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,6 @@ sf apex get test --test-run-id <test run id> --code-coverage --result-format jso

The code coverage JSONs created by the Salesforce CLI aren't accepted automatically for Salesforce DX repositories and needs to be converted using this plugin.

**Disclaimer**: Due to existing bugs with how the Salesforce CLI reports covered lines during deployments (see [5511](https://github.com/forcedotcom/salesforcedx-vscode/issues/5511) and [1568](https://github.com/forcedotcom/cli/issues/1568)), to add support for covered lines in this plugin for deployment coverage files, I had to add a function to re-number out-of-range covered lines the CLI may report (ex: line 100 in a 98-line Apex Class is reported back as covered by the Salesforce CLI deploy command). Salesforce's coverage result may also include extra lines as covered (ex: 120 lines are included in the coverage report for a 100 line file), so the coverage percentage may vary based on how many lines the API returns in the coverage report. Once Salesforce fixes the API to correctly return covered lines in the deploy command, this function will be removed.

## Command

The `apex-code-coverage-transformer` has 1 command:
Expand Down
8 changes: 0 additions & 8 deletions src/helpers/getTotalLines.ts

This file was deleted.

45 changes: 0 additions & 45 deletions src/helpers/setCoveredLinesCobertura.ts

This file was deleted.

40 changes: 0 additions & 40 deletions src/helpers/setCoveredLinesSonar.ts

This file was deleted.

48 changes: 20 additions & 28 deletions src/helpers/transformDeployCoverageReport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@ import {
} from './types.js';
import { getPackageDirectories } from './getPackageDirectories.js';
import { findFilePath } from './findFilePath.js';
import { setCoveredLinesSonar } from './setCoveredLinesSonar.js';
import { setCoveredLinesCobertura } from './setCoveredLinesCobertura.js';
import { normalizePathToUnix } from './normalizePathToUnix.js';
import { generateXml } from './generateXml.js';

Expand Down Expand Up @@ -87,20 +85,13 @@ export async function transformDeployCoverageReport(
.map(Number);

if (format === 'sonar') {
await handleSonarFormat(
relativeFilePath,
uncoveredLines,
coveredLines,
repoRoot,
coverageObj as SonarCoverageObject
);
handleSonarFormat(relativeFilePath, fileInfo.s, coverageObj as SonarCoverageObject);
} else {
await handleCoberturaFormat(
handleCoberturaFormat(
relativeFilePath,
formattedFileName,
uncoveredLines,
coveredLines,
repoRoot,
coverageObj as CoberturaCoverageObject,
packageObj!
);
Expand All @@ -113,34 +104,32 @@ export async function transformDeployCoverageReport(
return { xml, warnings, filesProcessed };
}

async function handleSonarFormat(
filePath: string,
uncoveredLines: number[],
coveredLines: number[],
repoRoot: string,
coverageObj: SonarCoverageObject
): Promise<void> {
function handleSonarFormat(filePath: string, lines: Record<string, number>, coverageObj: SonarCoverageObject): void {
const fileObj: SonarClass = {
'@path': normalizePathToUnix(filePath),
lineToCover: uncoveredLines.map((lineNumber) => ({
'@lineNumber': lineNumber,
'@covered': 'false',
})),
lineToCover: [],
};

await setCoveredLinesSonar(coveredLines, uncoveredLines, repoRoot, filePath, fileObj);
for (const lineNumberString in lines) {
if (!Object.hasOwn(lines, lineNumberString)) continue;
const covered = lines[lineNumberString] === 1 ? 'true' : 'false';
fileObj.lineToCover.push({
'@lineNumber': Number(lineNumberString),
'@covered': covered,
});
}

coverageObj.coverage.file.push(fileObj);
}

async function handleCoberturaFormat(
function handleCoberturaFormat(
filePath: string,
fileName: string,
uncoveredLines: number[],
coveredLines: number[],
repoRoot: string,
coverageObj: CoberturaCoverageObject,
packageObj: CoberturaPackage
): Promise<void> {
): void {
const classObj: CoberturaClass = {
'@name': fileName,
'@filename': normalizePathToUnix(filePath),
Expand All @@ -154,12 +143,15 @@ async function handleCoberturaFormat(
'@hits': 0,
'@branch': 'false',
})),
...coveredLines.map((lineNumber) => ({
'@number': lineNumber,
'@hits': 1,
'@branch': 'false',
})),
],
},
};

await setCoveredLinesCobertura(coveredLines, uncoveredLines, repoRoot, filePath, classObj);

coverageObj.coverage['@lines-valid'] += uncoveredLines.length + coveredLines.length;
coverageObj.coverage['@lines-covered'] += coveredLines.length;
packageObj.classes.class.push(classObj);
Expand Down
72 changes: 0 additions & 72 deletions test/baselines/classes/AccountProfile.cls

This file was deleted.

40 changes: 0 additions & 40 deletions test/baselines/triggers/AccountTrigger.trigger

This file was deleted.

17 changes: 9 additions & 8 deletions test/commands/acc-transformer/transform.nut.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use strict';

import { copyFile, writeFile, readFile, rm, mkdir } from 'node:fs/promises';
import { writeFile, readFile, rm, mkdir } from 'node:fs/promises';
import { strictEqual } from 'node:assert';
import { resolve } from 'node:path';

Expand All @@ -9,8 +9,10 @@ import { expect } from 'chai';

describe('acc-transformer transform NUTs', () => {
let session: TestSession;
const baselineClassPath = resolve('test/baselines/classes/AccountProfile.cls');
const baselineTriggerPath = resolve('test/baselines/triggers/AccountTrigger.trigger');
const mockClassContent = '// Test Apex Class';
const mockTriggerContent = '// Test Apex Trigger';
const baselineClassPath = resolve('force-app/main/default/classes/AccountProfile.cls');
const baselineTriggerPath = resolve('packaged/triggers/AccountTrigger.trigger');
const deployCoverageNoExts = resolve('test/deploy_coverage_no_file_exts.json');
const deployCoverageWithExts = resolve('test/deploy_coverage_with_file_exts.json');
const testCoverage = resolve('test/test_coverage.json');
Expand All @@ -29,7 +31,6 @@ describe('acc-transformer transform NUTs', () => {
packageDirectories: [{ path: 'force-app', default: true }, { path: 'packaged' }],
namespace: '',
sfdcLoginUrl: 'https://login.salesforce.com',
sourceApiVersion: '58.0',
};
const configJsonString = JSON.stringify(configFile, null, 2);

Expand All @@ -38,15 +39,15 @@ describe('acc-transformer transform NUTs', () => {
await writeFile(sfdxConfigFile, configJsonString);
await mkdir('force-app/main/default/classes', { recursive: true });
await mkdir('packaged/triggers', { recursive: true });
await copyFile(baselineClassPath, 'force-app/main/default/classes/AccountProfile.cls');
await copyFile(baselineTriggerPath, 'packaged/triggers/AccountTrigger.trigger');
await writeFile(baselineClassPath, mockClassContent);
await writeFile(baselineTriggerPath, mockTriggerContent);
});

after(async () => {
await session?.clean();
await rm(sfdxConfigFile);
await rm('force-app/main/default/classes/AccountProfile.cls');
await rm('packaged/triggers/AccountTrigger.trigger');
await rm(baselineClassPath);
await rm(baselineTriggerPath);
await rm('force-app', { recursive: true });
await rm('packaged', { recursive: true });
await rm(sonarXmlPath1);
Expand Down
Loading

0 comments on commit e0a3b86

Please sign in to comment.