mod test_helpers;
use runmat_parser::parse;
use test_helpers::execute;
use test_helpers::lower;
#[test]
fn error_identifier_and_catch() {
let ast = parse(
"try; error(\"RunMat:domainError\", \"bad\"); catch e; msg = getfield(e, 'message'); end",
)
.unwrap();
let hir = lower(&ast).unwrap();
let vars = execute(&hir).unwrap();
let has_msg = vars.iter().any(|v| matches!(v, runmat_builtins::Value::StringArray(sa) if !sa.data.is_empty() && sa.data.iter().any(|s| s.contains("bad"))));
let has_exc = vars
.iter()
.any(|v| matches!(v, runmat_builtins::Value::MException(me) if me.message.contains("bad")));
assert!(has_msg || has_exc);
}
#[test]
fn nested_try_catch_rethrow() {
let ast =
parse("try; try; error('RunMat:oops','x'); catch e; rethrow(e); end; catch f; g=1; end")
.unwrap();
let hir = lower(&ast).unwrap();
let vars = execute(&hir).unwrap();
assert!(vars
.iter()
.any(|v| matches!(v, runmat_builtins::Value::Num(n) if (*n - 1.0).abs()<1e-9)));
}
#[test]
fn catch_and_multi_assign_propagation() {
let ast = parse("A=[1 2]; try; x=A(10); catch e; [m,ok] = deal(getfield(e,'message'), 1); end")
.unwrap();
let hir = lower(&ast).unwrap();
let vars = execute(&hir).unwrap();
let has_ok = vars
.iter()
.any(|v| matches!(v, runmat_builtins::Value::Num(n) if (*n - 1.0).abs()<1e-9));
assert!(has_ok);
}
#[test]
fn dot_access_identifier_and_message() {
let ast =
parse("A=[1 2]; try; x=A(10); catch e; id=e.identifier; msg=e.message; ok=1; end").unwrap();
let hir = lower(&ast).unwrap();
let vars = execute(&hir).unwrap();
let catch_ran = vars
.iter()
.any(|v| matches!(v, runmat_builtins::Value::Num(n) if (*n - 1.0).abs() < 1e-9));
assert!(catch_ran, "catch block did not run");
let has_id = vars
.iter()
.any(|v| matches!(v, runmat_builtins::Value::String(_)));
let has_msg = vars
.iter()
.any(|v| matches!(v, runmat_builtins::Value::String(_)));
assert!(
has_id,
"err.identifier did not produce a String via dot access"
);
assert!(
has_msg,
"err.message did not produce a String via dot access"
);
}
#[test]
fn catch_index_error_and_continue() {
let ast =
parse("A = [1 2;3 4]; try; x = A(10); catch e; msg = getfield(e,'message'); ok=1; end")
.unwrap();
let hir = lower(&ast).unwrap();
let vars = execute(&hir).unwrap();
assert!(vars
.iter()
.any(|v| matches!(v, runmat_builtins::Value::Num(n) if (*n - 1.0).abs()<1e-9)));
}