From f6f68cb2db1cb489ddef139e269da2201c4df196 Mon Sep 17 00:00:00 2001 From: semimikoh Date: Sat, 18 Apr 2026 12:34:15 +0900 Subject: [PATCH] assert: avoid expensive diff for large values --- lib/internal/assert/assertion_error.js | 16 ++++++++++++++++ test/parallel/test-assert-deep.js | 13 +++++++++++++ 2 files changed, 29 insertions(+) diff --git a/lib/internal/assert/assertion_error.js b/lib/internal/assert/assertion_error.js index 5dbf1e7a341380..8fb8134ac1d6cd 100644 --- a/lib/internal/assert/assertion_error.js +++ b/lib/internal/assert/assertion_error.js @@ -42,6 +42,8 @@ const kReadableOperator = { const kMaxShortStringLength = 12; const kMaxLongStringLength = 512; +const kMaxDiffLineCount = 1000; +const kMaxDiffLinesToShow = 50; const kMethodsWithCustomMessageDiff = new SafeSet() .add('deepStrictEqual') @@ -182,6 +184,13 @@ function isSimpleDiff(actual, inspectedActual, expected, inspectedExpected) { return typeof actual !== 'object' || actual === null || typeof expected !== 'object' || expected === null; } +function getTruncatedDiffValue(lines) { + if (lines.length > kMaxDiffLinesToShow) { + return `${ArrayPrototypeJoin(ArrayPrototypeSlice(lines, 0, kMaxDiffLinesToShow), '\n')}\n...`; + } + return ArrayPrototypeJoin(lines, '\n'); +} + function createErrDiff(actual, expected, operator, customMessage, diffType = 'simple') { operator = checkOperator(actual, expected, operator); @@ -213,6 +222,13 @@ function createErrDiff(actual, expected, operator, customMessage, diffType = 'si message = ArrayPrototypeJoin(inspectedSplitActual, '\n'); } header = ''; + } else if ( + diffType !== 'full' && + inspectedSplitActual.length + inspectedSplitExpected.length > kMaxDiffLineCount + ) { + message = `\n${colors.green}+${colors.white} ${getTruncatedDiffValue(inspectedSplitActual)}\n` + + `${colors.red}-${colors.white} ${getTruncatedDiffValue(inspectedSplitExpected)}`; + skipped = true; } else { const checkCommaDisparity = actual != null && typeof actual === 'object'; const diff = myersDiff(inspectedSplitActual, inspectedSplitExpected, checkCommaDisparity); diff --git a/test/parallel/test-assert-deep.js b/test/parallel/test-assert-deep.js index 5d856bf1f378b9..dc72f5c7654394 100644 --- a/test/parallel/test-assert-deep.js +++ b/test/parallel/test-assert-deep.js @@ -1180,6 +1180,19 @@ test('Strict equal with identical objects that are not identical ' + ); }); +test('Strict equal skips line diff for very large objects', () => { + const buffer = Buffer.alloc(1_000); + + assert.throws( + () => assert.strictEqual(buffer, [buffer]), + { + code: 'ERR_ASSERTION', + name: 'AssertionError', + message: /Skipped lines[\s\S]*Buffer\(1000\)/ + } + ); +}); + test('Basic valueOf check', () => { const a = new String(1); a.valueOf = undefined;