use std::process::Command;
fn ilo() -> Command {
Command::new(env!("CARGO_BIN_EXE_ilo"))
}
fn run(code: &str) -> (bool, String) {
let out = ilo()
.arg(code)
.output()
.unwrap_or_else(|e| panic!("failed to spawn ilo: {e}"));
let stderr = String::from_utf8_lossy(&out.stderr).to_string();
(out.status.success(), stderr)
}
fn assert_error(code: &str, expected_code: &str) {
let (ok, stderr) = run(code);
assert!(
!ok,
"expected failure for snippet {:?} (code {}), but it succeeded",
code, expected_code
);
assert!(
stderr.contains(expected_code),
"expected error code {} in stderr for snippet {:?}\nstderr was:\n{}",
expected_code,
code,
stderr
);
}
#[test]
fn t001_duplicate_type_definition() {
assert_error("type point{x:n;y:n} type point{a:n;b:n} f>n;42", "ILO-T001");
}
#[test]
fn t002_duplicate_function_definition() {
assert_error("f x:n>n;*x 2 f x:n>n;+x 1", "ILO-T002");
}
#[test]
fn t003_undefined_type_in_parameter() {
assert_error("f x:widget>n;42", "ILO-T003");
}
#[test]
fn t004_undefined_variable() {
assert_error("f x:n>n;missing-var", "ILO-T004");
}
#[test]
fn t005_undefined_function_call() {
assert_error("f x:n>n;no-such-func x", "ILO-T005");
}
#[test]
fn t006_arity_mismatch_too_few_args() {
assert_error("g a:n b:n>n;+a b f x:n>n;g x", "ILO-T006");
}
#[test]
fn t006_arity_mismatch_too_many_args() {
assert_error("g x:n>n;*x 2 f x:n>n;g x x", "ILO-T006");
}
#[test]
fn t007_wrong_argument_type_text_instead_of_number() {
assert_error("g x:n>n;*x 2 f s:t>n;g s", "ILO-T007");
}
#[test]
fn t008_return_type_mismatch_text_body_number_expected() {
assert_error(r#"f x:n>n;"hello""#, "ILO-T008");
}
#[test]
fn t008_return_type_mismatch_number_body_text_expected() {
assert_error("f x:n>t;*x 2", "ILO-T008");
}
#[test]
fn t009_add_number_and_text() {
assert_error(r#"f x:n y:t>n;+x y"#, "ILO-T009");
}
#[test]
fn t009_multiply_text_operands() {
assert_error(r#"f x:t y:n>n;*x y"#, "ILO-T009");
}
#[test]
fn t010_compare_number_and_text() {
assert_error(r#"f x:n y:t>b;>x y"#, "ILO-T010");
}
#[test]
fn t011_append_wrong_element_type() {
assert_error(r#"f>n;xs=[1 2 3];xs=+=xs "hello";len xs"#, "ILO-T011");
}
#[test]
fn t012_negate_text_value() {
assert_error(r#"f x:t>n;-x"#, "ILO-T012");
}
#[test]
fn t014_foreach_on_number() {
assert_error("f x:n>n;@v x{v};x", "ILO-T014");
}
#[test]
fn t018_field_access_on_number() {
assert_error("f x:n>n;x.field", "ILO-T018");
}
#[test]
fn t019_no_such_field_on_record() {
assert_error("type point{x:n;y:n} f p:point>n;p.z", "ILO-T019");
}
#[test]
fn t025_auto_unwrap_on_non_result_function() {
assert_error("g x:n>n;*x 2 f x:n>n;r=g! x;r", "ILO-T025");
}