Skip to content

Commit

Permalink
Create a process-exit message for process.exit()
Browse files Browse the repository at this point in the history
  • Loading branch information
gibson042 committed Aug 16, 2022
1 parent ae53bfc commit 19bed42
Show file tree
Hide file tree
Showing 7 changed files with 40 additions and 2 deletions.
19 changes: 19 additions & 0 deletions lib/reporters/default.js
Expand Up @@ -111,6 +111,7 @@ export default class Reporter {

this.failures = [];
this.internalErrors = [];
this.interrupts = [];
this.knownFailures = [];
this.lineNumberErrors = [];
this.sharedWorkerErrors = [];
Expand Down Expand Up @@ -193,6 +194,7 @@ export default class Reporter {
}

case 'interrupt': {
this.interrupts.push(event);
this.lineWriter.writeLine(colors.error(`\n${figures.cross} Exiting due to SIGINT`));
this.lineWriter.writeLine('');
this.writePendingTests(event);
Expand Down Expand Up @@ -233,6 +235,23 @@ export default class Reporter {
break;
}

case 'process-exit': {
this.interrupts.push(event);

if (event.testFile) {
this.write(colors.error(`${figures.cross} Exiting due to process.exit() when running ${this.relativeFile(event.testFile)}`));
} else {
this.write(colors.error(`${figures.cross} Exiting due to process.exit()`));
}

this.lineWriter.writeLine(colors.stack(event.err.summary));
this.lineWriter.writeLine(colors.errorStack(event.err.stack));
this.lineWriter.writeLine();
this.lineWriter.writeLine();

break;
}

case 'hook-finished': {
if (event.logs.length > 0) {
this.lineWriter.writeLine(` ${this.prefixTitle(event.testFile, event.title)}`);
Expand Down
3 changes: 3 additions & 0 deletions lib/reporters/tap.js
Expand Up @@ -158,6 +158,9 @@ export default class TapReporter {
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 'process-exit':
this.writeCrash(evt);
break;
case 'selected-test':
if (evt.skip) {
this.writeTest(evt, {passed: true, todo: false, skip: true});
Expand Down
6 changes: 6 additions & 0 deletions lib/run-status.js
Expand Up @@ -62,6 +62,7 @@ export default class RunStatus extends Emittery {
worker.onStateChange(data => this.emitStateChange(data));
}

// eslint-disable-next-line complexity
emitStateChange(event) {
const {stats} = this;
const fileStats = stats.byFile.get(event.testFile);
Expand Down Expand Up @@ -134,6 +135,10 @@ export default class RunStatus extends Emittery {
event.pendingTests = this.pendingTests;
this.pendingTests = new Map();
break;
case 'process-exit':
event.pendingTests = this.pendingTests;
this.pendingTests = new Map();
break;
case 'uncaught-exception':
stats.uncaughtExceptions++;
fileStats.uncaughtExceptions++;
Expand Down Expand Up @@ -175,6 +180,7 @@ export default class RunStatus extends Emittery {
|| this.stats.failedHooks > 0
|| this.stats.failedTests > 0
|| this.stats.failedWorkers > 0
|| this.stats.remainingTests > 0
|| this.stats.sharedWorkerErrors > 0
|| this.stats.timeouts > 0
|| this.stats.uncaughtExceptions > 0
Expand Down
1 change: 1 addition & 0 deletions lib/watcher.js
Expand Up @@ -294,6 +294,7 @@ export default class Watcher {
switch (evt.type) {
case 'hook-failed':
case 'internal-error':
case 'process-exit':
case 'test-failed':
case 'uncaught-exception':
case 'unhandled-rejection':
Expand Down
2 changes: 1 addition & 1 deletion lib/worker/base.js
Expand Up @@ -37,7 +37,7 @@ async function exit(code, forceSync = false) {

process.exit = new Proxy(realExit, {
apply(fn, receiver, args) {
channel.send({type: 'internal-error', err: serializeError('Forced exit error', false, new Error('Unexpected process.exit()'), runner?.file)});
channel.send({type: 'process-exit', err: serializeError('Forced exit error', false, new Error('Unexpected process.exit()'), runner?.file)});

// Make sure to extract the code only from `args` rather than e.g. `Array.prototype`.
// This level of paranoia is usually unwarranted, but we're dealing with test code
Expand Down
9 changes: 9 additions & 0 deletions test/helpers/exec.js
Expand Up @@ -70,6 +70,7 @@ export const fixture = async (args, options = {}) => {
failed: [],
failedHooks: [],
internalErrors: [],
interrupts: [],
passed: [],
selectedTestCount: 0,
sharedWorkerErrors: [],
Expand Down Expand Up @@ -102,6 +103,14 @@ export const fixture = async (args, options = {}) => {
break;
}

case 'process-exit': {
const {testFile} = statusEvent;
const statObject = {file: normalizePath(workingDir, testFile)};
errors.set(statObject, statusEvent.err);
stats.interrupts.push(statObject);
break;
}

case 'selected-test': {
stats.selectedTestCount++;
if (statusEvent.skip) {
Expand Down
2 changes: 1 addition & 1 deletion test/test-process-exit/test.js
Expand Up @@ -8,6 +8,6 @@ test('process.exit is intercepted', async t => {
t.like(result, {timedOut: false, isCanceled: false, killed: false});
t.is(result.stats.selectedTestCount, 3);
t.is(result.stats.passed.length, 2);
const error = result.stats.getError(result.stats.internalErrors[0]);
const error = result.stats.getError(result.stats.interrupts[0]);
t.is(error.message, 'Unexpected process.exit()');
});

0 comments on commit 19bed42

Please sign in to comment.