summaryrefslogtreecommitdiff
path: root/cli
diff options
context:
space:
mode:
Diffstat (limited to 'cli')
-rw-r--r--cli/js/40_test.js19
-rw-r--r--cli/tests/unit/os_test.ts94
-rw-r--r--cli/tsc/dts/lib.deno.ns.d.ts17
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.
*