From e02467ef36257859ed29a35f672bafe24df97c66 Mon Sep 17 00:00:00 2001 From: Nicolas DUBIEN Date: Sat, 11 May 2024 15:27:01 +0200 Subject: [PATCH] fix: support inspect on strings with unicode (#79) * Support inspect on strings with unicode * Update src/helpers.ts * fix lint --- src/helpers.ts | 10 +++++++++- test/strings.js | 19 +++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/src/helpers.ts b/src/helpers.ts index 39a494f..1b41d29 100644 --- a/src/helpers.ts +++ b/src/helpers.ts @@ -93,6 +93,10 @@ export function normaliseOptions( return options } +function isHighSurrogate(char: string): boolean { + return char >= '\ud800' && char <= '\udbff' +} + export function truncate(string: string | number, length: number, tail: typeof truncator = truncator) { string = String(string) const tailLength = tail.length @@ -101,7 +105,11 @@ export function truncate(string: string | number, length: number, tail: typeof t return tail } if (stringLength > length && stringLength > tailLength) { - return `${string.slice(0, length - tailLength)}${tail}` + let end = length - tailLength + if (end > 0 && isHighSurrogate(string[end - 1])) { + end = end - 1 + } + return `${string.slice(0, end)}${tail}` } return string } diff --git a/test/strings.js b/test/strings.js index aae1140..afe1fe7 100644 --- a/test/strings.js +++ b/test/strings.js @@ -59,6 +59,25 @@ describe('strings', () => { expect(inspect('foobarbaz', { truncate: 3 })).to.equal("'โ€ฆ'") }) + it('truncates strings involving surrogate pairs longer than truncate (7)', () => { + // not '๐Ÿฑ๐Ÿฑ\ud83dโ€ฆ' (length 7) but '๐Ÿฑ๐Ÿฑโ€ฆ' (length 6) + expect(inspect('๐Ÿฑ๐Ÿฑ๐Ÿฑ', { truncate: 7 })).to.equal("'๐Ÿฑ๐Ÿฑโ€ฆ'") + }) + + it('truncates strings involving surrogate pairs longer than truncate (6)', () => { + expect(inspect('๐Ÿฑ๐Ÿฑ๐Ÿฑ', { truncate: 6 })).to.equal("'๐Ÿฑโ€ฆ'") + }) + + it('truncates strings involving surrogate pairs longer than truncate (5)', () => { + // not '๐Ÿฑ\ud83dโ€ฆ' (length 5) but '๐Ÿฑโ€ฆ' (length 4) + expect(inspect('๐Ÿฑ๐Ÿฑ๐Ÿฑ', { truncate: 5 })).to.equal("'๐Ÿฑโ€ฆ'") + }) + + it('truncates strings involving graphemes than truncate (5)', () => { + // partial support: valid string for unicode + expect(inspect('๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘งโ€๐Ÿ‘ง', { truncate: 5 })).to.equal("'๐Ÿ‘จโ€ฆ'") + }) + it('disregards truncate when it cannot truncate further (2)', () => { expect(inspect('foobarbaz', { truncate: 2 })).to.equal("'โ€ฆ'") })