pub(crate) mod common; use common::assert_error_margin; use fasteval3::ez_eval; #[test] fn empty() { let mut ns = fasteval3::EmptyNamespace; let val = ez_eval("1 + 1", &mut ns).unwrap(); assert_error_margin(val, 2.0); } #[test] fn str_to_f64() { { let mut ns = fasteval3::StringToF64Namespace::new(); ns.insert(String::from("a"), 1.11); ns.insert(String::from("b"), 2.22); let val = ez_eval("a + b + 1", &mut ns).unwrap(); assert_error_margin(val, 4.33); } { let mut ns = fasteval3::StrToF64Namespace::new(); ns.insert("a", 1.11); ns.insert("b", 2.22); let val = ez_eval("a + b + 1", &mut ns).unwrap(); assert_error_margin(val, 4.33); } } #[test] fn str_to_cb() { { let mut ns = fasteval3::StringToCallbackNamespace::new(); ns.insert(String::from("a"), Box::new(|args| args[0])); ns.insert(String::from("b"), Box::new(|args| args[0] * 2.0)); let val = ez_eval("a(1.11) + b(1.11) + 1", &mut ns).unwrap(); assert_error_margin(val, 4.33); } { let mut ns = fasteval3::StrToCallbackNamespace::new(); ns.insert("a", Box::new(|args| args[0])); ns.insert("b", Box::new(|args| args[0] * 2.0)); let val = ez_eval("a(1.11) + b(1.11) + 1", &mut ns).unwrap(); assert_error_margin(val, 4.33); } } #[test] fn layered_str_to_f64() { let mut ns = fasteval3::LayeredStringToF64Namespace::new(); let mut layer0 = fasteval3::StringToF64Namespace::new(); layer0.insert(String::from("a"), 1.11); layer0.insert(String::from("b"), 2.22); ns.push(layer0); let val = ez_eval("a + b + 1", &mut ns).unwrap(); assert_error_margin(val, 4.33); let mut layer1 = fasteval3::StringToF64Namespace::new(); layer1.insert(String::from("a"), 11.11); ns.push(layer1); let val = ez_eval("a + b + 1", &mut ns).unwrap(); assert_error_margin(val, 14.33); ns.pop(); let val = ez_eval("a + b + 1", &mut ns).unwrap(); assert_error_margin(val, 4.33); } #[test] fn cb() { let mut ns = |name: &str, args: Vec| match name { "a" => Some(1.11), "b" => Some(2.22), "len" => Some(args.len() as f64), _ => None, }; let val = ez_eval("a + b + 1", &mut ns).unwrap(); assert_error_margin(val, 4.33); } #[test] fn cached_cb() { let mut ns = fasteval3::CachedCallbackNamespace::new(|name: &str, args: Vec| match name { "a" => { eprintln!("cached_cb: a: This should only be printed once."); Some(1.11) } "b" => Some(2.22), "len" => Some(args.len() as f64), _ => None, }); let val = ez_eval("a + b + 1", &mut ns).unwrap(); assert_error_margin(val, 4.33); ez_eval("a + b + 1", &mut ns).unwrap(); ez_eval("a + b + 1", &mut ns).unwrap(); ez_eval("a + b + 1", &mut ns).unwrap(); ez_eval("a + b + 1", &mut ns).unwrap(); } #[test] fn custom_vector_funcs() { let vecs_cell = std::cell::RefCell::new(Vec::>::new()); let mut ns = fasteval3::StrToCallbackNamespace::new(); ns.insert("x", Box::new(|_args| 2.0)); ns.insert( "vec_store", Box::new(|args| { let mut vecs = vecs_cell.borrow_mut(); let index = vecs.len(); vecs.push(args); index as f64 }), ); ns.insert( "vec_sum", Box::new(|args| { if let Some(index) = args.first() { if let Some(v) = vecs_cell.borrow().get(*index as usize) { return v.iter().sum(); } } std::f64::NAN }), ); let val = ez_eval("vec_sum(vec_store(1.1, x, 3.3)) + vec_sum(0)", &mut ns).unwrap(); assert_error_margin(val, 12.8); }