session-fixture-layout.spec.ts 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. import { describe, expect, it } from 'vitest'
  2. import { decodeStorageRecord, type SessionEvent } from '@deepseek-ai/dsh-session'
  3. import { canonicalSessionFixture } from './session-fixture-layout.ts'
  4. const HEADER = ' {"type":"session","version":0,"id":"fixture","createdAt":1,"delegationDepth":0} '
  5. function chunkRun(): SessionEvent[] {
  6. return Array.from({ length: 4 }, (_, index) => ({
  7. type: 'assistant/chunk',
  8. seq: index,
  9. time: 10 + index,
  10. data: {
  11. turn: 1,
  12. step: 1,
  13. chunk: { type: 'text-delta', index: 0, text: `part-${index}` },
  14. },
  15. }))
  16. }
  17. function unpackedFixture(): string {
  18. return [HEADER, ...chunkRun().map(event => JSON.stringify(event)), ''].join('\n')
  19. }
  20. function decodedBody(content: string): SessionEvent[] {
  21. return content.trimEnd().split('\n').slice(1)
  22. .flatMap(line => decodeStorageRecord(JSON.parse(line) as unknown))
  23. }
  24. describe('canonicalSessionFixture', () => {
  25. it('preserves the header line and packs an unpacked event run losslessly', () => {
  26. const canonical = canonicalSessionFixture(unpackedFixture(), 'fixture.jsonl')
  27. expect(canonical).toBeDefined()
  28. expect(canonical?.split('\n')[0]).toBe(HEADER)
  29. expect(JSON.parse(canonical?.split('\n')[1] ?? '{}')).toMatchObject({ type: 'text-chunks' })
  30. expect(decodedBody(canonical ?? '')).toStrictEqual(chunkRun())
  31. })
  32. it('ignores JSONL whose first record is not a session header', () => {
  33. expect(canonicalSessionFixture('{"type":"session_event"}\n{"value":1}\n')).toBeUndefined()
  34. })
  35. it('is idempotent for an already packed fixture', () => {
  36. const packed = canonicalSessionFixture(unpackedFixture())
  37. expect(packed).toBeDefined()
  38. expect(canonicalSessionFixture(packed ?? '')).toBe(packed)
  39. })
  40. it('fails loud on malformed records after a session header', () => {
  41. expect(() => canonicalSessionFixture(`${HEADER}\n{not-json}\n`, 'broken.jsonl'))
  42. .toThrow(/broken\.jsonl:2: invalid JSON/)
  43. })
  44. it('labels malformed packed rows with the fixture path and line', () => {
  45. expect(() => canonicalSessionFixture(`${HEADER}\n{"type":"text-chunks"}\n`, 'broken.jsonl'))
  46. .toThrow(/broken\.jsonl:2: invalid session storage record: malformed text-chunks storage row/)
  47. })
  48. })