use std::process::Command;
fn ilo() -> Command {
Command::new(env!("CARGO_BIN_EXE_ilo"))
}
fn check_stdout(engine: &str, src: &str, expected: &str) {
let out = ilo()
.args([src, engine, "f"])
.output()
.expect("failed to run ilo");
assert!(
out.status.success(),
"engine={engine}: expected success for `{src}`, got stderr={}",
String::from_utf8_lossy(&out.stderr)
);
assert_eq!(
String::from_utf8_lossy(&out.stdout).trim(),
expected,
"engine={engine}: stdout mismatch for `{src}`"
);
}
fn check_all(src: &str, expected: &str) {
check_stdout("--vm", src, expected);
check_stdout("--vm", src, expected);
#[cfg(feature = "cranelift")]
check_stdout("--jit", src, expected);
}
#[test]
fn spl_basic_cross_engine() {
check_all("f>L t;spl \"a,b,c\" \",\"", "[a, b, c]");
}
#[test]
fn cat_basic_cross_engine() {
check_all("f>t;cat [\"a\" \"b\" \"c\"] \",\"", "a,b,c");
}
#[test]
fn has_text_found_cross_engine() {
check_all("f>b;has \"hello world\" \"world\"", "true");
}
#[test]
fn has_text_not_found_cross_engine() {
check_all("f>b;has \"hello\" \"xyz\"", "false");
}
#[test]
fn has_list_found_cross_engine() {
check_all("f>b;has [1 2 3] 2", "true");
}
#[test]
fn has_list_not_found_cross_engine() {
check_all("f>b;has [1 2 3] 5", "false");
}
#[test]
fn range_basic_cross_engine() {
check_all("f>L n;range 0 4", "[0, 1, 2, 3]");
}
#[test]
fn range_empty_when_start_ge_end_cross_engine() {
check_all("f>L n;range 5 5", "[]");
}
#[test]
fn window_basic_cross_engine() {
check_all("f>L (L n);window 2 [1 2 3 4]", "[[1, 2], [2, 3], [3, 4]]");
}
#[test]
fn window_larger_than_input_cross_engine() {
check_all("f>L (L n);window 5 [1 2 3]", "[]");
}
#[test]
fn zip_basic_cross_engine() {
check_all(
"f>L (L n);zip [1 2 3] [10 20 30]",
"[[1, 10], [2, 20], [3, 30]]",
);
}
#[test]
fn zip_truncates_to_shorter_cross_engine() {
check_all("f>L (L n);zip [1 2 3 4] [10 20]", "[[1, 10], [2, 20]]");
}
#[test]
fn chunks_basic_cross_engine() {
check_all("f>L (L n);chunks 2 [1 2 3 4 5]", "[[1, 2], [3, 4], [5]]");
}
#[test]
fn enumerate_basic_cross_engine() {
check_all(
"f>L (L n);enumerate [10 20 30]",
"[[0, 10], [1, 20], [2, 30]]",
);
}
#[test]
fn setunion_basic_cross_engine() {
check_all("f>L n;setunion [1 2 3] [3 4 5]", "[1, 2, 3, 4, 5]");
}
#[test]
fn setinter_basic_cross_engine() {
check_all("f>L n;setinter [1 2 3 4] [3 4 5 6]", "[3, 4]");
}
#[test]
fn setdiff_basic_cross_engine() {
check_all("f>L n;setdiff [1 2 3 4] [3 4 5]", "[1, 2]");
}
#[test]
fn rev_string_cross_engine() {
check_all("f>t;rev \"hello\"", "olleh");
}
#[test]
fn rev_list_cross_engine() {
check_all("f>L n;rev [1 2 3]", "[3, 2, 1]");
}
#[test]
fn srt_numbers_cross_engine() {
check_all("f>L n;srt [3 1 2]", "[1, 2, 3]");
}
#[test]
fn srt_strings_cross_engine() {
check_all("f>L t;srt [\"c\" \"a\" \"b\"]", "[a, b, c]");
}
#[test]
fn srt_empty_list_cross_engine() {
check_all("f>L n;srt []", "[]");
}
#[test]
fn rsrt_numbers_cross_engine() {
check_all("f>L n;rsrt [1 3 2]", "[3, 2, 1]");
}
#[test]
fn rsrt_strings_cross_engine() {
check_all("f>L t;rsrt [\"a\" \"c\" \"b\"]", "[c, b, a]");
}
#[test]
fn cumsum_basic_cross_engine() {
check_all("f>L n;cumsum [1 2 3 4]", "[1, 3, 6, 10]");
}
#[test]
fn cumsum_empty_cross_engine() {
check_all("f>L n;cumsum []", "[]");
}