8ca0608b21
Foundation for append-only log rendering and HTTP log streaming. - FormattedLine gains a stable, monotonically increasing `id` (new lineId.ts sequence), assigned centrally in formatLogs. Internal formatters now return id-less FormattedLineContent. This lets the viewer use `track by log.id` so already-rendered rows are never re-bound (fixes the text-selection collapse). - formatJSONLine: runtime guard so a bare JSON string/array log line falls back to plain text instead of rendering Object.keys as `0=h 1=e ...`. - createLogStreamProcessor: stateful demuxer that buffers streamed text, emits only complete lines (carrying the partial remainder), and reuses formatLogs/stripHeadersFunc for Docker 8-byte frame demux. - Unit tests for the demuxer, stable-id assignment and the JSON guard. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
27 lines
962 B
TypeScript
27 lines
962 B
TypeScript
import { formatJSONLine } from './formatJSONLogs';
|
|
|
|
describe('formatJSONLine 0=d 1=e guard', () => {
|
|
it('renders a bare JSON string as plain text (not index=char pairs)', () => {
|
|
const raw = '"hello"';
|
|
const lines = formatJSONLine(raw);
|
|
expect(lines).toHaveLength(1);
|
|
// faithfully passes the raw line through instead of iterating its chars
|
|
expect(lines[0].line).toBe(raw);
|
|
// would previously have produced "0=h 1=e 2=l ..." via Object.keys on a string
|
|
expect(lines[0].line).not.toContain('0=h');
|
|
});
|
|
|
|
it('renders a bare JSON array as plain text', () => {
|
|
const raw = '[1,2,3]';
|
|
const lines = formatJSONLine(raw);
|
|
expect(lines).toHaveLength(1);
|
|
expect(lines[0].line).toBe(raw);
|
|
});
|
|
|
|
it('still parses a real JSON-object log line', () => {
|
|
const lines = formatJSONLine('{"level":"info","message":"hi"}');
|
|
expect(lines[0].line).toContain('hi');
|
|
expect(lines[0].line).not.toContain('0=');
|
|
});
|
|
});
|