Repository: nodejs/node
Pull request: assert: move assert.fail with multiple arguments to eol

Calling `assert.fail` with multiple arguments has been deprecated for years. Remove it finally.



Changed files:
filename: doc/api/assert.md
patch: @@ -1071,107 +1071,6 @@ assert.fail(new TypeError('need array'));
 // TypeError: need array
 ```
 
-Using `assert.fail()` with more than two arguments is possible but deprecated.
-See below for further details.
-
-## `assert.fail(actual, expected[, message[, operator[, stackStartFn]]])`
-
-<!-- YAML
-added: v0.1.21
-changes:
-  - version: v10.0.0
-    pr-url: https://github.com/nodejs/node/pull/18418
-    description: Calling `assert.fail()` with more than one argument is
-                 deprecated and emits a warning.
--->
-
-> Stability: 0 - Deprecated: Use `assert.fail([message])` or other assert
-> functions instead.
-
-* `actual` {any}
-* `expected` {any}
-* `message` {string|Error}
-* `operator` {string} **Default:** `'!='`
-* `stackStartFn` {Function} **Default:** `assert.fail`
-
-If `message` is falsy, the error message is set as the values of `actual` and
-`expected` separated by the provided `operator`. If just the two `actual` and
-`expected` arguments are provided, `operator` will default to `'!='`. If
-`message` is provided as third argument it will be used as the error message and
-the other arguments will be stored as properties on the thrown object. If
-`stackStartFn` is provided, all stack frames above that function will be
-removed from stacktrace (see [`Error.captureStackTrace`][]). If no arguments are
-given, the default message `Failed` will be used.
-
-```mjs
-import assert from 'node:assert/strict';
-
-assert.fail('a', 'b');
-// AssertionError [ERR_ASSERTION]: 'a' != 'b'
-
-assert.fail(1, 2, undefined, '>');
-// AssertionError [ERR_ASSERTION]: 1 > 2
-
-assert.fail(1, 2, 'fail');
-// AssertionError [ERR_ASSERTION]: fail
-
-assert.fail(1, 2, 'whoops', '>');
-// AssertionError [ERR_ASSERTION]: whoops
-
-assert.fail(1, 2, new TypeError('need array'));
-// TypeError: need array
-```
-
-```cjs
-const assert = require('node:assert/strict');
-
-assert.fail('a', 'b');
-// AssertionError [ERR_ASSERTION]: 'a' != 'b'
-
-assert.fail(1, 2, undefined, '>');
-// AssertionError [ERR_ASSERTION]: 1 > 2
-
-assert.fail(1, 2, 'fail');
-// AssertionError [ERR_ASSERTION]: fail
-
-assert.fail(1, 2, 'whoops', '>');
-// AssertionError [ERR_ASSERTION]: whoops
-
-assert.fail(1, 2, new TypeError('need array'));
-// TypeError: need array
-```
-
-In the last three cases `actual`, `expected`, and `operator` have no
-influence on the error message.
-
-Example use of `stackStartFn` for truncating the exception's stacktrace:
-
-```mjs
-import assert from 'node:assert/strict';
-
-function suppressFrame() {
-  assert.fail('a', 'b', undefined, '!==', suppressFrame);
-}
-suppressFrame();
-// AssertionError [ERR_ASSERTION]: 'a' !== 'b'
-//     at repl:1:1
-//     at ContextifyScript.Script.runInThisContext (vm.js:44:33)
-//     ...
-```
-
-```cjs
-const assert = require('node:assert/strict');
-
-function suppressFrame() {
-  assert.fail('a', 'b', undefined, '!==', suppressFrame);
-}
-suppressFrame();
-// AssertionError [ERR_ASSERTION]: 'a' !== 'b'
-//     at repl:1:1
-//     at ContextifyScript.Script.runInThisContext (vm.js:44:33)
-//     ...
-```
-
 ## `assert.ifError(value)`
 
 <!-- YAML
@@ -2437,7 +2336,6 @@ assert.partialDeepStrictEqual(
 [`AssertionError`]: #class-assertassertionerror
 [`Class`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes
 [`ERR_INVALID_RETURN_VALUE`]: errors.md#err_invalid_return_value
-[`Error.captureStackTrace`]: errors.md#errorcapturestacktracetargetobject-constructoropt
 [`Object.is()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
 [`assert.deepEqual()`]: #assertdeepequalactual-expected-message
 [`assert.deepStrictEqual()`]: #assertdeepstrictequalactual-expected-message

filename: doc/api/deprecations.md
patch: @@ -2068,12 +2068,15 @@ and `crypto.getFips()` instead.
 
 <!-- YAML
 changes:
+  - version: REPLACEME
+    pr-url: https://github.com/nodejs/node/pull/58532
+    description: End-of-Life.
   - version: v10.0.0
     pr-url: https://github.com/nodejs/node/pull/18418
     description: Runtime deprecation.
 -->
 
-Type: Runtime
+Type: End-of-Life
 
 Using `assert.fail()` with more than one argument is deprecated. Use
 `assert.fail()` with only one argument or use a different `node:assert` module

filename: lib/assert.js
patch: @@ -72,8 +72,6 @@ function lazyLoadComparison() {
   isPartialStrictEqual = comparison.isPartialStrictEqual;
 }
 
-let warned = false;
-
 // The assert module provides functions that throw
 // AssertionError's when particular conditions are not met. The
 // assert module must conform to the following interface.
@@ -95,43 +93,21 @@ function innerFail(obj) {
 }
 
 /**
- * @param {any} actual
- * @param {any} expected
- * @param {string | Error} [message]
- * @param {string} [operator]
- * @param {Function} [stackStartFn]
+ * Throws an AssertionError with the given message.
+ * @param {any | Error} [message]
  */
-function fail(actual, expected, message, operator, stackStartFn) {
-  const argsLen = arguments.length;
+function fail(message) {
+  if (isError(message)) throw message;
 
   let internalMessage = false;
-  if (actual == null && argsLen <= 1) {
-    internalMessage = true;
+  if (message === undefined) {
     message = 'Failed';
-  } else if (argsLen === 1) {
-    message = actual;
-    actual = undefined;
-  } else {
-    if (warned === false) {
-      warned = true;
-      process.emitWarning(
-        'assert.fail() with more than one argument is deprecated. ' +
-          'Please use assert.strictEqual() instead or only pass a message.',
-        'DeprecationWarning',
-        'DEP0094',
-      );
-    }
-    if (argsLen === 2)
-      operator = '!=';
+    internalMessage = true;
   }
 
-  if (message instanceof Error) throw message;
-
   const errArgs = {
-    actual,
-    expected,
-    operator: operator === undefined ? 'fail' : operator,
-    stackStartFn: stackStartFn || fail,
+    operator: 'fail',
+    stackStartFn: fail,
     message,
   };
   const err = new AssertionError(errArgs);

filename: test/parallel/test-assert-fail-deprecation.js
patch: @@ -1,70 +0,0 @@
-// Flags: --no-warnings
-'use strict';
-
-const { expectWarning } = require('../common');
-const assert = require('assert');
-const { test } = require('node:test');
-
-expectWarning(
-  'DeprecationWarning',
-  'assert.fail() with more than one argument is deprecated. ' +
-    'Please use assert.strictEqual() instead or only pass a message.',
-  'DEP0094'
-);
-
-test('Two args only, operator defaults to "!="', () => {
-  assert.throws(() => {
-    assert.fail('first', 'second');
-  }, {
-    code: 'ERR_ASSERTION',
-    name: 'AssertionError',
-    message: '\'first\' != \'second\'',
-    operator: '!=',
-    actual: 'first',
-    expected: 'second',
-    generatedMessage: true
-  });
-});
-
-test('Three args', () => {
-  assert.throws(() => {
-    assert.fail('ignored', 'ignored', 'another custom message');
-  }, {
-    code: 'ERR_ASSERTION',
-    name: 'AssertionError',
-    message: 'another custom message',
-    operator: 'fail',
-    actual: 'ignored',
-    expected: 'ignored',
-    generatedMessage: false
-  });
-});
-
-test('Three args with custom Error', () => {
-  assert.throws(() => {
-    assert.fail(typeof 1, 'object', new TypeError('another custom message'));
-  }, {
-    name: 'TypeError',
-    message: 'another custom message'
-  });
-});
-
-test('No third arg (but a fourth arg)', () => {
-  assert.throws(() => {
-    assert.fail('first', 'second', undefined, 'operator');
-  }, {
-    code: 'ERR_ASSERTION',
-    name: 'AssertionError',
-    message: '\'first\' operator \'second\'',
-    operator: 'operator',
-    actual: 'first',
-    expected: 'second'
-  });
-});
-
-test('The stackFrameFunction should exclude the foo frame', () => {
-  assert.throws(
-    function foo() { assert.fail('first', 'second', 'message', '!==', foo); },
-    (err) => !/^\s*at\sfoo\b/m.test(err.stack)
-  );
-});