From f8f0ccc84e552296a5f0095bf171daf1f3e059dc Mon Sep 17 00:00:00 2001 From: Andrew Patton Date: Thu, 28 Mar 2024 17:19:30 -0700 Subject: [PATCH] Handle missing values in objects (+ new test case) --- packages/parsing/src/parse-as-json.test.ts | 33 ++++++++++++++++++++++ packages/parsing/src/parse-as-json.ts | 12 ++++++++ 2 files changed, 45 insertions(+) diff --git a/packages/parsing/src/parse-as-json.test.ts b/packages/parsing/src/parse-as-json.test.ts index 21b346a8..0521cf95 100644 --- a/packages/parsing/src/parse-as-json.test.ts +++ b/packages/parsing/src/parse-as-json.test.ts @@ -21,6 +21,7 @@ describe('@acusti/parsing', () => { it('handles extraneous escape characters', extraneousEscapeCharactersTestCase); it('handles unescaped double quotes', unescapedDoubleQuotesTestCase); it('detects premature closing curly brace and ignores it', prematureClosingCurliesTestCase); + it('detects an object key with a missing value and fills it in', missingValuesTestCase); }); }); @@ -638,3 +639,35 @@ function prematureClosingCurliesTestCase() { ], }); } + +function missingValuesTestCase() { + const response = `\ +\`\`\`json +{"heading":"Digg FAQ","subheading":"Get the Answers You Need","items":[{"heading":"What is Digg?","subheading":"","description":"Digg is an American news aggregator that curates a front page of the most popular stories on the Internet. It covers topics such as science, trending political issues, and viral Internet issues.","button":""},{"heading":"How does Digg work?","subheading","description":"Digg uses a combination of editorial curation and algorithmic sorting to select the most popular stories on the Internet. Users can submit stories, which are then voted on by other users. The stories with the most votes appear on the Digg front page.","button":""},{"heading":"How do I submit a story to Digg?","subheading","description":"To submit a story to Digg, you need to create an account and then click on the 'Submit a Story' button. You will then be prompted to enter the URL of the story you want to submit. Once submitted, other users can vote on your story, and if it gains enough votes, it may appear on the Digg front page.","button":""}]} +\`\`\``; + + expect(parseAsJSON(response)).toEqual({ + heading: 'Digg FAQ', + subheading: 'Get the Answers You Need', + items: [ + { + heading: 'What is Digg?', + subheading: "", + description: 'Digg is an American news aggregator that curates a front page of the most popular stories on the Internet. It covers topics such as science, trending political issues, and viral Internet issues.', + button: "", + }, + { + heading: 'How does Digg work?', + subheading: '', + description: 'Digg uses a combination of editorial curation and algorithmic sorting to select the most popular stories on the Internet. Users can submit stories, which are then voted on by other users. The stories with the most votes appear on the Digg front page.', + button: "", + }, + { + heading: 'How do I submit a story to Digg?', + subheading: '', + description: 'To submit a story to Digg, you need to create an account and then click on the \'Submit a Story\' button. You will then be prompted to enter the URL of the story you want to submit. Once submitted, other users can vote on your story, and if it gains enough votes, it may appear on the Digg front page.', + button: "", + } + ], + }); +} diff --git a/packages/parsing/src/parse-as-json.ts b/packages/parsing/src/parse-as-json.ts index 9db7a0f3..66d73d37 100644 --- a/packages/parsing/src/parse-as-json.ts +++ b/packages/parsing/src/parse-as-json.ts @@ -377,6 +377,18 @@ export function parseAsJSON(text: string): ParsedValue | null { char = ','; } } + } else if (char === ',' && stack.at(-1) === '}') { + // ensure this follows a full key/value pair + const lastEndKeyIndexA = newText.lastIndexOf('":"'); + const lastEndKeyIndexB = newText.lastIndexOf('": "'); + const lastEndKeyIndex = Math.max(lastEndKeyIndexA, lastEndKeyIndexB); + const lastEndValueIndexA = newText.lastIndexOf('","'); + const lastEndValueIndexB = newText.lastIndexOf('", "'); + const lastEndValueIndex = Math.max(lastEndValueIndexA, lastEndValueIndexB); + // if the last string is a value (not a key), add an empty value + if (lastEndValueIndex > 0 && lastEndKeyIndex > 0 && lastEndValueIndex > lastEndKeyIndex) { + char = ': "",'; + } } }