diff options
Diffstat (limited to 'cli')
-rw-r--r-- | cli/js/40_test.js | 19 | ||||
-rw-r--r-- | cli/tests/unit/os_test.ts | 94 | ||||
-rw-r--r-- | cli/tsc/dts/lib.deno.ns.d.ts | 17 |
3 files changed, 129 insertions, 1 deletions
diff --git a/cli/js/40_test.js b/cli/js/40_test.js index 2877bfa9b..5a081e217 100644 --- a/cli/js/40_test.js +++ b/cli/js/40_test.js @@ -28,6 +28,10 @@ const { import { setExitHandler } from "ext:runtime/30_os.js"; +// Capture `Deno` global so that users deleting or mangling it, won't +// have impact on our sanitizers. +const DenoNs = globalThis.Deno; + /** * @typedef {{ * id: number, @@ -101,7 +105,20 @@ function assertExit(fn, isTest) { try { const innerResult = await fn(...new SafeArrayIterator(params)); - if (innerResult) return innerResult; + const exitCode = DenoNs.exitCode; + if (exitCode !== 0) { + // Reset the code to allow other tests to run... + DenoNs.exitCode = 0; + // ...and fail the current test. + throw new Error( + `${ + isTest ? "Test case" : "Bench" + } finished with exit code set to ${exitCode}.`, + ); + } + if (innerResult) { + return innerResult; + } } finally { setExitHandler(null); } diff --git a/cli/tests/unit/os_test.ts b/cli/tests/unit/os_test.ts new file mode 100644 index 000000000..af6ef219a --- /dev/null +++ b/cli/tests/unit/os_test.ts @@ -0,0 +1,94 @@ +// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. + +import { assertEquals, assertThrows } from "../../testing/asserts.ts"; + +Deno.test("Deno.exitCode getter and setter", () => { + // Initial value is 0 + assertEquals(Deno.exitCode, 0); + + // Set a new value + Deno.exitCode = 5; + assertEquals(Deno.exitCode, 5); + + // Reset to initial value + Deno.exitCode = 0; + assertEquals(Deno.exitCode, 0); +}); + +Deno.test("Setting Deno.exitCode to NaN throws TypeError", () => { + // @ts-expect-error; + Deno.exitCode = "123"; + assertEquals(Deno.exitCode, 123); + + // Reset + Deno.exitCode = 0; + assertEquals(Deno.exitCode, 0); + + // Throws on non-number values + assertThrows( + () => { + // @ts-expect-error Testing for runtime error + Deno.exitCode = "not a number"; + }, + TypeError, + "Exit code must be a number.", + ); +}); + +Deno.test("Setting Deno.exitCode does not cause an immediate exit", () => { + let exited = false; + const originalExit = Deno.exit; + + // @ts-expect-error; read-only + Deno.exit = () => { + exited = true; + }; + + Deno.exitCode = 1; + assertEquals(exited, false); + + // @ts-expect-error; read-only + Deno.exit = originalExit; +}); + +Deno.test("Running Deno.exit(value) overrides Deno.exitCode", () => { + let args: unknown[] | undefined; + + const originalExit = Deno.exit; + // @ts-expect-error; read-only + Deno.exit = (...x) => { + args = x; + }; + + Deno.exitCode = 42; + Deno.exit(0); + + assertEquals(args, [0]); + // @ts-expect-error; read-only + Deno.exit = originalExit; +}); + +Deno.test("Running Deno.exit() uses Deno.exitCode as fallback", () => { + let args: unknown[] | undefined; + + const originalExit = Deno.exit; + // @ts-expect-error; read-only + Deno.exit = (...x) => { + args = x; + }; + + Deno.exitCode = 42; + Deno.exit(); + + assertEquals(args, [42]); + // @ts-expect-error; read-only + Deno.exit = originalExit; +}); + +Deno.test("Retrieving the set exit code before process termination", () => { + Deno.exitCode = 42; + assertEquals(Deno.exitCode, 42); + + // Reset to initial value + Deno.exitCode = 0; +}); diff --git a/cli/tsc/dts/lib.deno.ns.d.ts b/cli/tsc/dts/lib.deno.ns.d.ts index 76b59761c..cf8e4ba05 100644 --- a/cli/tsc/dts/lib.deno.ns.d.ts +++ b/cli/tsc/dts/lib.deno.ns.d.ts @@ -1466,6 +1466,23 @@ declare namespace Deno { */ export function exit(code?: number): never; + /** The exit code for the Deno process. + * + * If no exit code has been supplied, then Deno will assume a return code of `0`. + * + * When setting an exit code value, a number or non-NaN string must be provided, + * otherwise a TypeError will be thrown. + * + * ```ts + * console.log(Deno.exitCode); //-> 0 + * Deno.exitCode = 1; + * console.log(Deno.exitCode); //-> 1 + * ``` + * + * @category Runtime + */ + export var exitCode: number; + /** An interface containing methods to interact with the process environment * variables. * |