test(core): add config and watcher test services (#39157)
This commit is contained in:
parent
f5700808c5
commit
713658c07b
20 changed files with 468 additions and 498 deletions
|
|
@ -4,7 +4,7 @@ import { makeLocationNode } from "@opencode-ai/util/effect/app-node"
|
|||
import path from "path"
|
||||
import { isDeepStrictEqual } from "node:util"
|
||||
import { type ParseError, parse } from "jsonc-parser"
|
||||
import { Context, Effect, Fiber, Layer, Option, PubSub, Schema, Semaphore, Stream } from "effect"
|
||||
import { Context, Effect, Fiber, Layer, Option, PubSub, Ref, Schema, Semaphore, Stream } from "effect"
|
||||
import { Permission } from "@opencode-ai/schema/permission"
|
||||
import { Config as ConfigSchema } from "@opencode-ai/schema/config"
|
||||
import { Integration } from "@opencode-ai/schema/integration"
|
||||
|
|
@ -176,6 +176,31 @@ export type Options = typeof Options.Type
|
|||
|
||||
export class Service extends Context.Service<Service, Interface>()("@opencode/Config") {}
|
||||
|
||||
export interface TestInterface extends Interface {
|
||||
/** Replaces the entries returned by subsequent entries() calls. */
|
||||
readonly setEntries: (entries: Entry[]) => Effect.Effect<void>
|
||||
/** Emits one filesystem update to every changes() subscriber. */
|
||||
readonly emitChange: (update: Watcher.Update) => Effect.Effect<void>
|
||||
}
|
||||
|
||||
export class Test extends Context.Service<Test, TestInterface>()("@opencode/Config/Test") {}
|
||||
|
||||
/** In-memory config for tests: static entries with replaceable state and a test-driven change feed. */
|
||||
export const testLayer = (initial: Entry[] = []) =>
|
||||
Layer.effectContext(
|
||||
Effect.gen(function* () {
|
||||
const entries = yield* Ref.make(initial)
|
||||
const updates = yield* PubSub.unbounded<Watcher.Update>()
|
||||
const service = Test.of({
|
||||
entries: () => Ref.get(entries),
|
||||
changes: () => Stream.fromPubSub(updates),
|
||||
setEntries: (next) => Ref.set(entries, next),
|
||||
emitChange: (update) => PubSub.publish(updates, update).pipe(Effect.asVoid),
|
||||
})
|
||||
return Context.empty().pipe(Context.add(Service, service), Context.add(Test, service))
|
||||
}),
|
||||
)
|
||||
|
||||
export const layer = (options?: Options) => Layer.effect(
|
||||
Service,
|
||||
Effect.gen(function* () {
|
||||
|
|
|
|||
|
|
@ -56,6 +56,32 @@ export type Options = typeof Options.Type
|
|||
|
||||
export class Service extends Context.Service<Service, Interface>()("@opencode/Watcher") {}
|
||||
|
||||
export interface TestInterface extends Interface {
|
||||
/** Broadcasts one update to every subscriber. */
|
||||
readonly emit: (update: Update) => Effect.Effect<void>
|
||||
/** Returns every subscribe call observed so far, in order. */
|
||||
readonly subscriptions: () => Effect.Effect<readonly WatchInput[]>
|
||||
}
|
||||
|
||||
export class Test extends Context.Service<Test, TestInterface>()("@opencode/Watcher/Test") {}
|
||||
|
||||
/** In-memory watcher for tests: records subscribe calls and broadcasts emitted updates. */
|
||||
export const testLayer = Layer.effectContext(
|
||||
Effect.gen(function* () {
|
||||
const updates = yield* PubSub.unbounded<Update>()
|
||||
const subscriptions: WatchInput[] = []
|
||||
const service = Test.of({
|
||||
subscribe: (input) => {
|
||||
subscriptions.push(input)
|
||||
return Stream.fromPubSub(updates)
|
||||
},
|
||||
emit: (update) => PubSub.publish(updates, update).pipe(Effect.asVoid),
|
||||
subscriptions: () => Effect.sync(() => [...subscriptions]),
|
||||
})
|
||||
return Context.empty().pipe(Context.add(Service, service), Context.add(Test, service))
|
||||
}),
|
||||
)
|
||||
|
||||
export const layer = (options?: Options) => Layer.effect(
|
||||
Service,
|
||||
Effect.gen(function* () {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue