summaryrefslogtreecommitdiffhomepage
path: root/packages/app/src/context/comments.test.ts
blob: 4f223e5f8697e4a49b479f9c4c793c22d6cce419 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
import { beforeAll, describe, expect, mock, test } from "bun:test"
import { createRoot } from "solid-js"
import type { LineComment } from "./comments"

let createCommentSessionForTest: typeof import("./comments").createCommentSessionForTest

beforeAll(async () => {
  mock.module("@solidjs/router", () => ({
    useNavigate: () => () => undefined,
    useParams: () => ({}),
  }))
  mock.module("@opencode-ai/ui/context", () => ({
    createSimpleContext: () => ({
      use: () => undefined,
      provider: () => undefined,
    }),
  }))
  const mod = await import("./comments")
  createCommentSessionForTest = mod.createCommentSessionForTest
})

function line(file: string, id: string, time: number): LineComment {
  return {
    id,
    file,
    comment: id,
    time,
    selection: { start: 1, end: 1 },
  }
}

describe("comments session indexing", () => {
  test("keeps file list behavior and aggregate chronological order", () => {
    createRoot((dispose) => {
      const now = Date.now()
      const comments = createCommentSessionForTest({
        "a.ts": [line("a.ts", "a-late", now + 20_000), line("a.ts", "a-early", now + 1_000)],
        "b.ts": [line("b.ts", "b-mid", now + 10_000)],
      })

      expect(comments.list("a.ts").map((item) => item.id)).toEqual(["a-late", "a-early"])
      expect(comments.all().map((item) => item.id)).toEqual(["a-early", "b-mid", "a-late"])

      const next = comments.add({
        file: "b.ts",
        comment: "next",
        selection: { start: 2, end: 2 },
      })

      expect(comments.list("b.ts").at(-1)?.id).toBe(next.id)
      expect(comments.all().map((item) => item.time)).toEqual(
        comments
          .all()
          .map((item) => item.time)
          .slice()
          .sort((a, b) => a - b),
      )

      dispose()
    })
  })

  test("remove updates file and aggregate indexes consistently", () => {
    createRoot((dispose) => {
      const comments = createCommentSessionForTest({
        "a.ts": [line("a.ts", "a1", 10), line("a.ts", "shared", 20)],
        "b.ts": [line("b.ts", "shared", 30)],
      })

      comments.setFocus({ file: "a.ts", id: "shared" })
      comments.setActive({ file: "a.ts", id: "shared" })
      comments.remove("a.ts", "shared")

      expect(comments.list("a.ts").map((item) => item.id)).toEqual(["a1"])
      expect(
        comments
          .all()
          .filter((item) => item.id === "shared")
          .map((item) => item.file),
      ).toEqual(["b.ts"])
      expect(comments.focus()).toBeNull()
      expect(comments.active()).toEqual({ file: "a.ts", id: "shared" })

      dispose()
    })
  })

  test("clear resets file and aggregate indexes plus focus state", () => {
    createRoot((dispose) => {
      const comments = createCommentSessionForTest({
        "a.ts": [line("a.ts", "a1", 10)],
      })

      const next = comments.add({
        file: "b.ts",
        comment: "next",
        selection: { start: 2, end: 2 },
      })

      comments.setActive({ file: "b.ts", id: next.id })
      comments.clear()

      expect(comments.list("a.ts")).toEqual([])
      expect(comments.list("b.ts")).toEqual([])
      expect(comments.all()).toEqual([])
      expect(comments.focus()).toBeNull()
      expect(comments.active()).toBeNull()

      dispose()
    })
  })
})