| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121 |
- import { afterEach, describe, expect, mock, spyOn, test } from "bun:test"
- import fs from "fs/promises"
- import path from "path"
- import { tmpdir } from "../../fixture/fixture"
- import * as App from "../../../src/cli/cmd/tui/app"
- import { Rpc } from "../../../src/util"
- import { UI } from "../../../src/cli/ui"
- import * as Timeout from "../../../src/util/timeout"
- import * as Network from "../../../src/cli/network"
- import * as Win32 from "../../../src/cli/cmd/tui/win32"
- import { TuiConfig } from "../../../src/cli/cmd/tui/config/tui"
- const stop = new Error("stop")
- const seen = {
- tui: [] as string[],
- }
- function setup() {
- // Intentionally avoid mock.module() here: Bun keeps module overrides in cache
- // and mock.restore() does not reset mock.module values. If this switches back
- // to module mocks, later suites can see mocked @/config/tui and fail (e.g.
- // plugin-loader tests expecting real TuiConfig.waitForDependencies). See:
- // https://github.com/oven-sh/bun/issues/7823 and #12823.
- spyOn(App, "tui").mockImplementation(async (input) => {
- if (input.directory) seen.tui.push(input.directory)
- throw stop
- })
- spyOn(Rpc, "client").mockImplementation(() => ({
- call: async () => ({ url: "http://127.0.0.1" }) as never,
- on: () => () => {},
- }))
- spyOn(UI, "error").mockImplementation(() => {})
- spyOn(Timeout, "withTimeout").mockImplementation((input) => input)
- spyOn(Network, "resolveNetworkOptions").mockResolvedValue({
- mdns: false,
- port: 0,
- hostname: "127.0.0.1",
- mdnsDomain: "opencode.local",
- cors: [],
- })
- spyOn(Win32, "win32DisableProcessedInput").mockImplementation(() => {})
- spyOn(Win32, "win32InstallCtrlCGuard").mockReturnValue(undefined)
- }
- describe("tui thread", () => {
- afterEach(() => {
- mock.restore()
- })
- async function call(project?: string) {
- const { TuiThreadCommand } = await import("../../../src/cli/cmd/tui/thread")
- const args: Parameters<NonNullable<typeof TuiThreadCommand.handler>>[0] = {
- _: [],
- $0: "kilo", // kilocode_change
- project,
- prompt: "hi",
- model: undefined,
- agent: undefined,
- session: undefined,
- continue: false,
- fork: false,
- "cloud-fork": undefined, // kilocode_change
- cloudFork: undefined, // kilocode_change
- port: 0,
- hostname: "127.0.0.1",
- mdns: false,
- "mdns-domain": "kilo.local", // kilocode_change
- mdnsDomain: "kilo.local", // kilocode_change
- cors: [],
- }
- return TuiThreadCommand.handler(args)
- }
- async function check(project?: string) {
- setup()
- await using tmp = await tmpdir({ git: true })
- const cwd = process.cwd()
- const pwd = process.env.PWD
- const worker = globalThis.Worker
- const tty = Object.getOwnPropertyDescriptor(process.stdin, "isTTY")
- const link = path.join(path.dirname(tmp.path), path.basename(tmp.path) + "-link")
- const type = process.platform === "win32" ? "junction" : "dir"
- seen.tui.length = 0
- await fs.symlink(tmp.path, link, type)
- Object.defineProperty(process.stdin, "isTTY", {
- configurable: true,
- value: true,
- })
- globalThis.Worker = class extends EventTarget {
- onerror = null
- onmessage = null
- onmessageerror = null
- postMessage() {}
- terminate() {}
- } as unknown as typeof Worker
- try {
- process.chdir(tmp.path)
- process.env.PWD = link
- await expect(call(project)).rejects.toBe(stop)
- expect(seen.tui[0]).toBe(tmp.path)
- } finally {
- process.chdir(cwd)
- if (pwd === undefined) delete process.env.PWD
- else process.env.PWD = pwd
- if (tty) Object.defineProperty(process.stdin, "isTTY", tty)
- else delete (process.stdin as { isTTY?: boolean }).isTTY
- globalThis.Worker = worker
- await fs.rm(link, { recursive: true, force: true }).catch(() => undefined)
- }
- }
- test("uses the real cwd when PWD points at a symlink", async () => {
- await check()
- })
- test("uses the real cwd after resolving a relative project from PWD", async () => {
- await check(".")
- })
- })
|