| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071 |
- import { describe, expect, test } from "bun:test"
- import { Readable } from "node:stream"
- import { INTERACTIVE_INPUT_ERROR, resolveInteractiveStdin } from "@/cli/cmd/run/runtime.stdin"
- function stream(isTTY: boolean) {
- return Object.assign(new Readable({ read() {} }), { isTTY }) as NodeJS.ReadStream
- }
- describe("run interactive stdin", () => {
- test("reuses stdin when it is already a tty", () => {
- const stdin = stream(true)
- const seen: string[] = []
- const result = resolveInteractiveStdin(
- stdin,
- (path) => {
- seen.push(path)
- return stream(true)
- },
- "linux",
- )
- expect(result.stdin).toBe(stdin)
- expect(result.cleanup).toBeUndefined()
- expect(seen).toEqual([])
- })
- test("opens the controlling terminal when stdin is piped", () => {
- const tty = stream(true)
- const seen: string[] = []
- const result = resolveInteractiveStdin(
- stream(false),
- (path) => {
- seen.push(path)
- return tty
- },
- "linux",
- )
- expect(result.stdin).toBe(tty)
- expect(seen).toEqual(["/dev/tty"])
- result.cleanup?.()
- expect(tty.destroyed).toBe(true)
- })
- test("uses CONIN$ on windows", () => {
- const seen: string[] = []
- resolveInteractiveStdin(
- stream(false),
- (path) => {
- seen.push(path)
- return stream(true)
- },
- "win32",
- )
- expect(seen).toEqual(["CONIN$"])
- })
- test("throws a clear error when no controlling terminal is available", () => {
- expect(() =>
- resolveInteractiveStdin(
- stream(false),
- () => {
- throw new Error("open failed")
- },
- "linux",
- ),
- ).toThrow(INTERACTIVE_INPUT_ERROR)
- })
- })
|