|
@@ -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",
|
|
|
() =>
|
|
() =>
|
|
|
- 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.branch ?? "").toStartWith("opencode/")
|
|
|
|
|
- expect(info.directory).toBeDefined()
|
|
|
|
|
-
|
|
|
|
|
- yield* Fiber.join(ready)
|
|
|
|
|
- yield* disposeWorktreeInstance(info.directory)
|
|
|
|
|
-
|
|
|
|
|
- const ok = yield* svc.remove({ directory: info.directory })
|
|
|
|
|
- expect(ok).toBe(true)
|
|
|
|
|
- }),
|
|
|
|
|
|
|
+ withCreatedWorktree(undefined, ({ info }) =>
|
|
|
|
|
+ Effect.gen(function* () {
|
|
|
|
|
+ expect(info.name).toBeDefined()
|
|
|
|
|
+ expect(info.branch ?? "").toStartWith("opencode/")
|
|
|
|
|
+ expect(info.directory).toBeDefined()
|
|
|
|
|
+ }),
|
|
|
|
|
+ ),
|
|
|
{ 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",
|
|
|
() =>
|
|
() =>
|
|
|
- Effect.gen(function* () {
|
|
|
|
|
- const test = yield* TestInstance
|
|
|
|
|
- const fs = yield* AppFileSystem.Service
|
|
|
|
|
- const svc = yield* Worktree.Service
|
|
|
|
|
- const ready = yield* waitReady().pipe(Effect.forkScoped)
|
|
|
|
|
- const info = yield* svc.create()
|
|
|
|
|
-
|
|
|
|
|
- expect(info.name).toBeDefined()
|
|
|
|
|
- expect(info.branch ?? "").toStartWith("opencode/")
|
|
|
|
|
|
|
+ withCreatedWorktree(undefined, ({ info, ready }) =>
|
|
|
|
|
+ Effect.gen(function* () {
|
|
|
|
|
+ const svc = yield* Worktree.Service
|
|
|
|
|
|
|
|
- const text = yield* git(test.directory, ["worktree", "list", "--porcelain"])
|
|
|
|
|
- const next = yield* fs.realPath(info.directory).pipe(Effect.catch(() => Effect.succeed(info.directory)))
|
|
|
|
|
- expect(normalize(text)).toContain(normalize(next))
|
|
|
|
|
|
|
+ expect(info.name).toBeDefined()
|
|
|
|
|
+ expect(info.branch ?? "").toStartWith("opencode/")
|
|
|
|
|
|
|
|
- const props = yield* Fiber.join(ready)
|
|
|
|
|
- expect(props.name).toBe(info.name)
|
|
|
|
|
- expect(props.branch).toBe(info.branch)
|
|
|
|
|
|
|
+ expect(ready.name).toBe(info.name)
|
|
|
|
|
+ expect(ready.branch).toBe(info.branch)
|
|
|
|
|
|
|
|
- yield* disposeWorktreeInstance(info.directory)
|
|
|
|
|
- yield* svc.remove({ directory: info.directory })
|
|
|
|
|
- }),
|
|
|
|
|
|
|
+ const list = yield* svc.list()
|
|
|
|
|
+ expect(list).toContainEqual(expect.objectContaining({ name: info.name, branch: info.branch }))
|
|
|
|
|
+ }),
|
|
|
|
|
+ ),
|
|
|
{ git: true },
|
|
{ git: true },
|
|
|
)
|
|
)
|
|
|
|
|
|
|
|
it.instance(
|
|
it.instance(
|
|
|
"create with custom name",
|
|
"create with custom name",
|
|
|
() =>
|
|
() =>
|
|
|
- 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.branch).toBe("opencode/test-workspace")
|
|
|
|
|
-
|
|
|
|
|
- yield* Fiber.join(ready)
|
|
|
|
|
- yield* disposeWorktreeInstance(info.directory)
|
|
|
|
|
- yield* svc.remove({ directory: info.directory })
|
|
|
|
|
- }),
|
|
|
|
|
|
|
+ withCreatedWorktree({ name: "test-workspace" }, ({ info }) =>
|
|
|
|
|
+ Effect.gen(function* () {
|
|
|
|
|
+ expect(info.name).toBe("test-workspace")
|
|
|
|
|
+ expect(info.branch).toBe("opencode/test-workspace")
|
|
|
|
|
+ }),
|
|
|
|
|
+ ),
|
|
|
{ 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* svc.remove({ directory: info.directory })
|
|
|
|
|
|
|
+ yield* removeCreatedWorktree(info.directory)
|
|
|
}),
|
|
}),
|
|
|
{ git: true },
|
|
{ git: true },
|
|
|
)
|
|
)
|