use std::process::{Command, Output};
fn typechar(args: &[&str]) -> Output {
Command::new(env!("CARGO_BIN_EXE_typechar"))
.args(args)
.output()
.expect("failed to run typechar binary")
}
#[test]
fn help_prints_usage_on_stdout_and_exits_zero() {
let out = typechar(&["--help"]);
assert_eq!(out.status.code(), Some(0));
let stdout = String::from_utf8(out.stdout).unwrap();
assert!(stdout.contains("Usage:"));
assert!(stdout.contains("--unicode"));
assert!(out.stderr.is_empty());
}
#[test]
fn version_matches_cargo_toml() {
let out = typechar(&["--version"]);
assert_eq!(out.status.code(), Some(0));
let stdout = String::from_utf8(out.stdout).unwrap();
assert_eq!(
stdout.trim(),
format!("typechar {}", env!("CARGO_PKG_VERSION"))
);
}
#[test]
fn no_args_is_a_usage_error_on_stderr_with_exit_2() {
let out = typechar(&[]);
assert_eq!(out.status.code(), Some(2));
let stderr = String::from_utf8(out.stderr).unwrap();
assert!(stderr.contains("nothing to type"));
assert!(
stderr.contains("Usage:"),
"usage errors should reprint the usage"
);
assert!(out.stdout.is_empty());
}
#[test]
fn unknown_flag_is_a_usage_error_with_exit_2() {
let out = typechar(&["--frobnicate"]);
assert_eq!(out.status.code(), Some(2));
let stderr = String::from_utf8(out.stderr).unwrap();
assert!(stderr.contains("unknown option: --frobnicate"));
}
#[test]
fn invalid_codepoint_is_a_usage_error_with_exit_2() {
let out = typechar(&["--unicode", "zzz"]);
assert_eq!(out.status.code(), Some(2));
let stderr = String::from_utf8(out.stderr).unwrap();
assert!(stderr.contains("invalid hex codepoint: zzz"));
}
#[test]
fn typing_without_permission_fails_with_exit_1_not_2() {
let out = typechar(&[""]);
let code = out.status.code();
assert!(
code == Some(0) || code == Some(1),
"expected 0 (permitted) or 1 (permission denied), got {code:?}"
);
if code == Some(1) {
let stderr = String::from_utf8(out.stderr).unwrap();
assert!(
stderr.contains("Accessibility"),
"error should tell the user the fix"
);
}
}