mirror of
https://github.com/anomalyco/opencode.git
synced 2026-07-19 23:23:29 +00:00
90 lines
3.3 KiB
TypeScript
90 lines
3.3 KiB
TypeScript
import { describe, expect, test } from "bun:test"
|
|
import { createRoot } from "solid-js"
|
|
import { createPromptAttachmentsCore } from "@/components/prompt-input/attachments"
|
|
import { createPromptState } from "@/context/prompt"
|
|
|
|
describe("prompt attachment session ownership", () => {
|
|
test("adds an asynchronously read image to the session where the read started", async () => {
|
|
await createRoot(async (dispose) => {
|
|
const sessions = { A: createPromptState(), B: createPromptState() }
|
|
let active: "A" | "B" = "A"
|
|
const attachments = createPromptAttachmentsCore({
|
|
capture: () => sessions[active].capture(),
|
|
editor: () => document.createElement("div"),
|
|
})
|
|
const pending = attachments.addAttachment(new File([new Uint8Array(1024 * 1024)], "a.png", { type: "image/png" }))
|
|
|
|
active = "B"
|
|
await pending
|
|
|
|
expect(images(sessions.A)).toHaveLength(1)
|
|
expect(images(sessions.B)).toHaveLength(0)
|
|
dispose()
|
|
})
|
|
})
|
|
|
|
test("finishes the captured attachment after the active editor is removed", async () => {
|
|
await createRoot(async (dispose) => {
|
|
const prompt = createPromptState()
|
|
let editor: HTMLDivElement | undefined = document.createElement("div")
|
|
const attachments = createPromptAttachmentsCore({
|
|
capture: prompt.capture,
|
|
editor: () => editor,
|
|
})
|
|
const pending = attachments.addAttachment(new File([new Uint8Array(1024 * 1024)], "a.png", { type: "image/png" }))
|
|
|
|
editor = undefined
|
|
await pending
|
|
|
|
expect(images(prompt)).toHaveLength(1)
|
|
dispose()
|
|
})
|
|
})
|
|
|
|
test("keeps every file in a batch on the session where the batch started", async () => {
|
|
await createRoot(async (dispose) => {
|
|
const sessions = { A: createPromptState(), B: createPromptState() }
|
|
let active: "A" | "B" = "A"
|
|
const attachments = createPromptAttachmentsCore({
|
|
capture: () => sessions[active].capture(),
|
|
editor: () => document.createElement("div"),
|
|
})
|
|
const pending = attachments.addAttachments([
|
|
new File([new Uint8Array(1024 * 1024)], "first.png", { type: "image/png" }),
|
|
new File([new Uint8Array(1024 * 1024)], "second.png", { type: "image/png" }),
|
|
])
|
|
|
|
active = "B"
|
|
await pending
|
|
|
|
expect(images(sessions.A)).toHaveLength(2)
|
|
expect(images(sessions.B)).toHaveLength(0)
|
|
dispose()
|
|
})
|
|
})
|
|
|
|
test("keeps a delayed native clipboard image on the session where paste started", async () => {
|
|
await createRoot(async (dispose) => {
|
|
const sessions = { A: createPromptState(), B: createPromptState() }
|
|
const read = Promise.withResolvers<File | null>()
|
|
let active: "A" | "B" = "A"
|
|
const attachments = createPromptAttachmentsCore({
|
|
capture: () => sessions[active].capture(),
|
|
editor: () => document.createElement("div"),
|
|
})
|
|
const pending = attachments.addClipboardAttachment(read.promise)
|
|
|
|
active = "B"
|
|
read.resolve(new File([new Uint8Array(1024 * 1024)], "clipboard.png", { type: "image/png" }))
|
|
await pending
|
|
|
|
expect(images(sessions.A)).toHaveLength(1)
|
|
expect(images(sessions.B)).toHaveLength(0)
|
|
dispose()
|
|
})
|
|
})
|
|
})
|
|
|
|
function images(prompt: ReturnType<typeof createPromptState>) {
|
|
return prompt.current().filter((part) => part.type === "image")
|
|
}
|