UNPKG

@salesforce/apex-node

Version:

Salesforce JS library for Apex

135 lines 6.19 kB
"use strict"; var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.JUnitFormatTransformer = void 0; const utils_1 = require("../utils"); const node_stream_1 = require("node:stream"); const narrowing_1 = require("../narrowing"); const core_1 = require("@salesforce/core"); // cli currently has spaces in multiples of four for junit format const tab = ' '; const timeProperties = [ 'testExecutionTimeInMs', 'testTotalTimeInMs', 'commandTimeInMs' ]; // properties not in cli junit spec const skippedProperties = ['skipRate', 'totalLines', 'linesCovered']; class JUnitFormatTransformer extends node_stream_1.Readable { testResult; logger; buffer; bufferSize; constructor(testResult, options) { super(options); this.testResult = testResult; this.testResult = testResult; this.logger = core_1.Logger.childFromRoot('JUnitFormatTransformer'); this.buffer = ''; this.bufferSize = options?.bufferSize || 256; // Default buffer size is 256 } pushToBuffer(chunk) { this.buffer += chunk; if (this.buffer.length >= this.bufferSize) { this.push(this.buffer); this.buffer = ''; } } _read() { this.logger.trace('starting _read'); utils_1.HeapMonitor.getInstance().checkHeapSize('JUnitFormatTransformer._read'); this.format(); if (this.buffer.length > 0) { this.push(this.buffer); } this.push(null); // Signal the end of the stream this.logger.trace('finishing _read'); utils_1.HeapMonitor.getInstance().checkHeapSize('JUnitFormatTransformer._read'); } format() { const { summary } = this.testResult; this.pushToBuffer(`<?xml version="1.0" encoding="UTF-8"?>\n`); this.pushToBuffer(`<testsuites>\n`); this.pushToBuffer(`${tab}<testsuite name="force.apex" `); this.pushToBuffer(`timestamp="${summary.testStartTime}" `); this.pushToBuffer(`hostname="${summary.hostname}" `); this.pushToBuffer(`tests="${summary.testsRan}" `); this.pushToBuffer(`failures="${summary.failing}" `); this.pushToBuffer(`errors="0" `); this.pushToBuffer(`time="${(0, utils_1.msToSecond)(summary.testExecutionTimeInMs)}">\n`); this.buildProperties(); this.buildTestCases(); this.pushToBuffer(`${tab}</testsuite>\n`); this.pushToBuffer(`</testsuites>\n`); } buildProperties() { this.pushToBuffer(`${tab}${tab}<properties>\n`); Object.entries(this.testResult.summary).forEach(([key, value]) => { if ((0, narrowing_1.isEmpty)(value) || skippedProperties.includes(key)) { return; } if (timeProperties.includes(key)) { value = `${(0, utils_1.msToSecond)(value)} s`; key = key.replace('InMs', ''); } if (key === 'outcome' && value === 'Passed') { value = 'Successful'; } if (key === 'testStartTime') { value = (0, utils_1.formatStartTime)(value); } this.pushToBuffer(`${tab}${tab}${tab}<property name="${key}" value="${value}"/>\n`); // this call to setImmediate will schedule the closure on the event loop // this action causing the current code to yield to the event loop // allowing other processes to get time on the event loop setImmediate(() => { }); }); this.pushToBuffer(`${tab}${tab}</properties>\n`); } buildTestCases() { const testCases = this.testResult.tests; for (const testCase of testCases) { const methodName = JUnitFormatTransformer.xmlEscape(testCase.methodName); this.pushToBuffer(`${tab}${tab}<testcase name="${methodName}" classname="${testCase.apexClass.fullName}" time="${(0, utils_1.msToSecond)(testCase.runTime)}">\n`); if (testCase.outcome === "Fail" /* ApexTestResultOutcome.Fail */ || testCase.outcome === "CompileFail" /* ApexTestResultOutcome.CompileFail */) { let message = (0, narrowing_1.isEmpty)(testCase.message) ? '' : testCase.message; message = JUnitFormatTransformer.xmlEscape(message); this.pushToBuffer(`${tab}${tab}${tab}<failure message="${message}">`); if (testCase.stackTrace) { this.pushToBuffer(`<![CDATA[${testCase.stackTrace}]]>`); } this.pushToBuffer(`</failure>\n`); } this.pushToBuffer(`${tab}${tab}</testcase>\n`); // this call to setImmediate will schedule the closure on the event loop // this action causing the current code to yield to the event loop // allowing other processes to get time on the event loop setImmediate(() => { }); } } static xmlEscape(value) { return value .replace(/&/g, '&amp;') .replace(/</g, '&lt;') .replace(/>/g, '&gt;') .replace(/"/g, '&quot;') .replace(/'/g, '&apos;'); } } exports.JUnitFormatTransformer = JUnitFormatTransformer; __decorate([ (0, utils_1.elapsedTime)() ], JUnitFormatTransformer.prototype, "format", null); __decorate([ (0, utils_1.elapsedTime)() ], JUnitFormatTransformer.prototype, "buildProperties", null); __decorate([ (0, utils_1.elapsedTime)() ], JUnitFormatTransformer.prototype, "buildTestCases", null); //# sourceMappingURL=junitFormatTransformer.js.map