Skip to content

Commit

Permalink
fix: improve the logic to determine whether a JSON document needs for…
Browse files Browse the repository at this point in the history
…matting
  • Loading branch information
josdejong committed Feb 15, 2024
1 parent eeaaa1a commit 0ca8a49
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 8 deletions.
13 changes: 9 additions & 4 deletions src/lib/utils/jsonUtils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -406,18 +406,23 @@ 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)
expect(needsFormatting('true')).toBe(false)
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)
})
})

Expand Down
9 changes: 5 additions & 4 deletions src/lib/utils/jsonUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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/

0 comments on commit 0ca8a49

Please sign in to comment.