use std::path::PathBuf;
use std::process::Command;
fn binary() -> PathBuf {
PathBuf::from(env!("CARGO_BIN_EXE_keyhog"))
}
#[test]
fn backend_default_returns_exit_zero_with_hardware_info() {
let output = Command::new(binary())
.arg("backend")
.output()
.expect("spawn keyhog backend");
assert_eq!(
output.status.code(),
Some(0),
"backend should exit 0; stderr={}",
String::from_utf8_lossy(&output.stderr)
);
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(
!stdout.is_empty(),
"backend should emit hardware detection info"
);
assert!(
stdout.to_lowercase().contains("backend")
|| stdout.to_lowercase().contains("gpu")
|| stdout.to_lowercase().contains("simd")
|| stdout.to_lowercase().contains("hardware"),
"backend output should describe detected hardware; got: {stdout}"
);
}
#[test]
fn backend_self_test_executes_and_returns_valid_exit_code() {
let output = Command::new(binary())
.arg("backend")
.arg("--self-test")
.output()
.expect("spawn keyhog backend --self-test");
let code = output.status.code();
assert!(
code == Some(0) || code == Some(4),
"backend --self-test should exit 0 (pass) or 4 (fail); got {code:?}"
);
}
#[test]
fn backend_self_test_json_emits_structured_output() {
let output = Command::new(binary())
.arg("backend")
.arg("--self-test")
.arg("--json")
.output()
.expect("spawn keyhog backend --self-test --json");
let code = output.status.code();
assert!(
code == Some(0) || code == Some(4),
"backend --self-test --json should exit 0 or 4; got {code:?}"
);
let stdout = String::from_utf8_lossy(&output.stdout);
let parsed: Result<serde_json::Value, _> = serde_json::from_str(&stdout);
assert!(
parsed.is_ok(),
"backend --self-test --json should emit valid JSON; got: {stdout}"
);
}
#[test]
fn backend_probe_bytes_tests_routing_threshold() {
let output = Command::new(binary())
.arg("backend")
.arg("--probe-bytes")
.arg("268435456")
.output()
.expect("spawn keyhog backend --probe-bytes");
assert_eq!(
output.status.code(),
Some(0),
"backend --probe-bytes should exit 0; stderr={}",
String::from_utf8_lossy(&output.stderr)
);
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(
!stdout.is_empty(),
"backend --probe-bytes should emit routing info"
);
assert!(
stdout.contains("backend") || stdout.contains("gpu") || stdout.contains("route"),
"probe output should show backend routing decision; got: {stdout}"
);
}
#[test]
fn backend_patterns_flag_alters_routing_decision() {
let output = Command::new(binary())
.arg("backend")
.arg("--patterns")
.arg("2000")
.output()
.expect("spawn keyhog backend --patterns");
assert_eq!(
output.status.code(),
Some(0),
"backend --patterns should exit 0"
);
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(
!stdout.is_empty(),
"backend --patterns should emit routing info with the custom pattern count"
);
}
#[test]
fn backend_patterns_non_numeric_exits_two() {
let output = Command::new(binary())
.arg("backend")
.arg("--patterns")
.arg("not-a-number")
.output()
.expect("spawn keyhog backend --patterns <non-numeric>");
assert_eq!(
output.status.code(),
Some(2),
"backend with non-numeric --patterns should exit 2 (user error)"
);
let stderr = String::from_utf8_lossy(&output.stderr);
assert!(
stderr.to_lowercase().contains("pattern")
|| stderr.to_lowercase().contains("invalid")
|| stderr.contains("number"),
"error should identify the invalid patterns argument; stderr: {stderr}"
);
}