test(worktree): scope created worktree cleanup (#27191)
This commit is contained in:
@@ -38,12 +38,31 @@ const waitReady = Effect.fn("WorktreeTest.waitReady")(function* () {
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
const disposeWorktreeInstance = (directory: string) =>
|
const removeCreatedWorktree = (directory: string) =>
|
||||||
Effect.gen(function* () {
|
Effect.gen(function* () {
|
||||||
|
const svc = yield* Worktree.Service
|
||||||
const ctx = yield* Effect.sync(() => Instance.current).pipe(provideInstance(directory))
|
const ctx = yield* Effect.sync(() => Instance.current).pipe(provideInstance(directory))
|
||||||
yield* Effect.promise(() => InstanceRuntime.disposeInstance(ctx))
|
yield* Effect.promise(() => InstanceRuntime.disposeInstance(ctx))
|
||||||
|
const ok = yield* svc.remove({ directory })
|
||||||
|
if (!ok) return yield* Effect.fail(new Error(`failed to remove worktree ${directory}`))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const withCreatedWorktree = <A, E, R>(
|
||||||
|
input: Parameters<Worktree.Interface["create"]>[0],
|
||||||
|
use: (created: { info: Worktree.Info; ready: { name: string; branch?: string } }) => Effect.Effect<A, E, R>,
|
||||||
|
) =>
|
||||||
|
Effect.acquireUseRelease(
|
||||||
|
Effect.gen(function* () {
|
||||||
|
const svc = yield* Worktree.Service
|
||||||
|
const ready = yield* waitReady().pipe(Effect.forkScoped)
|
||||||
|
const info = yield* svc.create(input)
|
||||||
|
const props = yield* Fiber.join(ready)
|
||||||
|
return { info, ready: props }
|
||||||
|
}),
|
||||||
|
use,
|
||||||
|
({ info }) => removeCreatedWorktree(info.directory),
|
||||||
|
)
|
||||||
|
|
||||||
const git = Effect.fn("WorktreeTest.git")(function* (cwd: string, args: string[]) {
|
const git = Effect.fn("WorktreeTest.git")(function* (cwd: string, args: string[]) {
|
||||||
const service = yield* Git.Service
|
const service = yield* Git.Service
|
||||||
const result = yield* service.run(args, { cwd })
|
const result = yield* service.run(args, { cwd })
|
||||||
@@ -158,66 +177,45 @@ describe("Worktree", () => {
|
|||||||
it.instance(
|
it.instance(
|
||||||
"create returns worktree info and remove cleans up",
|
"create returns worktree info and remove cleans up",
|
||||||
() =>
|
() =>
|
||||||
|
withCreatedWorktree(undefined, ({ info }) =>
|
||||||
Effect.gen(function* () {
|
Effect.gen(function* () {
|
||||||
const svc = yield* Worktree.Service
|
|
||||||
const ready = yield* waitReady().pipe(Effect.forkScoped)
|
|
||||||
const info = yield* svc.create()
|
|
||||||
|
|
||||||
expect(info.name).toBeDefined()
|
expect(info.name).toBeDefined()
|
||||||
expect(info.branch ?? "").toStartWith("opencode/")
|
expect(info.branch ?? "").toStartWith("opencode/")
|
||||||
expect(info.directory).toBeDefined()
|
expect(info.directory).toBeDefined()
|
||||||
|
|
||||||
yield* Fiber.join(ready)
|
|
||||||
yield* disposeWorktreeInstance(info.directory)
|
|
||||||
|
|
||||||
const ok = yield* svc.remove({ directory: info.directory })
|
|
||||||
expect(ok).toBe(true)
|
|
||||||
}),
|
}),
|
||||||
|
),
|
||||||
{ git: true },
|
{ git: true },
|
||||||
)
|
)
|
||||||
|
|
||||||
it.instance(
|
it.instance(
|
||||||
"create returns after setup and fires Event.Ready after bootstrap",
|
"create returns after setup and fires Event.Ready after bootstrap",
|
||||||
() =>
|
() =>
|
||||||
|
withCreatedWorktree(undefined, ({ info, ready }) =>
|
||||||
Effect.gen(function* () {
|
Effect.gen(function* () {
|
||||||
const test = yield* TestInstance
|
|
||||||
const fs = yield* AppFileSystem.Service
|
|
||||||
const svc = yield* Worktree.Service
|
const svc = yield* Worktree.Service
|
||||||
const ready = yield* waitReady().pipe(Effect.forkScoped)
|
|
||||||
const info = yield* svc.create()
|
|
||||||
|
|
||||||
expect(info.name).toBeDefined()
|
expect(info.name).toBeDefined()
|
||||||
expect(info.branch ?? "").toStartWith("opencode/")
|
expect(info.branch ?? "").toStartWith("opencode/")
|
||||||
|
|
||||||
const text = yield* git(test.directory, ["worktree", "list", "--porcelain"])
|
expect(ready.name).toBe(info.name)
|
||||||
const next = yield* fs.realPath(info.directory).pipe(Effect.catch(() => Effect.succeed(info.directory)))
|
expect(ready.branch).toBe(info.branch)
|
||||||
expect(normalize(text)).toContain(normalize(next))
|
|
||||||
|
|
||||||
const props = yield* Fiber.join(ready)
|
const list = yield* svc.list()
|
||||||
expect(props.name).toBe(info.name)
|
expect(list).toContainEqual(expect.objectContaining({ name: info.name, branch: info.branch }))
|
||||||
expect(props.branch).toBe(info.branch)
|
|
||||||
|
|
||||||
yield* disposeWorktreeInstance(info.directory)
|
|
||||||
yield* svc.remove({ directory: info.directory })
|
|
||||||
}),
|
}),
|
||||||
|
),
|
||||||
{ git: true },
|
{ git: true },
|
||||||
)
|
)
|
||||||
|
|
||||||
it.instance(
|
it.instance(
|
||||||
"create with custom name",
|
"create with custom name",
|
||||||
() =>
|
() =>
|
||||||
|
withCreatedWorktree({ name: "test-workspace" }, ({ info }) =>
|
||||||
Effect.gen(function* () {
|
Effect.gen(function* () {
|
||||||
const svc = yield* Worktree.Service
|
|
||||||
const ready = yield* waitReady().pipe(Effect.forkScoped)
|
|
||||||
const info = yield* svc.create({ name: "test-workspace" })
|
|
||||||
|
|
||||||
expect(info.name).toBe("test-workspace")
|
expect(info.name).toBe("test-workspace")
|
||||||
expect(info.branch).toBe("opencode/test-workspace")
|
expect(info.branch).toBe("opencode/test-workspace")
|
||||||
|
|
||||||
yield* Fiber.join(ready)
|
|
||||||
yield* disposeWorktreeInstance(info.directory)
|
|
||||||
yield* svc.remove({ directory: info.directory })
|
|
||||||
}),
|
}),
|
||||||
|
),
|
||||||
{ git: true },
|
{ git: true },
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
@@ -239,8 +237,7 @@ describe("Worktree", () => {
|
|||||||
expect(normalizedList).toContain(normalizedDir)
|
expect(normalizedList).toContain(normalizedDir)
|
||||||
|
|
||||||
yield* Fiber.join(ready)
|
yield* Fiber.join(ready)
|
||||||
yield* disposeWorktreeInstance(info.directory)
|
yield* removeCreatedWorktree(info.directory)
|
||||||
yield* svc.remove({ directory: info.directory })
|
|
||||||
}),
|
}),
|
||||||
{ git: true },
|
{ git: true },
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user