@@ -109,6 +109,136 @@ describe('jsonParse', () => {
109109 it ( 'optionally returns a `fallbackValue`' , ( ) => {
110110 expect ( jsonParse ( '' , { fallbackValue : { foo : 'bar' } } ) ) . toEqual ( { foo : 'bar' } ) ;
111111 } ) ;
112+
113+ describe ( 'JSON repair' , ( ) => {
114+ describe ( 'Recovery edge cases' , ( ) => {
115+ it ( 'should handle simple object with single quotes' , ( ) => {
116+ const result = jsonParse ( "{name: 'John', age: 30}" , { repairJSON : true } ) ;
117+ expect ( result ) . toEqual ( { name : 'John' , age : 30 } ) ;
118+ } ) ;
119+
120+ it ( 'should handle nested objects with single quotes' , ( ) => {
121+ const result = jsonParse ( "{user: {name: 'John', active: true},}" , { repairJSON : true } ) ;
122+ expect ( result ) . toEqual ( { user : { name : 'John' , active : true } } ) ;
123+ } ) ;
124+
125+ it ( 'should handle empty string values' , ( ) => {
126+ const result = jsonParse ( "{key: ''}" , { repairJSON : true } ) ;
127+ expect ( result ) . toEqual ( { key : '' } ) ;
128+ } ) ;
129+
130+ it ( 'should handle numeric string values' , ( ) => {
131+ const result = jsonParse ( "{key: '123'}" , { repairJSON : true } ) ;
132+ expect ( result ) . toEqual ( { key : '123' } ) ;
133+ } ) ;
134+
135+ it ( 'should handle multiple keys with trailing comma' , ( ) => {
136+ const result = jsonParse ( "{a: '1', b: '2', c: '3',}" , { repairJSON : true } ) ;
137+ expect ( result ) . toEqual ( { a : '1' , b : '2' , c : '3' } ) ;
138+ } ) ;
139+
140+ it ( 'should recover single quotes around strings' , ( ) => {
141+ const result = jsonParse ( "{key: 'value'}" , { repairJSON : true } ) ;
142+ expect ( result ) . toEqual ( { key : 'value' } ) ;
143+ } ) ;
144+
145+ it ( 'should recover unquoted keys' , ( ) => {
146+ const result = jsonParse ( "{myKey: 'value'}" , { repairJSON : true } ) ;
147+ expect ( result ) . toEqual ( { myKey : 'value' } ) ;
148+ } ) ;
149+
150+ it ( 'should recover trailing commas in objects' , ( ) => {
151+ const result = jsonParse ( "{key: 'value',}" , { repairJSON : true } ) ;
152+ expect ( result ) . toEqual ( { key : 'value' } ) ;
153+ } ) ;
154+
155+ it ( 'should recover trailing commas in nested objects' , ( ) => {
156+ const result = jsonParse ( "{outer: {inner: 'value',},}" , { repairJSON : true } ) ;
157+ expect ( result ) . toEqual ( { outer : { inner : 'value' } } ) ;
158+ } ) ;
159+
160+ it ( 'should recover multiple issues at once' , ( ) => {
161+ const result = jsonParse ( "{key1: 'value1', key2: 'value2',}" , { repairJSON : true } ) ;
162+ expect ( result ) . toEqual ( { key1 : 'value1' , key2 : 'value2' } ) ;
163+ } ) ;
164+
165+ it ( 'should recover numeric values with single quotes' , ( ) => {
166+ const result = jsonParse ( "{key: '123'}" , { repairJSON : true } ) ;
167+ expect ( result ) . toEqual ( { key : '123' } ) ;
168+ } ) ;
169+
170+ it ( 'should recover boolean values with single quotes' , ( ) => {
171+ const result = jsonParse ( "{key: 'true'}" , { repairJSON : true } ) ;
172+ expect ( result ) . toEqual ( { key : 'true' } ) ;
173+ } ) ;
174+
175+ it ( 'should handle urls' , ( ) => {
176+ const result = jsonParse ( '{"key": "https://example.com",}' , { repairJSON : true } ) ;
177+ expect ( result ) . toEqual ( { key : 'https://example.com' } ) ;
178+ } ) ;
179+
180+ it ( 'should handle ipv6 addresses' , ( ) => {
181+ const result = jsonParse ( '{"key": "2a01:c50e:3544:bd00:4df0:7609:251a:f6d0",}' , {
182+ repairJSON : true ,
183+ } ) ;
184+ expect ( result ) . toEqual ( { key : '2a01:c50e:3544:bd00:4df0:7609:251a:f6d0' } ) ;
185+ } ) ;
186+
187+ it ( 'should handle single quotes containing double quotes' , ( ) => {
188+ const result = jsonParse ( '{key: \'value with "quotes" inside\'}' , { repairJSON : true } ) ;
189+ expect ( result ) . toEqual ( { key : 'value with "quotes" inside' } ) ;
190+ } ) ;
191+
192+ it ( 'should handle escaped single quotes' , ( ) => {
193+ const result = jsonParse ( "{key: 'it\\'s escaped'}" , { repairJSON : true } ) ;
194+ expect ( result ) . toEqual ( { key : "it's escaped" } ) ;
195+ } ) ;
196+
197+ it ( 'should handle keys containing hyphens' , ( ) => {
198+ const result = jsonParse ( "{key-with-dash: 'value'}" , { repairJSON : true } ) ;
199+ expect ( result ) . toEqual ( { 'key-with-dash' : 'value' } ) ;
200+ } ) ;
201+
202+ it ( 'should handle keys containing dots' , ( ) => {
203+ const result = jsonParse ( "{key.name: 'value'}" , { repairJSON : true } ) ;
204+ expect ( result ) . toEqual ( { 'key.name' : 'value' } ) ;
205+ } ) ;
206+
207+ it ( 'should handle unquoted string values' , ( ) => {
208+ const result = jsonParse ( '{key: value}' , { repairJSON : true } ) ;
209+ expect ( result ) . toEqual ( { key : 'value' } ) ;
210+ } ) ;
211+
212+ it ( 'should handle unquoted multi-word values' , ( ) => {
213+ const result = jsonParse ( '{key: some text}' , { repairJSON : true } ) ;
214+ expect ( result ) . toEqual ( { key : 'some text' } ) ;
215+ } ) ;
216+
217+ it ( 'should handle input with double quotes mixed with single quotes' , ( ) => {
218+ const result = jsonParse ( '{key: "value with \'single\' quotes"}' , { repairJSON : true } ) ;
219+ expect ( result ) . toEqual ( { key : "value with 'single' quotes" } ) ;
220+ } ) ;
221+
222+ it ( 'should handle keys starting with numbers' , ( ) => {
223+ const result = jsonParse ( "{123key: 'value'}" , { repairJSON : true } ) ;
224+ expect ( result ) . toEqual ( { '123key' : 'value' } ) ;
225+ } ) ;
226+
227+ it ( 'should handle nested objects containing quotes' , ( ) => {
228+ const result = jsonParse ( "{outer: {inner: 'value with \"quotes\"', other: 'test'},}" , {
229+ repairJSON : true ,
230+ } ) ;
231+ expect ( result ) . toEqual ( { outer : { inner : 'value with "quotes"' , other : 'test' } } ) ;
232+ } ) ;
233+
234+ it ( 'should handle complex nested quote conflicts' , ( ) => {
235+ const result = jsonParse ( "{key: 'value with \"quotes\" inside', nested: {inner: 'test'}}" , {
236+ repairJSON : true ,
237+ } ) ;
238+ expect ( result ) . toEqual ( { key : 'value with "quotes" inside' , nested : { inner : 'test' } } ) ;
239+ } ) ;
240+ } ) ;
241+ } ) ;
112242} ) ;
113243
114244describe ( 'jsonStringify' , ( ) => {
0 commit comments