fixtures.ts 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. /** Session/workspace fixture shapes and snapshot defaults for the test runtime. */
  2. import type {
  3. ConversationSnapshot, ISession, SessionId, SessionSummary, WorkspaceListState,
  4. } from '@deepseek-ai/dsh-client-runtime/client'
  5. import {
  6. EMPTY_CHAT_SNAPSHOT, EMPTY_CONVERSATION_VIEWS,
  7. } from '@deepseek-ai/dsh-client-runtime/client'
  8. /**
  9. * Fixture overrides for the session behavior face: any subset of the
  10. * production ISession verbs (typed against it, so a face change surfaces
  11. * here at compile time), plus extra members feature-specific casts consume.
  12. * The open Record tail means a misnamed EXTRA member is not caught by the
  13. * compiler (it grafts as dead weight); the ISession verbs stay safe — a
  14. * misnamed verb leaves the fail-loud stub in place, which names itself at
  15. * the first call.
  16. */
  17. export type SessionBehaviorOverrides = Partial<ISession> & Record<string, unknown>
  18. /**
  19. * act-wrapped mutation runner shared by every runtime object: public mutators
  20. * funnel through it so tests never handle SlotCore microtask batching or
  21. * React act themselves.
  22. */
  23. export type Stabilizer = (fn: () => void | Promise<void>) => Promise<void>
  24. /**
  25. * Session fixture accepted by {@link TestSessions.add}: identity plus optional
  26. * snapshot/list-row overrides and the session behavior face the feature under
  27. * test actually calls (kept open — the runtime never fakes methods a test did
  28. * not supply, so an unstubbed call fails loud at the call site).
  29. */
  30. export interface SessionFixture {
  31. id: string
  32. /** Overrides merged over {@link conversationSnapshot} (sessionId comes from `id`). */
  33. snapshot?: Partial<Omit<ConversationSnapshot, 'sessionId'>>
  34. /** List-row overrides merged over the defaults derived from `id`. */
  35. summary?: Partial<Omit<SessionSummary, 'id'>>
  36. /** Session behavior face: exactly the methods the feature under test calls (ISession subset + extras). */
  37. session?: SessionBehaviorOverrides
  38. }
  39. /**
  40. * A complete quiescent conversation snapshot (open window, no traffic).
  41. * @param sessionId - owning session id.
  42. * @returns the snapshot; spread fixture overrides on top.
  43. */
  44. export function conversationSnapshot(sessionId: SessionId): ConversationSnapshot {
  45. return {
  46. sessionId,
  47. views: EMPTY_CONVERSATION_VIEWS,
  48. chat: EMPTY_CHAT_SNAPSHOT,
  49. nodes: [],
  50. turnTimings: new Map(),
  51. turnEnds: new Map(),
  52. partial: null,
  53. runningCalls: [],
  54. pending: [],
  55. queue: [],
  56. running: false,
  57. subagent: null,
  58. composerPhase: 'active',
  59. removed: false,
  60. openState: 'open',
  61. openError: null,
  62. hasMore: false,
  63. loadingOlder: false,
  64. promptError: null,
  65. blank: false,
  66. lastAgentError: null,
  67. }
  68. }
  69. /**
  70. * A ready workspace list with no workspaces (the shape WorkspaceRuntime
  71. * projects after both baselines land).
  72. * @returns the initial state of the test workspaces store.
  73. */
  74. export function workspaceListState(): WorkspaceListState {
  75. return {
  76. items: [],
  77. archivedSessionIds: [],
  78. state: 'idle',
  79. phase: 'ready',
  80. error: null,
  81. baselinesReady: true,
  82. recentWorkspaceId: undefined,
  83. }
  84. }