reference.test.ts 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. import { describe, expect } from "bun:test"
  2. import { Effect, Exit, Layer, Scope } from "effect"
  3. import { AbsolutePath } from "@opencode-ai/core/schema"
  4. import { Global } from "@opencode-ai/core/global"
  5. import { Reference } from "@opencode-ai/core/reference"
  6. import { Repository } from "@opencode-ai/core/repository"
  7. import { RepositoryCache } from "@opencode-ai/core/repository-cache"
  8. import { EventV2 } from "@opencode-ai/core/event"
  9. import { it } from "./lib/effect"
  10. const cache = Layer.mock(RepositoryCache.Service, {
  11. ensure: () => Effect.die("unexpected Git materialization"),
  12. })
  13. describe("Reference", () => {
  14. it.effect("registers normalized sources for the owning scope", () =>
  15. Effect.gen(function* () {
  16. const references = yield* Reference.Service
  17. const scope = yield* Scope.make()
  18. const update = yield* references.transform().pipe(Effect.provideService(Scope.Scope, scope))
  19. const path = AbsolutePath.make("/docs")
  20. const source = new Reference.LocalSource({
  21. type: "local",
  22. path,
  23. description: "Use for API documentation",
  24. hidden: true,
  25. })
  26. yield* update((editor) => editor.add("docs", source))
  27. expect(yield* references.list()).toEqual([
  28. new Reference.Info({ name: "docs", path, description: "Use for API documentation", hidden: true, source }),
  29. ])
  30. yield* Scope.close(scope, Exit.void)
  31. expect(yield* references.list()).toEqual([])
  32. }).pipe(
  33. Effect.provide(Reference.layer),
  34. Effect.provide(cache),
  35. Effect.provide(EventV2.defaultLayer),
  36. Effect.provide(Global.defaultLayer),
  37. ),
  38. )
  39. it.effect("derives Git paths without exposing cache operations", () =>
  40. Effect.gen(function* () {
  41. const references = yield* Reference.Service
  42. const update = yield* references.transform()
  43. const repository = Repository.parseRemote("owner/repo")
  44. const source = new Reference.GitSource({ type: "git", repository: "owner/repo", branch: "main" })
  45. yield* update((editor) => editor.add("sdk", source))
  46. expect(yield* references.list()).toEqual([
  47. new Reference.Info({
  48. name: "sdk",
  49. path: AbsolutePath.make(Repository.cachePath(Global.Path.repos, repository)),
  50. source,
  51. }),
  52. ])
  53. }).pipe(
  54. Effect.scoped,
  55. Effect.provide(Reference.layer),
  56. Effect.provide(cache),
  57. Effect.provide(EventV2.defaultLayer),
  58. Effect.provide(Global.defaultLayer),
  59. ),
  60. )
  61. it.effect("preserves configured Git descriptions", () =>
  62. Effect.gen(function* () {
  63. const references = yield* Reference.Service
  64. const update = yield* references.transform()
  65. const repository = Repository.parseRemote("owner/repo")
  66. const source = new Reference.GitSource({
  67. type: "git",
  68. repository: "owner/repo",
  69. description: "Use for SDK implementation details",
  70. })
  71. yield* update((editor) => editor.add("sdk", source))
  72. expect(yield* references.list()).toEqual([
  73. new Reference.Info({
  74. name: "sdk",
  75. path: AbsolutePath.make(Repository.cachePath(Global.Path.repos, repository)),
  76. description: "Use for SDK implementation details",
  77. source,
  78. }),
  79. ])
  80. }).pipe(
  81. Effect.scoped,
  82. Effect.provide(Reference.layer),
  83. Effect.provide(cache),
  84. Effect.provide(EventV2.defaultLayer),
  85. Effect.provide(Global.defaultLayer),
  86. ),
  87. )
  88. })