search.test.ts 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243
  1. import { describe, expect } from "bun:test"
  2. import fs from "fs/promises"
  3. import path from "path"
  4. import { Effect } from "effect"
  5. import { Ripgrep } from "@opencode-ai/core/ripgrep"
  6. import { AbsolutePath, RelativePath } from "@opencode-ai/core/schema"
  7. import { tmpdir } from "../fixture/tmpdir"
  8. import { testEffect } from "../lib/effect"
  9. const it = testEffect(Ripgrep.defaultLayer)
  10. const withTmp = <A, E, R>(f: (directory: AbsolutePath) => Effect.Effect<A, E, R>) =>
  11. Effect.acquireRelease(
  12. Effect.promise(() => tmpdir()),
  13. (tmp) => Effect.promise(() => tmp[Symbol.asyncDispose]()),
  14. ).pipe(Effect.flatMap((tmp) => f(AbsolutePath.make(tmp.path))))
  15. describe("Ripgrep", () => {
  16. it.live("globs files as an array", () =>
  17. withTmp((cwd) =>
  18. Effect.gen(function* () {
  19. yield* Effect.promise(() => fs.mkdir(path.join(cwd, "src")))
  20. yield* Effect.promise(() => fs.writeFile(path.join(cwd, "src", "match.ts"), "needle\n"))
  21. const result = yield* (yield* Ripgrep.Service).glob({ cwd, pattern: "**/*.ts", limit: 10 })
  22. expect(result.map((item) => item.path)).toEqual([RelativePath.make("src/match.ts")])
  23. }),
  24. ),
  25. )
  26. it.live("greps files with include filtering", () =>
  27. withTmp((cwd) =>
  28. Effect.gen(function* () {
  29. yield* Effect.promise(() => fs.mkdir(path.join(cwd, "src")))
  30. yield* Effect.promise(() => fs.writeFile(path.join(cwd, "src", "match.ts"), "needle\n"))
  31. yield* Effect.promise(() => fs.writeFile(path.join(cwd, "src", "skip.txt"), "needle\n"))
  32. const result = yield* (yield* Ripgrep.Service).grep({ cwd, pattern: "needle", include: "*.ts", limit: 10 })
  33. expect(result).toHaveLength(1)
  34. expect(result[0]?.entry.path).toBe(RelativePath.make("src/match.ts"))
  35. expect(result[0]?.submatches[0]?.text).toBe("needle")
  36. }),
  37. ),
  38. )
  39. })