Skip to content

Commit 257fcaf

Browse files
authored
test(tool): migrate edit concurrency test (#26983)
1 parent 04aafe2 commit 257fcaf

1 file changed

Lines changed: 47 additions & 71 deletions

File tree

packages/opencode/test/tool/edit.test.ts

Lines changed: 47 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
1-
import { afterAll, afterEach, describe, test, expect } from "bun:test"
1+
import { afterEach, describe, expect } from "bun:test"
22
import path from "path"
33
import fs from "fs/promises"
4-
import { Cause, Deferred, Effect, Exit, Layer, ManagedRuntime } from "effect"
4+
import { Cause, Deferred, Effect, Exit, Fiber, Layer } from "effect"
55
import { EditTool } from "../../src/tool/edit"
6-
import { WithInstance } from "../../src/project/with-instance"
7-
import { disposeAllInstances, TestInstance, tmpdir } from "../fixture/fixture"
6+
import { disposeAllInstances, TestInstance } from "../fixture/fixture"
87
import { LSP } from "@/lsp/lsp"
98
import { AppFileSystem } from "@opencode-ai/core/filesystem"
109
import { Format } from "../../src/format"
@@ -42,20 +41,6 @@ const layer = Layer.mergeAll(
4241

4342
const it = testEffect(layer)
4443

45-
const runtime = ManagedRuntime.make(layer)
46-
47-
afterAll(async () => {
48-
await runtime.dispose()
49-
})
50-
51-
const resolve = () =>
52-
runtime.runPromise(
53-
Effect.gen(function* () {
54-
const info = yield* EditTool
55-
return yield* info.init()
56-
}),
57-
)
58-
5944
const init = Effect.fn("EditToolTest.init")(function* () {
6045
const info = yield* EditTool
6146
return yield* info.init()
@@ -500,58 +485,49 @@ describe("tool.edit", () => {
500485
})
501486

502487
describe("concurrent editing", () => {
503-
test("preserves concurrent edits to different sections of the same file", async () => {
504-
await using tmp = await tmpdir()
505-
const filepath = path.join(tmp.path, "file.txt")
506-
await fs.writeFile(filepath, "top = 0\nmiddle = keep\nbottom = 0\n", "utf-8")
507-
508-
await WithInstance.provide({
509-
directory: tmp.path,
510-
fn: async () => {
511-
const edit = await resolve()
512-
let asks = 0
513-
const firstAsk = Promise.withResolvers<void>()
514-
const delayedCtx = {
515-
...ctx,
516-
ask: () =>
517-
Effect.gen(function* () {
518-
asks++
519-
if (asks !== 1) return
520-
firstAsk.resolve()
521-
yield* Effect.promise(() => Bun.sleep(50))
522-
}),
523-
}
524-
525-
const promise1 = Effect.runPromise(
526-
edit.execute(
527-
{
528-
filePath: filepath,
529-
oldString: "top = 0",
530-
newString: "top = 1",
531-
},
532-
delayedCtx,
533-
),
534-
)
535-
536-
await firstAsk.promise
537-
538-
const promise2 = Effect.runPromise(
539-
edit.execute(
540-
{
541-
filePath: filepath,
542-
oldString: "bottom = 0",
543-
newString: "bottom = 2",
544-
},
545-
delayedCtx,
546-
),
547-
)
548-
549-
const results = await Promise.allSettled([promise1, promise2])
550-
expect(results[0]?.status).toBe("fulfilled")
551-
expect(results[1]?.status).toBe("fulfilled")
552-
expect(await fs.readFile(filepath, "utf-8")).toBe("top = 1\nmiddle = keep\nbottom = 2\n")
553-
},
554-
})
555-
})
488+
it.instance("preserves concurrent edits to different sections of the same file", () =>
489+
Effect.gen(function* () {
490+
const test = yield* TestInstance
491+
const filepath = path.join(test.directory, "file.txt")
492+
yield* put(filepath, "top = 0\nmiddle = keep\nbottom = 0\n")
493+
494+
const firstAsk = yield* Deferred.make<void>()
495+
let asks = 0
496+
const delayedCtx = {
497+
...ctx,
498+
ask: () =>
499+
Effect.gen(function* () {
500+
asks++
501+
if (asks !== 1) return
502+
yield* Deferred.succeed(firstAsk, undefined)
503+
yield* Effect.promise(() => Bun.sleep(50))
504+
}),
505+
}
506+
507+
const first = yield* run(
508+
{
509+
filePath: filepath,
510+
oldString: "top = 0",
511+
newString: "top = 1",
512+
},
513+
delayedCtx,
514+
).pipe(Effect.forkScoped)
515+
516+
yield* Deferred.await(firstAsk)
517+
yield* Effect.all([
518+
Fiber.join(first),
519+
run(
520+
{
521+
filePath: filepath,
522+
oldString: "bottom = 0",
523+
newString: "bottom = 2",
524+
},
525+
delayedCtx,
526+
),
527+
])
528+
529+
expect(yield* load(filepath)).toBe("top = 1\nmiddle = keep\nbottom = 2\n")
530+
}),
531+
)
556532
})
557533
})

0 commit comments

Comments
 (0)