use std::process::Command;
fn ilo() -> Command {
Command::new(env!("CARGO_BIN_EXE_ilo"))
}
fn run_ok(src: &str, entry_fn: &str, args: &[&str]) -> String {
let mut cmd = ilo();
cmd.arg(src).arg("--vm").arg(entry_fn);
for a in args {
cmd.arg(a);
}
let out = cmd.output().expect("failed to run ilo");
assert!(
out.status.success(),
"ilo --vm failed: stderr={}",
String::from_utf8_lossy(&out.stderr)
);
String::from_utf8_lossy(&out.stdout).trim().to_string()
}
const U32_SRC: &str = "add-u32 a:U32 b:U32>U32;+ a b";
#[test]
fn u32_param_return_type_accepted() {
assert_eq!(run_ok(U32_SRC, "add-u32", &["3", "4"]), "7");
}
const U64_SRC: &str = "add-u64 a:U64 b:U64>U64;+ a b";
#[test]
fn u64_param_return_type_accepted() {
assert_eq!(run_ok(U64_SRC, "add-u64", &["100000", "200000"]), "300000");
}
const I64_SRC: &str = "negate a:I64>I64;- 0 a";
#[test]
fn i64_param_return_type_accepted() {
assert_eq!(run_ok(I64_SRC, "negate", &["42"]), "-42");
}
const LIST_U32_SRC: &str = "len-u32 xs:L U32>U32;len xs";
#[test]
fn u32_in_list_type_position() {
assert_eq!(run_ok(LIST_U32_SRC, "len-u32", &["[1, 2, 3]"]), "3");
}
const OPT_U32_SRC: &str = "unwrap-or x:O U32>U32;?? x 0";
#[test]
fn u32_in_optional_nil() {
assert_eq!(run_ok(OPT_U32_SRC, "unwrap-or", &["nil"]), "0");
}
#[test]
fn u32_in_optional_value() {
assert_eq!(run_ok(OPT_U32_SRC, "unwrap-or", &["5"]), "5");
}
const MIX_SRC: &str = "double x:U32>n;* x 2";
#[test]
fn u32_compatible_with_number_return() {
assert_eq!(run_ok(MIX_SRC, "double", &["21"]), "42");
}
const BAND_U32_SRC: &str = "mask a:U32 b:U32>U32;band a b";
#[test]
fn band_on_u32_annotated_values() {
assert_eq!(run_ok(BAND_U32_SRC, "mask", &["12", "10"]), "8");
}
const DIFF_I64_SRC: &str = "diff a:I64 b:I64>I64;- a b";
#[test]
fn i64_negative_result() {
assert_eq!(run_ok(DIFF_I64_SRC, "diff", &["3", "10"]), "-7");
}
#[allow(dead_code)]
const FN_U64_SRC: &str = "apply-fn f:F U64 U64 x:U64>U64;f x";
#[test]
fn u64_in_fn_type_position() {
let src = "dbl x:U64>U64;* x 2\napply-fn f:F U64 U64 x:U64>U64;f x";
assert_eq!(run_ok(src, "apply-fn", &["dbl", "5"]), "10");
}
const ALIAS_SRC: &str = "alias uint U32\nadd-uint a:uint b:uint>uint;+ a b";
#[test]
fn u32_type_alias() {
assert_eq!(run_ok(ALIAS_SRC, "add-uint", &["6", "7"]), "13");
}