search.test.ts 1.9 KB

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