use std::process::Command;
fn ilo() -> Command {
Command::new(env!("CARGO_BIN_EXE_ilo"))
}
fn write_temp(content: &str) -> (tempfile::TempDir, std::path::PathBuf) {
let dir = tempfile::tempdir().expect("tempdir");
let path = dir.path().join("prog.ilo");
std::fs::write(&path, content).expect("write temp ilo");
(dir, path)
}
fn run_engine(path: &str, func: &str, arg: &str, engine_flag: Option<&str>) -> String {
let mut cmd = ilo();
cmd.arg(path).arg(func).arg(arg);
if let Some(flag) = engine_flag {
cmd.arg(flag);
}
let out = cmd
.output()
.unwrap_or_else(|e| panic!("failed to spawn ilo: {e}"));
assert!(
out.status.success(),
"engine {:?}: exit={:?}, stderr={}",
engine_flag,
out.status.code(),
String::from_utf8_lossy(&out.stderr)
);
String::from_utf8_lossy(&out.stdout).trim().to_string()
}
#[test]
fn text_param_with_digit_input_num_unwraps_across_engines() {
let src = "f arg:t>n;r=num arg;?r{~i:i;^e:0 - 1}\n";
let (_dir, path) = write_temp(src);
let p = path.to_str().unwrap();
for engine in [None, Some("--run-tree"), Some("--run-vm"), Some("--jit")] {
let out = run_engine(p, "f", "2", engine);
assert_eq!(
out, "2",
"engine {engine:?}: expected `2`, got `{out}` (pre-fix bug: arg arrived as Number, num returned nil, match collapsed)"
);
}
}
#[test]
fn text_param_with_non_numeric_input_hits_err_arm_across_engines() {
let src = "f arg:t>n;r=num arg;?r{~i:i;^e:0 - 1}\n";
let (_dir, path) = write_temp(src);
let p = path.to_str().unwrap();
for engine in [None, Some("--run-tree"), Some("--run-vm"), Some("--jit")] {
let out = run_engine(p, "f", "abc", engine);
assert_eq!(out, "-1", "engine {engine:?}: expected `-1`, got `{out}`");
}
}
#[test]
fn text_param_preserves_bool_shaped_input_across_engines() {
let src = "id arg:t>t;arg\n";
let (_dir, path) = write_temp(src);
let p = path.to_str().unwrap();
for engine in [None, Some("--run-tree"), Some("--run-vm"), Some("--jit")] {
let out = run_engine(p, "id", "true", engine);
assert_eq!(out, "true", "engine {engine:?}: got `{out}`");
}
}
#[test]
fn text_param_preserves_nil_shaped_input_across_engines() {
let src = "id arg:t>t;arg\n";
let (_dir, path) = write_temp(src);
let p = path.to_str().unwrap();
for engine in [None, Some("--run-tree"), Some("--run-vm"), Some("--jit")] {
let out = run_engine(p, "id", "nil", engine);
assert_eq!(out, "nil", "engine {engine:?}: got `{out}`");
}
}
#[test]
fn number_param_still_parses_as_number_across_engines() {
let src = "double x:n>n;*x 2\n";
let (_dir, path) = write_temp(src);
let p = path.to_str().unwrap();
for engine in [None, Some("--run-tree"), Some("--run-vm"), Some("--jit")] {
let out = run_engine(p, "double", "21", engine);
assert_eq!(out, "42", "engine {engine:?}: got `{out}`");
}
}