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()
}
#[test]
fn urlenc_simple_ascii_unchanged() {
let src = "f>t;urlenc \"abc-123_XYZ.~\"";
for e in ENGINES {
assert_eq!(run_ok(e, src, "f"), "abc-123_XYZ.~", "engine={e}");
}
}
#[test]
fn urlenc_reserved_chars_encoded() {
let src = "f>t;urlenc \"a b&c=d\"";
for e in ENGINES {
assert_eq!(run_ok(e, src, "f"), "a%20b%26c%3Dd", "engine={e}");
}
}
#[test]
fn urlenc_utf8_multibyte() {
let src = "f>t;urlenc \"café\"";
for e in ENGINES {
assert_eq!(run_ok(e, src, "f"), "caf%C3%A9", "engine={e}");
}
}
#[test]
fn urldec_round_trip_through_urlenc() {
let src = "f>R t t;urldec (urlenc \"hello world & friends=42\")";
for e in ENGINES {
assert_eq!(
run_ok(e, src, "f"),
"hello world & friends=42",
"engine={e}"
);
}
}
#[test]
fn urldec_recovers_utf8_multibyte() {
let src = "f>R t t;urldec \"caf%C3%A9\"";
for e in ENGINES {
assert_eq!(run_ok(e, src, "f"), "café", "engine={e}");
}
}
#[test]
fn urldec_invalid_escape_errors() {
let src = "f>t;r=urldec \"abc%\";?r{~_:\"ok\";^_:\"err\"}";
for e in ENGINES {
assert_eq!(run_ok(e, src, "f"), "err", "engine={e}");
}
}
#[test]
fn urldec_short_escape_errors() {
let src = "f>t;r=urldec \"abc%2\";?r{~_:\"ok\";^_:\"err\"}";
for e in ENGINES {
assert_eq!(run_ok(e, src, "f"), "err", "engine={e}");
}
}
#[test]
fn b64u_simple_ascii() {
let src = "f>t;b64u \"hello\"";
for e in ENGINES {
assert_eq!(run_ok(e, src, "f"), "aGVsbG8", "engine={e}");
}
}
#[test]
fn b64u_uses_urlsafe_alphabet() {
let src = "f>t;b64u \"??>\"";
for e in ENGINES {
assert_eq!(run_ok(e, src, "f"), "Pz8-", "engine={e}");
}
}
#[test]
fn b64u_no_padding_emitted() {
let src = "f>t;b64u \"a\"";
for e in ENGINES {
let out = run_ok(e, src, "f");
assert_eq!(out, "YQ", "engine={e}");
assert!(!out.contains('='), "engine={e}: padding leaked: {out}");
}
}
#[test]
fn b64u_dec_round_trip() {
let src = "f>R t t;b64u-dec (b64u \"hello, world! 🎉\")";
for e in ENGINES {
assert_eq!(run_ok(e, src, "f"), "hello, world! 🎉", "engine={e}");
}
}
#[test]
fn b64u_dec_recovers_known_value() {
let src = "f>R t t;b64u-dec \"aGVsbG8\"";
for e in ENGINES {
assert_eq!(run_ok(e, src, "f"), "hello", "engine={e}");
}
}
#[test]
fn b64u_dec_invalid_alphabet_errors() {
let src = "f>t;r=b64u-dec \"abc!def\";?r{~_:\"ok\";^_:\"err\"}";
for e in ENGINES {
assert_eq!(run_ok(e, src, "f"), "err", "engine={e}");
}
}
#[test]
fn b64u_dec_standard_padding_rejected() {
let src = "f>t;r=b64u-dec \"aGVsbG8=\";?r{~_:\"ok\";^_:\"err\"}";
for e in ENGINES {
assert_eq!(run_ok(e, src, "f"), "err", "engine={e}");
}
}
#[test]
fn b64u_dec_invalid_utf8_errors() {
let src = "f>t;r=b64u-dec \"__8\";?r{~_:\"ok\";^_:\"err\"}";
for e in ENGINES {
assert_eq!(run_ok(e, src, "f"), "err", "engine={e}");
}
}
#[test]
fn b64u_jwt_header_shape() {
let src = "f>t;b64u \"{\\\"alg\\\":\\\"HS256\\\",\\\"typ\\\":\\\"JWT\\\"}\"";
for e in ENGINES {
assert_eq!(
run_ok(e, src, "f"),
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9",
"engine={e}"
);
}
}