mirror of
https://gitea.toothfairyai.com/ToothFairyAI/tf_code.git
synced 2026-04-23 17:14:55 +00:00
chore: refactoring and tests, splitting up files (#12495)
This commit is contained in:
201
packages/app/src/context/global-sync/event-reducer.test.ts
Normal file
201
packages/app/src/context/global-sync/event-reducer.test.ts
Normal file
@@ -0,0 +1,201 @@
|
||||
import { describe, expect, test } from "bun:test"
|
||||
import type { Message, Part, Project, Session } from "@opencode-ai/sdk/v2/client"
|
||||
import { createStore } from "solid-js/store"
|
||||
import type { State } from "./types"
|
||||
import { applyDirectoryEvent, applyGlobalEvent } from "./event-reducer"
|
||||
|
||||
const rootSession = (input: { id: string; parentID?: string; archived?: number }) =>
|
||||
({
|
||||
id: input.id,
|
||||
parentID: input.parentID,
|
||||
time: {
|
||||
created: 1,
|
||||
updated: 1,
|
||||
archived: input.archived,
|
||||
},
|
||||
}) as Session
|
||||
|
||||
const userMessage = (id: string, sessionID: string) =>
|
||||
({
|
||||
id,
|
||||
sessionID,
|
||||
role: "user",
|
||||
time: { created: 1 },
|
||||
agent: "assistant",
|
||||
model: { providerID: "openai", modelID: "gpt" },
|
||||
}) as Message
|
||||
|
||||
const textPart = (id: string, sessionID: string, messageID: string) =>
|
||||
({
|
||||
id,
|
||||
sessionID,
|
||||
messageID,
|
||||
type: "text",
|
||||
text: id,
|
||||
}) as Part
|
||||
|
||||
const baseState = (input: Partial<State> = {}) =>
|
||||
({
|
||||
status: "complete",
|
||||
agent: [],
|
||||
command: [],
|
||||
project: "",
|
||||
projectMeta: undefined,
|
||||
icon: undefined,
|
||||
provider: {} as State["provider"],
|
||||
config: {} as State["config"],
|
||||
path: { directory: "/tmp" } as State["path"],
|
||||
session: [],
|
||||
sessionTotal: 0,
|
||||
session_status: {},
|
||||
session_diff: {},
|
||||
todo: {},
|
||||
permission: {},
|
||||
question: {},
|
||||
mcp: {},
|
||||
lsp: [],
|
||||
vcs: undefined,
|
||||
limit: 10,
|
||||
message: {},
|
||||
part: {},
|
||||
...input,
|
||||
}) as State
|
||||
|
||||
describe("applyGlobalEvent", () => {
|
||||
test("upserts project.updated in sorted position", () => {
|
||||
const project = [{ id: "a" }, { id: "c" }] as Project[]
|
||||
let refreshCount = 0
|
||||
applyGlobalEvent({
|
||||
event: { type: "project.updated", properties: { id: "b" } },
|
||||
project,
|
||||
refresh: () => {
|
||||
refreshCount += 1
|
||||
},
|
||||
setGlobalProject(next) {
|
||||
if (typeof next === "function") next(project)
|
||||
},
|
||||
})
|
||||
|
||||
expect(project.map((x) => x.id)).toEqual(["a", "b", "c"])
|
||||
expect(refreshCount).toBe(0)
|
||||
})
|
||||
|
||||
test("handles global.disposed by triggering refresh", () => {
|
||||
let refreshCount = 0
|
||||
applyGlobalEvent({
|
||||
event: { type: "global.disposed" },
|
||||
project: [],
|
||||
refresh: () => {
|
||||
refreshCount += 1
|
||||
},
|
||||
setGlobalProject() {},
|
||||
})
|
||||
|
||||
expect(refreshCount).toBe(1)
|
||||
})
|
||||
})
|
||||
|
||||
describe("applyDirectoryEvent", () => {
|
||||
test("inserts root sessions in sorted order and updates sessionTotal", () => {
|
||||
const [store, setStore] = createStore(
|
||||
baseState({
|
||||
session: [rootSession({ id: "b" })],
|
||||
sessionTotal: 1,
|
||||
}),
|
||||
)
|
||||
|
||||
applyDirectoryEvent({
|
||||
event: { type: "session.created", properties: { info: rootSession({ id: "a" }) } },
|
||||
store,
|
||||
setStore,
|
||||
push() {},
|
||||
directory: "/tmp",
|
||||
loadLsp() {},
|
||||
})
|
||||
|
||||
expect(store.session.map((x) => x.id)).toEqual(["a", "b"])
|
||||
expect(store.sessionTotal).toBe(2)
|
||||
|
||||
applyDirectoryEvent({
|
||||
event: { type: "session.created", properties: { info: rootSession({ id: "c", parentID: "a" }) } },
|
||||
store,
|
||||
setStore,
|
||||
push() {},
|
||||
directory: "/tmp",
|
||||
loadLsp() {},
|
||||
})
|
||||
|
||||
expect(store.sessionTotal).toBe(2)
|
||||
})
|
||||
|
||||
test("cleans session caches when archived", () => {
|
||||
const message = userMessage("msg_1", "ses_1")
|
||||
const [store, setStore] = createStore(
|
||||
baseState({
|
||||
session: [rootSession({ id: "ses_1" }), rootSession({ id: "ses_2" })],
|
||||
sessionTotal: 2,
|
||||
message: { ses_1: [message] },
|
||||
part: { [message.id]: [textPart("prt_1", "ses_1", message.id)] },
|
||||
session_diff: { ses_1: [] },
|
||||
todo: { ses_1: [] },
|
||||
permission: { ses_1: [] },
|
||||
question: { ses_1: [] },
|
||||
session_status: { ses_1: { type: "busy" } },
|
||||
}),
|
||||
)
|
||||
|
||||
applyDirectoryEvent({
|
||||
event: { type: "session.updated", properties: { info: rootSession({ id: "ses_1", archived: 10 }) } },
|
||||
store,
|
||||
setStore,
|
||||
push() {},
|
||||
directory: "/tmp",
|
||||
loadLsp() {},
|
||||
})
|
||||
|
||||
expect(store.session.map((x) => x.id)).toEqual(["ses_2"])
|
||||
expect(store.sessionTotal).toBe(1)
|
||||
expect(store.message.ses_1).toBeUndefined()
|
||||
expect(store.part[message.id]).toBeUndefined()
|
||||
expect(store.session_diff.ses_1).toBeUndefined()
|
||||
expect(store.todo.ses_1).toBeUndefined()
|
||||
expect(store.permission.ses_1).toBeUndefined()
|
||||
expect(store.question.ses_1).toBeUndefined()
|
||||
expect(store.session_status.ses_1).toBeUndefined()
|
||||
})
|
||||
|
||||
test("routes disposal and lsp events to side-effect handlers", () => {
|
||||
const [store, setStore] = createStore(baseState())
|
||||
const pushes: string[] = []
|
||||
let lspLoads = 0
|
||||
|
||||
applyDirectoryEvent({
|
||||
event: { type: "server.instance.disposed" },
|
||||
store,
|
||||
setStore,
|
||||
push(directory) {
|
||||
pushes.push(directory)
|
||||
},
|
||||
directory: "/tmp",
|
||||
loadLsp() {
|
||||
lspLoads += 1
|
||||
},
|
||||
})
|
||||
|
||||
applyDirectoryEvent({
|
||||
event: { type: "lsp.updated" },
|
||||
store,
|
||||
setStore,
|
||||
push(directory) {
|
||||
pushes.push(directory)
|
||||
},
|
||||
directory: "/tmp",
|
||||
loadLsp() {
|
||||
lspLoads += 1
|
||||
},
|
||||
})
|
||||
|
||||
expect(pushes).toEqual(["/tmp"])
|
||||
expect(lspLoads).toBe(1)
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user