use std::path::{Path, PathBuf};
use std::process::Command;
fn scratch(name: &str) -> PathBuf {
let dir = Path::new(env!("CARGO_TARGET_TMPDIR"))
.join("script_args")
.join(name);
let _ = std::fs::remove_dir_all(&dir);
std::fs::create_dir_all(dir.join("session")).expect("scratch dir");
dir
}
fn write_script(dir: &Path, file: &str, body: &str) -> PathBuf {
let path = dir.join(file);
std::fs::write(&path, body).expect("write the script");
path
}
fn ish(dir: &Path, args: &[&str]) -> (i32, String, String) {
let out = Command::new(env!("CARGO_BIN_EXE_ish"))
.args(args)
.current_dir(dir)
.env("IRONSHELL_SESSION_DIR", dir.join("session"))
.env("NO_COLOR", "1")
.env("IRONSHELL_ALLOW_SH", "")
.env_remove("IRONSHELL_MODE")
.output()
.expect("run ish");
(
out.status.code().unwrap_or(-1),
String::from_utf8_lossy(&out.stdout).trim().to_string(),
String::from_utf8_lossy(&out.stderr).into_owned(),
)
}
#[test]
fn the_words_after_the_script_are_its_arguments() {
let dir = scratch("count");
let script = write_script(&dir, "count.ish", "len(args())\n");
let script = script.to_str().unwrap();
let (code, out, err) = ish(&dir, &[script, "a", "b", "c"]);
assert_eq!(code, 0, "{err}");
assert_eq!(out, "3");
}
#[test]
fn flags_after_the_script_go_to_the_script() {
let dir = scratch("flags");
let script = write_script(&dir, "flags.ish", "args()\n");
let script = script.to_str().unwrap();
let (code, out, err) = ish(&dir, &[script, "--out", "-x"]);
assert_eq!(code, 0, "{err}");
assert!(out.contains("--out") && out.contains("-x"), "{out}");
}
#[test]
fn a_script_with_no_arguments_has_an_empty_args() {
let dir = scratch("none");
let script = write_script(&dir, "none.ish", "len(args())\n");
let script = script.to_str().unwrap();
let (code, out, _) = ish(&dir, &[script]);
assert_eq!(code, 0);
assert_eq!(out, "0");
}
#[test]
fn under_c_there_is_no_script_and_no_arguments() {
let dir = scratch("dash_c");
let (code, out, _) = ish(&dir, &["-c", "len(args())", "x", "y"]);
assert_eq!(code, 0);
assert_eq!(out, "0");
}
#[test]
fn bash_mode_names_the_arguments_as_positional_parameters() {
let dir = scratch("posix_args");
let script = write_script(&dir, "pos.sh", "echo \"$1-$2-$#\"\n");
let script = script.to_str().unwrap();
let (code, out, err) = ish(&dir, &["-b", script, "a", "b"]);
assert_eq!(code, 0, "{err}");
assert_eq!(out, "a-b-2");
}
#[test]
fn bash_mode_with_no_arguments_leaves_the_parameters_unset() {
let dir = scratch("posix_none");
let script = write_script(&dir, "none.sh", "echo \"[$1][$#]\"\n");
let script = script.to_str().unwrap();
let (code, out, err) = ish(&dir, &["-b", script]);
assert_eq!(code, 0, "{err}");
assert_eq!(out, "[][0]");
}
#[test]
fn subcommands_and_leading_flags_still_parse() {
let dir = scratch("subcommands");
let (code, _, err) = ish(&dir, &["agent", "--help"]);
assert_eq!(code, 0, "{err}");
let (code, out, err) = ish(&dir, &["--deterministic", "-c", "1 + 1"]);
assert_eq!(code, 0, "{err}");
assert_eq!(out, "2");
}