use std::path::PathBuf;
use std::process::Command;
fn binary() -> PathBuf {
PathBuf::from(env!("CARGO_BIN_EXE_keyhog"))
}
#[test]
fn completion_bash_returns_exit_zero_with_function() {
let output = Command::new(binary())
.arg("completion")
.arg("bash")
.output()
.expect("spawn keyhog completion bash");
assert_eq!(
output.status.code(),
Some(0),
"completion bash should exit 0; stderr={}",
String::from_utf8_lossy(&output.stderr)
);
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(
!stdout.is_empty(),
"completion bash should emit completion script"
);
assert!(
stdout.contains("keyhog") || stdout.contains("scan") || stdout.contains("complete"),
"bash completion should reference keyhog or its subcommands; got: {}",
&stdout[..stdout.len().min(200)]
);
}
#[test]
fn completion_zsh_returns_exit_zero_with_zsh_format() {
let output = Command::new(binary())
.arg("completion")
.arg("zsh")
.output()
.expect("spawn keyhog completion zsh");
assert_eq!(
output.status.code(),
Some(0),
"completion zsh should exit 0"
);
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(
!stdout.is_empty(),
"completion zsh should emit completion script"
);
assert!(
stdout.contains("keyhog")
|| stdout.contains("compdef")
|| stdout.contains("(")
|| stdout.contains("#"),
"zsh completion should be valid; got: {}",
&stdout[..stdout.len().min(200)]
);
}
#[test]
fn completion_fish_returns_exit_zero_with_fish_format() {
let output = Command::new(binary())
.arg("completion")
.arg("fish")
.output()
.expect("spawn keyhog completion fish");
assert_eq!(
output.status.code(),
Some(0),
"completion fish should exit 0"
);
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(
!stdout.is_empty(),
"completion fish should emit completion script"
);
assert!(
stdout.contains("complete") || stdout.contains("fish") || stdout.contains("keyhog"),
"fish completion should be valid; got: {}",
&stdout[..stdout.len().min(200)]
);
}
#[test]
fn completion_powershell_returns_exit_zero_with_powershell_format() {
let output = Command::new(binary())
.arg("completion")
.arg("powershell")
.output()
.expect("spawn keyhog completion powershell");
assert_eq!(
output.status.code(),
Some(0),
"completion powershell should exit 0"
);
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(
!stdout.is_empty(),
"completion powershell should emit completion script"
);
assert!(
stdout.contains("function") || stdout.contains("keyhog") || stdout.contains("Register"),
"powershell completion should be valid; got: {}",
&stdout[..stdout.len().min(200)]
);
}
#[test]
fn completion_invalid_shell_exits_two() {
let output = Command::new(binary())
.arg("completion")
.arg("tcsh")
.output()
.expect("spawn keyhog completion tcsh");
assert_eq!(
output.status.code(),
Some(2),
"completion with invalid shell should exit 2 (user error)"
);
let stderr = String::from_utf8_lossy(&output.stderr);
assert!(
stderr.to_lowercase().contains("tcsh")
|| stderr.to_lowercase().contains("invalid")
|| stderr.contains("shell"),
"error should name the invalid shell; stderr: {stderr}"
);
}
#[test]
fn completion_help_documents_available_shells() {
let output = Command::new(binary())
.arg("completion")
.arg("--help")
.output()
.expect("spawn keyhog completion --help");
assert_eq!(
output.status.code(),
Some(0),
"completion --help should exit 0"
);
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(
stdout.contains("bash")
|| stdout.contains("zsh")
|| stdout.contains("fish")
|| stdout.contains("shell"),
"help should document shell options; got: {stdout}"
);
}