189 行
7.1 KiB
JavaScript
189 行
7.1 KiB
JavaScript
|
|
"use strict";
|
||
|
|
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
|
||
|
|
// See LICENSE in the project root for license information.
|
||
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||
|
|
exports.StringBufferTerminalProvider = void 0;
|
||
|
|
const node_core_library_1 = require("@rushstack/node-core-library");
|
||
|
|
const ITerminalProvider_1 = require("./ITerminalProvider");
|
||
|
|
const AnsiEscape_1 = require("./AnsiEscape");
|
||
|
|
function _normalizeOptions(options) {
|
||
|
|
return {
|
||
|
|
normalizeSpecialCharacters: true,
|
||
|
|
...options
|
||
|
|
};
|
||
|
|
}
|
||
|
|
function _normalizeOutput(s, options) {
|
||
|
|
const { normalizeSpecialCharacters } = _normalizeOptions(options !== null && options !== void 0 ? options : {});
|
||
|
|
return _normalizeOutputInner(s, normalizeSpecialCharacters);
|
||
|
|
}
|
||
|
|
function _normalizeOutputInner(s, normalizeSpecialCharacters) {
|
||
|
|
s = node_core_library_1.Text.convertToLf(s);
|
||
|
|
if (normalizeSpecialCharacters) {
|
||
|
|
return AnsiEscape_1.AnsiEscape.formatForTests(s, { encodeNewlines: true });
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
return s;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
const LONGEST_SEVERITY_NAME_LENGTH = Object.keys(ITerminalProvider_1.TerminalProviderSeverity).reduce((max, k) => Math.max(max, k.length), 0);
|
||
|
|
/**
|
||
|
|
* Terminal provider that stores written data in buffers separated by severity.
|
||
|
|
* This terminal provider is designed to be used when code that prints to a terminal
|
||
|
|
* is being unit tested.
|
||
|
|
*
|
||
|
|
* @beta
|
||
|
|
*/
|
||
|
|
class StringBufferTerminalProvider {
|
||
|
|
constructor(supportsColor = false) {
|
||
|
|
this._standardBuffer = new node_core_library_1.StringBuilder();
|
||
|
|
this._verboseBuffer = new node_core_library_1.StringBuilder();
|
||
|
|
this._debugBuffer = new node_core_library_1.StringBuilder();
|
||
|
|
this._warningBuffer = new node_core_library_1.StringBuilder();
|
||
|
|
this._errorBuffer = new node_core_library_1.StringBuilder();
|
||
|
|
this._allOutputChunks = [];
|
||
|
|
this.supportsColor = supportsColor;
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* {@inheritDoc ITerminalProvider.write}
|
||
|
|
*/
|
||
|
|
write(text, severity) {
|
||
|
|
const severityName = ITerminalProvider_1.TerminalProviderSeverity[severity];
|
||
|
|
const lastChunk = this._allOutputChunks[this._allOutputChunks.length - 1];
|
||
|
|
if (lastChunk && lastChunk.severity === severityName) {
|
||
|
|
lastChunk.text += text;
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
this._allOutputChunks.push({
|
||
|
|
text,
|
||
|
|
severity: severityName
|
||
|
|
});
|
||
|
|
}
|
||
|
|
switch (severity) {
|
||
|
|
case ITerminalProvider_1.TerminalProviderSeverity.warning: {
|
||
|
|
this._warningBuffer.append(text);
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
case ITerminalProvider_1.TerminalProviderSeverity.error: {
|
||
|
|
this._errorBuffer.append(text);
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
case ITerminalProvider_1.TerminalProviderSeverity.verbose: {
|
||
|
|
this._verboseBuffer.append(text);
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
case ITerminalProvider_1.TerminalProviderSeverity.debug: {
|
||
|
|
this._debugBuffer.append(text);
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
case ITerminalProvider_1.TerminalProviderSeverity.log:
|
||
|
|
default: {
|
||
|
|
this._standardBuffer.append(text);
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* {@inheritDoc ITerminalProvider.eolCharacter}
|
||
|
|
*/
|
||
|
|
get eolCharacter() {
|
||
|
|
return '\n';
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Get everything that has been written at log-level severity.
|
||
|
|
*/
|
||
|
|
getOutput(options) {
|
||
|
|
return _normalizeOutput(this._standardBuffer.toString(), options);
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* @deprecated - use {@link StringBufferTerminalProvider.getVerboseOutput}
|
||
|
|
*/
|
||
|
|
getVerbose(options) {
|
||
|
|
return this.getVerboseOutput(options);
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Get everything that has been written at verbose-level severity.
|
||
|
|
*/
|
||
|
|
getVerboseOutput(options) {
|
||
|
|
return _normalizeOutput(this._verboseBuffer.toString(), options);
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Get everything that has been written at debug-level severity.
|
||
|
|
*/
|
||
|
|
getDebugOutput(options) {
|
||
|
|
return _normalizeOutput(this._debugBuffer.toString(), options);
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Get everything that has been written at error-level severity.
|
||
|
|
*/
|
||
|
|
getErrorOutput(options) {
|
||
|
|
return _normalizeOutput(this._errorBuffer.toString(), options);
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Get everything that has been written at warning-level severity.
|
||
|
|
*/
|
||
|
|
getWarningOutput(options) {
|
||
|
|
return _normalizeOutput(this._warningBuffer.toString(), options);
|
||
|
|
}
|
||
|
|
getAllOutput(sparse, options) {
|
||
|
|
const result = {};
|
||
|
|
const log = this.getOutput(options);
|
||
|
|
if (!sparse || log) {
|
||
|
|
result.log = log;
|
||
|
|
}
|
||
|
|
const warning = this.getWarningOutput(options);
|
||
|
|
if (!sparse || warning) {
|
||
|
|
result.warning = warning;
|
||
|
|
}
|
||
|
|
const error = this.getErrorOutput(options);
|
||
|
|
if (!sparse || error) {
|
||
|
|
result.error = error;
|
||
|
|
}
|
||
|
|
const verbose = this.getVerboseOutput(options);
|
||
|
|
if (!sparse || verbose) {
|
||
|
|
result.verbose = verbose;
|
||
|
|
}
|
||
|
|
const debug = this.getDebugOutput(options);
|
||
|
|
if (!sparse || debug) {
|
||
|
|
result.debug = debug;
|
||
|
|
}
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
getAllOutputAsChunks(options = {}) {
|
||
|
|
const { asLines, normalizeSpecialCharacters } = _normalizeOptions(options);
|
||
|
|
if (asLines) {
|
||
|
|
const lines = [];
|
||
|
|
for (const { text: rawText, severity: rawSeverity } of this._allOutputChunks) {
|
||
|
|
const severity = rawSeverity.padStart(LONGEST_SEVERITY_NAME_LENGTH, ' ');
|
||
|
|
const lfText = node_core_library_1.Text.convertToLf(rawText);
|
||
|
|
const rawLines = lfText.split('\n');
|
||
|
|
// Emit one entry per logical line.
|
||
|
|
for (let i = 0; i < rawLines.length; i++) {
|
||
|
|
const isLast = i === rawLines.length - 1;
|
||
|
|
const isFinalTrailingEmpty = isLast && rawLines[i] === '';
|
||
|
|
if (isFinalTrailingEmpty) {
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
const hasNewlineAfter = i < rawLines.length - 1;
|
||
|
|
// If the original output had a newline after this line, preserve it as the special token
|
||
|
|
// (e.g. "[n]") when normalization is enabled.
|
||
|
|
const shouldIncludeNewlineToken = normalizeSpecialCharacters && hasNewlineAfter;
|
||
|
|
const lineText = shouldIncludeNewlineToken ? `${rawLines[i]}\n` : rawLines[i];
|
||
|
|
const text = _normalizeOutputInner(lineText, normalizeSpecialCharacters);
|
||
|
|
lines.push(`[${severity}] ${text}`);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return lines;
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
return this._allOutputChunks.map(({ text: rawText, severity }) => {
|
||
|
|
const text = _normalizeOutputInner(rawText, normalizeSpecialCharacters);
|
||
|
|
return {
|
||
|
|
text,
|
||
|
|
severity
|
||
|
|
};
|
||
|
|
});
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
exports.StringBufferTerminalProvider = StringBufferTerminalProvider;
|
||
|
|
//# sourceMappingURL=StringBufferTerminalProvider.js.map
|