layout-scroll.test.ts 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. import { describe, expect, test, vi } from "bun:test"
  2. import { createScrollPersistence } from "./layout-scroll"
  3. describe("createScrollPersistence", () => {
  4. test("debounces persisted scroll writes", () => {
  5. vi.useFakeTimers()
  6. try {
  7. const snapshot = {
  8. session: {
  9. review: { x: 0, y: 0 },
  10. },
  11. } as Record<string, Record<string, { x: number; y: number }>>
  12. const writes: Array<Record<string, { x: number; y: number }>> = []
  13. const scroll = createScrollPersistence({
  14. debounceMs: 10,
  15. getSnapshot: (sessionKey) => snapshot[sessionKey],
  16. onFlush: (sessionKey, next) => {
  17. snapshot[sessionKey] = next
  18. writes.push(next)
  19. },
  20. })
  21. for (const i of Array.from({ length: 30 }, (_, n) => n + 1)) {
  22. scroll.setScroll("session", "review", { x: 0, y: i })
  23. }
  24. vi.advanceTimersByTime(9)
  25. expect(writes).toHaveLength(0)
  26. vi.advanceTimersByTime(1)
  27. expect(writes).toHaveLength(1)
  28. expect(writes[0]?.review).toEqual({ x: 0, y: 30 })
  29. scroll.setScroll("session", "review", { x: 0, y: 30 })
  30. vi.advanceTimersByTime(20)
  31. expect(writes).toHaveLength(1)
  32. scroll.dispose()
  33. } finally {
  34. vi.useRealTimers()
  35. }
  36. })
  37. test("reseeds empty cache after persisted snapshot loads", () => {
  38. const snapshot = {
  39. session: {},
  40. } as Record<string, Record<string, { x: number; y: number }>>
  41. const scroll = createScrollPersistence({
  42. getSnapshot: (sessionKey) => snapshot[sessionKey],
  43. onFlush: () => {},
  44. })
  45. expect(scroll.scroll("session", "review")).toBeUndefined()
  46. snapshot.session = {
  47. review: { x: 12, y: 34 },
  48. }
  49. expect(scroll.scroll("session", "review")).toEqual({ x: 12, y: 34 })
  50. scroll.dispose()
  51. })
  52. })