#[cfg(target_family = "unix")]
mod nu {
use std::io::Write;
use std::process::Command;
use tempfile::NamedTempFile;
fn bin_path() -> &'static str {
env!("CARGO_BIN_EXE_runex")
}
fn write_config() -> NamedTempFile {
let mut f = NamedTempFile::new().unwrap();
write!(
f,
"version = 1\n\n[[abbr]]\nkey = \"gcm\"\nexpand = \"echo EXPANDED\"\n"
)
.unwrap();
f.flush().unwrap();
f
}
fn nu_available() -> bool {
which::which("nu").is_ok()
}
fn run_nu(config: &NamedTempFile, line: &str, cursor: usize) -> String {
let bin = bin_path();
let script = format!(
r#"
let line = "{line}"
let cursor = {cursor}
let out = (^"{bin}" hook --shell nu --line $line --cursor $cursor | complete | get stdout | str trim --right)
if ($out | is-empty) {{
print $"($line) |($cursor + 1)"
}} else {{
let r = ($out | from json)
print $"($r.line)|($r.cursor)"
}}
"#
);
let output = Command::new("nu")
.args(["-c", &script])
.env("RUNEX_CONFIG", config.path())
.output()
.unwrap();
assert!(
output.status.success(),
"nu helper should succeed\nstdout:\n{}\nstderr:\n{}",
String::from_utf8_lossy(&output.stdout),
String::from_utf8_lossy(&output.stderr),
);
String::from_utf8_lossy(&output.stdout).trim().to_string()
}
#[test]
fn export_nu_is_parseable_by_nu() {
if !nu_available() {
eprintln!("skipping: nu not found on PATH");
return;
}
let bin = bin_path();
let output = Command::new("nu")
.args(["-c", &format!("^{bin} export nu | save --force /tmp/runex_nu_test.nu")])
.output()
.unwrap();
assert!(
output.status.success(),
"nu export should produce a parseable file\nstdout:\n{}\nstderr:\n{}",
String::from_utf8_lossy(&output.stdout),
String::from_utf8_lossy(&output.stderr),
);
}
#[test]
fn expand_at_end() {
if !nu_available() {
eprintln!("skipping: nu not found on PATH");
return;
}
let config = write_config();
assert_eq!(run_nu(&config, "gcm", 3), "echo EXPANDED |14");
}
#[test]
fn unknown_token_stays_as_is() {
if !nu_available() {
eprintln!("skipping: nu not found on PATH");
return;
}
let config = write_config();
assert_eq!(run_nu(&config, "xyz", 3), "xyz |4");
}
#[test]
fn midword_cursor_does_not_expand() {
if !nu_available() {
eprintln!("skipping: nu not found on PATH");
return;
}
let config = write_config();
assert_eq!(run_nu(&config, "gcm", 1), "g cm|2");
}
#[test]
fn argument_position_does_not_expand() {
if !nu_available() {
eprintln!("skipping: nu not found on PATH");
return;
}
let config = write_config();
assert_eq!(run_nu(&config, "echo gcm", 8), "echo gcm |9");
}
}