Repository: denoland/deno
Pull request: fix(ext/node): align assert throws/rejects signatures

Fixes #31931

Changed files:
filename: ext/node/polyfills/assert.ts
patch: @@ -519,46 +519,34 @@ function expectsNoError(
 
 function throws(
   fn: () => void,
-  message?: string,
-): void;
-function throws(
-  fn: () => void,
-  error?: Function,
   message?: string | Error,
 ): void;
 function throws(
   fn: () => void,
-  error?: RegExp,
-  message?: string,
+  error?: AssertPredicate,
+  message?: string | Error,
 ): void;
 function throws(
   fn: () => void,
-  expected?: AssertPredicate | string,
-  message?: Error | string,
+  ...args: [(AssertPredicate | string)?, (string | Error)?]
 ) {
-  expectsError(throws, getActual(fn), expected, message);
+  expectsError(throws, getActual(fn), ...args);
 }
 
 function doesNotThrow(
   fn: () => void,
-  message?: string,
-): void;
-function doesNotThrow(
-  fn: () => void,
-  error?: Function,
   message?: string | Error,
 ): void;
 function doesNotThrow(
   fn: () => void,
-  error?: RegExp,
-  message?: string,
+  error?: AssertPredicate,
+  message?: string | Error,
 ): void;
 function doesNotThrow(
   fn: () => void,
-  expected?: AssertPredicate | string,
-  message?: Error | string,
+  ...args: [(AssertPredicate | string)?, (string | Error)?]
 ) {
-  expectsNoError(() => {}, getActual(fn), expected, message);
+  expectsNoError(() => {}, getActual(fn), ...args);
 }
 
 function equal(
@@ -871,52 +859,33 @@ function strict(actual: unknown, message?: string | Error): asserts actual {
 }
 
 async function rejects(
-  // deno-lint-ignore no-explicit-any
-  asyncFn: Promise<any> | (() => Promise<any>),
-  error?: RegExp | Function | Error,
+  asyncFn: Promise<unknown> | (() => Promise<unknown>),
+  error?: AssertPredicate,
 ): Promise<void>;
-
 async function rejects(
-  // deno-lint-ignore no-explicit-any
-  asyncFn: Promise<any> | (() => Promise<any>),
-  message?: string,
+  asyncFn: Promise<unknown> | (() => Promise<unknown>),
+  message?: string | Error,
 ): Promise<void>;
-
-// Intentionally avoid using async/await because test-assert-async.js requires it
 async function rejects(
-  // deno-lint-ignore no-explicit-any
-  asyncFn: Promise<any> | (() => Promise<any>),
-  expected?: AssertPredicate | string,
-  message?: Error | string,
+  asyncFn: Promise<unknown> | (() => Promise<unknown>),
+  ...args: [(AssertPredicate | string)?, (string | Error)?]
 ) {
-  expectsError(rejects, await waitForActual(asyncFn), expected, message);
+  expectsError(rejects, await waitForActual(asyncFn), ...args);
 }
 
 async function doesNotReject(
-  // deno-lint-ignore no-explicit-any
-  asyncFn: Promise<any> | (() => Promise<any>),
-  error?: RegExp | Function,
+  asyncFn: Promise<unknown> | (() => Promise<unknown>),
+  error?: AssertPredicate,
 ): Promise<void>;
-
 async function doesNotReject(
-  // deno-lint-ignore no-explicit-any
-  asyncFn: Promise<any> | (() => Promise<any>),
-  message?: string,
+  asyncFn: Promise<unknown> | (() => Promise<unknown>),
+  message?: string | Error,
 ): Promise<void>;
-
-// Intentionally avoid using async/await because test-assert-async.js requires it
 async function doesNotReject(
-  // deno-lint-ignore no-explicit-any
-  asyncFn: Promise<any> | (() => Promise<any>),
-  expected?: AssertPredicate | string,
-  message?: Error | string,
+  asyncFn: Promise<unknown> | (() => Promise<unknown>),
+  ...args: [(AssertPredicate | string)?, (string | Error)?]
 ) {
-  expectsNoError(
-    doesNotReject,
-    await waitForActual(asyncFn),
-    expected,
-    message,
-  );
+  expectsNoError(doesNotReject, await waitForActual(asyncFn), ...args);
 }
 
 /**

filename: tests/unit_node/assert_test.ts
patch: @@ -62,3 +62,73 @@ Deno.test("[node/assert] deepStrictEqual passes for equal Number objects", () =>
     assert.deepStrictEqual(new Number(1), new Number(1));
   });
 });
+
+Deno.test("[node/assert] throws with 2 parameters", () => {
+  assert.throws(
+    () => {
+      throw new Error("test error");
+    },
+    "custom message",
+  );
+});
+
+Deno.test("[node/assert] throws with 3 parameters", () => {
+  assert.throws(
+    () => {
+      throw new TypeError("test error");
+    },
+    TypeError,
+    "custom message",
+  );
+});
+
+Deno.test("[node/assert] doesNotThrow with 2 parameters", () => {
+  assert.doesNotThrow(
+    () => {},
+    "custom message",
+  );
+});
+
+Deno.test("[node/assert] doesNotThrow with 3 parameters", () => {
+  assert.doesNotThrow(
+    () => {},
+    TypeError,
+    "custom message",
+  );
+});
+
+Deno.test("[node/assert] rejects with 2 parameters", async () => {
+  await assert.rejects(
+    // deno-lint-ignore require-await
+    async () => {
+      throw new Error("async error");
+    },
+    "custom message",
+  );
+});
+
+Deno.test("[node/assert] rejects with 3 parameters", async () => {
+  await assert.rejects(
+    // deno-lint-ignore require-await
+    async () => {
+      throw new TypeError("async error");
+    },
+    TypeError,
+    "custom message",
+  );
+});
+
+Deno.test("[node/assert] doesNotReject with 2 parameters", async () => {
+  await assert.doesNotReject(
+    async () => {},
+    "custom message",
+  );
+});
+
+Deno.test("[node/assert] doesNotReject with 3 parameters", async () => {
+  await assert.doesNotReject(
+    async () => {},
+    TypeError,
+    "custom message",
+  );
+});