use std::process::Command;
fn ilo() -> Command {
Command::new(env!("CARGO_BIN_EXE_ilo"))
}
fn run(engine: &str, src: &str, entry: &str) -> String {
let out = ilo()
.args([src, engine, entry])
.output()
.expect("failed to run ilo");
assert!(
out.status.success(),
"ilo {engine} failed: stderr={}",
String::from_utf8_lossy(&out.stderr)
);
String::from_utf8_lossy(&out.stdout).into_owned()
}
#[cfg(feature = "cranelift")]
const ENGINES_ALL: &[&str] = &["--run-tree", "--run-vm", "--run-cranelift"];
#[cfg(not(feature = "cranelift"))]
const ENGINES_ALL: &[&str] = &["--run-tree", "--run-vm"];
const SINGLE_EXPR: &str = r#"f>n;?2{0:0;1:1;2:42;_:99}"#;
#[test]
fn single_expr_arm_preserved_cross_engine() {
for engine in ENGINES_ALL {
let out = run(engine, SINGLE_EXPR, "f");
assert_eq!(out.trim(), "42", "{engine}: {out:?}");
}
}
const BLOCK_WITH_LOCAL: &str = r#"f>n;r=num "10";?r{~v:{d=*v 2;+d 1};^e:0}"#;
#[test]
fn brace_block_with_local_cross_engine() {
for engine in ENGINES_ALL {
let out = run(engine, BLOCK_WITH_LOCAL, "f");
assert_eq!(out.trim(), "21", "{engine}: {out:?}");
}
}
const BLOCK_ON_ERR: &str = r#"f>t;r=num "oops";?r{~v:str v;^e:{tag="err: ";+tag e}}"#;
#[test]
fn brace_block_on_err_cross_engine() {
for engine in ENGINES_ALL {
let out = run(engine, BLOCK_ON_ERR, "f");
assert_eq!(out.trim(), "err: oops", "{engine}: {out:?}");
}
}
const NESTED_MATCH: &str = r#"f>t;r=num "0";?r{~v:{?v{0:"zero";_:"nonzero"}};^e:"bad"}"#;
#[test]
fn nested_match_in_block_cross_engine() {
for engine in ENGINES_ALL {
let out = run(engine, NESTED_MATCH, "f");
assert_eq!(out.trim(), "zero", "{engine}: {out:?}");
}
}
const BOOL_BLOCKS: &str =
r#"f>t;?true{true:{tag="OK: ";+tag "all good"};false:{tag="FAIL: ";+tag "see logs"}}"#;
#[test]
fn bool_match_brace_blocks_cross_engine() {
for engine in ENGINES_ALL {
let out = run(engine, BOOL_BLOCKS, "f");
assert_eq!(out.trim(), "OK: all good", "{engine}: {out:?}");
}
}
const INLINE_SEMI: &str = r#"f>n;r=num "10";?r{~v:d=*v 2;+d 1;^e:0}"#;
#[test]
fn inline_semi_arm_body_preserved_cross_engine() {
for engine in ENGINES_ALL {
let out = run(engine, INLINE_SEMI, "f");
assert_eq!(out.trim(), "21", "{engine}: {out:?}");
}
}
const MATCH_EXPR_BLOCK: &str = r#"f>n;r=num "5";x=?r{~v:{d=*v 3;+d 1};^e:0};+x 0"#;
#[test]
fn match_expr_brace_block_cross_engine() {
for engine in ENGINES_ALL {
let out = run(engine, MATCH_EXPR_BLOCK, "f");
assert_eq!(out.trim(), "16", "{engine}: {out:?}");
}
}