From 0ca8a493e42a3dbaa2d9560ba772dc12c9ef50ab Mon Sep 17 00:00:00 2001 From: Jos de Jong Date: Thu, 15 Feb 2024 10:14:44 +0100 Subject: [PATCH] fix: improve the logic to determine whether a JSON document needs formatting --- src/lib/utils/jsonUtils.test.ts | 13 +++++++++---- src/lib/utils/jsonUtils.ts | 9 +++++---- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/lib/utils/jsonUtils.test.ts b/src/lib/utils/jsonUtils.test.ts index 4e2d4fa0..5c610abf 100644 --- a/src/lib/utils/jsonUtils.test.ts +++ b/src/lib/utils/jsonUtils.test.ts @@ -406,8 +406,7 @@ describe('jsonUtils', () => { expect(needsFormatting('')).toBe(false) expect(needsFormatting('[\n1,\n 2,\n 3\n]')).toBe(false) - expect(needsFormatting('{\n "a":true,\n "b":false\n}')).toBe(false) - expect(needsFormatting('\n[1,2,3]')).toBe(false) + expect(needsFormatting('{\n "a": true,\n "b": false\n}')).toBe(false) expect(needsFormatting('1234')).toBe(false) expect(needsFormatting('"abc"')).toBe(false) @@ -415,9 +414,15 @@ describe('jsonUtils', () => { expect(needsFormatting('false')).toBe(false) expect(needsFormatting('null')).toBe(false) - // cannot detect partially formatted content - expect(needsFormatting('[1, 2, 3]')).toBe(true) + expect(needsFormatting('[1, 2, 3]')).toBe(false) + expect(needsFormatting('{"a": 1, "b": 2}')).toBe(false) expect(needsFormatting('{"a":1, "b":2}')).toBe(true) + expect(needsFormatting('{\n "a": "some:message"\n}')).toBe(false) + expect(needsFormatting('{\n "a": "some,message"\n}')).toBe(false) + + // a colon or comma inside a string gives a false positive (when the text doesn't contain a return character) + expect(needsFormatting('{"a": "some:message"}')).toBe(true) + expect(needsFormatting('{"a": "some,message"}')).toBe(true) }) }) diff --git a/src/lib/utils/jsonUtils.ts b/src/lib/utils/jsonUtils.ts index 9cd92555..716a6949 100644 --- a/src/lib/utils/jsonUtils.ts +++ b/src/lib/utils/jsonUtils.ts @@ -484,9 +484,10 @@ export function isEqualParser(a: JSONParser, b: JSONParser): boolean { * Apply a fast and cheap heuristic to determine whether the content needs formatting (i.e. is compact). */ export function needsFormatting(jsonText: string): boolean { - // the check for the length>2 is because an empty array or object does not need formatting - return NEEDS_FORMATTING_REGEX.test(jsonText) && jsonText.length > 2 + const maxLength = 999 + const head = jsonText.substring(0, maxLength) + return !head.includes('\n') && DELIMITER_WITHOUT_SPACING_REGEX.test(head) } -// regex that matches the start of an object or array, followed by a non-whitespace character -const NEEDS_FORMATTING_REGEX = /^[[{]\S/ +// This regex matches cases of a comma or colon NOT followed by a whitespace +const DELIMITER_WITHOUT_SPACING_REGEX = /[,:]\S/