diff --git a/test/coverageUtils.test.ts b/test/coverageUtils.test.ts index 4ae501e79..0d72ab209 100644 --- a/test/coverageUtils.test.ts +++ b/test/coverageUtils.test.ts @@ -8,182 +8,296 @@ import { expect } from 'chai'; import { MockTestOrgData, TestContext } from '@salesforce/core/lib/testSetup'; import { AuthInfo, Connection } from '@salesforce/core'; import { createSandbox, SinonSandbox } from 'sinon'; -import { transformCoverageToApexCoverage } from '../src/coverageUtils'; +import * as chalk from 'chalk'; +import { transformCoverageToApexCoverage, prepCoverageForDisplay } from '../src/coverageUtils'; import { transformDeployTestsResultsToTestResult } from '../src/coverageUtils'; -const sampleRunTestResult = { - codeCoverage: [ - { - id: '01p19000002uDLAAA2', - locationsNotCovered: { - column: '0', - line: '12', - numExecutions: '0', - time: '-1.0', - }, - name: 'PagedResult', - namespace: { - $: { - 'xsi:nil': 'true', +// methods are mutating the object instead of returning new ones +function getSampleTestResult() { + return { + codeCoverage: [ + { + id: '01p19000002uDLAAA2', + locationsNotCovered: { + column: '0', + line: '12', + numExecutions: '0', + time: '-1.0', }, + name: 'PagedResult', + namespace: { + $: { + 'xsi:nil': 'true', + }, + }, + numLocations: '4', + numLocationsNotCovered: '1', + type: 'Class', }, - numLocations: '4', - numLocationsNotCovered: '1', - type: 'Class', - }, - { - id: '01p19000002uDLBAA2', - locationsNotCovered: [ - { + { + id: '01p19000002uDLBAA2', + locationsNotCovered: [ + { + column: '0', + line: '26', + numExecutions: '0', + time: '-1.0', + }, + { + column: '0', + line: '31', + numExecutions: '0', + time: '-1.0', + }, + { + column: '0', + line: '78', + numExecutions: '0', + time: '-1.0', + }, + ], + name: 'PropertyController', + namespace: { + $: { + 'xsi:nil': 'true', + }, + }, + numLocations: '44', + numLocationsNotCovered: '3', + type: 'Class', + }, + { + id: '01p19000002uDLCAA2', + name: 'SampleDataController', + namespace: { + $: { + 'xsi:nil': 'true', + }, + }, + numLocations: '34', + numLocationsNotCovered: '0', + type: 'Class', + }, + { + id: '01p19000002uDL8AAM', + name: 'GeocodingService', + namespace: { + $: { + 'xsi:nil': 'true', + }, + }, + numLocations: '36', + numLocationsNotCovered: '0', + type: 'Class', + }, + { + id: '01p19000002uDLAAAN', + locationsNotCovered: { column: '0', - line: '26', + line: '12', numExecutions: '0', time: '-1.0', }, - { + name: 'A', + namespace: { + $: { + 'xsi:nil': 'true', + }, + }, + numLocations: '100', + numLocationsNotCovered: '100', + type: 'Class', + }, + { + id: '01p19000002uDLAAAN', + locationsNotCovered: { column: '0', - line: '31', + line: '12', numExecutions: '0', time: '-1.0', }, - { + name: 'B', + namespace: { + $: { + 'xsi:nil': 'true', + }, + }, + numLocations: '100', + numLocationsNotCovered: '26', + type: 'Class', + }, + { + id: '01p19000002uDLAABN', + locationsNotCovered: { column: '0', - line: '78', + line: '12', numExecutions: '0', time: '-1.0', }, - ], - name: 'PropertyController', - namespace: { - $: { - 'xsi:nil': 'true', + name: 'C', + namespace: { + $: { + 'xsi:nil': 'true', + }, }, + numLocations: '100', + numLocationsNotCovered: '25', + type: 'Class', }, - numLocations: '44', - numLocationsNotCovered: '3', - type: 'Class', - }, - { - id: '01p19000002uDLCAA2', - name: 'SampleDataController', - namespace: { - $: { - 'xsi:nil': 'true', + { + id: '01p19000002uDLAABN', + locationsNotCovered: { + column: '0', + line: '12', + numExecutions: '0', + time: '-1.0', + }, + name: 'D', + namespace: { + $: { + 'xsi:nil': 'true', + }, }, + numLocations: '100', + numLocationsNotCovered: '11', + type: 'Class', }, - numLocations: '34', - numLocationsNotCovered: '0', - type: 'Class', - }, - { - id: '01p19000002uDL8AAM', - name: 'GeocodingService', - namespace: { - $: { - 'xsi:nil': 'true', + { + id: '01p19000002uDLAABN', + locationsNotCovered: { + column: '0', + line: '12', + numExecutions: '0', + time: '-1.0', }, + name: 'E', + namespace: { + $: { + 'xsi:nil': 'true', + }, + }, + numLocations: '100', + numLocationsNotCovered: '10', + type: 'Class', }, - numLocations: '36', - numLocationsNotCovered: '0', - type: 'Class', - }, - ], - failures: { - id: '01p19000002uDLDAA2', - message: 'System.QueryException: Insufficient permissions: secure query included inaccessible field', - methodName: 'testGetPagedPropertyList', - name: 'TestPropertyController', - namespace: { - $: { - 'xsi:nil': 'true', + { + id: '01p19000002uDLAACN', + locationsNotCovered: { + column: '0', + line: '12', + numExecutions: '0', + time: '-1.0', + }, + name: 'F', + namespace: { + $: { + 'xsi:nil': 'true', + }, + }, + numLocations: '100', + numLocationsNotCovered: '0', + type: 'Class', }, - }, - packageName: 'TestPropertyController', - stackTrace: - 'Class.PropertyController.getPagedPropertyList: line 52, column 1\nClass.TestPropertyController.testGetPagedPropertyList: line 22, column 1', - time: '604.0', - type: 'Class', - }, - numFailures: '1', - numTestsRun: '7', - successes: [ - { - id: '01p19000002uDL9AAM', - methodName: 'blankAddress', - name: 'GeocodingServiceTest', + ], + failures: { + id: '01p19000002uDLDAA2', + message: 'System.QueryException: Insufficient permissions: secure query included inaccessible field', + methodName: 'testGetPagedPropertyList', + name: 'TestPropertyController', namespace: { $: { 'xsi:nil': 'true', }, }, - time: '26.0', + packageName: 'TestPropertyController', + stackTrace: + 'Class.PropertyController.getPagedPropertyList: line 52, column 1\nClass.TestPropertyController.testGetPagedPropertyList: line 22, column 1', + time: '604.0', + type: 'Class', }, - { - id: '01p19000002uDL9AAM', - methodName: 'errorResponse', - name: 'GeocodingServiceTest', - namespace: { - $: { - 'xsi:nil': 'true', + numFailures: '1', + numTestsRun: '7', + successes: [ + { + id: '01p19000002uDL9AAM', + methodName: 'blankAddress', + name: 'GeocodingServiceTest', + namespace: { + $: { + 'xsi:nil': 'true', + }, }, + time: '26.0', }, - time: '77.0', - }, - { - id: '01p19000002uDL9AAM', - methodName: 'successResponse', - name: 'GeocodingServiceTest', - namespace: { - $: { - 'xsi:nil': 'true', + { + id: '01p19000002uDL9AAM', + methodName: 'errorResponse', + name: 'GeocodingServiceTest', + namespace: { + $: { + 'xsi:nil': 'true', + }, }, + time: '77.0', }, - time: '63.0', - }, - { - id: '01p19000002uDLDAA2', - methodName: 'testGetPicturesNoResults', - name: 'TestPropertyController', - namespace: { - $: { - 'xsi:nil': 'true', + { + id: '01p19000002uDL9AAM', + methodName: 'successResponse', + name: 'GeocodingServiceTest', + namespace: { + $: { + 'xsi:nil': 'true', + }, }, + time: '63.0', }, - time: '691.0', - }, - { - id: '01p19000002uDLDAA2', - methodName: 'testGetPicturesWithResults', - name: 'TestPropertyController', - namespace: { - $: { - 'xsi:nil': 'true', + { + id: '01p19000002uDLDAA2', + methodName: 'testGetPicturesNoResults', + name: 'TestPropertyController', + namespace: { + $: { + 'xsi:nil': 'true', + }, }, + time: '691.0', }, - time: '1873.0', - }, - { - id: '01p19000002uDLEAA2', - methodName: 'importSampleData', - name: 'TestSampleDataController', - namespace: { - $: { - 'xsi:nil': 'true', + { + id: '01p19000002uDLDAA2', + methodName: 'testGetPicturesWithResults', + name: 'TestPropertyController', + namespace: { + $: { + 'xsi:nil': 'true', + }, }, + time: '1873.0', }, - time: '1535.0', - }, - ], - totalTime: '4952.0', -}; + { + id: '01p19000002uDLEAA2', + methodName: 'importSampleData', + name: 'TestSampleDataController', + namespace: { + $: { + 'xsi:nil': 'true', + }, + }, + time: '1535.0', + }, + ], + totalTime: '4952.0', + }; +} describe('transform md RunTestResult', () => { const $$ = new TestContext(); let mockConnection: Connection; const testData = new MockTestOrgData(); + let sampleTestResult = getSampleTestResult(); let sandboxStub: SinonSandbox; beforeEach(async () => { + sampleTestResult = getSampleTestResult(); sandboxStub = createSandbox(); $$.setConfigStubContents('StateAggregator', { @@ -206,9 +320,10 @@ describe('transform md RunTestResult', () => { afterEach(() => { sandboxStub.restore(); }); + it('should transform md coverage to apex coverage format', () => { - const apexCoverage = transformCoverageToApexCoverage(sampleRunTestResult.codeCoverage); - expect(apexCoverage.records).to.have.length(4); + const apexCoverage = transformCoverageToApexCoverage(sampleTestResult.codeCoverage); + expect(apexCoverage.records).to.have.length(10); expect(apexCoverage.records[0].ApexClassOrTrigger.Name).to.equal('PagedResult'); expect(apexCoverage.records[1].ApexClassOrTrigger.Name).to.equal('PropertyController'); expect(apexCoverage.records[2].ApexClassOrTrigger.Name).to.equal('SampleDataController'); @@ -219,8 +334,42 @@ describe('transform md RunTestResult', () => { expect(apexCoverage.records[2].Coverage.uncoveredLines).to.have.lengthOf(apexCoverage.records[2].NumLinesUncovered); expect(apexCoverage.records[2].Coverage.coveredLines).to.have.lengthOf(apexCoverage.records[2].NumLinesCovered); }); + it('should transform md test results to apex test results format', () => { - const apexTestResults = transformDeployTestsResultsToTestResult(mockConnection, sampleRunTestResult); + const apexTestResults = transformDeployTestsResultsToTestResult(mockConnection, sampleTestResult); expect(apexTestResults).to.be.ok; }); + + it('should display code coverage classes ordered alphabetically', () => { + const codeCoverage = prepCoverageForDisplay(sampleTestResult.codeCoverage); + + expect(codeCoverage[0].name).to.equal('A'); + expect(codeCoverage[1].name).to.equal('B'); + expect(codeCoverage[2].name).to.equal('C'); + expect(codeCoverage[3].name).to.equal('D'); + expect(codeCoverage[4].name).to.equal('E'); + expect(codeCoverage[5].name).to.equal('F'); + expect(codeCoverage[6].name).to.equal('GeocodingService'); + expect(codeCoverage[7].name).to.equal('PagedResult'); + expect(codeCoverage[8].name).to.equal('PropertyController'); + expect(codeCoverage[9].name).to.equal('SampleDataController'); + }); + + it('should display code coverage percentage with red color when its value is < 75%', () => { + const codeCoverage = prepCoverageForDisplay(sampleTestResult.codeCoverage); + expect(codeCoverage[0].numLocations).to.equal(chalk.red('0%')); + expect(codeCoverage[1].numLocations).to.equal(chalk.red('74%')); + }); + + it('should display code coverage percentage with yellow color when its value is >= 75% and < 90%', () => { + const codeCoverage = prepCoverageForDisplay(sampleTestResult.codeCoverage); + expect(codeCoverage[2].numLocations).to.equal(chalk.yellow('75%')); + expect(codeCoverage[3].numLocations).to.equal(chalk.yellow('89%')); + }); + + it('should display code coverage percentage with green color when its value is >= 90%', () => { + const codeCoverage = prepCoverageForDisplay(sampleTestResult.codeCoverage); + expect(codeCoverage[4].numLocations).to.equal(chalk.green('90%')); + expect(codeCoverage[5].numLocations).to.equal(chalk.green('100%')); + }); });