replace jest with ava

This commit is contained in:
Robert Brignull 2020-05-04 18:50:13 +01:00
parent 27cc8b23fe
commit 0347b72305
11775 changed files with 84546 additions and 1440575 deletions

73
node_modules/ava/lib/reporters/beautify-stack.js generated vendored Normal file
View file

@ -0,0 +1,73 @@
'use strict';
const StackUtils = require('stack-utils');
const stackUtils = new StackUtils({
ignoredPackages: [
'@ava/babel',
'@ava/require-precompiled',
'@ava/typescript',
'append-transform',
'ava',
'empower-core',
'esm',
'nyc'
],
internals: [
// AVA internals, which ignoredPackages don't ignore when we run our own unit tests.
/\/ava\/(?:lib\/|lib\/worker\/)?[\w-]+\.js:\d+:\d+\)?$/,
// Only ignore Node.js internals that really are not useful for debugging.
...StackUtils.nodeInternals().filter(regexp => !/\(internal/.test(regexp.source)),
/\(internal\/process\/task_queues\.js:\d+:\d+\)$/,
/\(internal\/modules\/cjs\/.+?\.js:\d+:\d+\)$/,
/async Promise\.all \(index/,
/new Promise \(<anonymous>\)/
]
});
/*
* Given a string value of the format generated for the `stack` property of a
* V8 error object, return a string that contains only stack frame information
* for frames that have relevance to the consumer.
*
* For example, given the following string value:
*
* ```
* Error
* at inner (/home/ava/ex.js:7:12)
* at /home/ava/ex.js:12:5
* at outer (/home/ava/ex.js:13:4)
* at Object.<anonymous> (/home/ava/ex.js:14:3)
* at Module._compile (module.js:570:32)
* at Object.Module._extensions..js (module.js:579:10)
* at Module.load (module.js:487:32)
* at tryModuleLoad (module.js:446:12)
* at Function.Module._load (module.js:438:3)
* at Module.runMain (module.js:604:10)
* ```
*
* ...this function returns the following string value:
*
* ```
* inner (/home/ava/ex.js:7:12)
* /home/ava/ex.js:12:5
* outer (/home/ava/ex.js:13:4)
* Object.<anonymous> (/home/ava/ex.js:14:3)
* Module._compile (module.js:570:32)
* Object.Module._extensions..js (module.js:579:10)
* Module.load (module.js:487:32)
* tryModuleLoad (module.js:446:12)
* Function.Module._load (module.js:438:3)
* Module.runMain (module.js:604:10)
* ```
*/
module.exports = stack => {
if (!stack) {
return [];
}
return stackUtils.clean(stack)
.trim()
.split('\n')
.map(line => line.trim())
.filter(line => line !== '');
};

17
node_modules/ava/lib/reporters/colors.js generated vendored Normal file
View file

@ -0,0 +1,17 @@
'use strict';
const chalk = require('../chalk').get();
module.exports = {
log: chalk.gray,
title: chalk.bold,
error: chalk.red,
skip: chalk.yellow,
todo: chalk.blue,
pass: chalk.green,
duration: chalk.gray.dim,
errorSource: chalk.gray,
errorStack: chalk.gray,
errorStackInternal: chalk.gray.dim,
stack: chalk.red,
information: chalk.magenta
};

View file

@ -0,0 +1,27 @@
'use strict';
const trimOffNewlines = require('trim-off-newlines');
const chalk = require('../chalk').get();
function formatSerializedError(error) {
const printMessage = error.values.length === 0 ?
Boolean(error.message) :
!error.values[0].label.startsWith(error.message);
if (error.statements.length === 0 && error.values.length === 0) {
return {formatted: null, printMessage};
}
let formatted = '';
for (const value of error.values) {
formatted += `${value.label}\n\n${trimOffNewlines(value.formatted)}\n\n`;
}
for (const statement of error.statements) {
formatted += `${statement[0]}\n${chalk.grey('=>')} ${trimOffNewlines(statement[1])}\n\n`;
}
formatted = trimOffNewlines(formatted);
return {formatted, printMessage};
}
module.exports = formatSerializedError;

View file

@ -0,0 +1,55 @@
'use strict';
const chalk = require('../chalk').get();
const pkg = require('../../package.json');
exports.forError = error => {
if (!error.improperUsage) {
return null;
}
const {assertion} = error;
if (assertion === 'throws' || assertion === 'notThrows') {
return `Try wrapping the first argument to \`t.${assertion}()\` in a function:
${chalk.cyan(`t.${assertion}(() => { `)}${chalk.grey('/* your code here */')}${chalk.cyan(' })')}
Visit the following URL for more details:
${chalk.blue.underline(`https://github.com/avajs/ava/blob/v${pkg.version}/docs/03-assertions.md#throwsfn-expected-message`)}`;
}
if (assertion === 'snapshot') {
const {name, snapPath} = error.improperUsage;
if (name === 'ChecksumError') {
return `The snapshot file is corrupted.
File path: ${chalk.yellow(snapPath)}
Please run AVA again with the ${chalk.cyan('--update-snapshots')} flag to recreate it.`;
}
if (name === 'LegacyError') {
return `The snapshot file was created with AVA 0.19. Its not supported by this AVA version.
File path: ${chalk.yellow(snapPath)}
Please run AVA again with the ${chalk.cyan('--update-snapshots')} flag to upgrade.`;
}
if (name === 'VersionMismatchError') {
const {snapVersion, expectedVersion} = error.improperUsage;
const upgradeMessage = snapVersion < expectedVersion ?
`Please run AVA again with the ${chalk.cyan('--update-snapshots')} flag to upgrade.` :
'You should upgrade AVA.';
return `The snapshot file is v${snapVersion}, but only v${expectedVersion} is supported.
File path: ${chalk.yellow(snapPath)}
${upgradeMessage}`;
}
}
return null;
};

619
node_modules/ava/lib/reporters/mini.js generated vendored Normal file
View file

@ -0,0 +1,619 @@
'use strict';
const os = require('os');
const path = require('path');
const stream = require('stream');
const cliCursor = require('cli-cursor');
const figures = require('figures');
const indentString = require('indent-string');
const ora = require('ora');
const plur = require('plur');
const trimOffNewlines = require('trim-off-newlines');
const beautifyStack = require('./beautify-stack');
const chalk = require('../chalk').get();
const codeExcerpt = require('../code-excerpt');
const colors = require('./colors');
const formatSerializedError = require('./format-serialized-error');
const improperUsageMessages = require('./improper-usage-messages');
const prefixTitle = require('./prefix-title');
const whileCorked = require('./while-corked');
const nodeInternals = require('stack-utils').nodeInternals();
class LineWriter extends stream.Writable {
constructor(dest, spinner) {
super();
this.dest = dest;
this.columns = dest.columns || 80;
this.spinner = spinner;
this.lastSpinnerText = '';
}
_write(chunk, encoding, callback) {
// Discard the current spinner output. Any lines that were meant to be
// preserved should be rewritten.
this.spinner.clear();
this._writeWithSpinner(chunk.toString('utf8'));
callback();
}
_writev(pieces, callback) {
// Discard the current spinner output. Any lines that were meant to be
// preserved should be rewritten.
this.spinner.clear();
const last = pieces.pop();
for (const piece of pieces) {
this.dest.write(piece.chunk);
}
this._writeWithSpinner(last.chunk.toString('utf8'));
callback();
}
_writeWithSpinner(string) {
if (!this.spinner.id) {
this.dest.write(string);
return;
}
this.lastSpinnerText = string;
// Ignore whitespace at the end of the chunk. We're continiously rewriting
// the last line through the spinner. Also be careful to remove the indent
// as the spinner adds its own.
this.spinner.text = string.trimEnd().slice(2);
this.spinner.render();
}
writeLine(string) {
if (string) {
this.write(indentString(string, 2) + os.EOL);
} else {
this.write(os.EOL);
}
}
}
class MiniReporter {
constructor(options) {
this.reportStream = options.reportStream;
this.stdStream = options.stdStream;
this.watching = options.watching;
this.spinner = ora({
isEnabled: true,
color: options.spinner ? options.spinner.color : 'gray',
discardStdin: !options.watching,
hideCursor: false,
spinner: options.spinner || (process.platform === 'win32' ? 'line' : 'dots'),
stream: options.reportStream
});
this.lineWriter = new LineWriter(this.reportStream, this.spinner);
this.consumeStateChange = whileCorked(this.reportStream, whileCorked(this.lineWriter, this.consumeStateChange));
this.endRun = whileCorked(this.reportStream, whileCorked(this.lineWriter, this.endRun));
this.relativeFile = file => path.relative(options.projectDir, file);
this.reset();
}
reset() {
if (this.removePreviousListener) {
this.removePreviousListener();
}
this.failFastEnabled = false;
this.failures = [];
this.filesWithMissingAvaImports = new Set();
this.filesWithoutDeclaredTests = new Set();
this.filesWithoutMatchedLineNumbers = new Set();
this.internalErrors = [];
this.knownFailures = [];
this.lineNumberErrors = [];
this.matching = false;
this.prefixTitle = (testFile, title) => title;
this.previousFailures = 0;
this.removePreviousListener = null;
this.stats = null;
this.uncaughtExceptions = [];
this.unhandledRejections = [];
}
startRun(plan) {
if (plan.bailWithoutReporting) {
return;
}
this.reset();
this.failFastEnabled = plan.failFastEnabled;
this.matching = plan.matching;
this.previousFailures = plan.previousFailures;
if (this.watching || plan.files.length > 1) {
this.prefixTitle = (testFile, title) => prefixTitle(plan.filePathPrefix, testFile, title);
}
this.removePreviousListener = plan.status.on('stateChange', evt => this.consumeStateChange(evt));
if (this.watching && plan.runVector > 1) {
this.reportStream.write(chalk.gray.dim('\u2500'.repeat(this.lineWriter.columns)) + os.EOL);
}
cliCursor.hide(this.reportStream);
this.lineWriter.writeLine();
this.spinner.start();
}
consumeStateChange(evt) { // eslint-disable-line complexity
const fileStats = this.stats && evt.testFile ? this.stats.byFile.get(evt.testFile) : null;
switch (evt.type) {
case 'declared-test':
// Ignore
break;
case 'hook-failed':
this.failures.push(evt);
this.writeTestSummary(evt);
break;
case 'internal-error':
this.internalErrors.push(evt);
if (evt.testFile) {
this.writeWithCounts(colors.error(`${figures.cross} Internal error when running ${this.relativeFile(evt.testFile)}`));
} else {
this.writeWithCounts(colors.error(`${figures.cross} Internal error`));
}
break;
case 'line-number-selection-error':
this.lineNumberErrors.push(evt);
this.writeWithCounts(colors.information(`${figures.warning} Could not parse ${this.relativeFile(evt.testFile)} for line number selection`));
break;
case 'missing-ava-import':
this.filesWithMissingAvaImports.add(evt.testFile);
this.writeWithCounts(colors.error(`${figures.cross} No tests found in ${this.relativeFile(evt.testFile)}, make sure to import "ava" at the top of your test file`));
break;
case 'selected-test':
// Ignore
break;
case 'stats':
this.stats = evt.stats;
break;
case 'test-failed':
this.failures.push(evt);
this.writeTestSummary(evt);
break;
case 'test-passed':
if (evt.knownFailing) {
this.knownFailures.push(evt);
}
this.writeTestSummary(evt);
break;
case 'timeout':
this.lineWriter.writeLine(colors.error(`\n${figures.cross} Timed out while running tests`));
this.lineWriter.writeLine('');
this.writePendingTests(evt);
break;
case 'interrupt':
this.lineWriter.writeLine(colors.error(`\n${figures.cross} Exiting due to SIGINT`));
this.lineWriter.writeLine('');
this.writePendingTests(evt);
break;
case 'uncaught-exception':
this.uncaughtExceptions.push(evt);
break;
case 'unhandled-rejection':
this.unhandledRejections.push(evt);
break;
case 'worker-failed':
if (fileStats.declaredTests === 0) {
this.filesWithoutDeclaredTests.add(evt.testFile);
}
break;
case 'worker-finished':
if (fileStats.declaredTests === 0) {
this.filesWithoutDeclaredTests.add(evt.testFile);
this.writeWithCounts(colors.error(`${figures.cross} No tests found in ${this.relativeFile(evt.testFile)}`));
} else if (fileStats.selectingLines && fileStats.selectedTests === 0) {
this.filesWithoutMatchedLineNumbers.add(evt.testFile);
this.writeWithCounts(colors.error(`${figures.cross} Line numbers for ${this.relativeFile(evt.testFile)} did not match any tests`));
}
break;
case 'worker-stderr':
case 'worker-stdout':
// Forcibly clear the spinner, writing the chunk corrupts the TTY.
this.spinner.clear();
this.stdStream.write(evt.chunk);
// If the chunk does not end with a linebreak, *forcibly* write one to
// ensure it remains visible in the TTY.
// Tests cannot assume their standard output is not interrupted. Indeed
// we multiplex stdout and stderr into a single stream. However as
// long as stdStream is different from reportStream users can read
// their original output by redirecting the streams.
if (evt.chunk[evt.chunk.length - 1] !== 0x0A) {
// Use write() rather than writeLine() so the (presumably corked)
// line writer will actually write the empty line before re-rendering
// the last spinner text below.
this.lineWriter.write(os.EOL);
}
this.lineWriter.write(this.lineWriter.lastSpinnerText);
break;
default:
break;
}
}
writeWithCounts(string) {
if (!this.stats) {
return this.lineWriter.writeLine(string);
}
string = string || '';
if (string !== '') {
string += os.EOL;
}
let firstLinePostfix = this.watching ?
' ' + chalk.gray.dim('[' + new Date().toLocaleTimeString('en-US', {hour12: false}) + ']') :
'';
if (this.stats.passedTests > 0) {
string += os.EOL + colors.pass(`${this.stats.passedTests} passed`) + firstLinePostfix;
firstLinePostfix = '';
}
if (this.stats.passedKnownFailingTests > 0) {
string += os.EOL + colors.error(`${this.stats.passedKnownFailingTests} ${plur('known failure', this.stats.passedKnownFailingTests)}`);
}
if (this.stats.failedHooks > 0) {
string += os.EOL + colors.error(`${this.stats.failedHooks} ${plur('hook', this.stats.failedHooks)} failed`) + firstLinePostfix;
firstLinePostfix = '';
}
if (this.stats.failedTests > 0) {
string += os.EOL + colors.error(`${this.stats.failedTests} ${plur('test', this.stats.failedTests)} failed`) + firstLinePostfix;
firstLinePostfix = '';
}
if (this.stats.skippedTests > 0) {
string += os.EOL + colors.skip(`${this.stats.skippedTests} skipped`);
}
if (this.stats.todoTests > 0) {
string += os.EOL + colors.todo(`${this.stats.todoTests} todo`);
}
this.lineWriter.writeLine(string);
}
writeErr(evt) {
if (evt.err.name === 'TSError' && evt.err.object && evt.err.object.diagnosticText) {
this.lineWriter.writeLine(colors.errorStack(trimOffNewlines(evt.err.object.diagnosticText)));
return;
}
if (evt.err.source) {
this.lineWriter.writeLine(colors.errorSource(`${this.relativeFile(evt.err.source.file)}:${evt.err.source.line}`));
const excerpt = codeExcerpt(evt.err.source, {maxWidth: this.lineWriter.columns - 2});
if (excerpt) {
this.lineWriter.writeLine();
this.lineWriter.writeLine(excerpt);
}
}
if (evt.err.avaAssertionError) {
const result = formatSerializedError(evt.err);
if (result.printMessage) {
this.lineWriter.writeLine();
this.lineWriter.writeLine(evt.err.message);
}
if (result.formatted) {
this.lineWriter.writeLine();
this.lineWriter.writeLine(result.formatted);
}
const message = improperUsageMessages.forError(evt.err);
if (message) {
this.lineWriter.writeLine();
this.lineWriter.writeLine(message);
}
} else if (evt.err.nonErrorObject) {
this.lineWriter.writeLine(trimOffNewlines(evt.err.formatted));
} else {
this.lineWriter.writeLine();
this.lineWriter.writeLine(evt.err.summary);
}
const formatted = this.formatErrorStack(evt.err);
if (formatted.length > 0) {
this.lineWriter.writeLine();
this.lineWriter.writeLine(formatted.join('\n'));
}
}
formatErrorStack(error) {
if (!error.stack) {
return [];
}
if (error.shouldBeautifyStack) {
return beautifyStack(error.stack).map(line => {
if (nodeInternals.some(internal => internal.test(line))) {
return colors.errorStackInternal(`${figures.pointerSmall} ${line}`);
}
return colors.errorStack(`${figures.pointerSmall} ${line}`);
});
}
return [error.stack];
}
writeLogs(evt) {
if (evt.logs) {
for (const log of evt.logs) {
const logLines = indentString(colors.log(log), 4);
const logLinesWithLeadingFigure = logLines.replace(
/^ {4}/,
` ${colors.information(figures.info)} `
);
this.lineWriter.writeLine(logLinesWithLeadingFigure);
}
}
}
writeTestSummary(evt) {
if (evt.type === 'hook-failed' || evt.type === 'test-failed') {
this.writeWithCounts(`${this.prefixTitle(evt.testFile, evt.title)}`);
} else if (evt.knownFailing) {
this.writeWithCounts(`${colors.error(this.prefixTitle(evt.testFile, evt.title))}`);
} else {
this.writeWithCounts(`${this.prefixTitle(evt.testFile, evt.title)}`);
}
}
writeFailure(evt) {
this.lineWriter.writeLine(`${colors.title(this.prefixTitle(evt.testFile, evt.title))}`);
this.writeLogs(evt);
this.lineWriter.writeLine();
this.writeErr(evt);
}
writePendingTests(evt) {
for (const [file, testsInFile] of evt.pendingTests) {
if (testsInFile.size === 0) {
continue;
}
this.lineWriter.writeLine(`${testsInFile.size} tests were pending in ${this.relativeFile(file)}\n`);
for (const title of testsInFile) {
this.lineWriter.writeLine(`${figures.circleDotted} ${this.prefixTitle(file, title)}`);
}
this.lineWriter.writeLine('');
}
}
endRun() { // eslint-disable-line complexity
this.spinner.stop();
cliCursor.show(this.reportStream);
if (!this.stats) {
this.lineWriter.writeLine(colors.error(`${figures.cross} Couldnt find any files to test`));
this.lineWriter.writeLine();
return;
}
if (this.matching && this.stats.selectedTests === 0) {
this.lineWriter.writeLine(colors.error(`${figures.cross} Couldnt find any matching tests`));
this.lineWriter.writeLine();
return;
}
this.lineWriter.writeLine();
let firstLinePostfix = this.watching ?
' ' + chalk.gray.dim('[' + new Date().toLocaleTimeString('en-US', {hour12: false}) + ']') :
'';
if (this.filesWithMissingAvaImports.size > 0) {
for (const testFile of this.filesWithMissingAvaImports) {
this.lineWriter.writeLine(colors.error(`${figures.cross} No tests found in ${this.relativeFile(testFile)}, make sure to import "ava" at the top of your test file`) + firstLinePostfix);
firstLinePostfix = '';
}
}
if (this.filesWithoutDeclaredTests.size > 0) {
for (const testFile of this.filesWithoutDeclaredTests) {
if (!this.filesWithMissingAvaImports.has(testFile)) {
this.lineWriter.writeLine(colors.error(`${figures.cross} No tests found in ${this.relativeFile(testFile)}`) + firstLinePostfix);
firstLinePostfix = '';
}
}
}
if (this.lineNumberErrors.length > 0) {
for (const evt of this.lineNumberErrors) {
this.lineWriter.writeLine(colors.information(`${figures.warning} Could not parse ${this.relativeFile(evt.testFile)} for line number selection`));
}
}
if (this.filesWithoutMatchedLineNumbers.size > 0) {
for (const testFile of this.filesWithoutMatchedLineNumbers) {
if (!this.filesWithMissingAvaImports.has(testFile) && !this.filesWithoutDeclaredTests.has(testFile)) {
this.lineWriter.writeLine(colors.error(`${figures.cross} Line numbers for ${this.relativeFile(testFile)} did not match any tests`) + firstLinePostfix);
firstLinePostfix = '';
}
}
}
if (this.filesWithMissingAvaImports.size > 0 || this.filesWithoutDeclaredTests.size > 0 || this.filesWithoutMatchedLineNumbers.size > 0) {
this.lineWriter.writeLine();
}
if (this.stats.failedHooks > 0) {
this.lineWriter.writeLine(colors.error(`${this.stats.failedHooks} ${plur('hook', this.stats.failedHooks)} failed`) + firstLinePostfix);
firstLinePostfix = '';
}
if (this.stats.failedTests > 0) {
this.lineWriter.writeLine(colors.error(`${this.stats.failedTests} ${plur('test', this.stats.failedTests)} failed`) + firstLinePostfix);
firstLinePostfix = '';
}
if (this.stats.failedHooks === 0 && this.stats.failedTests === 0 && this.stats.passedTests > 0) {
this.lineWriter.writeLine(colors.pass(`${this.stats.passedTests} ${plur('test', this.stats.passedTests)} passed`) + firstLinePostfix);
firstLinePostfix = '';
}
if (this.stats.passedKnownFailingTests > 0) {
this.lineWriter.writeLine(colors.error(`${this.stats.passedKnownFailingTests} ${plur('known failure', this.stats.passedKnownFailingTests)}`));
}
if (this.stats.skippedTests > 0) {
this.lineWriter.writeLine(colors.skip(`${this.stats.skippedTests} ${plur('test', this.stats.skippedTests)} skipped`));
}
if (this.stats.todoTests > 0) {
this.lineWriter.writeLine(colors.todo(`${this.stats.todoTests} ${plur('test', this.stats.todoTests)} todo`));
}
if (this.stats.unhandledRejections > 0) {
this.lineWriter.writeLine(colors.error(`${this.stats.unhandledRejections} unhandled ${plur('rejection', this.stats.unhandledRejections)}`));
}
if (this.stats.uncaughtExceptions > 0) {
this.lineWriter.writeLine(colors.error(`${this.stats.uncaughtExceptions} uncaught ${plur('exception', this.stats.uncaughtExceptions)}`));
}
if (this.previousFailures > 0) {
this.lineWriter.writeLine(colors.error(`${this.previousFailures} previous ${plur('failure', this.previousFailures)} in test files that were not rerun`));
}
if (this.stats.passedKnownFailingTests > 0) {
this.lineWriter.writeLine();
for (const evt of this.knownFailures) {
this.lineWriter.writeLine(colors.error(this.prefixTitle(evt.testFile, evt.title)));
}
}
const shouldWriteFailFastDisclaimer = this.failFastEnabled && (this.stats.remainingTests > 0 || this.stats.files > this.stats.finishedWorkers);
if (this.failures.length > 0) {
const writeTrailingLines = shouldWriteFailFastDisclaimer || this.internalErrors.length > 0 || this.uncaughtExceptions.length > 0 || this.unhandledRejections.length > 0;
this.lineWriter.writeLine();
const last = this.failures[this.failures.length - 1];
for (const evt of this.failures) {
this.writeFailure(evt);
if (evt !== last || writeTrailingLines) {
this.lineWriter.writeLine();
this.lineWriter.writeLine();
this.lineWriter.writeLine();
}
}
}
if (this.internalErrors.length > 0) {
const writeLeadingLine = this.failures.length === 0;
const writeTrailingLines = shouldWriteFailFastDisclaimer || this.uncaughtExceptions.length > 0 || this.unhandledRejections.length > 0;
if (writeLeadingLine) {
this.lineWriter.writeLine();
}
const last = this.internalErrors[this.internalErrors.length - 1];
for (const evt of this.internalErrors) {
if (evt.testFile) {
this.lineWriter.writeLine(colors.error(`${figures.cross} Internal error when running ${this.relativeFile(evt.testFile)}`));
} else {
this.lineWriter.writeLine(colors.error(`${figures.cross} Internal error`));
}
this.lineWriter.writeLine(colors.stack(evt.err.summary));
this.lineWriter.writeLine(colors.errorStack(evt.err.stack));
if (evt !== last || writeTrailingLines) {
this.lineWriter.writeLine();
this.lineWriter.writeLine();
this.lineWriter.writeLine();
}
}
}
if (this.uncaughtExceptions.length > 0) {
const writeLeadingLine = this.failures.length === 0 && this.internalErrors.length === 0;
const writeTrailingLines = shouldWriteFailFastDisclaimer || this.unhandledRejections.length > 0;
if (writeLeadingLine) {
this.lineWriter.writeLine();
}
const last = this.uncaughtExceptions[this.uncaughtExceptions.length - 1];
for (const evt of this.uncaughtExceptions) {
this.lineWriter.writeLine(colors.title(`Uncaught exception in ${this.relativeFile(evt.testFile)}`));
this.lineWriter.writeLine();
this.writeErr(evt);
if (evt !== last || writeTrailingLines) {
this.lineWriter.writeLine();
this.lineWriter.writeLine();
this.lineWriter.writeLine();
}
}
}
if (this.unhandledRejections.length > 0) {
const writeLeadingLine = this.failures.length === 0 && this.internalErrors.length === 0 && this.uncaughtExceptions.length === 0;
const writeTrailingLines = shouldWriteFailFastDisclaimer;
if (writeLeadingLine) {
this.lineWriter.writeLine();
}
const last = this.unhandledRejections[this.unhandledRejections.length - 1];
for (const evt of this.unhandledRejections) {
this.lineWriter.writeLine(colors.title(`Unhandled rejection in ${this.relativeFile(evt.testFile)}`));
this.lineWriter.writeLine();
this.writeErr(evt);
if (evt !== last || writeTrailingLines) {
this.lineWriter.writeLine();
this.lineWriter.writeLine();
this.lineWriter.writeLine();
}
}
}
if (shouldWriteFailFastDisclaimer) {
let remaining = '';
if (this.stats.remainingTests > 0) {
remaining += `At least ${this.stats.remainingTests} ${plur('test was', 'tests were', this.stats.remainingTests)} skipped`;
if (this.stats.files > this.stats.finishedWorkers) {
remaining += ', as well as ';
}
}
if (this.stats.files > this.stats.finishedWorkers) {
const skippedFileCount = this.stats.files - this.stats.finishedWorkers;
remaining += `${skippedFileCount} ${plur('test file', 'test files', skippedFileCount)}`;
if (this.stats.remainingTests === 0) {
remaining += ` ${plur('was', 'were', skippedFileCount)} skipped`;
}
}
this.lineWriter.writeLine(colors.information(`\`--fail-fast\` is on. ${remaining}.`));
}
this.lineWriter.writeLine();
}
}
module.exports = MiniReporter;

21
node_modules/ava/lib/reporters/prefix-title.js generated vendored Normal file
View file

@ -0,0 +1,21 @@
'use strict';
const path = require('path');
const figures = require('figures');
const chalk = require('../chalk').get();
const SEPERATOR = ' ' + chalk.gray.dim(figures.pointerSmall) + ' ';
module.exports = (base, file, title) => {
const prefix = file
// Only replace base if it is found at the start of the path
.replace(base, (match, offset) => offset === 0 ? '' : match)
.replace(/\.spec/, '')
.replace(/\.test/, '')
.replace(/test-/g, '')
.replace(/\.js$/, '')
.split(path.sep)
.filter(p => p !== '__tests__')
.join(SEPERATOR);
return prefix + SEPERATOR + title;
};

209
node_modules/ava/lib/reporters/tap.js generated vendored Normal file
View file

@ -0,0 +1,209 @@
'use strict';
const os = require('os');
const path = require('path');
const plur = require('plur');
const stripAnsi = require('strip-ansi');
const supertap = require('supertap');
const indentString = require('indent-string');
const beautifyStack = require('./beautify-stack');
const prefixTitle = require('./prefix-title');
function dumpError(error) {
const object = {...error.object};
if (error.name) {
object.name = error.name;
}
if (error.message) {
object.message = error.message;
}
if (error.avaAssertionError) {
if (error.assertion) {
object.assertion = error.assertion;
}
if (error.operator) {
object.operator = error.operator;
}
if (error.values.length > 0) {
object.values = error.values.reduce((acc, value) => {
acc[value.label] = stripAnsi(value.formatted);
return acc;
}, {});
}
}
if (error.nonErrorObject) {
object.message = 'Non-error object';
object.formatted = stripAnsi(error.formatted);
}
if (error.stack) {
object.at = error.shouldBeautifyStack ? beautifyStack(error.stack).join('\n') : error.stack;
}
return object;
}
class TapReporter {
constructor(options) {
this.i = 0;
this.stdStream = options.stdStream;
this.reportStream = options.reportStream;
this.crashCount = 0;
this.filesWithMissingAvaImports = new Set();
this.prefixTitle = (testFile, title) => title;
this.relativeFile = file => path.relative(options.projectDir, file);
this.stats = null;
}
startRun(plan) {
if (plan.files.length > 1) {
this.prefixTitle = (testFile, title) => prefixTitle(plan.filePathPrefix, testFile, title);
}
plan.status.on('stateChange', evt => this.consumeStateChange(evt));
this.reportStream.write(supertap.start() + os.EOL);
}
endRun() {
if (this.stats) {
this.reportStream.write(supertap.finish({
crashed: this.crashCount,
failed: this.stats.failedTests + this.stats.remainingTests,
passed: this.stats.passedTests + this.stats.passedKnownFailingTests,
skipped: this.stats.skippedTests,
todo: this.stats.todoTests
}) + os.EOL);
if (this.stats.parallelRuns) {
const {currentFileCount, currentIndex, totalRuns} = this.stats.parallelRuns;
this.reportStream.write(`# Ran ${currentFileCount} test ${plur('file', currentFileCount)} out of ${this.stats.files} for job ${currentIndex + 1} of ${totalRuns}` + os.EOL + os.EOL);
}
} else {
this.reportStream.write(supertap.finish({
crashed: this.crashCount,
failed: 0,
passed: 0,
skipped: 0,
todo: 0
}) + os.EOL);
}
}
writeTest(evt, flags) {
this.reportStream.write(supertap.test(this.prefixTitle(evt.testFile, evt.title), {
comment: evt.logs,
error: evt.err ? dumpError(evt.err) : null,
index: ++this.i,
passed: flags.passed,
skip: flags.skip,
todo: flags.todo
}) + os.EOL);
}
writeCrash(evt, title) {
this.crashCount++;
this.reportStream.write(supertap.test(title || evt.err.summary || evt.type, {
comment: evt.logs,
error: evt.err ? dumpError(evt.err) : null,
index: ++this.i,
passed: false,
skip: false,
todo: false
}) + os.EOL);
}
writeComment(evt, {title = this.prefixTitle(evt.testFile, evt.title)}) {
this.reportStream.write(`# ${stripAnsi(title)}${os.EOL}`);
if (evt.logs) {
for (const log of evt.logs) {
const logLines = indentString(log, 4).replace(/^ {4}/, ' # ');
this.reportStream.write(`${logLines}${os.EOL}`);
}
}
}
consumeStateChange(evt) { // eslint-disable-line complexity
const fileStats = this.stats && evt.testFile ? this.stats.byFile.get(evt.testFile) : null;
switch (evt.type) {
case 'declared-test':
// Ignore
break;
case 'hook-failed':
this.writeTest(evt, {passed: false, todo: false, skip: false});
break;
case 'hook-finished':
this.writeComment(evt, {});
break;
case 'internal-error':
this.writeCrash(evt);
break;
case 'missing-ava-import':
this.filesWithMissingAvaImports.add(evt.testFile);
this.writeCrash(evt, `No tests found in ${this.relativeFile(evt.testFile)}, make sure to import "ava" at the top of your test file`);
break;
case 'selected-test':
if (evt.skip) {
this.writeTest(evt, {passed: true, todo: false, skip: true});
} else if (evt.todo) {
this.writeTest(evt, {passed: false, todo: true, skip: false});
}
break;
case 'stats':
this.stats = evt.stats;
break;
case 'test-failed':
this.writeTest(evt, {passed: false, todo: false, skip: false});
break;
case 'test-passed':
this.writeTest(evt, {passed: true, todo: false, skip: false});
break;
case 'timeout':
this.writeCrash(evt, `Exited because no new tests completed within the last ${evt.period}ms of inactivity`);
break;
case 'uncaught-exception':
this.writeCrash(evt);
break;
case 'unhandled-rejection':
this.writeCrash(evt);
break;
case 'worker-failed':
if (!this.filesWithMissingAvaImports.has(evt.testFile)) {
if (evt.nonZeroExitCode) {
this.writeCrash(evt, `${this.relativeFile(evt.testFile)} exited with a non-zero exit code: ${evt.nonZeroExitCode}`);
} else {
this.writeCrash(evt, `${this.relativeFile(evt.testFile)} exited due to ${evt.signal}`);
}
}
break;
case 'worker-finished':
if (!evt.forcedExit && !this.filesWithMissingAvaImports.has(evt.testFile)) {
if (fileStats.declaredTests === 0) {
this.writeCrash(evt, `No tests found in ${this.relativeFile(evt.testFile)}`);
} else if (!this.failFastEnabled && fileStats.remainingTests > 0) {
this.writeComment(evt, {title: `${fileStats.remainingTests} ${plur('test', fileStats.remainingTests)} remaining in ${this.relativeFile(evt.testFile)}`});
}
}
break;
case 'worker-stderr':
case 'worker-stdout':
this.stdStream.write(evt.chunk);
break;
default:
break;
}
}
}
module.exports = TapReporter;

463
node_modules/ava/lib/reporters/verbose.js generated vendored Normal file
View file

@ -0,0 +1,463 @@
'use strict';
const os = require('os');
const path = require('path');
const stream = require('stream');
const figures = require('figures');
const indentString = require('indent-string');
const plur = require('plur');
const prettyMs = require('pretty-ms');
const trimOffNewlines = require('trim-off-newlines');
const beautifyStack = require('./beautify-stack');
const chalk = require('../chalk').get();
const codeExcerpt = require('../code-excerpt');
const colors = require('./colors');
const formatSerializedError = require('./format-serialized-error');
const improperUsageMessages = require('./improper-usage-messages');
const prefixTitle = require('./prefix-title');
const whileCorked = require('./while-corked');
const nodeInternals = require('stack-utils').nodeInternals();
class LineWriter extends stream.Writable {
constructor(dest) {
super();
this.dest = dest;
this.columns = dest.columns || 80;
this.lastLineIsEmpty = false;
}
_write(chunk, encoding, callback) {
this.dest.write(chunk);
callback();
}
writeLine(string) {
if (string) {
this.write(indentString(string, 2) + os.EOL);
this.lastLineIsEmpty = false;
} else {
this.write(os.EOL);
this.lastLineIsEmpty = true;
}
}
ensureEmptyLine() {
if (!this.lastLineIsEmpty) {
this.writeLine();
}
}
}
class VerboseReporter {
constructor(options) {
this.durationThreshold = options.durationThreshold || 100;
this.reportStream = options.reportStream;
this.stdStream = options.stdStream;
this.watching = options.watching;
this.lineWriter = new LineWriter(this.reportStream);
this.consumeStateChange = whileCorked(this.reportStream, this.consumeStateChange);
this.endRun = whileCorked(this.reportStream, this.endRun);
this.relativeFile = file => path.relative(options.projectDir, file);
this.reset();
}
reset() {
if (this.removePreviousListener) {
this.removePreviousListener();
}
this.failFastEnabled = false;
this.failures = [];
this.filesWithMissingAvaImports = new Set();
this.knownFailures = [];
this.runningTestFiles = new Map();
this.lastLineIsEmpty = false;
this.matching = false;
this.prefixTitle = (testFile, title) => title;
this.previousFailures = 0;
this.removePreviousListener = null;
this.stats = null;
}
startRun(plan) {
if (plan.bailWithoutReporting) {
return;
}
this.reset();
this.failFastEnabled = plan.failFastEnabled;
this.matching = plan.matching;
this.previousFailures = plan.previousFailures;
this.emptyParallelRun = plan.status.emptyParallelRun;
if (this.watching || plan.files.length > 1) {
this.prefixTitle = (testFile, title) => prefixTitle(plan.filePathPrefix, testFile, title);
}
this.removePreviousListener = plan.status.on('stateChange', evt => this.consumeStateChange(evt));
if (this.watching && plan.runVector > 1) {
this.lineWriter.write(chalk.gray.dim('\u2500'.repeat(this.reportStream.columns || 80)) + os.EOL);
}
this.lineWriter.writeLine();
}
consumeStateChange(evt) { // eslint-disable-line complexity
const fileStats = this.stats && evt.testFile ? this.stats.byFile.get(evt.testFile) : null;
switch (evt.type) {
case 'hook-failed':
this.failures.push(evt);
this.writeTestSummary(evt);
break;
case 'internal-error':
if (evt.testFile) {
this.lineWriter.writeLine(colors.error(`${figures.cross} Internal error when running ${this.relativeFile(evt.testFile)}`));
} else {
this.lineWriter.writeLine(colors.error(`${figures.cross} Internal error`));
}
this.lineWriter.writeLine(colors.stack(evt.err.summary));
this.lineWriter.writeLine(colors.errorStack(evt.err.stack));
this.lineWriter.writeLine();
this.lineWriter.writeLine();
break;
case 'line-number-selection-error':
this.lineWriter.writeLine(colors.information(`${figures.warning} Could not parse ${this.relativeFile(evt.testFile)} for line number selection`));
break;
case 'missing-ava-import':
this.filesWithMissingAvaImports.add(evt.testFile);
this.lineWriter.writeLine(colors.error(`${figures.cross} No tests found in ${this.relativeFile(evt.testFile)}, make sure to import "ava" at the top of your test file`));
break;
case 'hook-finished':
if (evt.logs.length > 0) {
this.lineWriter.writeLine(` ${this.prefixTitle(evt.testFile, evt.title)}`);
this.writeLogs(evt);
}
break;
case 'selected-test':
if (evt.skip) {
this.lineWriter.writeLine(colors.skip(`- ${this.prefixTitle(evt.testFile, evt.title)}`));
} else if (evt.todo) {
this.lineWriter.writeLine(colors.todo(`- ${this.prefixTitle(evt.testFile, evt.title)}`));
}
break;
case 'stats':
this.stats = evt.stats;
break;
case 'test-failed':
this.failures.push(evt);
this.writeTestSummary(evt);
break;
case 'test-passed':
if (evt.knownFailing) {
this.knownFailures.push(evt);
}
this.writeTestSummary(evt);
break;
case 'timeout':
this.lineWriter.writeLine(colors.error(`\n${figures.cross} Timed out while running tests`));
this.lineWriter.writeLine('');
this.writePendingTests(evt);
break;
case 'interrupt':
this.lineWriter.writeLine(colors.error(`\n${figures.cross} Exiting due to SIGINT`));
this.lineWriter.writeLine('');
this.writePendingTests(evt);
break;
case 'uncaught-exception':
this.lineWriter.ensureEmptyLine();
this.lineWriter.writeLine(colors.title(`Uncaught exception in ${this.relativeFile(evt.testFile)}`));
this.lineWriter.writeLine();
this.writeErr(evt);
this.lineWriter.writeLine();
break;
case 'unhandled-rejection':
this.lineWriter.ensureEmptyLine();
this.lineWriter.writeLine(colors.title(`Unhandled rejection in ${this.relativeFile(evt.testFile)}`));
this.lineWriter.writeLine();
this.writeErr(evt);
this.lineWriter.writeLine();
break;
case 'worker-failed':
if (!this.filesWithMissingAvaImports.has(evt.testFile)) {
if (evt.nonZeroExitCode) {
this.lineWriter.writeLine(colors.error(`${figures.cross} ${this.relativeFile(evt.testFile)} exited with a non-zero exit code: ${evt.nonZeroExitCode}`));
} else {
this.lineWriter.writeLine(colors.error(`${figures.cross} ${this.relativeFile(evt.testFile)} exited due to ${evt.signal}`));
}
}
break;
case 'worker-finished':
if (!evt.forcedExit && !this.filesWithMissingAvaImports.has(evt.testFile)) {
if (fileStats.declaredTests === 0) {
this.lineWriter.writeLine(colors.error(`${figures.cross} No tests found in ${this.relativeFile(evt.testFile)}`));
} else if (fileStats.selectingLines && fileStats.selectedTests === 0) {
this.lineWriter.writeLine(colors.error(`${figures.cross} Line numbers for ${this.relativeFile(evt.testFile)} did not match any tests`));
} else if (!this.failFastEnabled && fileStats.remainingTests > 0) {
this.lineWriter.writeLine(colors.error(`${figures.cross} ${fileStats.remainingTests} ${plur('test', fileStats.remainingTests)} remaining in ${this.relativeFile(evt.testFile)}`));
}
}
break;
case 'worker-stderr':
case 'worker-stdout':
this.stdStream.write(evt.chunk);
// If the chunk does not end with a linebreak, *forcibly* write one to
// ensure it remains visible in the TTY.
// Tests cannot assume their standard output is not interrupted. Indeed
// we multiplex stdout and stderr into a single stream. However as
// long as stdStream is different from reportStream users can read
// their original output by redirecting the streams.
if (evt.chunk[evt.chunk.length - 1] !== 0x0A) {
this.reportStream.write(os.EOL);
}
break;
default:
break;
}
}
writeErr(evt) {
if (evt.err.name === 'TSError' && evt.err.object && evt.err.object.diagnosticText) {
this.lineWriter.writeLine(colors.errorStack(trimOffNewlines(evt.err.object.diagnosticText)));
return;
}
if (evt.err.source) {
this.lineWriter.writeLine(colors.errorSource(`${this.relativeFile(evt.err.source.file)}:${evt.err.source.line}`));
const excerpt = codeExcerpt(evt.err.source, {maxWidth: this.reportStream.columns - 2});
if (excerpt) {
this.lineWriter.writeLine();
this.lineWriter.writeLine(excerpt);
}
}
if (evt.err.avaAssertionError) {
const result = formatSerializedError(evt.err);
if (result.printMessage) {
this.lineWriter.writeLine();
this.lineWriter.writeLine(evt.err.message);
}
if (result.formatted) {
this.lineWriter.writeLine();
this.lineWriter.writeLine(result.formatted);
}
const message = improperUsageMessages.forError(evt.err);
if (message) {
this.lineWriter.writeLine();
this.lineWriter.writeLine(message);
}
} else if (evt.err.nonErrorObject) {
this.lineWriter.writeLine(trimOffNewlines(evt.err.formatted));
} else {
this.lineWriter.writeLine();
this.lineWriter.writeLine(evt.err.summary);
}
const formatted = this.formatErrorStack(evt.err);
if (formatted.length > 0) {
this.lineWriter.writeLine();
this.lineWriter.writeLine(formatted.join('\n'));
}
}
formatErrorStack(error) {
if (!error.stack) {
return [];
}
if (error.shouldBeautifyStack) {
return beautifyStack(error.stack).map(line => {
if (nodeInternals.some(internal => internal.test(line))) {
return colors.errorStackInternal(`${figures.pointerSmall} ${line}`);
}
return colors.errorStack(`${figures.pointerSmall} ${line}`);
});
}
return [error.stack];
}
writePendingTests(evt) {
for (const [file, testsInFile] of evt.pendingTests) {
if (testsInFile.size === 0) {
continue;
}
this.lineWriter.writeLine(`${testsInFile.size} tests were pending in ${this.relativeFile(file)}\n`);
for (const title of testsInFile) {
this.lineWriter.writeLine(`${figures.circleDotted} ${this.prefixTitle(file, title)}`);
}
this.lineWriter.writeLine('');
}
}
writeLogs(evt) {
if (evt.logs) {
for (const log of evt.logs) {
const logLines = indentString(colors.log(log), 4);
const logLinesWithLeadingFigure = logLines.replace(
/^ {4}/,
` ${colors.information(figures.info)} `
);
this.lineWriter.writeLine(logLinesWithLeadingFigure);
}
}
}
writeTestSummary(evt) {
if (evt.type === 'hook-failed' || evt.type === 'test-failed') {
this.lineWriter.writeLine(`${colors.error(figures.cross)} ${this.prefixTitle(evt.testFile, evt.title)} ${colors.error(evt.err.message)}`);
} else if (evt.knownFailing) {
this.lineWriter.writeLine(`${colors.error(figures.tick)} ${colors.error(this.prefixTitle(evt.testFile, evt.title))}`);
} else {
const duration = evt.duration > this.durationThreshold ? colors.duration(' (' + prettyMs(evt.duration) + ')') : '';
this.lineWriter.writeLine(`${colors.pass(figures.tick)} ${this.prefixTitle(evt.testFile, evt.title)}${duration}`);
}
this.writeLogs(evt);
}
writeFailure(evt) {
this.lineWriter.writeLine(`${colors.title(this.prefixTitle(evt.testFile, evt.title))}`);
this.writeLogs(evt);
this.lineWriter.writeLine();
this.writeErr(evt);
}
endRun() { // eslint-disable-line complexity
if (this.emptyParallelRun) {
this.lineWriter.writeLine('No files tested in this parallel run');
this.lineWriter.writeLine();
return;
}
if (!this.stats) {
this.lineWriter.writeLine(colors.error(`${figures.cross} Couldnt find any files to test`));
this.lineWriter.writeLine();
return;
}
if (this.matching && this.stats.selectedTests === 0) {
this.lineWriter.writeLine(colors.error(`${figures.cross} Couldnt find any matching tests`));
this.lineWriter.writeLine();
return;
}
this.lineWriter.writeLine();
if (this.stats.parallelRuns) {
const {currentFileCount, currentIndex, totalRuns} = this.stats.parallelRuns;
this.lineWriter.writeLine(colors.information(`Ran ${currentFileCount} test ${plur('file', currentFileCount)} out of ${this.stats.files} for job ${currentIndex + 1} of ${totalRuns}`));
this.lineWriter.writeLine();
}
let firstLinePostfix = this.watching ?
' ' + chalk.gray.dim('[' + new Date().toLocaleTimeString('en-US', {hour12: false}) + ']') :
'';
if (this.stats.failedHooks > 0) {
this.lineWriter.writeLine(colors.error(`${this.stats.failedHooks} ${plur('hook', this.stats.failedHooks)} failed`) + firstLinePostfix);
firstLinePostfix = '';
}
if (this.stats.failedTests > 0) {
this.lineWriter.writeLine(colors.error(`${this.stats.failedTests} ${plur('test', this.stats.failedTests)} failed`) + firstLinePostfix);
firstLinePostfix = '';
}
if (this.stats.failedHooks === 0 && this.stats.failedTests === 0 && this.stats.passedTests > 0) {
this.lineWriter.writeLine(colors.pass(`${this.stats.passedTests} ${plur('test', this.stats.passedTests)} passed`) + firstLinePostfix);
firstLinePostfix = '';
}
if (this.stats.passedKnownFailingTests > 0) {
this.lineWriter.writeLine(colors.error(`${this.stats.passedKnownFailingTests} ${plur('known failure', this.stats.passedKnownFailingTests)}`));
}
if (this.stats.skippedTests > 0) {
this.lineWriter.writeLine(colors.skip(`${this.stats.skippedTests} ${plur('test', this.stats.skippedTests)} skipped`));
}
if (this.stats.todoTests > 0) {
this.lineWriter.writeLine(colors.todo(`${this.stats.todoTests} ${plur('test', this.stats.todoTests)} todo`));
}
if (this.stats.unhandledRejections > 0) {
this.lineWriter.writeLine(colors.error(`${this.stats.unhandledRejections} unhandled ${plur('rejection', this.stats.unhandledRejections)}`));
}
if (this.stats.uncaughtExceptions > 0) {
this.lineWriter.writeLine(colors.error(`${this.stats.uncaughtExceptions} uncaught ${plur('exception', this.stats.uncaughtExceptions)}`));
}
if (this.previousFailures > 0) {
this.lineWriter.writeLine(colors.error(`${this.previousFailures} previous ${plur('failure', this.previousFailures)} in test files that were not rerun`));
}
if (this.stats.passedKnownFailingTests > 0) {
this.lineWriter.writeLine();
for (const evt of this.knownFailures) {
this.lineWriter.writeLine(colors.error(this.prefixTitle(evt.testFile, evt.title)));
}
}
const shouldWriteFailFastDisclaimer = this.failFastEnabled && (this.stats.remainingTests > 0 || this.stats.files > this.stats.finishedWorkers);
if (this.failures.length > 0) {
this.lineWriter.writeLine();
const lastFailure = this.failures[this.failures.length - 1];
for (const evt of this.failures) {
this.writeFailure(evt);
if (evt !== lastFailure || shouldWriteFailFastDisclaimer) {
this.lineWriter.writeLine();
this.lineWriter.writeLine();
this.lineWriter.writeLine();
}
}
}
if (shouldWriteFailFastDisclaimer) {
let remaining = '';
if (this.stats.remainingTests > 0) {
remaining += `At least ${this.stats.remainingTests} ${plur('test was', 'tests were', this.stats.remainingTests)} skipped`;
if (this.stats.files > this.stats.finishedWorkers) {
remaining += ', as well as ';
}
}
if (this.stats.files > this.stats.finishedWorkers) {
const skippedFileCount = this.stats.files - this.stats.finishedWorkers;
remaining += `${skippedFileCount} ${plur('test file', 'test files', skippedFileCount)}`;
if (this.stats.remainingTests === 0) {
remaining += ` ${plur('was', 'were', skippedFileCount)} skipped`;
}
}
this.lineWriter.writeLine(colors.information(`\`--fail-fast\` is on. ${remaining}.`));
}
this.lineWriter.writeLine();
}
}
module.exports = VerboseReporter;

13
node_modules/ava/lib/reporters/while-corked.js generated vendored Normal file
View file

@ -0,0 +1,13 @@
'use strict';
function whileCorked(stream, fn) {
return function (...args) {
stream.cork();
try {
fn.apply(this, args);
} finally {
stream.uncork();
}
};
}
module.exports = whileCorked;