use tabulon::{JitError, Tabula, function, register_functions};
#[function]
pub fn mock_min(a: f64, b: f64) -> f64 {
if a < b { a } else { b }
}
#[test]
fn register_after_compile_requires_free_then_succeeds() {
let mut eng = Tabula::new();
let c = eng.compile_ref("1 + 2").unwrap();
assert_eq!(c.eval(&[]).unwrap(), 3.0);
let err = register_functions!(eng, mock_min).unwrap_err();
match err {
JitError::Internal(msg) => {
assert!(
msg.contains("cannot register functions"),
"unexpected message: {}",
msg
);
}
other => panic!("expected Internal error, got: {other:?}"),
}
eng.free_memory();
register_functions!(eng, mock_min).unwrap();
let compiled = eng.compile_ref("mock_min(A, B)").unwrap();
let a = 3.0;
let b = 5.0;
assert_eq!(compiled.eval(&[&a, &b]).unwrap(), 3.0);
}
#[test]
fn clearing_functions_prevents_calls_until_reregistered() {
let mut eng = Tabula::new();
register_functions!(eng, mock_min).unwrap();
let compiled = eng.compile_ref("mock_min(A,B)").unwrap();
let a = 1.0;
let b = 2.0;
assert_eq!(compiled.eval(&[&a, &b]).unwrap(), 1.0);
eng.free_memory();
eng.clear_registered_functions();
match eng.compile_ref("mock_min(1,2)") {
Err(JitError::UnknownFunction { name, arity }) => {
assert_eq!(name, "mock_min");
assert_eq!(arity, 2);
}
Ok(_) => panic!("expected UnknownFunction, got Ok(_)"),
Err(other) => panic!("expected UnknownFunction, got: {other:?}"),
}
eng.free_memory();
register_functions!(eng, min).unwrap();
let compiled2 = eng.compile_ref("min(1,2)").unwrap();
assert_eq!(compiled2.eval(&[]).unwrap(), 1.0);
}
#[test]
fn eval_after_free_returns_invalidated_error() {
let mut eng = Tabula::new();
let compiled = eng.compile_ref("A + B").unwrap();
let a = 1.0;
let b = 2.0;
assert_eq!(compiled.eval(&[&a, &b]).unwrap(), 3.0);
eng.free_memory();
match compiled.eval(&[&a, &b]) {
Err(JitError::Invalidated) => {}
other => panic!("expected Invalidated, got: {:?}", other),
}
}