From 4f5d11e6fbb791bf4cdd21c5e900f740452da04c Mon Sep 17 00:00:00 2001 From: Miguel Marcondes Filho Date: Tue, 5 Aug 2025 11:15:02 -0300 Subject: [PATCH] lib: restructure assert to become a class MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR-URL: https://github.com/nodejs/node/pull/58253 Reviewed-By: Ruben Bridgewater Reviewed-By: Michaël Zasso Reviewed-By: Antoine du Hamel Reviewed-By: James M Snell Reviewed-By: Matteo Collina --- doc/api/assert.md | 47 ++ lib/assert.js | 153 +++++- lib/internal/assert/assertion_error.js | 19 +- lib/internal/errors.js | 1 + test/fixtures/errors/error_exit.snapshot | 3 +- .../errors/if-error-has-good-stack.snapshot | 3 +- .../output/assertion-color-tty.snapshot | 3 +- .../test-runner/output/dot_reporter.snapshot | 6 +- .../output/junit_reporter.snapshot | 6 +- .../test-runner/output/spec_reporter.snapshot | 6 +- .../output/spec_reporter_cli.snapshot | 6 +- test/message/assert_throws_stack.out | 4 +- .../test-assert-class-destructuring.js | 133 +++++ test/parallel/test-assert-class.js | 480 ++++++++++++++++++ test/parallel/test-runner-assert.js | 2 + 15 files changed, 823 insertions(+), 49 deletions(-) create mode 100644 test/parallel/test-assert-class-destructuring.js create mode 100644 test/parallel/test-assert-class.js diff --git a/doc/api/assert.md b/doc/api/assert.md index f063c84af9a..e7b21b58b28 100644 --- a/doc/api/assert.md +++ b/doc/api/assert.md @@ -149,6 +149,8 @@ added: v0.1.21 * `operator` {string} The `operator` property on the error instance. * `stackStartFn` {Function} If provided, the generated stack trace omits frames before this function. + * `diff` {string} If set to `'full'`, shows the full diff in assertion errors. Defaults to `'simple'`. + Accepted values: `'simple'`, `'full'`. A subclass of {Error} that indicates the failure of an assertion. @@ -215,6 +217,51 @@ try { } ``` +## Class: `assert.Assert` + + + +The `Assert` class allows creating independent assertion instances with custom options. + +### `new assert.Assert([options])` + +* `options` {Object} + * `diff` {string} If set to `'full'`, shows the full diff in assertion errors. Defaults to `'simple'`. + Accepted values: `'simple'`, `'full'`. + * `strict` {boolean} If set to `true`, non-strict methods behave like their + corresponding strict methods. Defaults to `true`. + +Creates a new assertion instance. The `diff` option controls the verbosity of diffs in assertion error messages. + +```js +const { Assert } = require('node:assert'); +const assertInstance = new Assert({ diff: 'full' }); +assertInstance.deepStrictEqual({ a: 1 }, { a: 2 }); +// Shows a full diff in the error message. +``` + +**Important**: When destructuring assertion methods from an `Assert` instance, +the methods lose their connection to the instance's configuration options (such as `diff` and `strict` settings). +The destructured methods will fall back to default behavior instead. + +```js +const myAssert = new Assert({ diff: 'full' }); + +// This works as expected - uses 'full' diff +myAssert.strictEqual({ a: 1 }, { b: { c: 1 } }); + +// This loses the 'full' diff setting - falls back to default 'simple' diff +const { strictEqual } = myAssert; +strictEqual({ a: 1 }, { b: { c: 1 } }); +``` + +When destructured, methods lose access to the instance's `this` context and revert to default assertion behavior +(diff: 'simple', non-strict mode). +To maintain custom options when using destructured methods, avoid +destructuring and call methods directly on the instance. + ## `assert(value[, message])`