refactor(core): convert opencode tests to nodes (#34453)
This commit is contained in:
parent
b10d617c80
commit
bc5ce5eab1
36 changed files with 112 additions and 106 deletions
|
|
@ -1,6 +1,7 @@
|
|||
export * as Observability from "./observability"
|
||||
|
||||
import { NodeFileSystem } from "@effect/platform-node"
|
||||
import { LayerNode } from "./effect/layer-node"
|
||||
import { Effect, Layer, Logger, References } from "effect"
|
||||
import { FetchHttpClient } from "effect/unstable/http"
|
||||
import { OtlpSerialization } from "effect/unstable/observability"
|
||||
|
|
@ -19,3 +20,5 @@ export const layer = Layer.unwrap(
|
|||
return Layer.merge(logs, yield* Effect.promise(Otlp.tracingLayer))
|
||||
}),
|
||||
)
|
||||
|
||||
export const node = LayerNode.make({ name: "observability", layer, deps: [] })
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import type { McpServer } from "@agentclientprotocol/sdk"
|
||||
import type { Message, Part } from "@opencode-ai/sdk/v2"
|
||||
import { LayerNode } from "@opencode-ai/core/effect/layer-node"
|
||||
import { ProviderV2 } from "@opencode-ai/core/provider"
|
||||
import { ModelV2 } from "@opencode-ai/core/model"
|
||||
import { Context, Effect, Layer, Ref } from "effect"
|
||||
|
|
@ -202,6 +203,8 @@ export const layer = Layer.effect(
|
|||
|
||||
export const defaultLayer = layer
|
||||
|
||||
export const node = LayerNode.make({ service: Service, layer, deps: [] })
|
||||
|
||||
function makeSession(input: StoreInput): Info {
|
||||
return {
|
||||
id: input.id,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import { expect } from "bun:test"
|
||||
import { LayerNode } from "@opencode-ai/core/effect/layer-node"
|
||||
import { Effect, Layer, Option } from "effect"
|
||||
import { sql } from "drizzle-orm"
|
||||
|
||||
|
|
@ -13,9 +14,10 @@ const truncate = Layer.effectDiscard(
|
|||
yield* db.run(sql`DELETE FROM account_state`)
|
||||
yield* db.run(sql`DELETE FROM account`)
|
||||
}),
|
||||
).pipe(Layer.provide(Database.defaultLayer))
|
||||
)
|
||||
const truncateNode = LayerNode.make({ name: "truncate-account", layer: truncate, deps: [Database.node] })
|
||||
|
||||
const it = testEffect(Layer.merge(AccountRepo.defaultLayer, truncate))
|
||||
const it = testEffect(LayerNode.compile(LayerNode.group([AccountRepo.node, truncateNode])))
|
||||
|
||||
it.live("list returns empty when no accounts exist", () =>
|
||||
Effect.gen(function* () {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import { describe, expect, it } from "bun:test"
|
||||
import type { AgentSideConnection } from "@agentclientprotocol/sdk"
|
||||
import { LayerNode } from "@opencode-ai/core/effect/layer-node"
|
||||
import type { Event, Message, OpencodeClient, Part, SessionMessageResponse, ToolPart } from "@opencode-ai/sdk/v2"
|
||||
import { Effect, ManagedRuntime } from "effect"
|
||||
import { ACPEvent } from "@/acp/event"
|
||||
|
|
@ -30,7 +31,7 @@ const pollUntil = async (
|
|||
}
|
||||
|
||||
function makeSessionService() {
|
||||
return ManagedRuntime.make(ACPSession.defaultLayer).runSync(
|
||||
return ManagedRuntime.make(LayerNode.compile(ACPSession.node)).runSync(
|
||||
ACPSession.Service.use((service) => Effect.succeed(service)),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import type {
|
|||
SessionUpdate,
|
||||
} from "@agentclientprotocol/sdk"
|
||||
import type { Event, OpencodeClient } from "@opencode-ai/sdk/v2"
|
||||
import { LayerNode } from "@opencode-ai/core/effect/layer-node"
|
||||
import { createTwoFilesPatch } from "diff"
|
||||
import { Effect, ManagedRuntime } from "effect"
|
||||
import { mkdtemp, rm } from "node:fs/promises"
|
||||
|
|
@ -37,7 +38,7 @@ const pollUntil = async (
|
|||
}
|
||||
|
||||
function makeSessionService() {
|
||||
return ManagedRuntime.make(ACPSession.defaultLayer).runSync(
|
||||
return ManagedRuntime.make(LayerNode.compile(ACPSession.node)).runSync(
|
||||
ACPSession.Service.use((service) => Effect.succeed(service)),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import { describe, expect } from "bun:test"
|
||||
import type { McpServer } from "@agentclientprotocol/sdk"
|
||||
import { LayerNode } from "@opencode-ai/core/effect/layer-node"
|
||||
import { Effect } from "effect"
|
||||
import { ProviderV2 } from "@opencode-ai/core/provider"
|
||||
import { ModelV2 } from "@opencode-ai/core/model"
|
||||
|
|
@ -7,7 +8,7 @@ import * as ACPError from "@/acp/error"
|
|||
import * as ACPSession from "@/acp/session"
|
||||
import { testEffect } from "../lib/effect"
|
||||
|
||||
const sessionTest = testEffect(ACPSession.defaultLayer)
|
||||
const sessionTest = testEffect(LayerNode.compile(ACPSession.node))
|
||||
|
||||
const model = (providerID: string, modelID: string): ACPSession.SelectedModel => ({
|
||||
providerID: ProviderV2.ID.make(providerID),
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import { PermissionV1 } from "@opencode-ai/core/v1/permission"
|
||||
import { LayerNode } from "@opencode-ai/core/effect/layer-node"
|
||||
import { expect } from "bun:test"
|
||||
import { Effect } from "effect"
|
||||
import { Agent } from "../../src/agent/agent"
|
||||
|
|
@ -6,7 +7,7 @@ import { deriveSubagentSessionPermission } from "../../src/agent/subagent-permis
|
|||
import { Permission } from "../../src/permission"
|
||||
import { testEffect } from "../lib/effect"
|
||||
|
||||
const it = testEffect(Agent.defaultLayer)
|
||||
const it = testEffect(LayerNode.compile(Agent.node))
|
||||
|
||||
function testAgent(input: {
|
||||
name: string
|
||||
|
|
|
|||
|
|
@ -1,12 +1,10 @@
|
|||
import { describe, expect } from "bun:test"
|
||||
import { Effect, Layer } from "effect"
|
||||
import { LayerNode } from "@opencode-ai/core/effect/layer-node"
|
||||
import { Effect } from "effect"
|
||||
import { Auth } from "../../src/auth"
|
||||
import { CrossSpawnSpawner } from "@opencode-ai/core/cross-spawn-spawner"
|
||||
import { testEffect } from "../lib/effect"
|
||||
|
||||
const node = CrossSpawnSpawner.defaultLayer
|
||||
|
||||
const it = testEffect(Layer.mergeAll(Auth.defaultLayer, node))
|
||||
const it = testEffect(LayerNode.compile(Auth.node))
|
||||
|
||||
describe("Auth", () => {
|
||||
it.instance("set normalizes trailing slashes in keys", () =>
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
import { describe, expect } from "bun:test"
|
||||
import { LayerNode } from "@opencode-ai/core/effect/layer-node"
|
||||
import { Deferred, Effect } from "effect"
|
||||
import { BackgroundJob } from "@/background/job"
|
||||
import { testEffect } from "../lib/effect"
|
||||
|
||||
const it = testEffect(BackgroundJob.defaultLayer)
|
||||
const it = testEffect(LayerNode.compile(BackgroundJob.node))
|
||||
|
||||
describe("background.job", () => {
|
||||
it.instance("tracks started jobs through completion", () =>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import { afterEach, expect } from "bun:test"
|
||||
import { LayerNode } from "@opencode-ai/core/effect/layer-node"
|
||||
import { FSUtil } from "@opencode-ai/core/fs-util"
|
||||
import { Effect } from "effect"
|
||||
import { fileURLToPath } from "url"
|
||||
|
|
@ -6,7 +7,7 @@ import { InstanceRef } from "../../src/effect/instance-ref"
|
|||
import { disposeAllInstances, TestInstance } from "../fixture/fixture"
|
||||
import { testEffect } from "../lib/effect"
|
||||
|
||||
const it = testEffect(FSUtil.defaultLayer)
|
||||
const it = testEffect(LayerNode.compile(FSUtil.node))
|
||||
|
||||
afterEach(async () => {
|
||||
await disposeAllInstances()
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
import { expect } from "bun:test"
|
||||
import { Effect, Layer } from "effect"
|
||||
import { CrossSpawnSpawner } from "@opencode-ai/core/cross-spawn-spawner"
|
||||
import { LayerNode } from "@opencode-ai/core/effect/layer-node"
|
||||
import { Effect } from "effect"
|
||||
import { Config } from "@/config/config"
|
||||
import { Agent as AgentSvc } from "../../src/agent/agent"
|
||||
import { testEffect } from "../lib/effect"
|
||||
|
||||
const it = testEffect(Layer.mergeAll(Config.defaultLayer, AgentSvc.defaultLayer, CrossSpawnSpawner.defaultLayer))
|
||||
const it = testEffect(LayerNode.compile(LayerNode.group([Config.node, AgentSvc.node])))
|
||||
|
||||
it.instance(
|
||||
"agent color parsed from project config",
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import { expect } from "bun:test"
|
||||
import { LayerNode } from "@opencode-ai/core/effect/layer-node"
|
||||
import { Context, Deferred, Effect, Fiber, Layer, Logger } from "effect"
|
||||
import { CrossSpawnSpawner } from "@opencode-ai/core/cross-spawn-spawner"
|
||||
import { AppLayer } from "../../src/effect/app-runtime"
|
||||
|
|
@ -9,7 +10,8 @@ import { attach } from "../../src/effect/run-service"
|
|||
import { TestInstance } from "../fixture/fixture"
|
||||
import { testEffect } from "../lib/effect"
|
||||
|
||||
const it = testEffect(CrossSpawnSpawner.defaultLayer)
|
||||
const observabilityLayer = LayerNode.compile(Observability.node)
|
||||
const it = testEffect(LayerNode.compile(CrossSpawnSpawner.node))
|
||||
|
||||
function check(loggers: ReadonlySet<Logger.Logger<unknown, any>>) {
|
||||
return {
|
||||
|
|
@ -34,7 +36,7 @@ it.live("makeRuntime installs the observability logger", () =>
|
|||
)
|
||||
|
||||
const current = yield* Dummy.use((svc) => svc.current()).pipe(
|
||||
Effect.provide(Layer.provideMerge(layer, Observability.layer)),
|
||||
Effect.provide(Layer.provideMerge(layer, observabilityLayer)),
|
||||
)
|
||||
|
||||
expect(current.size).toBeGreaterThan(0)
|
||||
|
|
@ -94,6 +96,6 @@ it.instance(
|
|||
|
||||
expect(result.directory).toBe(test.directory)
|
||||
expect(result.size).toBeGreaterThan(0)
|
||||
}).pipe(Effect.provide(Observability.layer)),
|
||||
}).pipe(Effect.provide(observabilityLayer)),
|
||||
{ git: true },
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,12 +1,11 @@
|
|||
import { describe, test, expect } from "bun:test"
|
||||
import { Effect, Layer } from "effect"
|
||||
import { NodeFileSystem } from "@effect/platform-node"
|
||||
import { LayerNode } from "@opencode-ai/core/effect/layer-node"
|
||||
import { Effect } from "effect"
|
||||
import { FSUtil } from "@opencode-ai/core/fs-util"
|
||||
import { testEffect } from "../lib/effect"
|
||||
import path from "path"
|
||||
|
||||
const live = FSUtil.layer.pipe(Layer.provide(NodeFileSystem.layer))
|
||||
const { effect: it } = testEffect(live)
|
||||
const { effect: it } = testEffect(LayerNode.compile(FSUtil.node))
|
||||
|
||||
describe("FSUtil", () => {
|
||||
describe("isDir", () => {
|
||||
|
|
|
|||
|
|
@ -1,20 +1,18 @@
|
|||
import { describe, expect } from "bun:test"
|
||||
import { Cause, Effect, Exit, Layer } from "effect"
|
||||
import { LayerNode } from "@opencode-ai/core/effect/layer-node"
|
||||
import { Cause, Effect, Exit } from "effect"
|
||||
import { Image } from "@/image/image"
|
||||
import { Config } from "@/config/config"
|
||||
import { MessageID, PartID, SessionID } from "@/session/schema"
|
||||
import path from "node:path"
|
||||
import { TestConfig } from "../fixture/config"
|
||||
import { testEffect } from "../lib/effect"
|
||||
|
||||
const it = testEffect(Layer.mergeAll(Image.layer.pipe(Layer.provide(TestConfig.layer()))))
|
||||
const it = testEffect(LayerNode.compile(Image.node, [[Config.node, TestConfig.layer()]]))
|
||||
const tiny = testEffect(
|
||||
Layer.mergeAll(
|
||||
Image.layer.pipe(
|
||||
Layer.provide(
|
||||
TestConfig.layer({ get: () => Effect.succeed({ attachment: { image: { max_base64_bytes: 1 } } }) }),
|
||||
),
|
||||
),
|
||||
),
|
||||
LayerNode.compile(Image.node, [
|
||||
[Config.node, TestConfig.layer({ get: () => Effect.succeed({ attachment: { image: { max_base64_bytes: 1 } } }) })],
|
||||
]),
|
||||
)
|
||||
|
||||
function part(mime: string, data: string) {
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
import { afterEach, beforeEach, describe, expect, spyOn, test } from "bun:test"
|
||||
import path from "path"
|
||||
import { Effect, Layer } from "effect"
|
||||
import { LayerNode } from "@opencode-ai/core/effect/layer-node"
|
||||
import { Effect } from "effect"
|
||||
import { LSP } from "@/lsp/lsp"
|
||||
import * as LSPServer from "@/lsp/server"
|
||||
import { CrossSpawnSpawner } from "@opencode-ai/core/cross-spawn-spawner"
|
||||
import { TestInstance } from "../fixture/fixture"
|
||||
import { testEffect } from "../lib/effect"
|
||||
|
||||
const it = testEffect(Layer.mergeAll(LSP.defaultLayer, CrossSpawnSpawner.defaultLayer))
|
||||
const it = testEffect(LayerNode.compile(LSP.node))
|
||||
|
||||
describe("LSP service lifecycle", () => {
|
||||
let spawnSpy: ReturnType<typeof spyOn>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import { describe, expect, mock, beforeEach } from "bun:test"
|
||||
import { LayerNode } from "@opencode-ai/core/effect/layer-node"
|
||||
import { Effect } from "effect"
|
||||
import { testEffect } from "../lib/effect"
|
||||
|
||||
|
|
@ -46,7 +47,7 @@ beforeEach(() => {
|
|||
|
||||
// Import MCP after mocking
|
||||
const { MCP } = await import("../../src/mcp/index")
|
||||
const it = testEffect(MCP.defaultLayer)
|
||||
const it = testEffect(LayerNode.compile(MCP.node))
|
||||
|
||||
describe("mcp.headers", () => {
|
||||
it.instance("headers are passed to transports when oauth is enabled (default)", () =>
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import path from "node:path"
|
|||
import { pathToFileURL } from "node:url"
|
||||
import { expect, mock, beforeEach } from "bun:test"
|
||||
import { ListRootsRequestSchema, ToolListChangedNotificationSchema } from "@modelcontextprotocol/sdk/types.js"
|
||||
import { LayerNode } from "@opencode-ai/core/effect/layer-node"
|
||||
import { Cause, Effect, Exit } from "effect"
|
||||
import type { MCP as MCPNS } from "../../src/mcp/index"
|
||||
import { testEffect } from "../lib/effect"
|
||||
|
|
@ -275,7 +276,7 @@ beforeEach(() => {
|
|||
const { MCP } = await import("../../src/mcp/index")
|
||||
const { McpOAuthCallback } = await import("../../src/mcp/oauth-callback")
|
||||
|
||||
const it = testEffect(MCP.defaultLayer)
|
||||
const it = testEffect(LayerNode.compile(MCP.node))
|
||||
|
||||
function statusName(status: Record<string, MCPNS.Status> | MCPNS.Status, server: string) {
|
||||
if ("status" in status) return status.status
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import { describe, test, expect, beforeEach, afterEach } from "bun:test"
|
||||
import { LayerNode } from "@opencode-ai/core/effect/layer-node"
|
||||
import { Effect } from "effect"
|
||||
import * as fs from "fs/promises"
|
||||
import * as path from "path"
|
||||
|
|
@ -7,7 +8,7 @@ import { Patch } from "../../src/patch"
|
|||
import { FSUtil } from "@opencode-ai/core/fs-util"
|
||||
import { testEffect } from "../lib/effect"
|
||||
|
||||
const it = testEffect(FSUtil.defaultLayer)
|
||||
const it = testEffect(LayerNode.compile(FSUtil.node))
|
||||
|
||||
describe("Patch namespace", () => {
|
||||
let tempDir: string
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
import { PermissionV1 } from "@opencode-ai/core/v1/permission"
|
||||
import { LayerNode } from "@opencode-ai/core/effect/layer-node"
|
||||
import { describe, test, expect } from "bun:test"
|
||||
import { Effect } from "effect"
|
||||
import { Permission } from "../src/permission"
|
||||
import { Config } from "@/config/config"
|
||||
import { testEffect } from "./lib/effect"
|
||||
|
||||
const it = testEffect(Config.defaultLayer)
|
||||
const it = testEffect(LayerNode.compile(Config.node))
|
||||
|
||||
const load = Config.use.get()
|
||||
|
||||
|
|
|
|||
|
|
@ -2,16 +2,16 @@ import { afterEach, expect } from "bun:test"
|
|||
import { existsSync } from "node:fs"
|
||||
import path from "node:path"
|
||||
import { pathToFileURL } from "node:url"
|
||||
import { LayerNode } from "@opencode-ai/core/effect/layer-node"
|
||||
import { CrossSpawnSpawner } from "@opencode-ai/core/cross-spawn-spawner"
|
||||
import { Cause, Effect, Exit, Fiber, Layer } from "effect"
|
||||
import { bootstrap as cliBootstrap } from "../../src/cli/bootstrap"
|
||||
import { InstanceLayer } from "../../src/project/instance-layer"
|
||||
import { InstanceStore } from "../../src/project/instance-store"
|
||||
import { disposeAllInstances, tmpdirScoped } from "../fixture/fixture"
|
||||
import { testEffect } from "../lib/effect"
|
||||
import { waitGlobalBusEvent } from "../server/global-bus"
|
||||
|
||||
const it = testEffect(Layer.mergeAll(InstanceLayer.layer, CrossSpawnSpawner.defaultLayer))
|
||||
const it = testEffect(LayerNode.compile(LayerNode.group([InstanceStore.node, CrossSpawnSpawner.node])))
|
||||
|
||||
// InstanceBootstrap must run before any code touches the instance —
|
||||
// originally tracked by PRs #25389 and #25449, now a permanent
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
import { describe, expect } from "bun:test"
|
||||
import { LayerNode } from "@opencode-ai/core/effect/layer-node"
|
||||
import { CrossSpawnSpawner } from "@opencode-ai/core/cross-spawn-spawner"
|
||||
import { Deferred, Effect, Fiber, Layer } from "effect"
|
||||
import { InstanceRef } from "../../src/effect/instance-ref"
|
||||
import { registerDisposer } from "../../src/effect/instance-registry"
|
||||
import { InstanceBootstrap } from "../../src/project/bootstrap-service"
|
||||
import { InstanceBootstrap } from "../../src/project/bootstrap"
|
||||
import { InstanceStore } from "../../src/project/instance-store"
|
||||
import { tmpdirScoped } from "../fixture/fixture"
|
||||
import { testEffect } from "../lib/effect"
|
||||
|
|
@ -15,7 +16,9 @@ const noopBootstrap = Layer.succeed(
|
|||
)
|
||||
|
||||
const it = testEffect(
|
||||
Layer.mergeAll(InstanceStore.defaultLayer, CrossSpawnSpawner.defaultLayer).pipe(Layer.provide(noopBootstrap)),
|
||||
LayerNode.compile(LayerNode.group([InstanceStore.node, CrossSpawnSpawner.node]), [
|
||||
[InstanceBootstrap.node, noopBootstrap],
|
||||
]),
|
||||
)
|
||||
|
||||
const setBootstrap = (run: Effect.Effect<void>) =>
|
||||
|
|
|
|||
|
|
@ -9,11 +9,12 @@ import { ProjectV2 } from "@opencode-ai/core/project"
|
|||
import { SessionID } from "../../src/session/schema"
|
||||
import { $ } from "bun"
|
||||
import { tmpdirScoped } from "../fixture/fixture"
|
||||
import { Effect, Layer } from "effect"
|
||||
import { LayerNode } from "@opencode-ai/core/effect/layer-node"
|
||||
import { CrossSpawnSpawner } from "@opencode-ai/core/cross-spawn-spawner"
|
||||
import { Effect } from "effect"
|
||||
import { testEffect } from "../lib/effect"
|
||||
|
||||
const it = testEffect(Layer.mergeAll(Project.defaultLayer, CrossSpawnSpawner.defaultLayer, Database.defaultLayer))
|
||||
const it = testEffect(LayerNode.compile(LayerNode.group([Project.node, Database.node, CrossSpawnSpawner.node])))
|
||||
|
||||
function legacySessionID() {
|
||||
// Global-session migration covers persisted IDs from before prefixed session IDs.
|
||||
|
|
|
|||
|
|
@ -2,8 +2,9 @@ import { describe, expect } from "bun:test"
|
|||
import { $ } from "bun"
|
||||
import path from "path"
|
||||
import { eq } from "drizzle-orm"
|
||||
import { Effect, Layer } from "effect"
|
||||
import { LayerNode } from "@opencode-ai/core/effect/layer-node"
|
||||
import { CrossSpawnSpawner } from "@opencode-ai/core/cross-spawn-spawner"
|
||||
import { Effect } from "effect"
|
||||
import { Hash } from "@opencode-ai/core/util/hash"
|
||||
import { AbsolutePath } from "@opencode-ai/core/schema"
|
||||
import { Database } from "@opencode-ai/core/database/database"
|
||||
|
|
@ -13,7 +14,7 @@ import { Project } from "@/project/project"
|
|||
import { tmpdirScoped } from "../fixture/fixture"
|
||||
import { testEffect } from "../lib/effect"
|
||||
|
||||
const it = testEffect(Layer.mergeAll(Project.defaultLayer, Database.defaultLayer, CrossSpawnSpawner.defaultLayer))
|
||||
const it = testEffect(LayerNode.compile(LayerNode.group([Project.node, Database.node, CrossSpawnSpawner.node])))
|
||||
|
||||
function directories(projectID: ProjectV2.ID) {
|
||||
return Database.Service.use(({ db }) =>
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
import { afterEach, describe, expect } from "bun:test"
|
||||
import { LayerNode } from "@opencode-ai/core/effect/layer-node"
|
||||
import { FSUtil } from "@opencode-ai/core/fs-util"
|
||||
import { CrossSpawnSpawner } from "@opencode-ai/core/cross-spawn-spawner"
|
||||
import { parsePatch } from "diff"
|
||||
import { Deferred, Effect, Layer } from "effect"
|
||||
import { CrossSpawnSpawner } from "@opencode-ai/core/cross-spawn-spawner"
|
||||
import fs from "fs/promises"
|
||||
import path from "path"
|
||||
import {
|
||||
|
|
@ -24,11 +25,7 @@ import { testEffect } from "../lib/effect"
|
|||
|
||||
const weird = process.platform === "win32" ? "space file.txt" : "tab\tfile.txt"
|
||||
|
||||
const layer = Layer.mergeAll(
|
||||
Vcs.layer.pipe(Layer.provideMerge(Git.defaultLayer), Layer.provideMerge(EventV2Bridge.defaultLayer)),
|
||||
CrossSpawnSpawner.defaultLayer,
|
||||
FSUtil.defaultLayer,
|
||||
)
|
||||
const layer = LayerNode.compile(LayerNode.group([Vcs.node, Git.node, EventV2Bridge.node, FSUtil.node, CrossSpawnSpawner.node]))
|
||||
const it = testEffect(layer)
|
||||
const worktreeIt = testEffect(Layer.mergeAll(layer, testInstanceStoreLayer))
|
||||
|
||||
|
|
|
|||
|
|
@ -2,13 +2,13 @@ import { $ } from "bun"
|
|||
import { describe, expect } from "bun:test"
|
||||
import * as fs from "fs/promises"
|
||||
import path from "path"
|
||||
import { Effect, Layer } from "effect"
|
||||
import { CrossSpawnSpawner } from "@opencode-ai/core/cross-spawn-spawner"
|
||||
import { LayerNode } from "@opencode-ai/core/effect/layer-node"
|
||||
import { Effect } from "effect"
|
||||
import { Worktree } from "../../src/worktree"
|
||||
import { TestInstance } from "../fixture/fixture"
|
||||
import { testEffect } from "../lib/effect"
|
||||
|
||||
const it = testEffect(Layer.mergeAll(Worktree.defaultLayer, CrossSpawnSpawner.defaultLayer))
|
||||
const it = testEffect(LayerNode.compile(Worktree.node))
|
||||
const wintest = process.platform === "win32" ? it.instance : it.instance.skip
|
||||
|
||||
describe("Worktree.remove", () => {
|
||||
|
|
|
|||
|
|
@ -1,17 +1,15 @@
|
|||
import { afterEach, describe, expect } from "bun:test"
|
||||
import path from "path"
|
||||
import { LayerNode } from "@opencode-ai/core/effect/layer-node"
|
||||
import { FSUtil } from "@opencode-ai/core/fs-util"
|
||||
import { CrossSpawnSpawner } from "@opencode-ai/core/cross-spawn-spawner"
|
||||
import { Cause, Deferred, Effect, Exit, Fiber, Layer } from "effect"
|
||||
import { Cause, Deferred, Effect, Exit, Fiber } from "effect"
|
||||
import { GlobalBus, type GlobalEvent } from "../../src/bus/global"
|
||||
import { Git } from "../../src/git"
|
||||
import { Worktree } from "../../src/worktree"
|
||||
import { disposeAllInstances, provideInstance, TestInstance } from "../fixture/fixture"
|
||||
import { testEffect } from "../lib/effect"
|
||||
|
||||
const it = testEffect(
|
||||
Layer.mergeAll(Worktree.defaultLayer, FSUtil.defaultLayer, CrossSpawnSpawner.defaultLayer, Git.defaultLayer),
|
||||
)
|
||||
const it = testEffect(LayerNode.compile(LayerNode.group([Worktree.node, FSUtil.node, Git.node])))
|
||||
const wintest = process.platform !== "win32" ? it.instance : it.instance.skip
|
||||
|
||||
function normalize(input: string) {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import { afterEach, describe, expect, test } from "bun:test"
|
||||
import { Effect, Layer } from "effect"
|
||||
import { LayerNode } from "@opencode-ai/core/effect/layer-node"
|
||||
import { Effect } from "effect"
|
||||
import path from "path"
|
||||
import { unlink } from "fs/promises"
|
||||
import { Global } from "@opencode-ai/core/global"
|
||||
|
|
@ -12,7 +13,7 @@ import { testEffect } from "../lib/effect"
|
|||
import { ProviderV2 } from "@opencode-ai/core/provider"
|
||||
import { ModelV2 } from "@opencode-ai/core/model"
|
||||
|
||||
const it = testEffect(Layer.mergeAll(Provider.defaultLayer, Env.defaultLayer))
|
||||
const it = testEffect(LayerNode.compile(LayerNode.group([Provider.node, Env.node])))
|
||||
|
||||
const originalEnv = new Map<string, string | undefined>()
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import { expect } from "bun:test"
|
||||
import { LayerNode } from "@opencode-ai/core/effect/layer-node"
|
||||
import { Provider } from "../../src/provider/provider"
|
||||
|
||||
import { Effect } from "effect"
|
||||
|
|
@ -6,7 +7,7 @@ import { testEffect } from "../lib/effect"
|
|||
import { ProviderV2 } from "@opencode-ai/core/provider"
|
||||
|
||||
const DIGITALOCEAN = ProviderV2.ID.make("digitalocean")
|
||||
const it = testEffect(Provider.defaultLayer)
|
||||
const it = testEffect(LayerNode.compile(Provider.node))
|
||||
|
||||
const withEnv = <A, E, R>(values: Record<string, string>, effect: Effect.Effect<A, E, R>) =>
|
||||
Effect.acquireUseRelease(
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
import { afterEach, expect } from "bun:test"
|
||||
import { createServer, type Server } from "node:http"
|
||||
import { streamText } from "ai"
|
||||
import { Effect, Layer } from "effect"
|
||||
import { LayerNode } from "@opencode-ai/core/effect/layer-node"
|
||||
import { CrossSpawnSpawner } from "@opencode-ai/core/cross-spawn-spawner"
|
||||
import { Effect } from "effect"
|
||||
import { ProviderV2 } from "@opencode-ai/core/provider"
|
||||
import { ModelV2 } from "@opencode-ai/core/model"
|
||||
import { disposeAllInstances, provideTmpdirInstance } from "../fixture/fixture"
|
||||
|
|
@ -17,9 +18,7 @@ afterEach(async () => {
|
|||
await disposeAllInstances()
|
||||
})
|
||||
|
||||
const it = testEffect(
|
||||
Layer.mergeAll(Provider.defaultLayer, Env.defaultLayer, Plugin.defaultLayer, CrossSpawnSpawner.defaultLayer),
|
||||
)
|
||||
const it = testEffect(LayerNode.compile(LayerNode.group([Provider.node, Env.node, Plugin.node, CrossSpawnSpawner.node])))
|
||||
|
||||
it.live("headerTimeout does not abort delayed SSE body after headers arrive", () =>
|
||||
Effect.gen(function* () {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import { afterEach, expect } from "bun:test"
|
||||
import { LayerNode } from "@opencode-ai/core/effect/layer-node"
|
||||
import { Cause, Effect, Exit, Fiber, Layer, Queue } from "effect"
|
||||
import { Question } from "../../src/question"
|
||||
import { InstanceRef } from "../../src/effect/instance-ref"
|
||||
|
|
@ -10,13 +11,11 @@ import { testEffect } from "../lib/effect"
|
|||
import { CrossSpawnSpawner } from "@opencode-ai/core/cross-spawn-spawner"
|
||||
import { EventV2Bridge } from "../../src/event-v2-bridge"
|
||||
|
||||
const it = testEffect(
|
||||
Layer.mergeAll(Question.layer.pipe(Layer.provideMerge(EventV2Bridge.defaultLayer)), CrossSpawnSpawner.defaultLayer),
|
||||
)
|
||||
const questionLayer = LayerNode.compile(LayerNode.group([Question.node, EventV2Bridge.node, CrossSpawnSpawner.node]))
|
||||
const it = testEffect(questionLayer)
|
||||
const lifecycle = testEffect(
|
||||
Layer.mergeAll(
|
||||
Question.layer.pipe(Layer.provideMerge(EventV2Bridge.defaultLayer)),
|
||||
CrossSpawnSpawner.defaultLayer,
|
||||
questionLayer,
|
||||
testInstanceStoreLayer,
|
||||
),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,29 +1,26 @@
|
|||
import { describe, expect } from "bun:test"
|
||||
import { SessionV1 } from "@opencode-ai/core/v1/session"
|
||||
import { LayerNode } from "@opencode-ai/core/effect/layer-node"
|
||||
import { SessionProjector } from "@opencode-ai/core/session/projector"
|
||||
import fs from "fs/promises"
|
||||
import path from "path"
|
||||
import { Effect, Layer } from "effect"
|
||||
import { CrossSpawnSpawner } from "@opencode-ai/core/cross-spawn-spawner"
|
||||
import { Effect } from "effect"
|
||||
import { Session } from "@/session/session"
|
||||
|
||||
import { SessionRevert } from "../../src/session/revert"
|
||||
import { MessageV2 } from "../../src/session/message-v2"
|
||||
import { Snapshot } from "../../src/snapshot"
|
||||
import { MessageID, PartID, SessionID } from "../../src/session/schema"
|
||||
import { CrossSpawnSpawner } from "@opencode-ai/core/cross-spawn-spawner"
|
||||
import { provideTmpdirInstance } from "../fixture/fixture"
|
||||
import { testEffect } from "../lib/effect"
|
||||
import { ProviderV2 } from "@opencode-ai/core/provider"
|
||||
import { ModelV2 } from "@opencode-ai/core/model"
|
||||
|
||||
const env = Layer.mergeAll(
|
||||
Session.defaultLayer,
|
||||
SessionRevert.defaultLayer,
|
||||
Snapshot.defaultLayer,
|
||||
CrossSpawnSpawner.defaultLayer,
|
||||
const it = testEffect(
|
||||
LayerNode.compile(LayerNode.group([Session.node, SessionRevert.node, Snapshot.node, SessionProjector.node, CrossSpawnSpawner.node])),
|
||||
)
|
||||
|
||||
const it = testEffect(env)
|
||||
|
||||
const user = Effect.fn("test.user")(function* (sessionID: SessionID, agent = "default") {
|
||||
const session = yield* Session.Service
|
||||
return yield* session.updateMessage({
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import { describe, expect, beforeAll, afterAll } from "bun:test"
|
||||
import { LayerNode } from "@opencode-ai/core/effect/layer-node"
|
||||
import { FSUtil } from "@opencode-ai/core/fs-util"
|
||||
import { Effect, Layer } from "effect"
|
||||
import { Effect } from "effect"
|
||||
import { Discovery } from "../../src/skill/discovery"
|
||||
import { Global } from "@opencode-ai/core/global"
|
||||
import { Filesystem } from "@/util/filesystem"
|
||||
|
|
@ -18,7 +19,7 @@ let mutableFiles = ["SKILL.md"]
|
|||
|
||||
const fixturePath = path.join(import.meta.dir, "../fixture/skills")
|
||||
const cacheDir = path.join(Global.Path.cache, "skills")
|
||||
const it = testEffect(Layer.mergeAll(Discovery.defaultLayer, FSUtil.defaultLayer))
|
||||
const it = testEffect(LayerNode.compile(LayerNode.group([Discovery.node, FSUtil.node])))
|
||||
|
||||
beforeAll(async () => {
|
||||
await rm(cacheDir, { recursive: true, force: true })
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import { PermissionV1 } from "@opencode-ai/core/v1/permission"
|
||||
import { LayerNode } from "@opencode-ai/core/effect/layer-node"
|
||||
import { describe, expect } from "bun:test"
|
||||
import path from "path"
|
||||
import { Effect } from "effect"
|
||||
|
|
@ -11,7 +12,7 @@ import type { Permission } from "../../src/permission"
|
|||
import { SessionID, MessageID } from "../../src/session/schema"
|
||||
import { testEffect } from "../lib/effect"
|
||||
|
||||
const it = testEffect(CrossSpawnSpawner.defaultLayer)
|
||||
const it = testEffect(LayerNode.compile(CrossSpawnSpawner.node))
|
||||
|
||||
const baseCtx: Omit<Tool.Context, "ask"> = {
|
||||
sessionID: SessionID.make("ses_test"),
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
import { describe, expect } from "bun:test"
|
||||
import { Effect, Fiber, Layer, Queue } from "effect"
|
||||
import { LayerNode } from "@opencode-ai/core/effect/layer-node"
|
||||
import { Effect, Fiber, Queue } from "effect"
|
||||
import { QuestionTool } from "../../src/tool/question"
|
||||
import { Question } from "../../src/question"
|
||||
import { SessionID, MessageID } from "../../src/session/schema"
|
||||
import { Agent } from "../../src/agent/agent"
|
||||
import { CrossSpawnSpawner } from "@opencode-ai/core/cross-spawn-spawner"
|
||||
import { Truncate } from "@/tool/truncate"
|
||||
import { testEffect } from "../lib/effect"
|
||||
import { EventV2Bridge } from "../../src/event-v2-bridge"
|
||||
|
|
@ -20,14 +20,7 @@ const ctx = {
|
|||
ask: () => Effect.void,
|
||||
}
|
||||
|
||||
const it = testEffect(
|
||||
Layer.mergeAll(
|
||||
Question.layer.pipe(Layer.provideMerge(EventV2Bridge.defaultLayer)),
|
||||
CrossSpawnSpawner.defaultLayer,
|
||||
Truncate.defaultLayer,
|
||||
Agent.defaultLayer,
|
||||
),
|
||||
)
|
||||
const it = testEffect(LayerNode.compile(LayerNode.group([Question.node, EventV2Bridge.node, Truncate.node, Agent.node])))
|
||||
|
||||
const pending = Effect.fn("QuestionToolTest.pending")(function* (question: Question.Interface) {
|
||||
const events = yield* EventV2Bridge.Service
|
||||
|
|
|
|||
|
|
@ -1,12 +1,13 @@
|
|||
import { describe, expect } from "bun:test"
|
||||
import { Cause, Effect, Exit, Layer, Schema } from "effect"
|
||||
import { LayerNode } from "@opencode-ai/core/effect/layer-node"
|
||||
import { Cause, Effect, Exit, Schema } from "effect"
|
||||
import { Agent } from "../../src/agent/agent"
|
||||
import { MessageID, SessionID } from "../../src/session/schema"
|
||||
import { Tool } from "@/tool/tool"
|
||||
import { Truncate } from "@/tool/truncate"
|
||||
import { testEffect } from "../lib/effect"
|
||||
|
||||
const it = testEffect(Layer.mergeAll(Truncate.defaultLayer, Agent.defaultLayer))
|
||||
const it = testEffect(LayerNode.compile(LayerNode.group([Truncate.node, Agent.node])))
|
||||
|
||||
const params = Schema.Struct({ input: Schema.String })
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
import { describe, test, expect } from "bun:test"
|
||||
import { ConfigV1 } from "@opencode-ai/core/v1/config/config"
|
||||
import { NodeFileSystem } from "@effect/platform-node"
|
||||
import { LayerNode } from "@opencode-ai/core/effect/layer-node"
|
||||
import { filesystem } from "@opencode-ai/core/effect/app-node-platform"
|
||||
import { FSUtil } from "@opencode-ai/core/fs-util"
|
||||
import { Effect, FileSystem, Layer } from "effect"
|
||||
import { Effect, FileSystem } from "effect"
|
||||
import { Truncate } from "@/tool/truncate"
|
||||
import { Config } from "@/config/config"
|
||||
import { Identifier } from "../../src/id/id"
|
||||
|
|
@ -15,15 +16,12 @@ import { TestConfig } from "../fixture/config"
|
|||
const FIXTURES_DIR = path.join(import.meta.dir, "fixtures")
|
||||
const ROOT = path.resolve(import.meta.dir, "..", "..")
|
||||
|
||||
const it = testEffect(Layer.mergeAll(Truncate.defaultLayer, NodeFileSystem.layer, FSUtil.defaultLayer))
|
||||
const it = testEffect(LayerNode.compile(LayerNode.group([Truncate.node, FSUtil.node, filesystem])))
|
||||
|
||||
const configuredLayer = (cfg: ConfigV1.Info) =>
|
||||
Layer.mergeAll(
|
||||
Truncate.defaultLayer,
|
||||
NodeFileSystem.layer,
|
||||
FSUtil.defaultLayer,
|
||||
TestConfig.layer({ get: () => Effect.succeed(cfg) }),
|
||||
)
|
||||
LayerNode.compile(LayerNode.group([Truncate.node, FSUtil.node, filesystem, Config.node]), [
|
||||
[Config.node, TestConfig.layer({ get: () => Effect.succeed(cfg) })],
|
||||
])
|
||||
const configuredIt = (cfg: ConfigV1.Info) => testEffect(configuredLayer(cfg))
|
||||
|
||||
describe("Truncate", () => {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue