Files
anomalyco_opencode/packages/opencode/test/cli/tui/plugin-loader-missing-meta.test.ts
T
Sebastian Herrlinger f370d33273 id resolution
2026-03-26 21:44:07 +01:00

106 lines
3.1 KiB
TypeScript

import { expect, spyOn, test } from "bun:test"
import fs from "fs/promises"
import path from "path"
import { pathToFileURL } from "url"
import { tmpdir } from "../../fixture/fixture"
import { createTuiPluginApi } from "../../fixture/tui-plugin"
import { TuiConfig } from "../../../src/config/tui"
const { TuiPluginRuntime } = await import("../../../src/cli/cmd/tui/plugin/runtime")
test("continues loading tui plugins when a plugin is missing config metadata", async () => {
await using tmp = await tmpdir({
init: async (dir) => {
const badPluginPath = path.join(dir, "missing-meta-plugin.ts")
const nextPluginPath = path.join(dir, "next-plugin.ts")
const plainPluginPath = path.join(dir, "plain-plugin.ts")
const badSpec = pathToFileURL(badPluginPath).href
const nextSpec = pathToFileURL(nextPluginPath).href
const plainSpec = pathToFileURL(plainPluginPath).href
const badMarker = path.join(dir, "missing-meta-called.txt")
const nextMarker = path.join(dir, "next-called.txt")
const plainMarker = path.join(dir, "plain-called.txt")
await Bun.write(
badPluginPath,
`export default {
id: "demo.missing-meta",
tui: async (_api, options) => {
if (!options?.marker) return
await Bun.write(options.marker, "called")
},
}
`,
)
await Bun.write(
nextPluginPath,
`export default {
id: "demo.next",
tui: async (_api, options) => {
if (!options?.marker) return
await Bun.write(options.marker, "called")
},
}
`,
)
await Bun.write(
plainPluginPath,
`export default {
id: "demo.plain",
tui: async (_api, options) => {
await Bun.write(${JSON.stringify(plainMarker)}, options === undefined ? "undefined" : options === null ? "null" : "value")
},
}
`,
)
return {
badSpec,
nextSpec,
plainSpec,
badMarker,
nextMarker,
plainMarker,
}
},
})
process.env.OPENCODE_PLUGIN_META_FILE = path.join(tmp.path, "plugin-meta.json")
const get = spyOn(TuiConfig, "get").mockResolvedValue({
plugin: [
[tmp.extra.badSpec, { marker: tmp.extra.badMarker }],
[tmp.extra.nextSpec, { marker: tmp.extra.nextMarker }],
tmp.extra.plainSpec,
],
plugin_meta: {
[tmp.extra.nextSpec]: {
scope: "local",
source: path.join(tmp.path, "tui.json"),
},
[tmp.extra.plainSpec]: {
scope: "local",
source: path.join(tmp.path, "tui.json"),
},
},
})
const wait = spyOn(TuiConfig, "waitForDependencies").mockResolvedValue()
const cwd = spyOn(process, "cwd").mockImplementation(() => tmp.path)
try {
await TuiPluginRuntime.init(createTuiPluginApi())
await expect(fs.readFile(tmp.extra.badMarker, "utf8")).rejects.toThrow()
await expect(fs.readFile(tmp.extra.nextMarker, "utf8")).resolves.toBe("called")
await expect(fs.readFile(tmp.extra.plainMarker, "utf8")).resolves.toBe("undefined")
} finally {
await TuiPluginRuntime.dispose()
cwd.mockRestore()
get.mockRestore()
wait.mockRestore()
delete process.env.OPENCODE_PLUGIN_META_FILE
}
})