mirror of
https://github.com/anomalyco/opencode.git
synced 2026-11-08 01:07:06 +03:00
60 lines
2.4 KiB
TypeScript
60 lines
2.4 KiB
TypeScript
import { describe, expect, test } from "bun:test"
|
|
import { Effect, Result } from "effect"
|
|
import { CodeMode } from "./lib/index.js"
|
|
|
|
describe("CodeMode.scanTools", () => {
|
|
test("extracts dotted, bracketed and nested static tool calls in first-seen order", () => {
|
|
const scanned = CodeMode.scanTools(`
|
|
const chapters = await tools["hex-meetings"].get_chapters({ meeting_id: "m1" })
|
|
const thread = await tools.slack.read_thread({ ts: await tools.slack.latest_ts({}) })
|
|
await tools.slack.read_thread({ ts: "again" })
|
|
const ignored = { tools: 1 }.tools
|
|
return { wake: true, state: chapters }
|
|
`)
|
|
expect(Result.isSuccess(scanned)).toBe(true)
|
|
if (Result.isSuccess(scanned)) {
|
|
expect(scanned.success).toEqual(["hex-meetings.get_chapters", "slack.read_thread", "slack.latest_ts"])
|
|
}
|
|
})
|
|
|
|
test("ignores shadowed local tools bindings", () => {
|
|
const scanned = CodeMode.scanTools(`
|
|
function helper(tools) {
|
|
return tools[dynamicKey]()
|
|
}
|
|
{
|
|
const tools = { any: () => 1 }
|
|
tools.any()
|
|
}
|
|
return helper({ [dynamicKey]: () => ({ wake: false }) })
|
|
`)
|
|
expect(scanned).toEqual(Result.succeed([]))
|
|
})
|
|
|
|
test("rejects empty code, syntax errors, dynamic bracket access, and aliasing tools", () => {
|
|
expect(Result.isFailure(CodeMode.scanTools(" "))).toBe(true)
|
|
expect(Result.isFailure(CodeMode.scanTools("const x = {"))).toBe(true)
|
|
expect(Result.isFailure(CodeMode.scanTools("return await tools.slack[name]({})"))).toBe(true)
|
|
expect(Result.isFailure(CodeMode.scanTools("const s = tools.slack; return await s.read_thread({})"))).toBe(true)
|
|
expect(Result.isFailure(CodeMode.scanTools("return Object.keys(tools)"))).toBe(true)
|
|
})
|
|
|
|
test("binds outer globals that programs can read or shadow while keeping line numbers", async () => {
|
|
const read = await Effect.runPromise(
|
|
CodeMode.execute({
|
|
code: "return { prev: state.count, runs, same: input.state.count }",
|
|
bindings: { state: { count: 4 }, runs: 2, input: { state: { count: 4 } } },
|
|
}),
|
|
)
|
|
expect(read).toMatchObject({ ok: true, value: { prev: 4, runs: 2, same: 4 } })
|
|
|
|
const shadowed = await Effect.runPromise(
|
|
CodeMode.execute({
|
|
code: "const state = 9\nreturn { wake: true, state }",
|
|
bindings: { state: { count: 4 } },
|
|
}),
|
|
)
|
|
expect(shadowed).toMatchObject({ ok: true, value: { wake: true, state: 9 } })
|
|
})
|
|
})
|