Compare commits

...

1 Commits

Author SHA1 Message Date
Kit Langton 12ac69ee91 test: migrate config update fixtures 2026-05-18 20:34:29 -04:00
2 changed files with 58 additions and 74 deletions
+29 -46
View File
@@ -68,13 +68,6 @@ const load = (ctx: InstanceContext) =>
Effect.runPromise( Effect.runPromise(
Config.Service.use((svc) => provideCurrentInstance(svc.get(), ctx)).pipe(Effect.scoped, Effect.provide(layer)), Config.Service.use((svc) => provideCurrentInstance(svc.get(), ctx)).pipe(Effect.scoped, Effect.provide(layer)),
) )
const save = (config: Config.Info, ctx: InstanceContext) =>
Effect.runPromise(
Config.Service.use((svc) => provideCurrentInstance(svc.update(config), ctx)).pipe(
Effect.scoped,
Effect.provide(layer),
),
)
const saveGlobal = (config: Config.Info) => const saveGlobal = (config: Config.Info) =>
Effect.runPromise( Effect.runPromise(
Config.Service.use((svc) => svc.updateGlobal(config)).pipe( Config.Service.use((svc) => svc.updateGlobal(config)).pipe(
@@ -240,29 +233,23 @@ it.instance(
{ config: { shell: "bash" } }, { config: { shell: "bash" } },
) )
test("updates config and preserves empty shell sentinel", async () => { it.instance("updates config and preserves empty shell sentinel", () =>
await using tmp = await tmpdir({ Effect.gen(function* () {
init: async (dir) => { const test = yield* TestInstance
await writeConfig( yield* writeConfigEffect(
dir, test.directory,
{ { $schema: "https://opencode.ai/config.json", shell: "bash" },
$schema: "https://opencode.ai/config.json",
shell: "bash",
},
"config.json", "config.json",
) )
},
})
await withTestInstance({
directory: tmp.path,
fn: async (ctx) => {
await save({ shell: "" }, ctx)
const writtenConfig = await Filesystem.readJson<{ shell?: string }>(path.join(tmp.path, "config.json")) yield* Config.Service.use((svc) => svc.update(ConfigParse.schema(Config.Info, { shell: "" }, "test:config")))
const writtenConfig = yield* Effect.promise(() =>
Filesystem.readJson<{ shell?: string }>(path.join(test.directory, "config.json")),
)
expect(writtenConfig.shell).toBe("") expect(writtenConfig.shell).toBe("")
}, }),
}) )
})
test("updates global config and omits empty shell key in json", async () => { test("updates global config and omits empty shell key in json", async () => {
await using tmp = await tmpdir({ await using tmp = await tmpdir({
@@ -884,30 +871,26 @@ Nested command template`,
}) })
}) })
test("updates config and writes to file", async () => { it.instance("updates config and writes to file", () =>
await using tmp = await tmpdir() Effect.gen(function* () {
await withTestInstance({ const test = yield* TestInstance
directory: tmp.path, yield* Config.Service.use((svc) =>
fn: async (ctx) => { svc.update(ConfigParse.schema(Config.Info, { model: "updated/model" }, "test:config")),
const newConfig = { model: "updated/model" } )
await save(newConfig as any, ctx)
const writtenConfig = await Filesystem.readJson<{ model: string }>(path.join(tmp.path, "config.json")) const writtenConfig = yield* Effect.promise(() =>
Filesystem.readJson<{ model: string }>(path.join(test.directory, "config.json")),
)
expect(writtenConfig.model).toBe("updated/model") expect(writtenConfig.model).toBe("updated/model")
}, }),
}) )
})
test("gets config directories", async () => { it.instance("gets config directories", () =>
await using tmp = await tmpdir() Effect.gen(function* () {
await withTestInstance({ const dirs = yield* Config.Service.use((svc) => svc.directories())
directory: tmp.path,
fn: async (ctx) => {
const dirs = await listDirs(ctx)
expect(dirs.length).toBeGreaterThanOrEqual(1) expect(dirs.length).toBeGreaterThanOrEqual(1)
}, }),
}) )
})
test("does not try to install dependencies in read-only OPENCODE_CONFIG_DIR", async () => { test("does not try to install dependencies in read-only OPENCODE_CONFIG_DIR", async () => {
if (process.platform === "win32") return if (process.platform === "win32") return
+2 -1
View File
@@ -52,7 +52,7 @@ Repeated setup work, long sleeps/timeouts, serial integration tests, filesystem/
## Hypothesis Loop ## Hypothesis Loop
| Hypothesis | Change | Before | After | Decision | Notes | | Hypothesis | Change | Before | After | Decision | Notes |
| --------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- | --------- | ------- | -------- | --------------------------------------------------------------------------------------------------------------------------- | | --------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- | --------- | ------- | -------- | ---------------------------------------------------------------------------------------------------------------------------- |
| Repeated full-suite runs are too expensive for discovery | Switched full-suite benchmark to one run and added per-file profiler | ~250s/run | pending | keep | Bun has no slowest-test reporter in this version; profile files directly. | | Repeated full-suite runs are too expensive for discovery | Switched full-suite benchmark to one run and added per-file profiler | ~250s/run | pending | keep | Bun has no slowest-test reporter in this version; profile files directly. |
| Plugin install concurrency test spends time spawning more workers than needed to exercise lock contention | Reduced worker counts from 12/10/8 to 6/6/5; kept `holdMs: 30` | 7.800s | 6.204s | keep | Median from 3 targeted runs; still covers concurrent cross-process writes to server, server+tui, and existing json config. | | Plugin install concurrency test spends time spawning more workers than needed to exercise lock contention | Reduced worker counts from 12/10/8 to 6/6/5; kept `holdMs: 30` | 7.800s | 6.204s | keep | Median from 3 targeted runs; still covers concurrent cross-process writes to server, server+tui, and existing json config. |
| `httpapi-listen` PTY route tests pay for git repositories they do not assert on | Removed `git: true` from temp dirs while keeping config setup | 10.554s | 7.818s | keep | Median from 3 targeted runs; HTTP routes, tickets, websocket upgrade, restart, and no-auth paths still pass. | | `httpapi-listen` PTY route tests pay for git repositories they do not assert on | Removed `git: true` from temp dirs while keeping config setup | 10.554s | 7.818s | keep | Median from 3 targeted runs; HTTP routes, tickets, websocket upgrade, restart, and no-auth paths still pass. |
@@ -74,6 +74,7 @@ Repeated setup work, long sleeps/timeouts, serial integration tests, filesystem/
| Simple config load cases can use Effect-aware instance fixtures | Migrated JSON, shell, formatter, and lsp config load cases to `it.instance` | 14.18s | 3.93s | keep | Three-run medians before/after; removes manual `tmpdir` + `withTestInstance` setup from the first simple config block. | | Simple config load cases can use Effect-aware instance fixtures | Migrated JSON, shell, formatter, and lsp config load cases to `it.instance` | 14.18s | 3.93s | keep | Three-run medians before/after; removes manual `tmpdir` + `withTestInstance` setup from the first simple config block. |
| Config template, file include, and simple agent cases can use Effect-aware instance fixtures | Migrated JSONC, env/file substitution, invalid config, and agent config cases to `it.instance` | 1.87s | 1.90s | keep | Stacked on the first config slice; neutral timing but removes more manual `tmpdir` + instance plumbing. | | Config template, file include, and simple agent cases can use Effect-aware instance fixtures | Migrated JSONC, env/file substitution, invalid config, and agent config cases to `it.instance` | 1.87s | 1.90s | keep | Stacked on the first config slice; neutral timing but removes more manual `tmpdir` + instance plumbing. |
| Agent option, command, and legacy migration config cases can use Effect-aware instance fixtures | Migrated agent variant, command, autoshare, and mode migration cases to `it.instance` | 1.90s | 1.83s | keep | Stacked on the config template slice; small neutral-to-positive timing and less manual setup. | | Agent option, command, and legacy migration config cases can use Effect-aware instance fixtures | Migrated agent variant, command, autoshare, and mode migration cases to `it.instance` | 1.90s | 1.83s | keep | Stacked on the config template slice; small neutral-to-positive timing and less manual setup. |
| Local config update and directory cases can use Effect-aware instance fixtures | Migrated local `update` and `directories` cases to `it.instance` | 1.77s | 1.71s | keep | Three-run medians; small positive/neutral timing, removes manual instance plumbing, and eliminates one existing unsafe cast. |
## Profiling Results ## Profiling Results