error-handler-supplement.test.js
1 /** 2 * Error Handler Supplement — Hit JSON repair control-char paths (lines 126-139) 3 * 4 * safeJsonParse has a second-attempt repair path that escapes raw \n \r \t 5 * control characters inside JSON string values. These branches are hit when: 6 * 1. Initial JSON.parse fails (the JSON has raw control chars) 7 * 2. The repair loop encounters: escaped chars (\\), backslash-in-string, 8 * quote toggling, and raw \n \r \t inside strings 9 */ 10 11 import { test, describe } from 'node:test'; 12 import assert from 'node:assert/strict'; 13 import { safeJsonParse } from '../../src/utils/error-handler.js'; 14 15 describe('safeJsonParse - JSON repair control-char paths', () => { 16 test('repairs raw \\n inside JSON string (line 135)', () => { 17 // A JSON string with a literal newline char (invalid JSON) 18 const raw = '{"msg":"hello\nworld"}'; 19 const result = safeJsonParse(raw); 20 assert.ok(result !== null, 'should repair and return object'); 21 assert.ok( 22 result.msg.includes('\n') || result.msg.includes('\\n') || result.msg === 'hello\nworld' 23 ); 24 }); 25 26 test('repairs raw \\r inside JSON string (line 137)', () => { 27 const raw = '{"msg":"line1\rline2"}'; 28 const result = safeJsonParse(raw); 29 assert.ok(result !== null, 'should repair \\r in string'); 30 }); 31 32 test('repairs raw \\t inside JSON string (line 139)', () => { 33 const raw = '{"msg":"col1\tcol2"}'; 34 const result = safeJsonParse(raw); 35 assert.ok(result !== null, 'should repair \\t in string'); 36 }); 37 38 test('handles backslash-escaped char in string (lines 128-130)', () => { 39 // Valid JSON with backslash escape — should parse on first attempt 40 const raw = '{"path":"C:\\\\Users\\\\test"}'; 41 const result = safeJsonParse(raw); 42 assert.ok(result !== null); 43 assert.equal(result.path, 'C:\\Users\\test'); 44 }); 45 46 test('handles quote toggling in repair loop (lines 131-133)', () => { 47 // JSON with multiple string fields — quotes toggle inString state 48 const raw = '{"a":"hello\nworld","b":"foo\tbar"}'; 49 const result = safeJsonParse(raw); 50 assert.ok(result !== null, 'should parse multi-field JSON with control chars'); 51 assert.ok(result.a !== undefined); 52 assert.ok(result.b !== undefined); 53 }); 54 55 test('mixed: raw newlines and escaped backslashes together', () => { 56 // A string with both raw newlines and a backslash escape — exercises both paths 57 const raw = '{"text":"line1\nline2\\nstill_line2"}'; 58 const result = safeJsonParse(raw); 59 // Either it repairs successfully or returns null — just don't throw 60 assert.ok(result === null || typeof result === 'object'); 61 }); 62 63 test('returns fallback when repair also fails (totally invalid JSON)', () => { 64 const result = safeJsonParse('{broken json without quotes at all}', 'fallback'); 65 assert.equal(result, 'fallback'); 66 }); 67 });