From 80cde2a090bbba48d7d680ac5b4b31f492af1309 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ari=20Perkki=C3=B6?= Date: Tue, 26 Nov 2024 07:55:25 +0200 Subject: [PATCH] fix(reporters): write buffered stdout/stderr on process exit (#6932) --- packages/vitest/LICENSE.md | 24 --------------- packages/vitest/package.json | 1 - packages/vitest/src/node/reporters/base.ts | 2 +- .../reporters/renderers/windowedRenderer.ts | 29 +++++++++++++++++-- pnpm-lock.yaml | 26 ----------------- 5 files changed, 28 insertions(+), 54 deletions(-) diff --git a/packages/vitest/LICENSE.md b/packages/vitest/LICENSE.md index 375bf139ecfe..dd4d67915b7a 100644 --- a/packages/vitest/LICENSE.md +++ b/packages/vitest/LICENSE.md @@ -1245,30 +1245,6 @@ Repository: git://github.com/feross/run-parallel.git --------------------------------------- -## signal-exit -License: ISC -By: Ben Coe -Repository: https://github.com/tapjs/signal-exit.git - -> The ISC License -> -> Copyright (c) 2015, Contributors -> -> Permission to use, copy, modify, and/or distribute this software -> for any purpose with or without fee is hereby granted, provided -> that the above copyright notice and this permission notice -> appear in all copies. -> -> THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -> WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES -> OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE -> LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES -> OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -> WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, -> ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - ---------------------------------------- - ## sisteransi License: MIT By: Terkel Gjervig diff --git a/packages/vitest/package.json b/packages/vitest/package.json index 67ccc274df79..553355eea59e 100644 --- a/packages/vitest/package.json +++ b/packages/vitest/package.json @@ -162,7 +162,6 @@ "expect-type": "^1.1.0", "magic-string": "^0.30.12", "pathe": "^1.1.2", - "restore-cursor": "^5.1.0", "std-env": "^3.8.0", "tinybench": "^2.9.0", "tinyexec": "^0.3.1", diff --git a/packages/vitest/src/node/reporters/base.ts b/packages/vitest/src/node/reporters/base.ts index 6895adafa176..2847a4e21c10 100644 --- a/packages/vitest/src/node/reporters/base.ts +++ b/packages/vitest/src/node/reporters/base.ts @@ -140,7 +140,7 @@ export abstract class BaseReporter implements Reporter { } else if (this.renderSucceed || anyFailed) { - this.log(` ${c.green(c.dim(F_CHECK))} ${getTestName(test, c.dim(' > '))}`) + this.log(` ${c.dim(getStateSymbol(test))} ${getTestName(test, c.dim(' > '))}`) } } } diff --git a/packages/vitest/src/node/reporters/renderers/windowedRenderer.ts b/packages/vitest/src/node/reporters/renderers/windowedRenderer.ts index 3c7a9dcd2371..649b08a60bb2 100644 --- a/packages/vitest/src/node/reporters/renderers/windowedRenderer.ts +++ b/packages/vitest/src/node/reporters/renderers/windowedRenderer.ts @@ -1,7 +1,6 @@ import type { Writable } from 'node:stream' import type { Vitest } from '../../core' import { stripVTControlCharacters } from 'node:util' -import restoreCursor from 'restore-cursor' const DEFAULT_RENDER_INTERVAL = 16 @@ -49,9 +48,9 @@ export class WindowRenderer { this.cleanups.push( this.interceptStream(process.stdout, 'output'), this.interceptStream(process.stderr, 'error'), + this.addProcessExitListeners(), ) - restoreCursor() this.write(HIDE_CURSOR, 'output') this.start() @@ -175,6 +174,32 @@ export class WindowRenderer { private write(message: string, type: 'output' | 'error' = 'output') { (this.streams[type] as Writable['write'])(message) } + + private addProcessExitListeners() { + const onExit = (signal?: string | number, exitCode?: number) => { + // Write buffered content on unexpected exits, e.g. direct `process.exit()` calls + this.flushBuffer() + this.stop() + + // Interrupted signals don't set exit code automatically. + // Use same exit code as node: https://nodejs.org/api/process.html#signal-events + if (process.exitCode === undefined) { + process.exitCode = exitCode !== undefined ? (128 + exitCode) : Number(signal) + } + + process.exit() + } + + process.once('SIGINT', onExit) + process.once('SIGTERM', onExit) + process.once('exit', onExit) + + return function cleanup() { + process.off('SIGINT', onExit) + process.off('SIGTERM', onExit) + process.off('exit', onExit) + } + } } /** Calculate the actual row count needed to render `rows` into `stream` */ diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6c8bb9f19afd..46ee80d3241f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -883,9 +883,6 @@ importers: pathe: specifier: ^1.1.2 version: 1.1.2 - restore-cursor: - specifier: ^5.1.0 - version: 5.1.0 std-env: specifier: ^3.8.0 version: 3.8.0 @@ -7170,10 +7167,6 @@ packages: resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} engines: {node: '>=12'} - mimic-function@5.0.1: - resolution: {integrity: sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==} - engines: {node: '>=18'} - mimic-response@3.1.0: resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} engines: {node: '>=10'} @@ -7468,10 +7461,6 @@ packages: resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} engines: {node: '>=12'} - onetime@7.0.0: - resolution: {integrity: sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==} - engines: {node: '>=18'} - oniguruma-to-js@0.4.3: resolution: {integrity: sha512-X0jWUcAlxORhOqqBREgPMgnshB7ZGYszBNspP+tS9hPD3l13CdaXcHbgImoHUHlrvGx/7AvFEkTRhAGYh+jzjQ==} @@ -8031,10 +8020,6 @@ packages: resolution: {integrity: sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - restore-cursor@5.1.0: - resolution: {integrity: sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==} - engines: {node: '>=18'} - ret@0.2.2: resolution: {integrity: sha512-M0b3YWQs7R3Z917WRQy1HHA7Ba7D8hvZg6UE5mLykJxQVE2ju0IXbGlaHPPlkY+WN7wFP+wUMXmBFA0aV6vYGQ==} engines: {node: '>=4'} @@ -16424,8 +16409,6 @@ snapshots: mimic-fn@4.0.0: {} - mimic-function@5.0.1: {} - mimic-response@3.1.0: {} mimic-response@4.0.0: {} @@ -16686,10 +16669,6 @@ snapshots: dependencies: mimic-fn: 4.0.0 - onetime@7.0.0: - dependencies: - mimic-function: 5.0.1 - oniguruma-to-js@0.4.3: dependencies: regex: 4.3.3 @@ -17313,11 +17292,6 @@ snapshots: onetime: 5.1.2 signal-exit: 3.0.7 - restore-cursor@5.1.0: - dependencies: - onetime: 7.0.0 - signal-exit: 4.1.0 - ret@0.2.2: {} reusify@1.0.4: {}