import { spawnSync } from "node:child_process" ;
import fs from "node:fs/promises" ;
import os from "node:os" ;
import path from "node:path" ;
import { Command } from "commander" ;
import { describe, expect, it } from "vitest" ;
import { getCompletionScript } from "./completion-cli.js" ;
function createCompletionProgram(): Command {
const program = new Command();
program.name("openclaw" );
program.description("CLI root" );
program.option("-v, --verbose" , "Verbose output" );
const gateway = program.command("gateway" ).description("Gateway commands" );
gateway.option("--force" , "Force the action" );
gateway.command("status" ).description("Show gateway status" ).option("--json" , "JSON output" );
gateway.command("restart" ).description("Restart gateway" );
return program;
}
describe("completion-cli" , () => {
it("generates zsh functions for nested subcommands" , () => {
const script = getCompletionScript("zsh" , createCompletionProgram());
expect(script).toContain("_openclaw_gateway()" );
expect(script).toContain("(status) _openclaw_gateway_status ;;" );
expect(script).toContain("(restart) _openclaw_gateway_restart ;;" );
expect(script).toContain("--force[Force the action]" );
});
it("defers zsh registration until compinit is available" , async () => {
if (process.platform === "win32" ) {
return ;
}
const probe = spawnSync("zsh" , ["-fc" , "exit 0" ], { encoding: "utf8" });
if (probe.error) {
if (
"code" in probe.error &&
(probe.error.code === "ENOENT" || probe.error.code === "EACCES" )
) {
return ;
}
throw probe.error;
}
const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-zsh-completion-" ));
try {
const scriptPath = path.join(tempDir, "openclaw.zsh" );
await fs.writeFile(scriptPath, getCompletionScript("zsh" , createCompletionProgram()), "utf8" );
const result = spawnSync(
"zsh" ,
[
"-fc" ,
`
source ${JSON.stringify(scriptPath)}
[[ -z "\${_comps[openclaw]-}" ]] || exit 10
[[ "\${precmd_functions[(r)_openclaw_register_completion]}" = "_openclaw_register_completion" ]] || exit 11
autoload -Uz compinit
compinit -C
_openclaw_register_completion
[[ -z "\${precmd_functions[(r)_openclaw_register_completion]}" ]] || exit 12
[[ "\${_comps[openclaw]-}" = "_openclaw_root_completion" ]]
`,
],
{
encoding: "utf8" ,
env: {
...process.env,
HOME: tempDir,
ZDOTDIR: tempDir,
},
},
);
expect(result.stderr).not.toContain("command not found: compdef" );
expect(result.status).toBe(0 );
} finally {
await fs.rm(tempDir, { recursive: true , force: true });
}
});
it("generates PowerShell command paths without the executable prefix" , () => {
const script = getCompletionScript("powershell" , createCompletionProgram());
expect(script).toContain("if ($commandPath -eq 'gateway') {" );
expect(script).toContain("if ($commandPath -eq 'gateway status') {" );
expect(script).not.toContain("if ($commandPath -eq 'openclaw gateway') {" );
expect(script).toContain("$completions = @('status','restart','--force')" );
});
it("generates fish completions for root and nested command contexts" , () => {
const script = getCompletionScript("fish" , createCompletionProgram());
expect(script).toContain(
'complete -c openclaw -n "__fish_use_subcommand" -a "gateway" -d \' Gateway commands\'' ,
);
expect(script).toContain(
'complete -c openclaw -n "__fish_seen_subcommand_from gateway" -a "status" -d \' Show gateway status\'' ,
);
expect(script).toContain(
"complete -c openclaw -n \" __fish_seen_subcommand_from gateway\" -l force -d 'Force the action'" ,
);
});
});
Messung V0.5 in Prozent C=100 H=100 G=100
¤ Dauer der Verarbeitung: 0.15 Sekunden
(vorverarbeitet am 2026-06-09)
¤
*© Formatika GbR, Deutschland