Просмотр исходного кода

test(git): migrate git tests to Effect runner (#27121)

Kit Langton 3 месяцев назад
Родитель
Сommit
b668af29dd
1 измененных файлов с 113 добавлено и 110 удалено
  1. 113 110
      packages/opencode/test/git/git.test.ts

+ 113 - 110
packages/opencode/test/git/git.test.ts

@@ -1,71 +1,70 @@
 import { $ } from "bun"
-import { describe, expect, test } from "bun:test"
+import { describe, expect } from "bun:test"
 import fs from "fs/promises"
 import path from "path"
-import { ManagedRuntime } from "effect"
+import { Effect } from "effect"
 import { Git } from "../../src/git"
 import { tmpdir } from "../fixture/fixture"
+import { testEffect } from "../lib/effect"
 
 const weird = process.platform === "win32" ? "space file.txt" : "tab\tfile.txt"
+const it = testEffect(Git.defaultLayer)
 
-async function withGit<T>(body: (rt: ManagedRuntime.ManagedRuntime<Git.Service, never>) => Promise<T>) {
-  const rt = ManagedRuntime.make(Git.defaultLayer)
-  try {
-    return await body(rt)
-  } finally {
-    await rt.dispose()
-  }
-}
+const scopedTmpdir = (options?: Parameters<typeof tmpdir>[0]) =>
+  Effect.acquireRelease(
+    Effect.promise(() => tmpdir(options)),
+    (tmp) => Effect.promise(() => tmp[Symbol.asyncDispose]()),
+  )
 
 describe("Git", () => {
-  test("branch() returns current branch name", async () => {
-    await using tmp = await tmpdir({ git: true })
-
-    await withGit(async (rt) => {
-      const branch = await rt.runPromise(Git.Service.use((git) => git.branch(tmp.path)))
+  it.live("branch() returns current branch name", () =>
+    Effect.gen(function* () {
+      const tmp = yield* scopedTmpdir({ git: true })
+      const git = yield* Git.Service
+      const branch = yield* git.branch(tmp.path)
       expect(branch).toBeDefined()
       expect(typeof branch).toBe("string")
-    })
-  })
-
-  test("branch() returns undefined for non-git directories", async () => {
-    await using tmp = await tmpdir()
-
-    await withGit(async (rt) => {
-      const branch = await rt.runPromise(Git.Service.use((git) => git.branch(tmp.path)))
+    }),
+  )
+
+  it.live("branch() returns undefined for non-git directories", () =>
+    Effect.gen(function* () {
+      const tmp = yield* scopedTmpdir()
+      const git = yield* Git.Service
+      const branch = yield* git.branch(tmp.path)
       expect(branch).toBeUndefined()
-    })
-  })
-
-  test("branch() returns undefined for detached HEAD", async () => {
-    await using tmp = await tmpdir({ git: true })
-    const hash = (await $`git rev-parse HEAD`.cwd(tmp.path).quiet().text()).trim()
-    await $`git checkout --detach ${hash}`.cwd(tmp.path).quiet()
-
-    await withGit(async (rt) => {
-      const branch = await rt.runPromise(Git.Service.use((git) => git.branch(tmp.path)))
+    }),
+  )
+
+  it.live("branch() returns undefined for detached HEAD", () =>
+    Effect.gen(function* () {
+      const tmp = yield* scopedTmpdir({ git: true })
+      const hash = (yield* Effect.promise(() => $`git rev-parse HEAD`.cwd(tmp.path).quiet().text())).trim()
+      yield* Effect.promise(() => $`git checkout --detach ${hash}`.cwd(tmp.path).quiet())
+      const git = yield* Git.Service
+      const branch = yield* git.branch(tmp.path)
       expect(branch).toBeUndefined()
-    })
-  })
-
-  test("defaultBranch() uses init.defaultBranch when available", async () => {
-    await using tmp = await tmpdir({ git: true })
-    await $`git branch -M trunk`.cwd(tmp.path).quiet()
-    await $`git config init.defaultBranch trunk`.cwd(tmp.path).quiet()
-
-    await withGit(async (rt) => {
-      const branch = await rt.runPromise(Git.Service.use((git) => git.defaultBranch(tmp.path)))
+    }),
+  )
+
+  it.live("defaultBranch() uses init.defaultBranch when available", () =>
+    Effect.gen(function* () {
+      const tmp = yield* scopedTmpdir({ git: true })
+      yield* Effect.promise(() => $`git branch -M trunk`.cwd(tmp.path).quiet())
+      yield* Effect.promise(() => $`git config init.defaultBranch trunk`.cwd(tmp.path).quiet())
+      const git = yield* Git.Service
+      const branch = yield* git.defaultBranch(tmp.path)
       expect(branch?.name).toBe("trunk")
       expect(branch?.ref).toBe("trunk")
-    })
-  })
-
-  test("status() handles special filenames", async () => {
-    await using tmp = await tmpdir({ git: true })
-    await fs.writeFile(path.join(tmp.path, weird), "hello\n", "utf-8")
-
-    await withGit(async (rt) => {
-      const status = await rt.runPromise(Git.Service.use((git) => git.status(tmp.path)))
+    }),
+  )
+
+  it.live("status() handles special filenames", () =>
+    Effect.gen(function* () {
+      const tmp = yield* scopedTmpdir({ git: true })
+      yield* Effect.promise(() => fs.writeFile(path.join(tmp.path, weird), "hello\n", "utf-8"))
+      const git = yield* Git.Service
+      const status = yield* git.status(tmp.path)
       expect(status).toEqual(
         expect.arrayContaining([
           expect.objectContaining({
@@ -74,23 +73,24 @@ describe("Git", () => {
           }),
         ]),
       )
-    })
-  })
-
-  test("diff(), stats(), and mergeBase() parse tracked changes", async () => {
-    await using tmp = await tmpdir({ git: true })
-    await $`git branch -M main`.cwd(tmp.path).quiet()
-    await fs.writeFile(path.join(tmp.path, weird), "before\n", "utf-8")
-    await $`git add .`.cwd(tmp.path).quiet()
-    await $`git commit --no-gpg-sign -m "add file"`.cwd(tmp.path).quiet()
-    await $`git checkout -b feature/test`.cwd(tmp.path).quiet()
-    await fs.writeFile(path.join(tmp.path, weird), "after\n", "utf-8")
-
-    await withGit(async (rt) => {
-      const [base, diff, stats] = await Promise.all([
-        rt.runPromise(Git.Service.use((git) => git.mergeBase(tmp.path, "main"))),
-        rt.runPromise(Git.Service.use((git) => git.diff(tmp.path, "HEAD"))),
-        rt.runPromise(Git.Service.use((git) => git.stats(tmp.path, "HEAD"))),
+    }),
+  )
+
+  it.live("diff(), stats(), and mergeBase() parse tracked changes", () =>
+    Effect.gen(function* () {
+      const tmp = yield* scopedTmpdir({ git: true })
+      yield* Effect.promise(() => $`git branch -M main`.cwd(tmp.path).quiet())
+      yield* Effect.promise(() => fs.writeFile(path.join(tmp.path, weird), "before\n", "utf-8"))
+      yield* Effect.promise(() => $`git add .`.cwd(tmp.path).quiet())
+      yield* Effect.promise(() => $`git commit --no-gpg-sign -m "add file"`.cwd(tmp.path).quiet())
+      yield* Effect.promise(() => $`git checkout -b feature/test`.cwd(tmp.path).quiet())
+      yield* Effect.promise(() => fs.writeFile(path.join(tmp.path, weird), "after\n", "utf-8"))
+
+      const git = yield* Git.Service
+      const [base, diff, stats] = yield* Effect.all([
+        git.mergeBase(tmp.path, "main"),
+        git.diff(tmp.path, "HEAD"),
+        git.stats(tmp.path, "HEAD"),
       ])
 
       expect(base).toBeTruthy()
@@ -111,23 +111,24 @@ describe("Git", () => {
           }),
         ]),
       )
-    })
-  })
-
-  test("patch() returns capped native patch output", async () => {
-    await using tmp = await tmpdir({ git: true })
-    await fs.writeFile(path.join(tmp.path, weird), "before\n", "utf-8")
-    await fs.writeFile(path.join(tmp.path, "other.txt"), "old\n", "utf-8")
-    await $`git add .`.cwd(tmp.path).quiet()
-    await $`git commit --no-gpg-sign -m "add file"`.cwd(tmp.path).quiet()
-    await fs.writeFile(path.join(tmp.path, weird), "after\n", "utf-8")
-    await fs.writeFile(path.join(tmp.path, "other.txt"), "new\n", "utf-8")
-
-    await withGit(async (rt) => {
-      const [patch, all, capped] = await Promise.all([
-        rt.runPromise(Git.Service.use((git) => git.patch(tmp.path, "HEAD", weird, { context: 2_147_483_647 }))),
-        rt.runPromise(Git.Service.use((git) => git.patchAll(tmp.path, "HEAD", { context: 2_147_483_647 }))),
-        rt.runPromise(Git.Service.use((git) => git.patch(tmp.path, "HEAD", weird, { maxOutputBytes: 1 }))),
+    }),
+  )
+
+  it.live("patch() returns capped native patch output", () =>
+    Effect.gen(function* () {
+      const tmp = yield* scopedTmpdir({ git: true })
+      yield* Effect.promise(() => fs.writeFile(path.join(tmp.path, weird), "before\n", "utf-8"))
+      yield* Effect.promise(() => fs.writeFile(path.join(tmp.path, "other.txt"), "old\n", "utf-8"))
+      yield* Effect.promise(() => $`git add .`.cwd(tmp.path).quiet())
+      yield* Effect.promise(() => $`git commit --no-gpg-sign -m "add file"`.cwd(tmp.path).quiet())
+      yield* Effect.promise(() => fs.writeFile(path.join(tmp.path, weird), "after\n", "utf-8"))
+      yield* Effect.promise(() => fs.writeFile(path.join(tmp.path, "other.txt"), "new\n", "utf-8"))
+
+      const git = yield* Git.Service
+      const [patch, all, capped] = yield* Effect.all([
+        git.patch(tmp.path, "HEAD", weird, { context: 2_147_483_647 }),
+        git.patchAll(tmp.path, "HEAD", { context: 2_147_483_647 }),
+        git.patch(tmp.path, "HEAD", weird, { maxOutputBytes: 1 }),
       ])
 
       expect(patch.truncated).toBe(false)
@@ -140,17 +141,18 @@ describe("Git", () => {
       expect(all.text).toContain("+new")
       expect(capped.truncated).toBe(true)
       expect(capped.text).toBe("")
-    })
-  })
-
-  test("patchUntracked() and statUntracked() handle added files", async () => {
-    await using tmp = await tmpdir({ git: true })
-    await fs.writeFile(path.join(tmp.path, weird), "one\ntwo\n", "utf-8")
-
-    await withGit(async (rt) => {
-      const [patch, stat] = await Promise.all([
-        rt.runPromise(Git.Service.use((git) => git.patchUntracked(tmp.path, weird, { context: 2_147_483_647 }))),
-        rt.runPromise(Git.Service.use((git) => git.statUntracked(tmp.path, weird))),
+    }),
+  )
+
+  it.live("patchUntracked() and statUntracked() handle added files", () =>
+    Effect.gen(function* () {
+      const tmp = yield* scopedTmpdir({ git: true })
+      yield* Effect.promise(() => fs.writeFile(path.join(tmp.path, weird), "one\ntwo\n", "utf-8"))
+
+      const git = yield* Git.Service
+      const [patch, stat] = yield* Effect.all([
+        git.patchUntracked(tmp.path, weird, { context: 2_147_483_647 }),
+        git.statUntracked(tmp.path, weird),
       ])
 
       expect(patch.truncated).toBe(false)
@@ -158,18 +160,19 @@ describe("Git", () => {
       expect(patch.text).toContain("+one")
       expect(patch.text).toContain("+two")
       expect(stat).toEqual(expect.objectContaining({ file: weird, additions: 2, deletions: 0 }))
-    })
-  })
-
-  test("show() returns empty text for binary blobs", async () => {
-    await using tmp = await tmpdir({ git: true })
-    await fs.writeFile(path.join(tmp.path, "bin.dat"), new Uint8Array([0, 1, 2, 3]))
-    await $`git add .`.cwd(tmp.path).quiet()
-    await $`git commit --no-gpg-sign -m "add binary"`.cwd(tmp.path).quiet()
-
-    await withGit(async (rt) => {
-      const text = await rt.runPromise(Git.Service.use((git) => git.show(tmp.path, "HEAD", "bin.dat")))
+    }),
+  )
+
+  it.live("show() returns empty text for binary blobs", () =>
+    Effect.gen(function* () {
+      const tmp = yield* scopedTmpdir({ git: true })
+      yield* Effect.promise(() => fs.writeFile(path.join(tmp.path, "bin.dat"), new Uint8Array([0, 1, 2, 3])))
+      yield* Effect.promise(() => $`git add .`.cwd(tmp.path).quiet())
+      yield* Effect.promise(() => $`git commit --no-gpg-sign -m "add binary"`.cwd(tmp.path).quiet())
+
+      const git = yield* Git.Service
+      const text = yield* git.show(tmp.path, "HEAD", "bin.dat")
       expect(text).toBe("")
-    })
-  })
+    }),
+  )
 })