From 0fce2c80effc68464cd1fad023fb9f302a052dfe Mon Sep 17 00:00:00 2001 From: Arham Wani Date: Mon, 10 Aug 2026 06:33:47 +0530 Subject: [PATCH] assert: keep the beginning of long strings when truncating `addEllipsis()` truncates the long single-line `actual`/`expected` values shown in `AssertionError`'s custom inspect output. For a string longer than `kMaxLongStringLength` (512) it called `StringPrototypeSlice(string, kMaxLongStringLength)`, which drops the first 512 characters and keeps the tail, then appends `...` as if the end had been cut off. The three sibling truncations in the same file and the multi-line branch of this same function all keep the beginning of the string instead. Pass a start index of `0` so the first 512 characters are kept, which matches the sibling behaviour and the trailing `...`. The existing tests used homogeneous strings (`'A'.repeat(n)`), so the head and tail were indistinguishable and the buggy tail length was baked into the expectations; update those and add a heterogeneous regression test that actually distinguishes the beginning from the end. Signed-off-by: Arham Wani --- lib/internal/assert/assertion_error.js | 2 +- test/parallel/test-assert-class.js | 4 ++-- test/parallel/test-assert.js | 18 +++++++++++++++++- 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/lib/internal/assert/assertion_error.js b/lib/internal/assert/assertion_error.js index 5dbf1e7a3413..06eb4dead697 100644 --- a/lib/internal/assert/assertion_error.js +++ b/lib/internal/assert/assertion_error.js @@ -241,7 +241,7 @@ function addEllipsis(string) { lines.length = 10; return `${ArrayPrototypeJoin(lines, '\n')}\n...`; } else if (string.length > kMaxLongStringLength) { - return `${StringPrototypeSlice(string, kMaxLongStringLength)}...`; + return `${StringPrototypeSlice(string, 0, kMaxLongStringLength)}...`; } return string; } diff --git a/test/parallel/test-assert-class.js b/test/parallel/test-assert-class.js index cccc7a2f36ff..d9a07c86fc19 100644 --- a/test/parallel/test-assert-class.js +++ b/test/parallel/test-assert-class.js @@ -166,8 +166,8 @@ const truncatedBs = 'B\\n'.repeat(10) + '...'; const longStringOfAs = 'A'.repeat(10_000); const longStringOfBs = 'B'.repeat(10_000); -const longLinesOfAsWithEllipsis = longStringOfAs.substring(0, 9_488) + '...'; -const longLinesOFBsWithEllipsis = longStringOfBs.substring(0, 9_488) + '...'; +const longLinesOfAsWithEllipsis = longStringOfAs.substring(0, 512) + '...'; +const longLinesOFBsWithEllipsis = longStringOfBs.substring(0, 512) + '...'; test('Assert class non strict with full diff', () => { const assertInstance = new Assert({ diff: 'full', strict: false }); diff --git a/test/parallel/test-assert.js b/test/parallel/test-assert.js index d443bd54464f..fa5df83fe07d 100644 --- a/test/parallel/test-assert.js +++ b/test/parallel/test-assert.js @@ -538,7 +538,23 @@ test('Long values should be truncated for display', () => { `${strictEqualMessageStart}+ actual - expected\n\n` + `+ '${'A'.repeat(1000)}'\n- ''\n`); assert.strictEqual(err.actual.length, 1000); - assert.ok(inspect(err).includes(`actual: '${'A'.repeat(488)}...'`)); + assert.ok(inspect(err).includes(`actual: '${'A'.repeat(512)}...'`)); + return true; + }); +}); + +test('Truncated long values should keep the beginning of the string', () => { + // Use a heterogeneous string so the retained portion is distinguishable + // from the discarded portion (a homogeneous string cannot tell the head + // from the tail). The first `kMaxLongStringLength` (512) characters should + // be kept, followed by an ellipsis. + const actual = 'a'.repeat(300) + 'b'.repeat(300); + assert.throws(() => { + assert.strictEqual(actual, ''); + }, (err) => { + const kept = `${'a'.repeat(300)}${'b'.repeat(212)}`; + assert.ok(inspect(err).includes(`actual: '${kept}...'`), + `expected the beginning of the string to be kept, got ${inspect(err)}`); return true; }); });