opencode/packages/tui/test/context/storage.test.ts
ARH e8b3e19e85
fix(tui): don't crash when fs.watch throws (e.g. ENOSPC) (#51210)
Co-authored-by: Alireza Haghdoost <haghdoost@uber.com>
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-24 19:16:43 -05:00

37 lines
1.3 KiB
TypeScript

import { afterEach, expect, spyOn, test } from "bun:test"
import * as fs from "fs"
import { mkdtempSync, rmSync } from "fs"
import { tmpdir } from "os"
import path from "path"
import { createStorage } from "../../src/context/storage"
afterEach(() => {
spyOn(fs, "watch").mockRestore()
})
test("createStorage degrades gracefully when fs.watch throws (e.g. ENOSPC)", async () => {
const dir = mkdtempSync(path.join(tmpdir(), "storage-test-"))
// fs.watch throws synchronously when inotify_add_watch fails (e.g. the watch
// limit is exhausted). Simulate that scoped to this test only.
spyOn(fs, "watch").mockImplementation(() => {
throw Object.assign(new Error("ENOSPC: no space left on device, watch '/some/dir'"), { code: "ENOSPC" })
})
try {
let result: ReturnType<typeof createStorage> | undefined
expect(() => {
result = createStorage(dir, "next")
}).not.toThrow()
// storage should still be usable even though the live-reload watcher failed to attach
const [store, update] = result!.storage.store("kv", { initial: { count: 0 } })
expect(store.count).toBe(0)
await update((draft) => {
draft.count = 1
})
expect(store.count).toBe(1)
expect(() => result!.close()).not.toThrow()
} finally {
rmSync(dir, { recursive: true, force: true })
}
})