import { describe, expect, test } from "bun:test" import { Lock } from "../../src/util/lock" function tick() { return new Promise((r) => queueMicrotask(r)) } async function flush(n = 5) { for (let i = 0; i < n; i++) await tick() } describe("util.lock", () => { test("writer exclusivity: blocks reads and other writes while held", async () => { const key = "lock:" + Math.random().toString(36).slice(2) const state = { writer2: false, reader: false, writers: 0, } // Acquire writer1 using writer1 = await Lock.write(key) state.writers++ expect(state.writers).toBe(1) // Start writer2 candidate (should block) const writer2Task = (async () => { const w = await Lock.write(key) state.writers++ expect(state.writers).toBe(1) state.writer2 = true // Hold for a tick so reader cannot slip in await tick() return w })() // Start reader candidate (should block) const readerTask = (async () => { const r = await Lock.read(key) state.reader = true return r })() // Flush microtasks and assert neither acquired await flush() expect(state.writer2).toBe(false) expect(state.reader).toBe(false) // Release writer1 writer1[Symbol.dispose]() state.writers-- // writer2 should acquire next const writer2 = await writer2Task expect(state.writer2).toBe(true) // Reader still blocked while writer2 held await flush() expect(state.reader).toBe(false) // Release writer2 writer2[Symbol.dispose]() state.writers-- // Reader should now acquire const reader = await readerTask expect(state.reader).toBe(true) reader[Symbol.dispose]() }) })