133 lines
3.5 KiB
TypeScript
133 lines
3.5 KiB
TypeScript
import { describe, expect, it } from "bun:test"
|
|
|
|
import type { TmuxCommandResult } from "../runner"
|
|
import { closeTmuxPaneWithDependencies } from "./pane-close"
|
|
|
|
type CloseTmuxPaneDependencies = Parameters<typeof closeTmuxPaneWithDependencies>[1]
|
|
|
|
type TmuxCommandCall = {
|
|
readonly tmux: string
|
|
readonly args: string[]
|
|
}
|
|
|
|
type ClosePaneFixture = {
|
|
readonly calls: TmuxCommandCall[]
|
|
readonly delayCalls: number[]
|
|
readonly dependencies: CloseTmuxPaneDependencies
|
|
}
|
|
|
|
type FixtureOptions = {
|
|
readonly insideTmux?: boolean
|
|
readonly tmuxPath?: string | undefined
|
|
readonly results?: TmuxCommandResult[]
|
|
}
|
|
|
|
function tmuxResult(overrides: Partial<TmuxCommandResult> = {}): TmuxCommandResult {
|
|
return {
|
|
success: true,
|
|
output: "",
|
|
stdout: "",
|
|
stderr: "",
|
|
exitCode: 0,
|
|
...overrides,
|
|
}
|
|
}
|
|
|
|
function createFixture(options: FixtureOptions = {}): ClosePaneFixture {
|
|
const calls: TmuxCommandCall[] = []
|
|
const delayCalls: number[] = []
|
|
const results = [...(options.results ?? [tmuxResult()])]
|
|
const tmuxPath = "tmuxPath" in options ? options.tmuxPath : "tmux"
|
|
|
|
return {
|
|
calls,
|
|
delayCalls,
|
|
dependencies: {
|
|
isInsideTmux: () => options.insideTmux ?? true,
|
|
getTmuxPath: async () => tmuxPath,
|
|
runTmuxCommand: async (tmux, args) => {
|
|
calls.push({ tmux, args: [...args] })
|
|
return results.shift() ?? tmuxResult()
|
|
},
|
|
log: () => undefined,
|
|
delay: async (milliseconds) => {
|
|
delayCalls.push(milliseconds)
|
|
},
|
|
},
|
|
}
|
|
}
|
|
|
|
describe("closeTmuxPane", () => {
|
|
it("#given pane exists #when closeTmuxPane called #then returns true and invokes send-keys + kill-pane in order", async () => {
|
|
// given
|
|
const fixture = createFixture()
|
|
|
|
// when
|
|
const result = await closeTmuxPaneWithDependencies("%42", fixture.dependencies)
|
|
|
|
// then
|
|
expect(result).toBe(true)
|
|
expect(fixture.calls).toEqual([
|
|
{ tmux: "tmux", args: ["send-keys", "-t", "%42", "C-c"] },
|
|
{ tmux: "tmux", args: ["kill-pane", "-t", "%42"] },
|
|
])
|
|
expect(fixture.delayCalls).toEqual([250])
|
|
})
|
|
|
|
it("#given not inside tmux #when closeTmuxPane called #then returns false without runner calls", async () => {
|
|
// given
|
|
const fixture = createFixture({ insideTmux: false })
|
|
|
|
// when
|
|
const result = await closeTmuxPaneWithDependencies("%42", fixture.dependencies)
|
|
|
|
// then
|
|
expect(result).toBe(false)
|
|
expect(fixture.calls).toEqual([])
|
|
})
|
|
|
|
it("#given tmux not found #when closeTmuxPane called #then returns false without runner calls", async () => {
|
|
// given
|
|
const fixture = createFixture({ tmuxPath: undefined })
|
|
|
|
// when
|
|
const result = await closeTmuxPaneWithDependencies("%42", fixture.dependencies)
|
|
|
|
// then
|
|
expect(result).toBe(false)
|
|
expect(fixture.calls).toEqual([])
|
|
})
|
|
|
|
it("#given kill-pane fails with unknown error #when closeTmuxPane called #then returns false", async () => {
|
|
// given
|
|
const fixture = createFixture({
|
|
results: [
|
|
tmuxResult(),
|
|
tmuxResult({ success: false, stderr: "permission denied", exitCode: 1 }),
|
|
],
|
|
})
|
|
|
|
// when
|
|
const result = await closeTmuxPaneWithDependencies("%42", fixture.dependencies)
|
|
|
|
// then
|
|
expect(result).toBe(false)
|
|
})
|
|
|
|
it("#given pane already closed by Ctrl+C #when kill-pane reports can't find pane #then returns true", async () => {
|
|
// given
|
|
const fixture = createFixture({
|
|
results: [
|
|
tmuxResult(),
|
|
tmuxResult({ success: false, stderr: "can't find pane: %42", exitCode: 1 }),
|
|
],
|
|
})
|
|
|
|
// when
|
|
const result = await closeTmuxPaneWithDependencies("%42", fixture.dependencies)
|
|
|
|
// then
|
|
expect(result).toBe(true)
|
|
})
|
|
})
|