UNPKG

@salesforce/plugin-apex

Version:
166 lines 6.99 kB
/* * Copyright (c) 2020, salesforce.com, inc. * All rights reserved. * Licensed under the BSD 3-Clause license. * For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause */ import { HumanReporter, JUnitReporter, ResultFormat, TapReporter, TestService, } from '@salesforce/apex-node'; import { Messages } from '@salesforce/core'; import { JsonReporter } from './jsonReporter.js'; const FAILURE_EXIT_CODE = 100; Messages.importMessagesDirectoryFromMetaUrl(import.meta.url); const messages = Messages.loadMessages('@salesforce/plugin-apex', 'runtest'); export class TestReporter { ux; connection; /** * Create a TestReporter that will format test results * * @param ux a new Ux instance based on if the command is in json mode * @param connection a connection to the org the tests are being run against - used for getting username for hints */ constructor(ux, connection) { this.ux = ux; this.connection = connection; } async report(result, options) { if (options['output-dir']) { const jsonOutput = this.formatResultInJson(result); const outputDirConfig = this.buildOutputDirConfig(result, jsonOutput, options['output-dir'], options['result-format'], Boolean(options['detailed-coverage']), options.concise, options.synchronous); const testService = new TestService(this.connection); await testService.writeResultFiles(result, outputDirConfig, options['code-coverage']); } try { if (result.summary && result.summary.outcome === 'Failed') { process.exitCode = FAILURE_EXIT_CODE; } switch (options['result-format']) { case 'human': this.logHuman(result, options['detailed-coverage'], options['concise'], options['output-dir']); break; case 'tap': this.logTap(result); break; case 'junit': this.logJUnit(result); break; case 'json': // when --json flag is specified, we should log CLI json format if (!options.json) { this.ux.styledJSON({ status: process.exitCode, result: this.formatResultInJson(result), }); } break; default: this.logHuman(result, options['detailed-coverage'], options['concise'], options['output-dir']); } } catch (e) { this.ux.styledJSON(result); throw messages.createError('testResultProcessErr', [e.message]); } return this.formatResultInJson(result); } /** * Builds output directory configuration with CLI format result files * * @param result Test results from async/sync test run * @param jsonOutput JSON CLI format of test results * @param outputDir Output directory for result files * @param resultFormat Result format for output files * @param detailedCoverage Boolean to control detailed coverage reporting * @param synchronous Whether the test run was synchronous * @returns Output directory configuration */ // eslint-disable-next-line class-methods-use-this buildOutputDirConfig(result, jsonOutput, outputDir, resultFormat, detailedCoverage, concise, synchronous = false) { const outputDirConfig = { dirPath: outputDir, }; if ('summary' in result) { jsonOutput = jsonOutput; if (typeof resultFormat !== 'undefined' || synchronous) { outputDirConfig.fileInfos = [ { filename: result.summary.testRunId ? `test-result-${result.summary.testRunId}.json` : 'test-result.json', content: jsonOutput, }, ...(jsonOutput.coverage ? [ { filename: 'test-result-codecoverage.json', content: jsonOutput.coverage?.coverage, }, ] : []), ]; outputDirConfig.resultFormats = [ResultFormat.junit]; } if (typeof resultFormat === 'undefined' && synchronous) { resultFormat = ResultFormat.human; } switch (resultFormat) { case ResultFormat.tap: outputDirConfig.fileInfos?.push({ filename: 'test-result.txt', content: new TapReporter().format(result), }); outputDirConfig.resultFormats?.push(ResultFormat.tap); break; case ResultFormat.junit: outputDirConfig.fileInfos?.push({ filename: 'test-result.xml', content: new JUnitReporter().format(result), }); break; case ResultFormat.human: outputDirConfig.fileInfos?.push({ filename: 'test-result.txt', content: new HumanReporter().format(result, detailedCoverage, concise), }); break; default: break; } } return outputDirConfig; } formatResultInJson(result) { try { const reporter = new JsonReporter(); return reporter.format(result); } catch (e) { this.ux.styledJSON(result); throw messages.createError('testResultProcessErr', [e.message]); } } logHuman(result, detailedCoverage, concise, outputDir) { if (outputDir) { this.ux.log(messages.getMessage('outputDirHint', [outputDir])); } const humanReporter = new HumanReporter(); const output = humanReporter.format(result, detailedCoverage, concise); this.ux.log(output); } logTap(result) { const reporter = new TapReporter(); const hint = this.formatReportHint(result); this.ux.log(reporter.format(result, [hint])); } logJUnit(result) { const reporter = new JUnitReporter(); this.ux.log(reporter.format(result)); } formatReportHint(result) { let reportArgs = `-i ${result.summary.testRunId}`; const username = this.connection?.getUsername(); if (username) { reportArgs += ` -o ${username}`; } return messages.getMessage('apexTestReportFormatHint', [reportArgs]); } } //# sourceMappingURL=testReporter.js.map