sse.spec.ts 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. import { describe, expect, it } from 'vitest';
  2. import { parseSseChunk } from '../../src/api/sse';
  3. describe('parseSseChunk', () => {
  4. it('parses named SSE events with JSON data and preserves remainder', () => {
  5. const result = parseSseChunk('', 'event: message_delta\ndata: {"text":"好的"}\n\npartial');
  6. expect(result.events).toEqual([{ type: 'message_delta', data: { text: '好的' } }]);
  7. expect(result.remainder).toBe('partial');
  8. });
  9. it('accumulates across multiple chunks', () => {
  10. const first = parseSseChunk('', 'event: message_delta\ndata: {"text":"好');
  11. expect(first.events).toEqual([]);
  12. expect(first.remainder).toBe('event: message_delta\ndata: {"text":"好');
  13. const second = parseSseChunk(first.remainder, '的"}\n\n');
  14. expect(second.events).toEqual([{ type: 'message_delta', data: { text: '好的' } }]);
  15. expect(second.remainder).toBe('');
  16. });
  17. it('handles multiple events in one chunk', () => {
  18. const result = parseSseChunk('', 'event: task_updated\ndata: {"taskId":"1"}\n\nevent: card_created\ndata: {"cardId":"c1"}\n\n');
  19. expect(result.events).toHaveLength(2);
  20. expect(result.events[0]).toEqual({ type: 'task_updated', data: { taskId: '1' } });
  21. expect(result.events[1]).toEqual({ type: 'card_created', data: { cardId: 'c1' } });
  22. });
  23. it('ignores malformed data events without throwing', () => {
  24. const result = parseSseChunk('', 'event: error\ndata: not-json\n\n');
  25. expect(result.events).toEqual([{ type: 'error', data: { message: 'SSE 数据解析失败' } }]);
  26. });
  27. it('skips events without both event and data lines', () => {
  28. const result = parseSseChunk('', 'event: something\n\n');
  29. expect(result.events).toEqual([]);
  30. expect(result.remainder).toBe('');
  31. });
  32. it('handles all six SSE event types', () => {
  33. const types = ['task_updated', 'message_delta', 'message_completed', 'card_created', 'error', 'completed'];
  34. for (const type of types) {
  35. const result = parseSseChunk('', `event: ${type}\ndata: {"key":"val"}\n\n`);
  36. expect(result.events[0].type).toBe(type);
  37. }
  38. });
  39. });