mirror of
https://gitea.toothfairyai.com/ToothFairyAI/tf_code.git
synced 2026-03-30 22:03:58 +00:00
- Rename packages/opencode → packages/tfcode (directory only) - Rename bin/opencode → bin/tfcode (CLI binary) - Rename .opencode → .tfcode (config directory) - Update package.json name and bin field - Update config directory path references (.tfcode) - Keep internal code references as 'opencode' for easy upstream sync - Keep @opencode-ai/* workspace package names This minimal branding approach allows clean merges from upstream opencode repository while providing tfcode branding for users.
73 lines
1.7 KiB
TypeScript
73 lines
1.7 KiB
TypeScript
import { describe, expect, test } from "bun:test"
|
|
import { Lock } from "../../src/util/lock"
|
|
|
|
function tick() {
|
|
return new Promise<void>((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]()
|
|
})
|
|
})
|