Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@salesforce/apex-node

Package Overview
Dependencies
Maintainers
48
Versions
115
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@salesforce/apex-node - npm Package Compare versions

Comparing version 6.0.1 to 6.1.0

lib/src/utils/heapMonitor.d.ts

3

lib/src/execute/executeService.js

@@ -40,2 +40,3 @@ "use strict";

const elapsedTime_1 = require("../utils/elapsedTime");
const os = __importStar(require("node:os"));
class ExecuteService {

@@ -100,3 +101,3 @@ connection;

timeout.refresh();
apexCode = apexCode + input + '\n';
apexCode = apexCode + input + os.EOL;
});

@@ -103,0 +104,0 @@ readInterface.on('close', () => {

@@ -40,3 +40,4 @@ "use strict";

const i18n_1 = require("../i18n");
const elapsedTime_1 = require("../utils/elapsedTime");
const utils_1 = require("../utils");
const os = __importStar(require("node:os"));
const startOfSource = (source) => {

@@ -150,3 +151,3 @@ if (source) {

.readFileSync(fileCoverageData.path, 'utf8')
.split('\n');
.split(os.EOL);
}

@@ -188,10 +189,10 @@ catch {

__decorate([
(0, elapsedTime_1.elapsedTime)()
(0, utils_1.elapsedTime)()
], CoverageReporter.prototype, "generateReports", null);
__decorate([
(0, elapsedTime_1.elapsedTime)()
(0, utils_1.elapsedTime)()
], CoverageReporter.prototype, "buildCoverageMap", null);
__decorate([
(0, elapsedTime_1.elapsedTime)()
(0, utils_1.elapsedTime)()
], CoverageReporter.prototype, "findFullPathToClass", null);
//# sourceMappingURL=coverageReporter.js.map

@@ -7,2 +7,3 @@ /// <reference types="node" />

private readonly detailedCoverage;
private logger;
constructor(testResult: TestResult, detailedCoverage: boolean, options?: ReadableOptions);

@@ -9,0 +10,0 @@ _read(): void;

@@ -8,2 +8,18 @@ "use strict";

*/
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {

@@ -15,2 +31,9 @@ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;

};
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });

@@ -24,5 +47,7 @@ exports.HumanFormatTransform = void 0;

const os_1 = require("os");
const os = __importStar(require("node:os"));
class HumanFormatTransform extends node_stream_1.Readable {
testResult;
detailedCoverage;
logger;
constructor(testResult, detailedCoverage, options) {

@@ -34,6 +59,15 @@ super(options);

this.detailedCoverage ??= false;
this.logger = core_1.Logger.childFromRoot('HumanFormatTransform');
}
_read() {
this.format();
this.push(null); // Indicates end of data
this.logger.trace('starting _read');
utils_1.HeapMonitor.getInstance().checkHeapSize('HumanFormatTransform._read');
try {
this.format();
this.push(null); // Indicates end of data
this.logger.trace('finishing _read');
}
finally {
utils_1.HeapMonitor.getInstance().checkHeapSize('HumanFormatTransform._read');
}
}

@@ -164,3 +198,3 @@ format() {

});
this.push('\n\n');
this.push(os.EOL.repeat(2));
tb.createTable(testRowArray, [

@@ -197,3 +231,3 @@ {

});
this.push('\n\n');
this.push(os.EOL.repeat(2));
tb.createTable(codeCovRowArray, [

@@ -200,0 +234,0 @@ {

@@ -8,2 +8,18 @@ "use strict";

*/
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {

@@ -15,2 +31,9 @@ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;

};
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });

@@ -21,15 +44,22 @@ exports.HumanReporter = void 0;

const core_1 = require("@salesforce/core");
const os = __importStar(require("node:os"));
class HumanReporter {
format(testResult, detailedCoverage) {
let tbResult = this.formatSummary(testResult);
if (!testResult.codecoverage || !detailedCoverage) {
tbResult += this.formatTestResults(testResult.tests);
}
if (testResult.codecoverage) {
if (detailedCoverage) {
tbResult += this.formatDetailedCov(testResult);
utils_1.HeapMonitor.getInstance().checkHeapSize('HumanReporter.format');
try {
let tbResult = this.formatSummary(testResult);
if (!testResult.codecoverage || !detailedCoverage) {
tbResult += this.formatTestResults(testResult.tests);
}
tbResult += this.formatCodeCov(testResult.codecoverage);
if (testResult.codecoverage) {
if (detailedCoverage) {
tbResult += this.formatDetailedCov(testResult);
}
tbResult += this.formatCodeCov(testResult.codecoverage);
}
return tbResult;
}
return tbResult;
finally {
utils_1.HeapMonitor.getInstance().checkHeapSize('HumanReporter.format');
}
}

@@ -107,3 +137,3 @@ formatSummary(testResult) {

});
let testResultTable = '\n\n';
let testResultTable = os.EOL.repeat(2);
testResultTable += tb.createTable(testRowArray, [

@@ -150,3 +180,3 @@ {

});
let detailedCovTable = '\n\n';
let detailedCovTable = os.EOL.repeat(2);
detailedCovTable += tb.createTable(testRowArray, [

@@ -184,3 +214,3 @@ {

});
let codeCovTable = '\n\n';
let codeCovTable = os.EOL.repeat(2);
codeCovTable += tb.createTable(codeCovRowArray, [

@@ -187,0 +217,0 @@ {

export { TapReporter } from './tapReporter';
export { JUnitReporter } from './junitReporter';
export { JUnitFormatTransformer } from './junitFormatTransformer';
export { HumanReporter } from './humanReporter';
export { HumanFormatTransform } from './humanFormatTransform';
export { CoverageReporter, CoverageReporterOptions, CoverageReportFormats, DefaultReportOptions, DefaultWatermarks } from './coverageReporter';
export { TapFormatTransformer } from './tapFormatTransform';
export { JUnitFormatTransformer } from './junitFormatTransformer';
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.JUnitFormatTransformer = exports.TapFormatTransformer = exports.DefaultWatermarks = exports.DefaultReportOptions = exports.CoverageReporter = exports.HumanReporter = exports.JUnitReporter = exports.TapReporter = void 0;
exports.TapFormatTransformer = exports.DefaultWatermarks = exports.DefaultReportOptions = exports.CoverageReporter = exports.HumanFormatTransform = exports.HumanReporter = exports.JUnitFormatTransformer = exports.JUnitReporter = exports.TapReporter = void 0;
/*

@@ -14,4 +14,8 @@ * Copyright (c) 2020, salesforce.com, inc.

Object.defineProperty(exports, "JUnitReporter", { enumerable: true, get: function () { return junitReporter_1.JUnitReporter; } });
var junitFormatTransformer_1 = require("./junitFormatTransformer");
Object.defineProperty(exports, "JUnitFormatTransformer", { enumerable: true, get: function () { return junitFormatTransformer_1.JUnitFormatTransformer; } });
var humanReporter_1 = require("./humanReporter");
Object.defineProperty(exports, "HumanReporter", { enumerable: true, get: function () { return humanReporter_1.HumanReporter; } });
var humanFormatTransform_1 = require("./humanFormatTransform");
Object.defineProperty(exports, "HumanFormatTransform", { enumerable: true, get: function () { return humanFormatTransform_1.HumanFormatTransform; } });
var coverageReporter_1 = require("./coverageReporter");

@@ -23,4 +27,2 @@ Object.defineProperty(exports, "CoverageReporter", { enumerable: true, get: function () { return coverageReporter_1.CoverageReporter; } });

Object.defineProperty(exports, "TapFormatTransformer", { enumerable: true, get: function () { return tapFormatTransform_1.TapFormatTransformer; } });
var junitFormatTransformer_1 = require("./junitFormatTransformer");
Object.defineProperty(exports, "JUnitFormatTransformer", { enumerable: true, get: function () { return junitFormatTransformer_1.JUnitFormatTransformer; } });
//# sourceMappingURL=index.js.map
/// <reference types="node" />
import { TestResult } from '../tests';
import { Readable, ReadableOptions } from 'node:stream';
export type JUnitFormatTransformerOptions = ReadableOptions & {
bufferSize?: number;
};
export declare class JUnitFormatTransformer extends Readable {
private readonly testResult;
constructor(testResult: TestResult, options?: ReadableOptions);
private logger;
private buffer;
private bufferSize;
constructor(testResult: TestResult, options?: JUnitFormatTransformerOptions);
private pushToBuffer;
_read(): void;

@@ -8,0 +15,0 @@ format(): void;

@@ -13,2 +13,3 @@ "use strict";

const narrowing_1 = require("../narrowing");
const core_1 = require("@salesforce/core");
// cli currently has spaces in multiples of four for junit format

@@ -25,2 +26,5 @@ const tab = ' ';

testResult;
logger;
buffer;
bufferSize;
constructor(testResult, options) {

@@ -30,25 +34,42 @@ super(options);

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.push(`<?xml version="1.0" encoding="UTF-8"?>\n`);
this.push(`<testsuites>\n`);
this.push(`${tab}<testsuite name="force.apex" `);
this.push(`timestamp="${summary.testStartTime}" `);
this.push(`hostname="${summary.hostname}" `);
this.push(`tests="${summary.testsRan}" `);
this.push(`failures="${summary.failing}" `);
this.push(`errors="0" `);
this.push(`time="${(0, utils_1.msToSecond)(summary.testExecutionTimeInMs)}">\n`);
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.push(`${tab}</testsuite>\n`);
this.push(`</testsuites>\n`);
this.pushToBuffer(`${tab}</testsuite>\n`);
this.pushToBuffer(`</testsuites>\n`);
}
buildProperties() {
this.push(`${tab}${tab}<properties>\n`);
this.pushToBuffer(`${tab}${tab}<properties>\n`);
Object.entries(this.testResult.summary).forEach(([key, value]) => {

@@ -68,5 +89,9 @@ if ((0, narrowing_1.isEmpty)(value) || skippedProperties.includes(key)) {

}
this.push(`${tab}${tab}${tab}<property name="${key}" value="${value}"/>\n`);
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.push(`${tab}${tab}</properties>\n`);
this.pushToBuffer(`${tab}${tab}</properties>\n`);
}

@@ -77,3 +102,3 @@ buildTestCases() {

const methodName = JUnitFormatTransformer.xmlEscape(testCase.methodName);
this.push(`${tab}${tab}<testcase name="${methodName}" classname="${testCase.apexClass.fullName}" time="${(0, utils_1.msToSecond)(testCase.runTime)}">\n`);
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 */ ||

@@ -83,9 +108,13 @@ testCase.outcome === "CompileFail" /* ApexTestResultOutcome.CompileFail */) {

message = JUnitFormatTransformer.xmlEscape(message);
this.push(`${tab}${tab}${tab}<failure message="${message}">`);
this.pushToBuffer(`${tab}${tab}${tab}<failure message="${message}">`);
if (testCase.stackTrace) {
this.push(`<![CDATA[${testCase.stackTrace}]]>`);
this.pushToBuffer(`<![CDATA[${testCase.stackTrace}]]>`);
}
this.push(`</failure>\n`);
this.pushToBuffer(`</failure>\n`);
}
this.push(`${tab}${tab}</testcase>\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(() => { });
}

@@ -92,0 +121,0 @@ }

@@ -24,17 +24,23 @@ "use strict";

format(testResult) {
const { summary, tests } = testResult;
let output = `<?xml version="1.0" encoding="UTF-8"?>\n`;
output += `<testsuites>\n`;
output += `${tab}<testsuite name="force.apex" `;
output += `timestamp="${summary.testStartTime}" `;
output += `hostname="${summary.hostname}" `;
output += `tests="${summary.testsRan}" `;
output += `failures="${summary.failing}" `;
output += `errors="0" `;
output += `time="${(0, utils_1.msToSecond)(summary.testExecutionTimeInMs)}">\n`;
output += this.buildProperties(testResult);
output += this.buildTestCases(tests);
output += `${tab}</testsuite>\n`;
output += `</testsuites>\n`;
return output;
utils_1.HeapMonitor.getInstance().checkHeapSize('JUnitReporter.format');
try {
const { summary, tests } = testResult;
let output = `<?xml version="1.0" encoding="UTF-8"?>\n`;
output += `<testsuites>\n`;
output += `${tab}<testsuite name="force.apex" `;
output += `timestamp="${summary.testStartTime}" `;
output += `hostname="${summary.hostname}" `;
output += `tests="${summary.testsRan}" `;
output += `failures="${summary.failing}" `;
output += `errors="0" `;
output += `time="${(0, utils_1.msToSecond)(summary.testExecutionTimeInMs)}">\n`;
output += this.buildProperties(testResult);
output += this.buildTestCases(tests);
output += `${tab}</testsuite>\n`;
output += `</testsuites>\n`;
return output;
}
finally {
utils_1.HeapMonitor.getInstance().checkHeapSize('JUnitReporter.format');
}
}

@@ -41,0 +47,0 @@ buildProperties(testResult) {

@@ -10,6 +10,13 @@ /// <reference types="node" />

}
export type TapFormatTransformerOptions = ReadableOptions & {
bufferSize?: number;
};
export declare class TapFormatTransformer extends Readable {
private readonly logger;
private testResult;
private epilogue?;
constructor(testResult: TestResult, epilogue?: string[], options?: ReadableOptions);
private buffer;
private bufferSize;
constructor(testResult: TestResult, epilogue?: string[], options?: TapFormatTransformerOptions);
private pushToBuffer;
_read(): void;

@@ -16,0 +23,0 @@ format(): void;

"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {

@@ -8,2 +24,9 @@ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;

};
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });

@@ -17,7 +40,12 @@ exports.TapFormatTransformer = void 0;

*/
const core_1 = require("@salesforce/core");
const node_stream_1 = require("node:stream");
const utils_1 = require("../utils");
const os = __importStar(require("node:os"));
class TapFormatTransformer extends node_stream_1.Readable {
logger;
testResult;
epilogue;
buffer;
bufferSize;
constructor(testResult, epilogue, options) {

@@ -27,13 +55,30 @@ super(options);

this.epilogue = epilogue;
this.logger = core_1.Logger.childFromRoot('TapFormatTransformer');
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 format');
utils_1.HeapMonitor.getInstance().checkHeapSize('TapFormatTransformer._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 format');
utils_1.HeapMonitor.getInstance().checkHeapSize('TapFormatTransformer._read');
}
format() {
const testPointCount = this.testResult.tests.length;
this.push(`1..${testPointCount}\n`);
this.pushToBuffer(`1..${testPointCount}\n`);
this.buildTapResults();
this.epilogue?.forEach((c) => {
this.push(`# ${c}\n`);
this.pushToBuffer(`# ${c}\n`);
});

@@ -45,5 +90,5 @@ }

const outcome = test.outcome === "Pass" /* ApexTestResultOutcome.Pass */ ? 'ok' : 'not ok';
this.push(`${outcome} ${testNumber} ${test.fullName}\n`);
this.pushToBuffer(`${outcome} ${testNumber} ${test.fullName}\n`);
this.buildTapDiagnostics(test).forEach((s) => {
this.push(`# ${s}\n`);
this.pushToBuffer(`# ${s}\n`);
});

@@ -72,3 +117,3 @@ });

if (testResult.stackTrace) {
testResult.stackTrace.split('\n').forEach((line) => {
testResult.stackTrace.split(os.EOL).forEach((line) => {
message.push(line);

@@ -75,0 +120,0 @@ });

"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {

@@ -8,21 +24,35 @@ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;

};
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.TapReporter = void 0;
const elapsedTime_1 = require("../utils/elapsedTime");
const utils_1 = require("../utils");
const os = __importStar(require("node:os"));
class TapReporter {
format(testResult, epilog) {
const results = this.buildTapResults(testResult);
const testPointCount = results.length;
let out = '';
out = out.concat(`1..${testPointCount}\n`);
results.forEach((testPoint) => {
out = out.concat(`${testPoint.outcome} ${testPoint.testNumber} ${testPoint.description}\n`);
testPoint.diagnostics.forEach((s) => {
out = out.concat(`# ${s}\n`);
utils_1.HeapMonitor.getInstance().checkHeapSize('TapReporter.format');
try {
const results = this.buildTapResults(testResult);
const testPointCount = results.length;
let out = '';
out = out.concat(`1..${testPointCount}\n`);
results.forEach((testPoint) => {
out = out.concat(`${testPoint.outcome} ${testPoint.testNumber} ${testPoint.description}\n`);
testPoint.diagnostics.forEach((s) => {
out = out.concat(`# ${s}\n`);
});
});
});
epilog?.forEach((c) => {
out = out.concat(`# ${c}\n`);
});
return out;
epilog?.forEach((c) => {
out = out.concat(`# ${c}\n`);
});
return out;
}
finally {
utils_1.HeapMonitor.getInstance().checkHeapSize('TapReporter.format');
}
}

@@ -63,3 +93,3 @@ buildTapResults(testResult) {

if (testResult.stackTrace) {
testResult.stackTrace.split('\n').forEach((line) => {
testResult.stackTrace.split(os.EOL).forEach((line) => {
message.push(line);

@@ -74,10 +104,10 @@ });

__decorate([
(0, elapsedTime_1.elapsedTime)()
(0, utils_1.elapsedTime)()
], TapReporter.prototype, "format", null);
__decorate([
(0, elapsedTime_1.elapsedTime)()
(0, utils_1.elapsedTime)()
], TapReporter.prototype, "buildTapResults", null);
__decorate([
(0, elapsedTime_1.elapsedTime)()
(0, utils_1.elapsedTime)()
], TapReporter.prototype, "buildTapDiagnostics", null);
//# sourceMappingURL=tapReporter.js.map
export { AsyncTestRun, StreamingClient } from './streamingClient';
export { JSONStringifyStream } from './jsonStringifyStream';
export { TestResultStringifyStream } from './testResultStringifyStream';
export { determineType, getArrayEntries, getPrimitiveEntries, getObjectEntries, pushArrayToStream } from './utils';
export { determineType, getArrayEntries, getPrimitiveEntries, getObjectEntries } from './utils';
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.pushArrayToStream = exports.getObjectEntries = exports.getPrimitiveEntries = exports.getArrayEntries = exports.determineType = exports.TestResultStringifyStream = exports.JSONStringifyStream = exports.StreamingClient = void 0;
exports.getObjectEntries = exports.getPrimitiveEntries = exports.getArrayEntries = exports.determineType = exports.TestResultStringifyStream = exports.StreamingClient = void 0;
/*

@@ -12,4 +12,2 @@ * Copyright (c) 2020, salesforce.com, inc.

Object.defineProperty(exports, "StreamingClient", { enumerable: true, get: function () { return streamingClient_1.StreamingClient; } });
var jsonStringifyStream_1 = require("./jsonStringifyStream");
Object.defineProperty(exports, "JSONStringifyStream", { enumerable: true, get: function () { return jsonStringifyStream_1.JSONStringifyStream; } });
var testResultStringifyStream_1 = require("./testResultStringifyStream");

@@ -22,3 +20,2 @@ Object.defineProperty(exports, "TestResultStringifyStream", { enumerable: true, get: function () { return testResultStringifyStream_1.TestResultStringifyStream; } });

Object.defineProperty(exports, "getObjectEntries", { enumerable: true, get: function () { return utils_1.getObjectEntries; } });
Object.defineProperty(exports, "pushArrayToStream", { enumerable: true, get: function () { return utils_1.pushArrayToStream; } });
//# sourceMappingURL=index.js.map
/// <reference types="node" />
import { Readable, ReadableOptions } from 'node:stream';
import { TestResult } from '../tests';
export type TestResultStringifyStreamOptions = ReadableOptions & {
bufferSize?: number;
};
export declare class TestResultStringifyStream extends Readable {
private readonly testResult;
constructor(testResult: TestResult, options?: ReadableOptions);
private readonly logger;
private buffer;
private readonly bufferSize;
constructor(testResult: TestResult, options?: TestResultStringifyStreamOptions);
private pushToBuffer;
_read(): void;

@@ -11,3 +18,4 @@ format(): void;

buildCodeCoverage(): void;
static fromTestResult(testResult: TestResult): TestResultStringifyStream;
static fromTestResult(testResult: TestResult, options?: TestResultStringifyStreamOptions): TestResultStringifyStream;
private pushArrayToBuffer;
}

@@ -16,7 +16,10 @@ "use strict";

*/
const core_1 = require("@salesforce/core");
const node_stream_1 = require("node:stream");
const utils_1 = require("./utils");
const utils_2 = require("../utils");
const utils_1 = require("../utils");
class TestResultStringifyStream extends node_stream_1.Readable {
testResult;
logger;
buffer;
bufferSize;
constructor(testResult, options) {

@@ -26,6 +29,22 @@ super({ ...options, objectMode: true });

this.testResult = testResult;
this.logger = core_1.Logger.childFromRoot('TestResultStringifyStream');
this.buffer = '';
this.bufferSize = options?.bufferSize || 256; // Default buffer size is 256
}
pushToBuffer(data) {
this.buffer += data;
if (this.buffer.length >= this.bufferSize) {
this.push(this.buffer);
this.buffer = '';
}
}
_read() {
this.logger.trace('starting format');
this.format();
if (this.buffer.length > 0) {
this.push(this.buffer);
this.buffer = '';
}
this.push(null); // Signal the end of the stream
this.logger.trace('finishing format');
}

@@ -36,70 +55,90 @@ format() {

// outer curly
this.push('{');
this.pushToBuffer('{');
// summary
this.push(`"summary":${JSON.stringify(summary)},`);
this.pushToBuffer(`"summary":${JSON.stringify(summary)},`);
this.buildTests();
this.buildCodeCoverage();
// closing outer curly
this.push(`}`);
this.pushToBuffer(`}`);
}
buildTests() {
this.push('"tests":[');
this.pushToBuffer('"tests":[');
const numberOfTests = this.testResult.tests.length - 1;
this.testResult.tests.forEach((test, index) => {
const { perClassCoverage, ...testRest } = test;
this.push(`${JSON.stringify(testRest).slice(0, -1)}`);
this.pushToBuffer(`${JSON.stringify(testRest).slice(0, -1)}`);
if (perClassCoverage) {
const numberOfPerClassCoverage = perClassCoverage.length - 1;
this.push(',"perClassCoverage":[');
this.pushToBuffer(',"perClassCoverage":[');
perClassCoverage.forEach((pcc, index) => {
const { coverage, ...coverageRest } = pcc;
this.push(`${JSON.stringify(coverageRest).slice(0, -1)}`);
this.push(`,"coverage":${JSON.stringify(coverage)}}`);
this.pushToBuffer(`${JSON.stringify(coverageRest).slice(0, -1)}`);
this.pushToBuffer(`,"coverage":${JSON.stringify(coverage)}}`);
if (numberOfPerClassCoverage !== index) {
this.push(',');
this.pushToBuffer(',');
}
});
this.push(']');
this.pushToBuffer(']');
// 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(() => { });
}
// close the tests
this.push('}');
this.pushToBuffer('}');
if (numberOfTests !== index) {
this.push(',');
this.pushToBuffer(',');
}
});
this.push(']');
this.pushToBuffer(']');
}
buildCodeCoverage() {
if (this.testResult.codecoverage) {
this.push(',"codecoverage":[');
this.pushToBuffer(',"codecoverage":[');
const numberOfCodeCoverage = this.testResult.codecoverage.length - 1;
this.testResult.codecoverage.forEach((coverage, index) => {
const { coveredLines, uncoveredLines, ...theRest } = coverage;
this.push(`${JSON.stringify(theRest).slice(0, -1)}`);
this.push(',"coveredLines":[');
(0, utils_1.pushArrayToStream)(coveredLines, this);
this.push('],"uncoveredLines":[');
(0, utils_1.pushArrayToStream)(uncoveredLines, this);
this.push(']}');
this.pushToBuffer(`${JSON.stringify(theRest).slice(0, -1)}`);
this.pushToBuffer(',"coveredLines":[');
this.pushArrayToBuffer(coveredLines);
this.pushToBuffer('],"uncoveredLines":[');
this.pushArrayToBuffer(uncoveredLines);
this.pushToBuffer(']}');
if (numberOfCodeCoverage !== index) {
this.push(',');
this.pushToBuffer(',');
}
// 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.push(']');
this.pushToBuffer(']');
}
}
static fromTestResult(testResult) {
return new TestResultStringifyStream(testResult);
static fromTestResult(testResult, options) {
return new TestResultStringifyStream(testResult, options);
}
pushArrayToBuffer(array) {
const chunkSize = 1000;
for (let i = 0; i < array.length; i += chunkSize) {
const chunk = array.slice(i, i + chunkSize);
let jsonString = JSON.stringify(chunk);
jsonString = jsonString.slice(1, -1); // remove '[' and ']'
this.pushToBuffer(jsonString);
if (i + chunkSize < array.length) {
this.pushToBuffer(','); // add comma for all but the last chunk
}
}
}
}
exports.TestResultStringifyStream = TestResultStringifyStream;
__decorate([
(0, utils_2.elapsedTime)()
(0, utils_1.elapsedTime)()
], TestResultStringifyStream.prototype, "format", null);
__decorate([
(0, utils_2.elapsedTime)()
(0, utils_1.elapsedTime)()
], TestResultStringifyStream.prototype, "buildTests", null);
__decorate([
(0, utils_2.elapsedTime)()
(0, utils_1.elapsedTime)()
], TestResultStringifyStream.prototype, "buildCodeCoverage", null);
//# sourceMappingURL=testResultStringifyStream.js.map

@@ -1,4 +0,1 @@

/// <reference types="node" />
import { Readable } from 'node:stream';
export declare const pushArrayToStream: (array: unknown[], stream: Readable) => void;
export declare const getPrimitiveEntries: (obj: object) => [string, unknown][];

@@ -5,0 +2,0 @@ export declare const getComplexEntries: (obj: object) => [string, unknown][];

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.determineType = exports.getArrayEntries = exports.getObjectEntries = exports.getComplexEntries = exports.getPrimitiveEntries = exports.pushArrayToStream = void 0;
exports.determineType = exports.getArrayEntries = exports.getObjectEntries = exports.getComplexEntries = exports.getPrimitiveEntries = void 0;
/*
* Copyright (c) 2023, 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
*/
const narrowing_1 = require("../narrowing");
const pushArrayToStream = (array, stream) => {
const chunkSize = 1000;
for (let i = 0; i < array.length; i += chunkSize) {
const chunk = array.slice(i, i + chunkSize);
let jsonString = JSON.stringify(chunk);
jsonString = jsonString.slice(1, -1); // remove '[' and ']'
stream.push(jsonString);
if (i + chunkSize < array.length) {
stream.push(','); // add comma for all but the last chunk
}
}
};
exports.pushArrayToStream = pushArrayToStream;
const getPrimitiveEntries = (obj) => {

@@ -19,0 +12,0 @@ return Object.entries(obj).filter((entry) => (0, narrowing_1.isPrimitive)(entry[1]));

@@ -9,2 +9,3 @@ import { Connection } from '@salesforce/core';

private readonly codecoverage;
private readonly logger;
constructor(connection: Connection);

@@ -21,2 +22,3 @@ /**

runTests(options: AsyncTestConfiguration | AsyncTestArrayConfiguration, codeCoverage?: boolean, exitOnTestRunId?: boolean, progress?: Progress<ApexTestProgressValue>, token?: CancellationToken, timeout?: Duration): Promise<TestResult | TestRunIdResult>;
private writeResultsToFile;
/**

@@ -48,2 +50,3 @@ * Report Asynchronous Test Run Results

* @param testRunId
* @param progress
*/

@@ -50,0 +53,0 @@ abortTestRun(testRunId: string, progress?: Progress<ApexTestProgressValue>): Promise<void>;

@@ -37,4 +37,8 @@ "use strict";

};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.AsyncTests = void 0;
const core_1 = require("@salesforce/core");
const i18n_1 = require("../i18n");

@@ -49,2 +53,9 @@ const streaming_1 = require("../streaming");

const narrowing_1 = require("../narrowing");
const node_fs_1 = require("node:fs");
const promises_1 = require("node:stream/promises");
const os = __importStar(require("node:os"));
const path_1 = __importDefault(require("path"));
const promises_2 = __importDefault(require("node:fs/promises"));
// eslint-disable-next-line @typescript-eslint/no-var-requires
const bfj = require('bfj');
const finishedStatuses = [

@@ -60,5 +71,7 @@ "Aborted" /* ApexTestRunResultStatus.Aborted */,

codecoverage;
logger;
constructor(connection) {
this.connection = connection;
this.codecoverage = new codeCoverage_1.CodeCoverage(this.connection);
this.logger = core_1.Logger.childFromRoot('AsyncTests');
}

@@ -75,2 +88,3 @@ /**

async runTests(options, codeCoverage = false, exitOnTestRunId = false, progress, token, timeout) {
utils_1.HeapMonitor.getInstance().checkHeapSize('asyncTests.runTests');
try {

@@ -99,3 +113,5 @@ const sClient = new streaming_1.StreamingClient(this.connection, progress);

const runResult = await this.checkRunStatus(asyncRunResult.runId);
return await this.formatAsyncResults(asyncRunResult, (0, utils_1.getCurrentTime)(), codeCoverage, runResult.testRunSummary, progress);
const formattedResults = await this.formatAsyncResults(asyncRunResult, (0, utils_1.getCurrentTime)(), codeCoverage, runResult.testRunSummary, progress);
await this.writeResultsToFile(formattedResults, asyncRunResult.runId);
return formattedResults;
}

@@ -105,3 +121,26 @@ catch (e) {

}
finally {
utils_1.HeapMonitor.getInstance().checkHeapSize('asyncTests.runTests');
}
}
async writeResultsToFile(formattedResults, runId) {
utils_1.HeapMonitor.getInstance().checkHeapSize('asyncTests.writeResultsToFile');
try {
if (this.logger.shouldLog(core_1.LoggerLevel.DEBUG)) {
const rawResultsPath = path_1.default.join(os.tmpdir(), runId, 'rawResults.json');
await promises_2.default.mkdir(path_1.default.dirname(rawResultsPath), { recursive: true });
const writeStream = (0, node_fs_1.createWriteStream)(path_1.default.join(os.tmpdir(), runId, 'rawResults.json'));
this.logger.debug(`Raw raw results written to: ${writeStream.path}`);
const stringifyStream = bfj.stringify(formattedResults, {
bufferLength: (0, utils_2.getBufferSize)(),
iterables: 'ignore',
space: (0, utils_2.getJsonIndent)()
});
return await (0, promises_1.pipeline)(stringifyStream, writeStream);
}
}
finally {
utils_1.HeapMonitor.getInstance().checkHeapSize('asyncTests.writeResultsToFile');
}
}
/**

@@ -114,2 +153,3 @@ * Report Asynchronous Test Run Results

async reportAsyncResults(testRunId, codeCoverage = false, token) {
utils_1.HeapMonitor.getInstance().checkHeapSize('asyncTests.reportAsyncResults');
try {

@@ -135,3 +175,5 @@ const sClient = new streaming_1.StreamingClient(this.connection);

}
return await this.formatAsyncResults({ queueItem, runId: testRunId }, (0, utils_1.getCurrentTime)(), codeCoverage, runResult.testRunSummary);
const formattedResults = await this.formatAsyncResults({ queueItem, runId: testRunId }, (0, utils_1.getCurrentTime)(), codeCoverage, runResult.testRunSummary);
await this.writeResultsToFile(formattedResults, testRunId);
return formattedResults;
}

@@ -141,2 +183,5 @@ catch (e) {

}
finally {
utils_1.HeapMonitor.getInstance().checkHeapSize('asyncTests.reportAsyncResults');
}
}

@@ -176,141 +221,159 @@ async checkRunStatus(testRunId, progress) {

async formatAsyncResults(asyncRunResult, commandStartTime, codeCoverage = false, testRunSummary, progress) {
const coveredApexClassIdSet = new Set();
const apexTestResults = await this.getAsyncTestResults(asyncRunResult.queueItem);
const { apexTestClassIdSet, testResults, globalTests } = await this.buildAsyncTestResults(apexTestResults);
let outcome = testRunSummary.Status;
if (globalTests.failed > 0) {
outcome = "Failed" /* ApexTestRunResultStatus.Failed */;
utils_1.HeapMonitor.getInstance().checkHeapSize('asyncTests.formatAsyncResults');
try {
const coveredApexClassIdSet = new Set();
const apexTestResults = await this.getAsyncTestResults(asyncRunResult.queueItem);
const { apexTestClassIdSet, testResults, globalTests } = await this.buildAsyncTestResults(apexTestResults);
let outcome = testRunSummary.Status;
if (globalTests.failed > 0) {
outcome = "Failed" /* ApexTestRunResultStatus.Failed */;
}
else if (globalTests.passed === 0) {
outcome = "Skipped" /* ApexTestRunResultStatus.Skipped */;
}
else if (testRunSummary.Status === "Completed" /* ApexTestRunResultStatus.Completed */) {
outcome = "Passed" /* ApexTestRunResultStatus.Passed */;
}
// TODO: deprecate testTotalTime
const result = {
summary: {
outcome,
testsRan: testResults.length,
passing: globalTests.passed,
failing: globalTests.failed,
skipped: globalTests.skipped,
passRate: (0, utils_2.calculatePercentage)(globalTests.passed, testResults.length),
failRate: (0, utils_2.calculatePercentage)(globalTests.failed, testResults.length),
skipRate: (0, utils_2.calculatePercentage)(globalTests.skipped, testResults.length),
testStartTime: (0, utils_1.formatStartTime)(testRunSummary.StartTime, 'ISO'),
testExecutionTimeInMs: testRunSummary.TestTime ?? 0,
testTotalTimeInMs: testRunSummary.TestTime ?? 0,
commandTimeInMs: (0, utils_1.getCurrentTime)() - commandStartTime,
hostname: this.connection.instanceUrl,
orgId: this.connection.getAuthInfoFields().orgId,
username: this.connection.getUsername(),
testRunId: asyncRunResult.runId,
userId: testRunSummary.UserId
},
tests: testResults
};
if (codeCoverage) {
const perClassCovMap = await this.codecoverage.getPerClassCodeCoverage(apexTestClassIdSet);
result.tests.forEach((item) => {
const keyCodeCov = `${item.apexClass.id}-${item.methodName}`;
const perClassCov = perClassCovMap.get(keyCodeCov);
// Skipped test is not in coverage map, check to see if perClassCov exists first
if (perClassCov) {
perClassCov.forEach((classCov) => coveredApexClassIdSet.add(classCov.apexClassOrTriggerId));
item.perClassCoverage = perClassCov;
}
});
progress?.report({
type: 'FormatTestResultProgress',
value: 'queryingForAggregateCodeCoverage',
message: i18n_1.nls.localize('queryingForAggregateCodeCoverage')
});
const { codeCoverageResults, totalLines, coveredLines } = await this.codecoverage.getAggregateCodeCoverage(coveredApexClassIdSet);
result.codecoverage = codeCoverageResults;
result.summary.totalLines = totalLines;
result.summary.coveredLines = coveredLines;
result.summary.testRunCoverage = (0, utils_2.calculatePercentage)(coveredLines, totalLines);
result.summary.orgWideCoverage =
await this.codecoverage.getOrgWideCoverage();
}
return result;
}
else if (globalTests.passed === 0) {
outcome = "Skipped" /* ApexTestRunResultStatus.Skipped */;
finally {
utils_1.HeapMonitor.getInstance().checkHeapSize('asyncTests.formatAsyncResults');
}
else if (testRunSummary.Status === "Completed" /* ApexTestRunResultStatus.Completed */) {
outcome = "Passed" /* ApexTestRunResultStatus.Passed */;
}
// TODO: deprecate testTotalTime
const result = {
summary: {
outcome,
testsRan: testResults.length,
passing: globalTests.passed,
failing: globalTests.failed,
skipped: globalTests.skipped,
passRate: (0, utils_2.calculatePercentage)(globalTests.passed, testResults.length),
failRate: (0, utils_2.calculatePercentage)(globalTests.failed, testResults.length),
skipRate: (0, utils_2.calculatePercentage)(globalTests.skipped, testResults.length),
testStartTime: (0, utils_1.formatStartTime)(testRunSummary.StartTime, 'ISO'),
testExecutionTimeInMs: testRunSummary.TestTime ?? 0,
testTotalTimeInMs: testRunSummary.TestTime ?? 0,
commandTimeInMs: (0, utils_1.getCurrentTime)() - commandStartTime,
hostname: this.connection.instanceUrl,
orgId: this.connection.getAuthInfoFields().orgId,
username: this.connection.getUsername(),
testRunId: asyncRunResult.runId,
userId: testRunSummary.UserId
},
tests: testResults
};
if (codeCoverage) {
const perClassCovMap = await this.codecoverage.getPerClassCodeCoverage(apexTestClassIdSet);
result.tests.forEach((item) => {
const keyCodeCov = `${item.apexClass.id}-${item.methodName}`;
const perClassCov = perClassCovMap.get(keyCodeCov);
// Skipped test is not in coverage map, check to see if perClassCov exists first
if (perClassCov) {
perClassCov.forEach((classCov) => coveredApexClassIdSet.add(classCov.apexClassOrTriggerId));
item.perClassCoverage = perClassCov;
}
});
progress?.report({
type: 'FormatTestResultProgress',
value: 'queryingForAggregateCodeCoverage',
message: i18n_1.nls.localize('queryingForAggregateCodeCoverage')
});
const { codeCoverageResults, totalLines, coveredLines } = await this.codecoverage.getAggregateCodeCoverage(coveredApexClassIdSet);
result.codecoverage = codeCoverageResults;
result.summary.totalLines = totalLines;
result.summary.coveredLines = coveredLines;
result.summary.testRunCoverage = (0, utils_2.calculatePercentage)(coveredLines, totalLines);
result.summary.orgWideCoverage =
await this.codecoverage.getOrgWideCoverage();
}
return result;
}
async getAsyncTestResults(testQueueResult) {
let apexTestResultQuery = 'SELECT Id, QueueItemId, StackTrace, Message, ';
apexTestResultQuery +=
'RunTime, TestTimestamp, AsyncApexJobId, MethodName, Outcome, ApexLogId, ';
apexTestResultQuery +=
'ApexClass.Id, ApexClass.Name, ApexClass.NamespacePrefix ';
apexTestResultQuery += 'FROM ApexTestResult WHERE QueueItemId IN (%s)';
const apexResultIds = testQueueResult.records.map((record) => record.Id);
// iterate thru ids, create query with id, & compare query length to char limit
const queries = [];
for (let i = 0; i < apexResultIds.length; i += constants_1.QUERY_RECORD_LIMIT) {
const recordSet = apexResultIds
.slice(i, i + constants_1.QUERY_RECORD_LIMIT)
.map((id) => `'${id}'`);
const query = util.format(apexTestResultQuery, recordSet.join(','));
queries.push(query);
utils_1.HeapMonitor.getInstance().checkHeapSize('asyncTests.getAsyncTestResults');
try {
let apexTestResultQuery = 'SELECT Id, QueueItemId, StackTrace, Message, ';
apexTestResultQuery +=
'RunTime, TestTimestamp, AsyncApexJobId, MethodName, Outcome, ApexLogId, ';
apexTestResultQuery +=
'ApexClass.Id, ApexClass.Name, ApexClass.NamespacePrefix ';
apexTestResultQuery += 'FROM ApexTestResult WHERE QueueItemId IN (%s)';
const apexResultIds = testQueueResult.records.map((record) => record.Id);
// iterate thru ids, create query with id, & compare query length to char limit
const queries = [];
for (let i = 0; i < apexResultIds.length; i += constants_1.QUERY_RECORD_LIMIT) {
const recordSet = apexResultIds
.slice(i, i + constants_1.QUERY_RECORD_LIMIT)
.map((id) => `'${id}'`);
const query = util.format(apexTestResultQuery, recordSet.join(','));
queries.push(query);
}
const queryPromises = queries.map((query) => {
return (0, utils_2.queryAll)(this.connection, query, true);
});
const apexTestResults = await Promise.all(queryPromises);
return apexTestResults;
}
const queryPromises = queries.map((query) => {
return (0, utils_2.queryAll)(this.connection, query, true);
});
const apexTestResults = await Promise.all(queryPromises);
return apexTestResults;
finally {
utils_1.HeapMonitor.getInstance().checkHeapSize('asyncTests.getAsyncTestResults');
}
}
async buildAsyncTestResults(apexTestResults) {
const apexTestClassIdSet = new Set();
let passed = 0;
let failed = 0;
let skipped = 0;
// Iterate over test results, format and add them as results.tests
const testResults = [];
for (const result of apexTestResults) {
result.records.forEach((item) => {
switch (item.Outcome) {
case "Pass" /* ApexTestResultOutcome.Pass */:
passed++;
break;
case "Fail" /* ApexTestResultOutcome.Fail */:
case "CompileFail" /* ApexTestResultOutcome.CompileFail */:
failed++;
break;
case "Skip" /* ApexTestResultOutcome.Skip */:
skipped++;
break;
}
apexTestClassIdSet.add(item.ApexClass.Id);
// Can only query the FullName field if a single record is returned, so manually build the field
item.ApexClass.FullName = item.ApexClass.NamespacePrefix
? `${item.ApexClass.NamespacePrefix}.${item.ApexClass.Name}`
: item.ApexClass.Name;
const diagnostic = item.Message || item.StackTrace ? (0, diagnosticUtil_1.getAsyncDiagnostic)(item) : null;
testResults.push({
id: item.Id,
queueItemId: item.QueueItemId,
stackTrace: item.StackTrace,
message: item.Message,
asyncApexJobId: item.AsyncApexJobId,
methodName: item.MethodName,
outcome: item.Outcome,
apexLogId: item.ApexLogId,
apexClass: {
id: item.ApexClass.Id,
name: item.ApexClass.Name,
namespacePrefix: item.ApexClass.NamespacePrefix,
fullName: item.ApexClass.FullName
},
runTime: item.RunTime ?? 0,
testTimestamp: item.TestTimestamp, // TODO: convert timestamp
fullName: `${item.ApexClass.FullName}.${item.MethodName}`,
...(diagnostic ? { diagnostic } : {})
utils_1.HeapMonitor.getInstance().checkHeapSize('asyncTests.buildAsyncTestResults');
try {
const apexTestClassIdSet = new Set();
let passed = 0;
let failed = 0;
let skipped = 0;
// Iterate over test results, format and add them as results.tests
const testResults = [];
for (const result of apexTestResults) {
result.records.forEach((item) => {
switch (item.Outcome) {
case "Pass" /* ApexTestResultOutcome.Pass */:
passed++;
break;
case "Fail" /* ApexTestResultOutcome.Fail */:
case "CompileFail" /* ApexTestResultOutcome.CompileFail */:
failed++;
break;
case "Skip" /* ApexTestResultOutcome.Skip */:
skipped++;
break;
}
apexTestClassIdSet.add(item.ApexClass.Id);
// Can only query the FullName field if a single record is returned, so manually build the field
item.ApexClass.FullName = item.ApexClass.NamespacePrefix
? `${item.ApexClass.NamespacePrefix}.${item.ApexClass.Name}`
: item.ApexClass.Name;
const diagnostic = item.Message || item.StackTrace ? (0, diagnosticUtil_1.getAsyncDiagnostic)(item) : null;
testResults.push({
id: item.Id,
queueItemId: item.QueueItemId,
stackTrace: item.StackTrace,
message: item.Message,
asyncApexJobId: item.AsyncApexJobId,
methodName: item.MethodName,
outcome: item.Outcome,
apexLogId: item.ApexLogId,
apexClass: {
id: item.ApexClass.Id,
name: item.ApexClass.Name,
namespacePrefix: item.ApexClass.NamespacePrefix,
fullName: item.ApexClass.FullName
},
runTime: item.RunTime ?? 0,
testTimestamp: item.TestTimestamp, // TODO: convert timestamp
fullName: `${item.ApexClass.FullName}.${item.MethodName}`,
...(diagnostic ? { diagnostic } : {})
});
});
});
}
return {
apexTestClassIdSet,
testResults,
globalTests: { passed, failed, skipped }
};
}
return {
apexTestClassIdSet,
testResults,
globalTests: { passed, failed, skipped }
};
finally {
utils_1.HeapMonitor.getInstance().checkHeapSize('asyncTests.buildAsyncTestResults');
}
}

@@ -320,2 +383,3 @@ /**

* @param testRunId
* @param progress
*/

@@ -342,3 +406,3 @@ async abortTestRun(testRunId, progress) {

getTestRunRequestAction(options) {
const requestTestRun = async () => {
return async () => {
const url = `${this.connection.tooling._baseUrl()}/runTestsAsynchronous`;

@@ -358,3 +422,2 @@ try {

};
return requestTestRun;
}

@@ -361,0 +424,0 @@ }

@@ -42,3 +42,3 @@ "use strict";

const constants_1 = require("./constants");
const elapsedTime_1 = require("../utils/elapsedTime");
const utils_2 = require("../utils");
class CodeCoverage {

@@ -54,7 +54,13 @@ connection;

async getOrgWideCoverage() {
const orgWideCoverageResult = (await this.connection.tooling.query('SELECT PercentCovered FROM ApexOrgWideCoverage'));
if (orgWideCoverageResult.records.length === 0) {
return '0%';
utils_2.HeapMonitor.getInstance().checkHeapSize('codeCoverage.getOrgWideCoverage');
try {
const orgWideCoverageResult = (await this.connection.tooling.query('SELECT PercentCovered FROM ApexOrgWideCoverage'));
if (orgWideCoverageResult.records.length === 0) {
return '0%';
}
return `${orgWideCoverageResult.records[0].PercentCovered}%`;
}
return `${orgWideCoverageResult.records[0].PercentCovered}%`;
finally {
utils_2.HeapMonitor.getInstance().checkHeapSize('codeCoverage.getOrgWideCoverage');
}
}

@@ -68,31 +74,37 @@ /**

async getPerClassCodeCoverage(apexTestClassSet) {
if (apexTestClassSet.size === 0) {
return new Map();
utils_2.HeapMonitor.getInstance().checkHeapSize('codeCoverage.getPerClassCodeCoverage');
try {
if (apexTestClassSet.size === 0) {
return new Map();
}
const perClassCodeCovResults = await this.queryPerClassCodeCov(apexTestClassSet);
const perClassCoverageMap = new Map();
perClassCodeCovResults.forEach((chunk) => {
chunk.records.forEach((item) => {
const totalLines = item.NumLinesCovered + item.NumLinesUncovered;
const percentage = (0, utils_1.calculatePercentage)(item.NumLinesCovered, totalLines);
const value = {
apexClassOrTriggerName: item.ApexClassOrTrigger.Name,
apexClassOrTriggerId: item.ApexClassOrTrigger.Id,
apexTestClassId: item.ApexTestClassId,
apexTestMethodName: item.TestMethodName,
numLinesCovered: item.NumLinesCovered,
numLinesUncovered: item.NumLinesUncovered,
percentage,
...(item.Coverage ? { coverage: item.Coverage } : {})
};
const key = `${item.ApexTestClassId}-${item.TestMethodName}`;
if (perClassCoverageMap.get(key)) {
perClassCoverageMap.get(key).push(value);
}
else {
perClassCoverageMap.set(`${item.ApexTestClassId}-${item.TestMethodName}`, [value]);
}
});
});
return perClassCoverageMap;
}
const perClassCodeCovResults = await this.queryPerClassCodeCov(apexTestClassSet);
const perClassCoverageMap = new Map();
perClassCodeCovResults.forEach((chunk) => {
chunk.records.forEach((item) => {
const totalLines = item.NumLinesCovered + item.NumLinesUncovered;
const percentage = (0, utils_1.calculatePercentage)(item.NumLinesCovered, totalLines);
const value = {
apexClassOrTriggerName: item.ApexClassOrTrigger.Name,
apexClassOrTriggerId: item.ApexClassOrTrigger.Id,
apexTestClassId: item.ApexTestClassId,
apexTestMethodName: item.TestMethodName,
numLinesCovered: item.NumLinesCovered,
numLinesUncovered: item.NumLinesUncovered,
percentage,
...(item.Coverage ? { coverage: item.Coverage } : {})
};
const key = `${item.ApexTestClassId}-${item.TestMethodName}`;
if (perClassCoverageMap.get(key)) {
perClassCoverageMap.get(key).push(value);
}
else {
perClassCoverageMap.set(`${item.ApexTestClassId}-${item.TestMethodName}`, [value]);
}
});
});
return perClassCoverageMap;
finally {
utils_2.HeapMonitor.getInstance().checkHeapSize('codeCoverage.getPerClassCodeCoverage');
}
}

@@ -105,32 +117,38 @@ /**

async getAggregateCodeCoverage(apexClassIdSet) {
const codeCoverageAggregates = await this.queryAggregateCodeCov(apexClassIdSet);
let totalLinesCovered = 0;
let totalLinesUncovered = 0;
const totalCodeCoverageResults = [];
codeCoverageAggregates.forEach((chunk) => {
const codeCoverageResults = chunk.records.map((item) => {
totalLinesCovered += item.NumLinesCovered;
totalLinesUncovered += item.NumLinesUncovered;
const totalLines = item.NumLinesCovered + item.NumLinesUncovered;
const percentage = (0, utils_1.calculatePercentage)(item.NumLinesCovered, totalLines);
return {
apexId: item.ApexClassOrTrigger.Id,
name: item.ApexClassOrTrigger.Name,
type: item.ApexClassOrTrigger.Id.startsWith('01p')
? 'ApexClass'
: 'ApexTrigger',
numLinesCovered: item.NumLinesCovered,
numLinesUncovered: item.NumLinesUncovered,
percentage,
coveredLines: item.Coverage.coveredLines,
uncoveredLines: item.Coverage.uncoveredLines
};
utils_2.HeapMonitor.getInstance().checkHeapSize('codeCoverage.getAggregateCodeCoverage');
try {
const codeCoverageAggregates = await this.queryAggregateCodeCov(apexClassIdSet);
let totalLinesCovered = 0;
let totalLinesUncovered = 0;
const totalCodeCoverageResults = [];
codeCoverageAggregates.forEach((chunk) => {
const codeCoverageResults = chunk.records.map((item) => {
totalLinesCovered += item.NumLinesCovered;
totalLinesUncovered += item.NumLinesUncovered;
const totalLines = item.NumLinesCovered + item.NumLinesUncovered;
const percentage = (0, utils_1.calculatePercentage)(item.NumLinesCovered, totalLines);
return {
apexId: item.ApexClassOrTrigger.Id,
name: item.ApexClassOrTrigger.Name,
type: item.ApexClassOrTrigger.Id.startsWith('01p')
? 'ApexClass'
: 'ApexTrigger',
numLinesCovered: item.NumLinesCovered,
numLinesUncovered: item.NumLinesUncovered,
percentage,
coveredLines: item.Coverage.coveredLines,
uncoveredLines: item.Coverage.uncoveredLines
};
});
totalCodeCoverageResults.push(...codeCoverageResults);
});
totalCodeCoverageResults.push(...codeCoverageResults);
});
return {
codeCoverageResults: totalCodeCoverageResults,
totalLines: totalLinesCovered + totalLinesUncovered,
coveredLines: totalLinesCovered
};
return {
codeCoverageResults: totalCodeCoverageResults,
totalLines: totalLinesCovered + totalLinesUncovered,
coveredLines: totalLinesCovered
};
}
finally {
utils_2.HeapMonitor.getInstance().checkHeapSize('codeCoverage.getAggregateCodeCoverage');
}
}

@@ -187,19 +205,19 @@ async queryPerClassCodeCov(apexTestClassSet) {

__decorate([
(0, elapsedTime_1.elapsedTime)()
(0, utils_2.elapsedTime)()
], CodeCoverage.prototype, "getOrgWideCoverage", null);
__decorate([
(0, elapsedTime_1.elapsedTime)()
(0, utils_2.elapsedTime)()
], CodeCoverage.prototype, "getPerClassCodeCoverage", null);
__decorate([
(0, elapsedTime_1.elapsedTime)()
(0, utils_2.elapsedTime)()
], CodeCoverage.prototype, "getAggregateCodeCoverage", null);
__decorate([
(0, elapsedTime_1.elapsedTime)()
(0, utils_2.elapsedTime)()
], CodeCoverage.prototype, "queryPerClassCodeCov", null);
__decorate([
(0, elapsedTime_1.elapsedTime)()
(0, utils_2.elapsedTime)()
], CodeCoverage.prototype, "queryAggregateCodeCov", null);
__decorate([
(0, elapsedTime_1.elapsedTime)()
(0, utils_2.elapsedTime)()
], CodeCoverage.prototype, "fetchResults", null);
//# sourceMappingURL=codeCoverage.js.map

@@ -20,3 +20,2 @@ "use strict";

const utils_2 = require("./utils");
const elapsedTime_1 = require("../utils/elapsedTime");
class SyncTests {

@@ -36,2 +35,3 @@ connection;

async runTests(options, codeCoverage = false, token) {
utils_1.HeapMonitor.getInstance().checkHeapSize('synctests.runTests');
try {

@@ -54,106 +54,121 @@ const url = `${this.connection.tooling._baseUrl()}/runTestsSynchronous`;

}
finally {
utils_1.HeapMonitor.getInstance().checkHeapSize('synctests.runTests');
}
}
async formatSyncResults(apiTestResult, startTime, codeCoverage = false) {
utils_1.HeapMonitor.getInstance().checkHeapSize('synctests.formatSyncResults');
const coveredApexClassIdSet = new Set();
const { apexTestClassIdSet, testResults } = this.buildSyncTestResults(apiTestResult);
const globalTestFailed = apiTestResult.failures.length;
const globalTestPassed = apiTestResult.successes.length;
const result = {
summary: {
outcome: globalTestFailed === 0
? "Passed" /* ApexTestRunResultStatus.Passed */
: "Failed" /* ApexTestRunResultStatus.Failed */,
testsRan: apiTestResult.numTestsRun,
passing: globalTestPassed,
failing: globalTestFailed,
skipped: 0,
passRate: (0, utils_2.calculatePercentage)(globalTestPassed, apiTestResult.numTestsRun),
failRate: (0, utils_2.calculatePercentage)(globalTestFailed, apiTestResult.numTestsRun),
skipRate: (0, utils_2.calculatePercentage)(0, apiTestResult.numTestsRun),
testStartTime: (0, utils_1.formatStartTime)(startTime, 'ISO'),
testExecutionTimeInMs: apiTestResult.totalTime ?? 0,
testTotalTimeInMs: apiTestResult.totalTime ?? 0,
commandTimeInMs: (0, utils_1.getCurrentTime)() - startTime,
hostname: this.connection.instanceUrl,
orgId: this.connection.getAuthInfoFields().orgId,
username: this.connection.getUsername(),
testRunId: '',
userId: this.connection.getConnectionOptions().userId
},
tests: testResults
};
if (codeCoverage) {
const perClassCovMap = await this.codecoverage.getPerClassCodeCoverage(apexTestClassIdSet);
if (perClassCovMap.size > 0) {
result.tests.forEach((item) => {
const keyCodeCov = `${item.apexClass.id}-${item.methodName}`;
const perClassCov = perClassCovMap.get(keyCodeCov);
if (perClassCov) {
perClassCov.forEach((classCov) => coveredApexClassIdSet.add(classCov.apexClassOrTriggerId));
item.perClassCoverage = perClassCov;
}
});
try {
const globalTestFailed = apiTestResult.failures.length;
const globalTestPassed = apiTestResult.successes.length;
const result = {
summary: {
outcome: globalTestFailed === 0
? "Passed" /* ApexTestRunResultStatus.Passed */
: "Failed" /* ApexTestRunResultStatus.Failed */,
testsRan: apiTestResult.numTestsRun,
passing: globalTestPassed,
failing: globalTestFailed,
skipped: 0,
passRate: (0, utils_2.calculatePercentage)(globalTestPassed, apiTestResult.numTestsRun),
failRate: (0, utils_2.calculatePercentage)(globalTestFailed, apiTestResult.numTestsRun),
skipRate: (0, utils_2.calculatePercentage)(0, apiTestResult.numTestsRun),
testStartTime: (0, utils_1.formatStartTime)(startTime, 'ISO'),
testExecutionTimeInMs: apiTestResult.totalTime ?? 0,
testTotalTimeInMs: apiTestResult.totalTime ?? 0,
commandTimeInMs: (0, utils_1.getCurrentTime)() - startTime,
hostname: this.connection.instanceUrl,
orgId: this.connection.getAuthInfoFields().orgId,
username: this.connection.getUsername(),
testRunId: '',
userId: this.connection.getConnectionOptions().userId
},
tests: testResults
};
if (codeCoverage) {
const perClassCovMap = await this.codecoverage.getPerClassCodeCoverage(apexTestClassIdSet);
if (perClassCovMap.size > 0) {
result.tests.forEach((item) => {
const keyCodeCov = `${item.apexClass.id}-${item.methodName}`;
const perClassCov = perClassCovMap.get(keyCodeCov);
if (perClassCov) {
perClassCov.forEach((classCov) => coveredApexClassIdSet.add(classCov.apexClassOrTriggerId));
item.perClassCoverage = perClassCov;
}
});
}
const { codeCoverageResults, totalLines, coveredLines } = await this.codecoverage.getAggregateCodeCoverage(coveredApexClassIdSet);
result.codecoverage = codeCoverageResults;
result.summary.totalLines = totalLines;
result.summary.coveredLines = coveredLines;
result.summary.testRunCoverage = (0, utils_2.calculatePercentage)(coveredLines, totalLines);
result.summary.orgWideCoverage =
await this.codecoverage.getOrgWideCoverage();
}
const { codeCoverageResults, totalLines, coveredLines } = await this.codecoverage.getAggregateCodeCoverage(coveredApexClassIdSet);
result.codecoverage = codeCoverageResults;
result.summary.totalLines = totalLines;
result.summary.coveredLines = coveredLines;
result.summary.testRunCoverage = (0, utils_2.calculatePercentage)(coveredLines, totalLines);
result.summary.orgWideCoverage =
await this.codecoverage.getOrgWideCoverage();
return result;
}
return result;
finally {
utils_1.HeapMonitor.getInstance().checkHeapSize('synctests.formatSyncResults');
}
}
buildSyncTestResults(apiTestResult) {
const testResults = [];
const apexTestClassIdSet = new Set();
apiTestResult.successes.forEach((item) => {
const nms = item.namespace ? `${item.namespace}.` : '';
apexTestClassIdSet.add(item.id);
testResults.push({
id: '',
queueItemId: '',
stackTrace: '',
message: '',
asyncApexJobId: '',
methodName: item.methodName,
outcome: "Pass" /* ApexTestResultOutcome.Pass */,
apexLogId: apiTestResult.apexLogId,
apexClass: {
id: item.id,
name: item.name,
namespacePrefix: item.namespace,
fullName: `${nms}${item.name}`
},
runTime: item.time ?? 0,
testTimestamp: '',
fullName: `${nms}${item.name}.${item.methodName}`
utils_1.HeapMonitor.getInstance().checkHeapSize('syncTests.buildSyncTestResults');
try {
const testResults = [];
const apexTestClassIdSet = new Set();
apiTestResult.successes.forEach((item) => {
const nms = item.namespace ? `${item.namespace}.` : '';
apexTestClassIdSet.add(item.id);
testResults.push({
id: '',
queueItemId: '',
stackTrace: '',
message: '',
asyncApexJobId: '',
methodName: item.methodName,
outcome: "Pass" /* ApexTestResultOutcome.Pass */,
apexLogId: apiTestResult.apexLogId,
apexClass: {
id: item.id,
name: item.name,
namespacePrefix: item.namespace,
fullName: `${nms}${item.name}`
},
runTime: item.time ?? 0,
testTimestamp: '',
fullName: `${nms}${item.name}.${item.methodName}`
});
});
});
apiTestResult.failures.forEach((item) => {
const nms = item.namespace ? `${item.namespace}__` : '';
apexTestClassIdSet.add(item.id);
const diagnostic = item.message || item.stackTrace ? (0, diagnosticUtil_1.getSyncDiagnostic)(item) : null;
testResults.push({
id: '',
queueItemId: '',
stackTrace: item.stackTrace,
message: item.message,
asyncApexJobId: '',
methodName: item.methodName,
outcome: "Fail" /* ApexTestResultOutcome.Fail */,
apexLogId: apiTestResult.apexLogId,
apexClass: {
id: item.id,
name: item.name,
namespacePrefix: item.namespace,
fullName: `${nms}${item.name}`
},
runTime: item.time ?? 0,
testTimestamp: '',
fullName: `${nms}${item.name}.${item.methodName}`,
...(diagnostic ? { diagnostic } : {})
apiTestResult.failures.forEach((item) => {
const nms = item.namespace ? `${item.namespace}__` : '';
apexTestClassIdSet.add(item.id);
const diagnostic = item.message || item.stackTrace ? (0, diagnosticUtil_1.getSyncDiagnostic)(item) : null;
testResults.push({
id: '',
queueItemId: '',
stackTrace: item.stackTrace,
message: item.message,
asyncApexJobId: '',
methodName: item.methodName,
outcome: "Fail" /* ApexTestResultOutcome.Fail */,
apexLogId: apiTestResult.apexLogId,
apexClass: {
id: item.id,
name: item.name,
namespacePrefix: item.namespace,
fullName: `${nms}${item.name}`
},
runTime: item.time ?? 0,
testTimestamp: '',
fullName: `${nms}${item.name}.${item.methodName}`,
...(diagnostic ? { diagnostic } : {})
});
});
});
return { apexTestClassIdSet, testResults };
return { apexTestClassIdSet, testResults };
}
finally {
utils_1.HeapMonitor.getInstance().checkHeapSize('syncTests.buildSyncTestResults');
}
}

@@ -163,10 +178,10 @@ }

__decorate([
(0, elapsedTime_1.elapsedTime)()
(0, utils_1.elapsedTime)()
], SyncTests.prototype, "runTests", null);
__decorate([
(0, elapsedTime_1.elapsedTime)()
(0, utils_1.elapsedTime)()
], SyncTests.prototype, "formatSyncResults", null);
__decorate([
(0, elapsedTime_1.elapsedTime)()
(0, utils_1.elapsedTime)()
], SyncTests.prototype, "buildSyncTestResults", null);
//# sourceMappingURL=syncTests.js.map

@@ -0,1 +1,2 @@

/// <reference types="node" />
import { Connection } from '@salesforce/core';

@@ -5,2 +6,3 @@ import { ApexTestProgressValue, AsyncTestArrayConfiguration, AsyncTestConfiguration, OutputDirConfig, SyncTestConfiguration, TestLevel, TestResult, TestRunIdResult, TestSuiteMembershipRecord } from './types';

import { AsyncTests } from './asyncTests';
import { Writable } from 'node:stream';
import { Duration } from '@salesforce/kit';

@@ -60,2 +62,3 @@ export declare class TestService {

* @param token cancellation token
* @param timeout
*/

@@ -82,2 +85,4 @@ runTestAsynchronous(options: AsyncTestConfiguration | AsyncTestArrayConfiguration, codeCoverage?: boolean, immediatelyReturn?: boolean, progress?: Progress<ApexTestProgressValue>, token?: CancellationToken, timeout?: Duration): Promise<TestResult | TestRunIdResult>;

private buildTestPayload;
private runPipeline;
createStream(filePath: string): Writable;
}

@@ -19,9 +19,10 @@ "use strict";

const promises_1 = require("node:fs/promises");
const node_fs_1 = require("node:fs");
const node_stream_1 = require("node:stream");
const promises_2 = require("node:stream/promises");
const streaming_1 = require("../streaming");
const codeCoverageStringifyStream_1 = require("../streaming/codeCoverageStringifyStream");
const utils_2 = require("../utils");
const narrowing_1 = require("../narrowing");
const promises_2 = require("node:stream/promises");
const node_fs_1 = require("node:fs");
// eslint-disable-next-line @typescript-eslint/no-var-requires
const bfj = require('bfj');
class TestService {

@@ -134,3 +135,9 @@ connection;

async runTestSynchronous(options, codeCoverage = false, token) {
return await this.syncService.runTests(options, codeCoverage, token);
utils_2.HeapMonitor.getInstance().startMonitoring();
try {
return await this.syncService.runTests(options, codeCoverage, token);
}
finally {
utils_2.HeapMonitor.getInstance().stopMonitoring();
}
}

@@ -144,5 +151,12 @@ /**

* @param token cancellation token
* @param timeout
*/
async runTestAsynchronous(options, codeCoverage = false, immediatelyReturn = false, progress, token, timeout) {
return await this.asyncService.runTests(options, codeCoverage, immediatelyReturn, progress, token, timeout);
utils_2.HeapMonitor.getInstance().startMonitoring();
try {
return await this.asyncService.runTests(options, codeCoverage, immediatelyReturn, progress, token, timeout);
}
finally {
utils_2.HeapMonitor.getInstance().stopMonitoring();
}
}

@@ -156,3 +170,9 @@ /**

async reportAsyncResults(testRunId, codeCoverage = false, token) {
return await this.asyncService.reportAsyncResults(testRunId, codeCoverage, token);
utils_2.HeapMonitor.getInstance().startMonitoring();
try {
return await this.asyncService.reportAsyncResults(testRunId, codeCoverage, token);
}
finally {
utils_2.HeapMonitor.getInstance().stopMonitoring();
}
}

@@ -167,97 +187,87 @@ /**

async writeResultFiles(result, outputDirConfig, codeCoverage = false) {
const filesWritten = [];
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { dirPath, resultFormats, fileInfos } = outputDirConfig;
// ensure supplied result formats are support here
if (resultFormats &&
!resultFormats.every((format) => format in types_1.ResultFormat)) {
throw new Error(i18n_1.nls.localize('resultFormatErr'));
}
const testRunId = (0, narrowing_1.isTestResult)(result)
? result.summary.testRunId
: result.testRunId;
const pipeThese = [];
await (0, promises_1.mkdir)(dirPath, { recursive: true });
pipeThese.push([
node_stream_1.Readable.from([testRunId]),
(0, node_fs_1.createWriteStream)((0, path_1.join)(dirPath, 'test-run-id.txt'), 'utf8')
]);
filesWritten.push((0, path_1.join)(dirPath, 'test-run-id.txt'));
// produce result formats
if (resultFormats) {
if (!(0, narrowing_1.isTestResult)(result)) {
throw new Error(i18n_1.nls.localize('runIdFormatErr'));
utils_2.HeapMonitor.getInstance().startMonitoring();
utils_2.HeapMonitor.getInstance().checkHeapSize('testService.writeResultFiles');
try {
const filesWritten = [];
const { dirPath, resultFormats, fileInfos } = outputDirConfig;
if (resultFormats &&
!resultFormats.every((format) => format in types_1.ResultFormat)) {
throw new Error(i18n_1.nls.localize('resultFormatErr'));
}
for (const format of resultFormats) {
switch (format) {
case types_1.ResultFormat.json:
// Create a readable stream from the JSON object
const jsonFilePath = (0, path_1.join)(dirPath, testRunId ? `test-result-${testRunId}.json` : `test-result.json`);
filesWritten.push(jsonFilePath);
pipeThese.push([
streaming_1.TestResultStringifyStream.fromTestResult(result),
(0, node_fs_1.createWriteStream)(jsonFilePath)
]);
break;
case types_1.ResultFormat.tap:
const tapFilePath = (0, path_1.join)(dirPath, `test-result-${testRunId}-tap.txt`);
filesWritten.push(tapFilePath);
pipeThese.push([
new reporters_1.TapFormatTransformer(result),
(0, node_fs_1.createWriteStream)(tapFilePath)
]);
break;
case types_1.ResultFormat.junit:
const filePath = (0, path_1.join)(dirPath, testRunId
? `test-result-${testRunId}-junit.xml`
: `test-result-junit.xml`);
filesWritten.push(filePath);
pipeThese.push([
new reporters_1.JUnitFormatTransformer(result),
(0, node_fs_1.createWriteStream)(filePath)
]);
break;
await (0, promises_1.mkdir)(dirPath, { recursive: true });
const testRunId = (0, narrowing_1.isTestResult)(result)
? result.summary.testRunId
: result.testRunId;
try {
await (0, promises_1.writeFile)((0, path_1.join)(dirPath, 'test-run-id.txt'), testRunId);
filesWritten.push((0, path_1.join)(dirPath, 'test-run-id.txt'));
}
catch (err) {
console.error(`Error writing file: ${err}`);
}
if (resultFormats) {
if (!(0, narrowing_1.isTestResult)(result)) {
throw new Error(i18n_1.nls.localize('runIdFormatErr'));
}
for (const format of resultFormats) {
let filePath;
let readable;
switch (format) {
case types_1.ResultFormat.json:
filePath = (0, path_1.join)(dirPath, `test-result-${testRunId || 'default'}.json`);
readable = streaming_1.TestResultStringifyStream.fromTestResult(result, {
bufferSize: (0, utils_1.getBufferSize)()
});
break;
case types_1.ResultFormat.tap:
filePath = (0, path_1.join)(dirPath, `test-result-${testRunId}-tap.txt`);
readable = new reporters_1.TapFormatTransformer(result, undefined, {
bufferSize: (0, utils_1.getBufferSize)()
});
break;
case types_1.ResultFormat.junit:
filePath = (0, path_1.join)(dirPath, `test-result-${testRunId || 'default'}-junit.xml`);
readable = new reporters_1.JUnitFormatTransformer(result, {
bufferSize: (0, utils_1.getBufferSize)()
});
break;
}
if (filePath && readable) {
filesWritten.push(await this.runPipeline(readable, filePath));
}
}
}
}
// produce code coverage
if (codeCoverage) {
if (!(0, narrowing_1.isTestResult)(result)) {
throw new Error(i18n_1.nls.localize('covIdFormatErr'));
if (codeCoverage) {
if (!(0, narrowing_1.isTestResult)(result)) {
throw new Error(i18n_1.nls.localize('covIdFormatErr'));
}
const filePath = (0, path_1.join)(dirPath, `test-result-${testRunId}-codecoverage.json`);
const c = result.tests
.map((record) => record.perClassCoverage)
.filter((pcc) => pcc?.length);
filesWritten.push(await this.runPipeline(bfj.stringify(c, {
bufferLength: (0, utils_1.getBufferSize)(),
iterables: 'ignore',
space: (0, utils_1.getJsonIndent)()
}), filePath));
}
const filePath = (0, path_1.join)(dirPath, `test-result-${testRunId}-codecoverage.json`);
const c = result.tests
.map((record) => {
return record.perClassCoverage;
})
.filter((pcc) => pcc?.length);
pipeThese.push([
node_stream_1.Readable.from(c),
new codeCoverageStringifyStream_1.CodeCoverageStringifyStream(),
(0, node_fs_1.createWriteStream)(filePath)
]);
filesWritten.push(filePath);
if (fileInfos) {
for (const fileInfo of fileInfos) {
const filePath = (0, path_1.join)(dirPath, fileInfo.filename);
const readable = typeof fileInfo.content === 'string'
? node_stream_1.Readable.from([fileInfo.content])
: bfj.stringify(fileInfo.content, {
bufferLength: (0, utils_1.getBufferSize)(),
iterables: 'ignore',
space: (0, utils_1.getJsonIndent)()
});
filesWritten.push(await this.runPipeline(readable, filePath));
}
}
return filesWritten;
}
fileInfos?.forEach((fileInfo) => {
const fileInfoPath = (0, path_1.join)(dirPath, fileInfo.filename);
if (typeof fileInfo.content === 'string') {
pipeThese.push([
node_stream_1.Readable.from([fileInfo.content]),
(0, node_fs_1.createWriteStream)(fileInfoPath)
]);
}
else {
pipeThese.push([
streaming_1.JSONStringifyStream.from(fileInfo.content),
(0, node_fs_1.createWriteStream)(fileInfoPath)
]);
}
filesWritten.push(fileInfoPath);
});
await Promise.all(pipeThese.map((streams) => (0, promises_2.pipeline)(streams))).catch((err) => {
const error = new Error('An error occurred writing files');
error.stack = err.stack;
throw error;
});
return filesWritten;
finally {
utils_2.HeapMonitor.getInstance().checkHeapSize('testService.writeResultFiles');
utils_2.HeapMonitor.getInstance().stopMonitoring();
}
}

@@ -397,2 +407,15 @@ // utils to build test run payloads that may contain namespaces

}
async runPipeline(readable, filePath, transform) {
const writable = this.createStream(filePath);
if (transform) {
await (0, promises_2.pipeline)(readable, transform, writable);
}
else {
await (0, promises_2.pipeline)(readable, writable);
}
return filePath;
}
createStream(filePath) {
return (0, node_fs_1.createWriteStream)(filePath, 'utf8');
}
}

@@ -399,0 +422,0 @@ exports.TestService = TestService;

@@ -8,1 +8,4 @@ import { Connection } from '@salesforce/core';

export declare const queryAll: <R>(connection: Connection, query: string, tooling?: boolean) => Promise<QueryResult<R>>;
export declare const getJsonIndent: () => number | undefined;
export declare const getBufferSize: () => number;
export declare const resetLimitsForTesting: () => void;

@@ -9,3 +9,12 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.queryAll = exports.queryNamespaces = exports.stringify = exports.calculatePercentage = void 0;
exports.resetLimitsForTesting = exports.getBufferSize = exports.getJsonIndent = exports.queryAll = exports.queryNamespaces = exports.stringify = exports.calculatePercentage = void 0;
const core_1 = require("@salesforce/core");
const DEFAULT_BUFFER_SIZE = 256;
const MIN_BUFFER_SIZE = 256;
const MAX_BUFFER_SIZE = 32_768;
const DEFAULT_JSON_INDENT = undefined;
const MIN_JSON_INDENT = 0;
const MAX_JSON_INDENT = 8;
let jsonIndent = null;
let bufferSize = null;
function calculatePercentage(dividend, divisor) {

@@ -55,2 +64,45 @@ let percentage = '0%';

exports.queryAll = queryAll;
const getJsonIndent = () => {
if (jsonIndent !== null) {
return jsonIndent;
}
let jsonIndentNum = DEFAULT_JSON_INDENT;
const envJsonIndent = process.env.SF_APEX_RESULTS_JSON_INDENT;
if (envJsonIndent && Number.isInteger(Number(envJsonIndent))) {
jsonIndentNum = Number(envJsonIndent);
}
if (jsonIndentNum < MIN_JSON_INDENT || jsonIndentNum > MAX_JSON_INDENT) {
const logger = core_1.Logger.childFromRoot('utils');
logger.warn(`Json indent ${jsonIndentNum} is outside of the valid range (${MIN_JSON_INDENT}-${MAX_JSON_INDENT}). Using default json indent of ${DEFAULT_JSON_INDENT}.`);
jsonIndentNum = DEFAULT_JSON_INDENT;
}
jsonIndent = jsonIndentNum;
return jsonIndent;
};
exports.getJsonIndent = getJsonIndent;
const getBufferSize = () => {
if (bufferSize !== null) {
return bufferSize;
}
let bufferSizeNum = DEFAULT_BUFFER_SIZE;
const jsonBufferSize = process.env.SF_APEX_JSON_BUFFER_SIZE;
if (jsonBufferSize && Number.isInteger(Number(jsonBufferSize))) {
bufferSizeNum = Number(jsonBufferSize);
}
if (bufferSizeNum < MIN_BUFFER_SIZE || bufferSizeNum > MAX_BUFFER_SIZE) {
const logger = core_1.Logger.childFromRoot('utils');
logger.warn(`Buffer size ${bufferSizeNum} is outside of the valid range (${MIN_BUFFER_SIZE}-${MAX_BUFFER_SIZE}). Using default buffer size of ${DEFAULT_BUFFER_SIZE}.`);
bufferSizeNum = DEFAULT_BUFFER_SIZE;
}
bufferSize = bufferSizeNum;
JSON.stringify(bufferSize);
return bufferSize;
};
exports.getBufferSize = getBufferSize;
// exported for testing
const resetLimitsForTesting = () => {
bufferSize = null;
jsonIndent = null;
};
exports.resetLimitsForTesting = resetLimitsForTesting;
//# sourceMappingURL=utils.js.map

@@ -7,1 +7,2 @@ export { createFile } from './fileSystemHandler';

export { elapsedTime } from './elapsedTime';
export { HeapMonitor } from './heapMonitor';

@@ -9,3 +9,3 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.elapsedTime = exports.refreshAuth = exports.msToSecond = exports.formatStartTime = exports.getCurrentTime = exports.Table = exports.createFile = void 0;
exports.HeapMonitor = exports.elapsedTime = exports.refreshAuth = exports.msToSecond = exports.formatStartTime = exports.getCurrentTime = exports.Table = exports.createFile = void 0;
var fileSystemHandler_1 = require("./fileSystemHandler");

@@ -23,2 +23,4 @@ Object.defineProperty(exports, "createFile", { enumerable: true, get: function () { return fileSystemHandler_1.createFile; } });

Object.defineProperty(exports, "elapsedTime", { enumerable: true, get: function () { return elapsedTime_1.elapsedTime; } });
var heapMonitor_1 = require("./heapMonitor");
Object.defineProperty(exports, "HeapMonitor", { enumerable: true, get: function () { return heapMonitor_1.HeapMonitor; } });
//# sourceMappingURL=index.js.map
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {

@@ -8,2 +24,9 @@ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;

};
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });

@@ -13,2 +36,3 @@ exports.TableWriteableStream = void 0;

const core_1 = require("@salesforce/core");
const os = __importStar(require("node:os"));
const COLUMN_SEPARATOR = ' ';

@@ -42,3 +66,3 @@ const COLUMN_FILLER = ' ';

if (columnHeader && headerSeparator) {
this.stream.push(`${title ? `=== ${title}\n` : ''}${columnHeader}\n${headerSeparator}\n`);
this.stream.push(`${title ? `=== ${title}${os.EOL}` : ''}${columnHeader}${os.EOL}${headerSeparator}${os.EOL}`);
}

@@ -51,3 +75,3 @@ rows.forEach((row) => {

const rowWidth = outputRow.length;
cell.split('\n').forEach((line, lineIndex) => {
cell.split(os.EOL).forEach((line, lineIndex) => {
const cellWidth = maxColWidths.get(col.key);

@@ -60,3 +84,3 @@ if (cellWidth) {

outputRow +=
'\n' +
os.EOL +
this.fillColumn('', rowWidth, COLUMN_FILLER, true) +

@@ -68,3 +92,7 @@ this.fillColumn(line, cellWidth, COLUMN_FILLER, isLastCol);

});
this.stream.push(outputRow + '\n');
this.stream.push(outputRow + os.EOL);
// 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(() => { });
});

@@ -87,3 +115,3 @@ }

const longestLineWidth = cell
.split('\n')
.split(os.EOL)
.reduce((maxLine, line) => line.length > maxLine.length ? line : maxLine).length;

@@ -90,0 +118,0 @@ if (longestLineWidth > maxColWidth) {

{
"name": "@salesforce/apex-node",
"description": "Salesforce JS library for Apex",
"version": "6.0.1",
"version": "6.1.0",
"author": "Salesforce",

@@ -10,10 +10,11 @@ "bugs": "https://github.com/forcedotcom/salesforcedx-apex/issues",

"@jsforce/jsforce-node": "^3.2.0",
"@salesforce/core": "^7.3.9",
"@salesforce/core": "^7.3.10",
"@salesforce/kit": "^3.1.2",
"@types/istanbul-reports": "^3.0.4",
"bfj": "^8.0.0",
"faye": "1.4.0",
"glob": "^10.3.10",
"glob": "^10.3.16",
"istanbul-lib-coverage": "^3.2.2",
"istanbul-lib-report": "^3.0.1",
"istanbul-reports": "^3.1.6"
"istanbul-reports": "^3.1.7"
},

@@ -24,9 +25,9 @@ "devDependencies": {

"@salesforce/ts-types": "^2.0.9",
"@types/chai": "^4.3.10",
"@types/chai": "^4.3.16",
"@types/glob": "^8.1.0",
"@types/istanbul-lib-coverage": "^2.0.6",
"@types/istanbul-lib-report": "^3.0.3",
"@types/mocha": "^10.0.4",
"@types/mocha": "^10.0.6",
"@types/node": "^18",
"@types/sinon": "^17.0.1",
"@types/sinon": "^17.0.3",
"@typescript-eslint/eslint-plugin": "^6.10.0",

@@ -41,14 +42,14 @@ "@typescript-eslint/parser": "^6.10.0",

"eslint-plugin-jsdoc": "^46.8.2",
"eslint-plugin-prettier": "^5.0.1",
"eslint-plugin-prettier": "^5.1.3",
"husky": "^8.0.0",
"lint-staged": "^15.0.2",
"mocha": "^10.2.0",
"lint-staged": "^15.2.4",
"mocha": "^10.4.0",
"mocha-junit-reporter": "^2.2.1",
"nyc": "^15.1.0",
"prettier": "^3.0.3",
"prettier": "^3.2.5",
"shx": "^0.3.4",
"sinon": "^17.0.1",
"source-map-support": "^0.5.16",
"ts-node": "^10.7.0",
"typescript": "^5.2.2"
"ts-node": "^10.9.2",
"typescript": "^5.4.5"
},

@@ -55,0 +56,0 @@ "homepage": "https://github.com/forcedotcom/salesforcedx-apex",

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc