From d562da0b5402cf460d28c6d3dd816c9e56a52efe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ari=20Perkki=C3=B6?= Date: Tue, 19 Nov 2024 14:15:12 +0200 Subject: [PATCH 1/3] fix(reporters): tests skipped by `.only` rendered success --- packages/vitest/src/node/reporters/base.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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(' > '))}`) } } } From d659260e7c866c76eb0185dcbb2aa7aff7107e7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ari=20Perkki=C3=B6?= Date: Tue, 19 Nov 2024 14:15:53 +0200 Subject: [PATCH 2/3] fix(reporters): write buffered stdout/stderr on process exit --- packages/vitest/LICENSE.md | 24 --------------- packages/vitest/package.json | 2 +- .../reporters/renderers/windowedRenderer.ts | 11 +++++-- pnpm-lock.yaml | 29 ++----------------- 4 files changed, 13 insertions(+), 53 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..c818601c8b42 100644 --- a/packages/vitest/package.json +++ b/packages/vitest/package.json @@ -162,7 +162,7 @@ "expect-type": "^1.1.0", "magic-string": "^0.30.12", "pathe": "^1.1.2", - "restore-cursor": "^5.1.0", + "signal-exit": "^3.0.7", "std-env": "^3.8.0", "tinybench": "^2.9.0", "tinyexec": "^0.3.1", diff --git a/packages/vitest/src/node/reporters/renderers/windowedRenderer.ts b/packages/vitest/src/node/reporters/renderers/windowedRenderer.ts index 3c7a9dcd2371..b66527cb7f07 100644 --- a/packages/vitest/src/node/reporters/renderers/windowedRenderer.ts +++ b/packages/vitest/src/node/reporters/renderers/windowedRenderer.ts @@ -1,7 +1,9 @@ import type { Writable } from 'node:stream' import type { Vitest } from '../../core' import { stripVTControlCharacters } from 'node:util' -import restoreCursor from 'restore-cursor' + +// @ts-expect-error -- untyped, cannot use v4 due to other deps +import onExit from 'signal-exit' const DEFAULT_RENDER_INTERVAL = 16 @@ -46,12 +48,17 @@ export class WindowRenderer { error: options.logger.errorStream.write.bind(options.logger.errorStream), } + // Write buffered content on unexpected exits, e.g. direct `process.exit()` calls + onExit(() => { + this.flushBuffer() + this.write(SHOW_CURSOR) + }) + this.cleanups.push( this.interceptStream(process.stdout, 'output'), this.interceptStream(process.stderr, 'error'), ) - restoreCursor() this.write(HIDE_CURSOR, 'output') this.start() diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6c8bb9f19afd..d26a8436430d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -883,9 +883,9 @@ importers: pathe: specifier: ^1.1.2 version: 1.1.2 - restore-cursor: - specifier: ^5.1.0 - version: 5.1.0 + signal-exit: + specifier: ^3.0.7 + version: 3.0.7 std-env: specifier: ^3.8.0 version: 3.8.0 @@ -7170,10 +7170,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 +7464,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 +8023,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 +16412,6 @@ snapshots: mimic-fn@4.0.0: {} - mimic-function@5.0.1: {} - mimic-response@3.1.0: {} mimic-response@4.0.0: {} @@ -16686,10 +16672,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 +17295,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: {} From ccba6a0348d841a7d39fddc9135c145f80a687de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ari=20Perkki=C3=B6?= Date: Thu, 21 Nov 2024 09:59:18 +0200 Subject: [PATCH 3/3] refactor: replace `signal-exit` with built-in solution --- packages/vitest/package.json | 1 - .../reporters/renderers/windowedRenderer.ts | 36 ++++++++++++++----- pnpm-lock.yaml | 3 -- 3 files changed, 27 insertions(+), 13 deletions(-) diff --git a/packages/vitest/package.json b/packages/vitest/package.json index c818601c8b42..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", - "signal-exit": "^3.0.7", "std-env": "^3.8.0", "tinybench": "^2.9.0", "tinyexec": "^0.3.1", diff --git a/packages/vitest/src/node/reporters/renderers/windowedRenderer.ts b/packages/vitest/src/node/reporters/renderers/windowedRenderer.ts index b66527cb7f07..649b08a60bb2 100644 --- a/packages/vitest/src/node/reporters/renderers/windowedRenderer.ts +++ b/packages/vitest/src/node/reporters/renderers/windowedRenderer.ts @@ -2,9 +2,6 @@ import type { Writable } from 'node:stream' import type { Vitest } from '../../core' import { stripVTControlCharacters } from 'node:util' -// @ts-expect-error -- untyped, cannot use v4 due to other deps -import onExit from 'signal-exit' - const DEFAULT_RENDER_INTERVAL = 16 const ESC = '\x1B[' @@ -48,15 +45,10 @@ export class WindowRenderer { error: options.logger.errorStream.write.bind(options.logger.errorStream), } - // Write buffered content on unexpected exits, e.g. direct `process.exit()` calls - onExit(() => { - this.flushBuffer() - this.write(SHOW_CURSOR) - }) - this.cleanups.push( this.interceptStream(process.stdout, 'output'), this.interceptStream(process.stderr, 'error'), + this.addProcessExitListeners(), ) this.write(HIDE_CURSOR, 'output') @@ -182,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 d26a8436430d..46ee80d3241f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -883,9 +883,6 @@ importers: pathe: specifier: ^1.1.2 version: 1.1.2 - signal-exit: - specifier: ^3.0.7 - version: 3.0.7 std-env: specifier: ^3.8.0 version: 3.8.0