Skip to content

Changing assert to become a class #58253

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 16 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
ed5089e
lib: restructure assert to use clasd implementation for basics assert
miguelmarcondesf Apr 25, 2025
c2099b0
lib: change static methods and add other compare methods
miguelmarcondesf May 4, 2025
8a4696a
lib: update assert module to use instance methods and preserve origin…
miguelmarcondesf May 5, 2025
95daa94
test: add Assert class tests with additional error scenarios
miguelmarcondesf May 7, 2025
99ab0da
test: update snapshot fixtures
miguelmarcondesf May 8, 2025
ef9d8c5
lib: update Assert class to use instance methods for error handling
miguelmarcondesf May 8, 2025
1313ff0
lib: add doesNotThrow and doesNotReject methods in Assert class
miguelmarcondesf May 8, 2025
d9d39b9
lib: add ifError method to Assert class
miguelmarcondesf May 9, 2025
7fe02ff
lib: refactor expectedException function into a private method in Ass…
miguelmarcondesf May 9, 2025
a6b25e4
lib: refactor compareExceptionKey function into a private method in A…
miguelmarcondesf May 9, 2025
73ed59b
lib: add private #waitForActual method to Assert class for promise ha…
miguelmarcondesf May 9, 2025
9777e7b
lib: add innerFail as private method to Assert class
miguelmarcondesf May 9, 2025
5c484e2
lib: add getActual as priivate method to Assert class
miguelmarcondesf May 9, 2025
bd259c6
lib: move checkIsPromise function to private method in Assert class
miguelmarcondesf May 9, 2025
3f1c996
lib: move hasMatchingError as private method to Assert
miguelmarcondesf May 9, 2025
132925f
test: move Assert class instance tests to separate file
miguelmarcondesf May 9, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,328 changes: 675 additions & 653 deletions lib/assert.js

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions test/fixtures/errors/error_exit.snapshot
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
Exiting with code=1
node:assert:*
throw new AssertionError(obj);
^
throw new AssertionError(obj);
^

AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:

1 !== 2

at Object.<anonymous> (*error_exit.js:*:*) {
at new AssertionError (node:internal*assert*assertion_error:*:*) {
generatedMessage: true,
code: 'ERR_ASSERTION',
actual: 1,
Expand Down
8 changes: 4 additions & 4 deletions test/fixtures/errors/if-error-has-good-stack.snapshot
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
node:assert:*
throw newErr;
^
throw newErr;
^

AssertionError [ERR_ASSERTION]: ifError got unwanted exception: test error
at new AssertionError (node:internal*assert*assertion_error:*:*)
at Assert.ifError (node:assert:*:*)
at z (*if-error-has-good-stack.js:*:*)
at y (*if-error-has-good-stack.js:*:*)
at x (*if-error-has-good-stack.js:*:*)
at Object.<anonymous> (*if-error-has-good-stack.js:*:*)
at c (*if-error-has-good-stack.js:*:*)
at b (*if-error-has-good-stack.js:*:*)
at a (*if-error-has-good-stack.js:*:*)
Expand Down
3 changes: 3 additions & 0 deletions test/fixtures/test-runner/output/describe_it.snapshot
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,9 @@ not ok 14 - async assertion fail
*
*
*
*
*
*
...
# Subtest: resolve pass
ok 15 - resolve pass
Expand Down
3 changes: 3 additions & 0 deletions test/fixtures/test-runner/output/dot_reporter.snapshot
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ Failed tests:
*
*
*
*
*
*
* {
generatedMessage: true,
code: 'ERR_ASSERTION',
Expand Down
3 changes: 3 additions & 0 deletions test/fixtures/test-runner/output/junit_reporter.snapshot
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,9 @@ true !== false
*
*
*
*
*
*
* {
generatedMessage: true,
code: 'ERR_ASSERTION',
Expand Down
3 changes: 3 additions & 0 deletions test/fixtures/test-runner/output/output.snapshot
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,9 @@ not ok 13 - async assertion fail
*
*
*
*
*
*
...
# Subtest: resolve pass
ok 14 - resolve pass
Expand Down
3 changes: 3 additions & 0 deletions test/fixtures/test-runner/output/output_cli.snapshot
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,9 @@ not ok 13 - async assertion fail
*
*
*
*
*
*
...
# Subtest: resolve pass
ok 14 - resolve pass
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ not ok 1 - fails
*
*
*
*
*
*
...
1..1
# tests 1
Expand Down
3 changes: 3 additions & 0 deletions test/fixtures/test-runner/output/spec_reporter.snapshot
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,9 @@
*
*
*
*
*
*
* {
generatedMessage: true,
code: 'ERR_ASSERTION',
Expand Down
3 changes: 3 additions & 0 deletions test/fixtures/test-runner/output/spec_reporter_cli.snapshot
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,9 @@
*
*
*
*
*
*
* {
generatedMessage: true,
code: 'ERR_ASSERTION',
Expand Down
106 changes: 106 additions & 0 deletions test/parallel/test-assert-class.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
'use strict';

require('../common');
const assert = require('assert');
const { Assert } = require('assert');
const { test } = require('node:test');

// Disable colored output to prevent color codes from breaking assertion
// message comparisons. This should only be an issue when process.stdout
// is a TTY.
if (process.stdout.isTTY) {
process.env.NODE_DISABLE_COLORS = '1';
}

test('Assert class basic instance', () => {
const assertInstance = new Assert();

assertInstance.ok(assert.AssertionError.prototype instanceof Error,
'assert.AssertionError instanceof Error');
assertInstance.ok(true);
assertInstance.throws(
() => { assertInstance.fail(); },
{
code: 'ERR_ASSERTION',
name: 'AssertionError',
message: 'Failed',
operator: 'fail',
actual: undefined,
expected: undefined,
generatedMessage: true,
stack: /Failed/
}
);
assertInstance.equal(undefined, undefined);
assertInstance.notEqual(true, false);
assertInstance.throws(
() => assertInstance.deepEqual(/a/),
{ code: 'ERR_MISSING_ARGS' }
);
assertInstance.throws(
() => assertInstance.notDeepEqual('test'),
{ code: 'ERR_MISSING_ARGS' }
);
assertInstance.notStrictEqual(2, '2');
assertInstance.throws(() => assertInstance.strictEqual(2, '2'),
assertInstance.AssertionError, 'strictEqual(2, \'2\')');
assertInstance.throws(
() => {
assertInstance.partialDeepStrictEqual({ a: true }, { a: false }, 'custom message');
},
{
code: 'ERR_ASSERTION',
name: 'AssertionError',
message: 'custom message\n+ actual - expected\n\n {\n+ a: true\n- a: false\n }\n'
}
);
assertInstance.throws(
() => assertInstance.match(/abc/, 'string'),
{
code: 'ERR_INVALID_ARG_TYPE',
message: 'The "regexp" argument must be an instance of RegExp. ' +
"Received type string ('string')"
}
);
assertInstance.throws(
() => assertInstance.doesNotMatch(/abc/, 'string'),
{
code: 'ERR_INVALID_ARG_TYPE',
message: 'The "regexp" argument must be an instance of RegExp. ' +
"Received type string ('string')"
}
);

/* eslint-disable no-restricted-syntax */
{
function thrower(errorConstructor) {
throw new errorConstructor({});
}

let threw = false;
try {
assertInstance.doesNotThrow(() => thrower(TypeError), assertInstance.AssertionError);
} catch (e) {
threw = true;
assertInstance.ok(e instanceof TypeError);
}
assertInstance.ok(threw, 'assertInstance.doesNotThrow with an explicit error is eating extra errors');
}
{
let threw = false;
const rangeError = new RangeError('my range');

try {
assertInstance.doesNotThrow(() => {
throw new TypeError('wrong type');
}, TypeError, rangeError);
} catch (e) {
threw = true;
assertInstance.ok(e.message.includes(rangeError.message));
assertInstance.ok(e instanceof assertInstance.AssertionError);
assertInstance.ok(!e.stack.includes('doesNotThrow'), e);
}
assertInstance.ok(threw);
}
/* eslint-enable no-restricted-syntax */
});
2 changes: 1 addition & 1 deletion test/parallel/test-fs-promises.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ assert.strictEqual(
code: 'ENOENT',
name: 'Error',
message: /^ENOENT: no such file or directory, access/,
stack: /at async ok\.rejects/
stack: /at async Assert\.rejects/
}
).then(common.mustCall());

Expand Down
2 changes: 2 additions & 0 deletions test/parallel/test-runner-assert.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ test('expected methods are on t.assert', (t) => {
const uncopiedKeys = [
'AssertionError',
'strict',
'Assert',
'options',
];
const assertKeys = Object.keys(assert).filter((key) => !uncopiedKeys.includes(key));
const expectedKeys = ['snapshot', 'fileSnapshot'].concat(assertKeys).sort();
Expand Down