use std::process::Command;
fn ilo() -> Command {
Command::new(env!("CARGO_BIN_EXE_ilo"))
}
#[cfg(feature = "cranelift")]
const ENGINES: &[&str] = &["--vm", "--jit"];
#[cfg(not(feature = "cranelift"))]
const ENGINES: &[&str] = &["--vm"];
fn run_ok(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} {src:?} {entry:?} failed: stderr={}",
String::from_utf8_lossy(&out.stderr)
);
String::from_utf8_lossy(&out.stdout).trim().to_string()
}
fn run_err(engine: &str, src: &str, entry: &str) -> String {
let out = ilo()
.args([src, engine, entry])
.output()
.expect("failed to run ilo");
String::from_utf8_lossy(&out.stderr).to_string()
}
#[test]
fn sha256_hex_of_abc_bytes() {
let src = "f>t;sha256-hex \"616263\"";
let expected = "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad";
for e in ENGINES {
assert_eq!(run_ok(e, src, "f"), expected, "engine={e}");
}
}
#[test]
fn sha256_hex_of_empty_bytes() {
let src = "f>t;sha256-hex \"\"";
let expected = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855";
for e in ENGINES {
assert_eq!(run_ok(e, src, "f"), expected, "engine={e}");
}
}
#[test]
fn sha256_hex_output_is_64_chars() {
let src = "f>n;len (sha256-hex \"deadbeef\")";
for e in ENGINES {
assert_eq!(run_ok(e, src, "f"), "64", "engine={e}");
}
}
#[test]
fn sha256_hex_uppercase_input_accepted() {
let src_upper = "f>t;sha256-hex \"DEADBEEF\"";
let src_lower = "f>t;sha256-hex \"deadbeef\"";
for e in ENGINES {
let upper = run_ok(e, src_upper, "f");
let lower = run_ok(e, src_lower, "f");
assert_eq!(upper, lower, "engine={e}: uppercase vs lowercase input");
}
}
#[test]
fn sha256_hex_odd_length_errors() {
let src = "f>t;sha256-hex \"abc\""; for e in ENGINES {
let stderr = run_err(e, src, "f");
assert!(
stderr.contains("ILO-R009"),
"engine={e}: expected ILO-R009 in stderr, got: {stderr}"
);
}
}
#[test]
fn sha256_hex_non_hex_input_errors() {
let src = "f>t;sha256-hex \"zz\""; for e in ENGINES {
let stderr = run_err(e, src, "f");
assert!(
stderr.contains("ILO-R009"),
"engine={e}: expected ILO-R009 in stderr, got: {stderr}"
);
}
}
#[test]
fn sha256d_of_abc_bytes() {
let src = "f>t;sha256d \"616263\"";
let expected = "4f8b42c22dd3729b519ba6f68d2da7cc5b2d606d05daed5ad5128cc03e6c6358";
for e in ENGINES {
assert_eq!(run_ok(e, src, "f"), expected, "engine={e}");
}
}
#[test]
fn sha256d_equals_double_sha256_hex() {
let src = "f>b;= (sha256d \"deadbeef\") (sha256-hex (sha256-hex \"deadbeef\"))";
for e in ENGINES {
assert_eq!(run_ok(e, src, "f"), "true", "engine={e}");
}
}
#[test]
fn sha256d_bitcoin_merkle_two_txids() {
let src = concat!(
"f>t;",
"tx1=\"0e3e2357e806b6cdb1f70b54c3a3a17b6714ee1f0e68bebb44a74b1efd512098\";",
"tx2=\"169e1e83e930853391bc6f35f605c6754cfead57cf8387639d3b4096c54f18f4\";",
"sha256d (+ tx1 tx2)"
);
let expected = "cba2bf79b14c6ff80108eb1a4d2f4b55cf4776dcdea24f292ba7dd163b5338bb";
for e in ENGINES {
assert_eq!(run_ok(e, src, "f"), expected, "engine={e}");
}
}
#[test]
fn sha256d_odd_length_errors() {
let src = "f>t;sha256d \"abc\"";
for e in ENGINES {
let stderr = run_err(e, src, "f");
assert!(
stderr.contains("ILO-R009"),
"engine={e}: expected ILO-R009 in stderr, got: {stderr}"
);
}
}
#[test]
fn sha256d_non_hex_input_errors() {
let src = "f>t;sha256d \"gg\"";
for e in ENGINES {
let stderr = run_err(e, src, "f");
assert!(
stderr.contains("ILO-R009"),
"engine={e}: expected ILO-R009 in stderr, got: {stderr}"
);
}
}