sync-cache.test.ts 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. import { describe, expect, test } from "bun:test"
  2. import type { Message, Part, SessionStatus, Todo, PermissionRequest, QuestionRequest } from "@opencode-ai/sdk/v2"
  3. import { dropSessionCache, pickSessionCacheEvictions } from "../../../src/cli/cmd/tui/context/sync-cache"
  4. const msg = (id: string, sessionID: string) =>
  5. ({
  6. id,
  7. sessionID,
  8. role: "user",
  9. time: { created: 1 },
  10. agent: "build",
  11. model: { providerID: "openai", modelID: "gpt-4o-mini" },
  12. }) as Message
  13. const part = (id: string, sessionID: string, messageID: string) =>
  14. ({
  15. id,
  16. sessionID,
  17. messageID,
  18. type: "text",
  19. text: id,
  20. }) as Part
  21. describe("tui sync cache", () => {
  22. test("dropSessionCache clears session scoped maps and related parts", () => {
  23. const m = msg("msg_1", "ses_1")
  24. const store = {
  25. session_status: { ses_1: { type: "busy" } as SessionStatus },
  26. session_diff: { ses_1: [] },
  27. todo: { ses_1: [] as Todo[] },
  28. message: { ses_1: [m] },
  29. part: { [m.id]: [part("prt_1", "ses_1", m.id)] },
  30. permission: { ses_1: [] as PermissionRequest[] },
  31. question: { ses_1: [] as QuestionRequest[] },
  32. }
  33. dropSessionCache(store, "ses_1")
  34. expect(store.message.ses_1).toBeUndefined()
  35. expect(store.part[m.id]).toBeUndefined()
  36. expect(store.todo.ses_1).toBeUndefined()
  37. expect(store.session_diff.ses_1).toBeUndefined()
  38. expect(store.session_status.ses_1).toBeUndefined()
  39. expect(store.permission.ses_1).toBeUndefined()
  40. expect(store.question.ses_1).toBeUndefined()
  41. })
  42. test("dropSessionCache clears orphaned parts without message rows", () => {
  43. const store = {
  44. session_status: {},
  45. session_diff: {},
  46. todo: {},
  47. message: {},
  48. part: { msg_1: [part("prt_1", "ses_1", "msg_1")] },
  49. permission: {},
  50. question: {},
  51. }
  52. dropSessionCache(store, "ses_1")
  53. expect(store.part.msg_1).toBeUndefined()
  54. })
  55. test("pickSessionCacheEvictions evicts oldest cached sessions", () => {
  56. const seen = new Set(["ses_1", "ses_2", "ses_3"])
  57. const stale = pickSessionCacheEvictions({
  58. seen,
  59. keep: "ses_4",
  60. limit: 2,
  61. })
  62. expect(stale).toEqual(["ses_1", "ses_2"])
  63. expect([...seen]).toEqual(["ses_3", "ses_4"])
  64. })
  65. test("pickSessionCacheEvictions refreshes recency for revisited sessions", () => {
  66. const seen = new Set(["ses_1", "ses_2", "ses_3"])
  67. const stale = pickSessionCacheEvictions({
  68. seen,
  69. keep: "ses_2",
  70. limit: 3,
  71. })
  72. expect(stale).toEqual([])
  73. expect([...seen]).toEqual(["ses_1", "ses_3", "ses_2"])
  74. })
  75. })