Skip to content

Commit

Permalink
assert: differentiate cases where cause is undefined or missing
Browse files Browse the repository at this point in the history
PR-URL: #55738
Reviewed-By: LiviaMedeiros <[email protected]>
Reviewed-By: Ruben Bridgewater <[email protected]>
Reviewed-By: Chengzhong Wu <[email protected]>
Reviewed-By: Luigi Pinca <[email protected]>
  • Loading branch information
aduh95 authored Nov 8, 2024
1 parent 979526f commit 6af5c4e
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 5 deletions.
5 changes: 3 additions & 2 deletions lib/internal/assert/assertion_error.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const {
ObjectAssign,
ObjectDefineProperty,
ObjectGetPrototypeOf,
ObjectPrototypeHasOwnProperty,
String,
StringPrototypeRepeat,
StringPrototypeSlice,
Expand Down Expand Up @@ -49,8 +50,8 @@ function copyError(source) {
__proto__: null,
value: source.message,
});
if (source.cause !== undefined) {
let cause = source.cause;
if (ObjectPrototypeHasOwnProperty(source, 'cause')) {
let { cause } = source;

if (isError(cause)) {
cause = copyError(cause);
Expand Down
9 changes: 6 additions & 3 deletions lib/internal/util/comparisons.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ const {
const { compare } = internalBinding('buffer');
const assert = require('internal/assert');
const { isURL } = require('internal/url');
const { isError } = require('internal/util');
const types = require('internal/util/types');
const {
isAnyArrayBuffer,
Expand Down Expand Up @@ -235,10 +236,10 @@ function innerDeepEqual(val1, val2, strict, memos) {
if (!isAnyArrayBuffer(val2) || !areEqualArrayBuffers(val1, val2)) {
return false;
}
} else if (isNativeError(val1) || val1 instanceof Error) {
} else if (isError(val1)) {
// Do not compare the stack as it might differ even though the error itself
// is otherwise identical.
if (!isNativeError(val2) && !(val2 instanceof Error)) {
if (!isError(val2)) {
return false;
}

Expand All @@ -252,7 +253,9 @@ function innerDeepEqual(val1, val2, strict, memos) {
(name1Enumerable !== ObjectPrototypePropertyIsEnumerable(val2, 'name') ||
(!name1Enumerable && val1.name !== val2.name)) ||
(cause1Enumerable !== ObjectPrototypePropertyIsEnumerable(val2, 'cause') ||
(!cause1Enumerable && !innerDeepEqual(val1.cause, val2.cause, strict, memos))) ||
(!cause1Enumerable && (
ObjectPrototypeHasOwnProperty(val1, 'cause') !== ObjectPrototypeHasOwnProperty(val2, 'cause') ||
!innerDeepEqual(val1.cause, val2.cause, strict, memos)))) ||
(errors1Enumerable !== ObjectPrototypePropertyIsEnumerable(val2, 'errors') ||
(!errors1Enumerable && !innerDeepEqual(val1.errors, val2.errors, strict, memos)))) {
return false;
Expand Down
43 changes: 43 additions & 0 deletions test/parallel/test-assert-deep-with-error.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,26 @@ const defaultStartMessage = 'Expected values to be strictly deep-equal:\n' +
'\n';

test('Handle error causes', () => {
assert.deepStrictEqual(new Error('a', { cause: new Error('x') }), new Error('a', { cause: new Error('x') }));
assert.deepStrictEqual(
new Error('a', { cause: new RangeError('x') }),
new Error('a', { cause: new RangeError('x') }),
);

assert.throws(() => {
assert.deepStrictEqual(new Error('a', { cause: new Error('x') }), new Error('a', { cause: new Error('y') }));
}, { message: defaultStartMessage + ' [Error: a] {\n' +
'+ [cause]: [Error: x]\n' +
'- [cause]: [Error: y]\n' +
' }\n' });

assert.throws(() => {
assert.deepStrictEqual(new Error('a', { cause: new Error('x') }), new Error('a', { cause: new TypeError('x') }));
}, { message: defaultStartMessage + ' [Error: a] {\n' +
'+ [cause]: [Error: x]\n' +
'- [cause]: [TypeError: x]\n' +
' }\n' });

assert.throws(() => {
assert.deepStrictEqual(new Error('a'), new Error('a', { cause: new Error('y') }));
}, { message: defaultStartMessage + '+ [Error: a]\n' +
Expand All @@ -37,3 +50,33 @@ test('Handle error causes', () => {
new Error('a', { cause: { prop: 'a different value' } })
);
});

test('Handle undefined causes', () => {
assert.deepStrictEqual(new Error('a', { cause: undefined }), new Error('a', { cause: undefined }));

assert.notDeepStrictEqual(new Error('a', { cause: 'undefined' }), new Error('a', { cause: undefined }));
assert.notDeepStrictEqual(new Error('a', { cause: undefined }), new Error('a'));
assert.notDeepStrictEqual(new Error('a'), new Error('a', { cause: undefined }));

assert.throws(() => {
assert.deepStrictEqual(new Error('a'), new Error('a', { cause: undefined }));
}, { message: defaultStartMessage +
'+ [Error: a]\n' +
'- [Error: a] {\n' +
'- [cause]: undefined\n' +
'- }\n' });

assert.throws(() => {
assert.deepStrictEqual(new Error('a', { cause: undefined }), new Error('a'));
}, { message: defaultStartMessage +
'+ [Error: a] {\n' +
'+ [cause]: undefined\n' +
'+ }\n' +
'- [Error: a]\n' });
assert.throws(() => {
assert.deepStrictEqual(new Error('a', { cause: undefined }), new Error('a', { cause: 'undefined' }));
}, { message: defaultStartMessage + ' [Error: a] {\n' +
'+ [cause]: undefined\n' +
'- [cause]: \'undefined\'\n' +
' }\n' });
});

0 comments on commit 6af5c4e

Please sign in to comment.