Files
ccs/tests/unit/glmt/sse-parser.test.ts
T
Kai (Tam Nhu) TranandGitHub 2ec23c6c3a fix(sse): make CRLF normalization chunk-boundary safe (#1359)
* fix(sse): handle CRLF split across chunk boundaries

* style: apply prettier formatting
2026-05-23 21:44:32 -04:00

64 lines
2.1 KiB
TypeScript

import { describe, expect, it } from 'bun:test';
import { SSEParser } from '../../../src/glmt/sse-parser';
describe('SSEParser', () => {
it('merges multi-line data fields into one JSON payload', () => {
const parser = new SSEParser({ throwOnMalformedJson: true });
const events = parser.parse(
[
'event: message',
'data: {"choices":[',
'data: {"delta":{"content":"Hello"}}',
'data: ]}',
'',
'',
].join('\n')
);
expect(events).toHaveLength(1);
expect(
(events[0]?.data as { choices?: Array<{ delta?: { content?: string } }> })?.choices?.[0]
?.delta?.content
).toBe('Hello');
});
it('keeps incomplete events buffered until the separator arrives', () => {
const parser = new SSEParser({ throwOnMalformedJson: true });
expect(parser.parse('data: {"choices":[{"delta":{"content":"Hi"}}]}')).toEqual([]);
const events = parser.parse('\n\n');
expect(events).toHaveLength(1);
expect(
(events[0]?.data as { choices?: Array<{ delta?: { content?: string } }> })?.choices?.[0]
?.delta?.content
).toBe('Hi');
});
it('accepts standalone carriage-return line endings', () => {
const parser = new SSEParser({ throwOnMalformedJson: true });
const events = parser.parse(
['event: message', 'data: {"choices":[{"delta":{"content":"Legacy"}}]}', '', ''].join('\r')
);
expect(events).toHaveLength(1);
expect(
(events[0]?.data as { choices?: Array<{ delta?: { content?: string } }> })?.choices?.[0]
?.delta?.content
).toBe('Legacy');
});
it('does not split events when CRLF is split across chunks', () => {
const parser = new SSEParser({ throwOnMalformedJson: true });
expect(parser.parse('data: {"choices":[\r')).toEqual([]);
const events = parser.parse('\ndata: {"delta":{"content":"Hello"}}\r\ndata: ]}\r\n\r\n');
expect(events).toHaveLength(1);
expect(
(events[0]?.data as { choices?: Array<{ delta?: { content?: string } }> })?.choices?.[0]
?.delta?.content
).toBe('Hello');
});
});