From 82854a58f85957f99bdd9ffb6d85903e041912f5 Mon Sep 17 00:00:00 2001 From: Ava Hahn Date: Fri, 24 Feb 2023 16:05:10 -0800 Subject: [PATCH] expand func call tests Signed-off-by: Ava Hahn --- src/sym.rs | 15 +++--- tests/test_func.rs | 124 ++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 118 insertions(+), 21 deletions(-) diff --git a/src/sym.rs b/src/sym.rs index fa0ae62..d62fc6a 100644 --- a/src/sym.rs +++ b/src/sym.rs @@ -149,6 +149,7 @@ impl Args { Args::Strict(ref arg_types) => { let mut idx: usize = 0; + let mut mismatch = false; let passes = args.circuit(&mut |c: &Ctr| -> bool { if idx >= arg_types.len() { return false; @@ -160,6 +161,7 @@ impl Args { idx += 1; return true; } + mismatch = true; false }); @@ -171,16 +173,15 @@ impl Args { } if !passes { - if idx < (arg_types.len() - 1) { - return Err(format!( - "argument {} is of wrong type (expected {})", - idx + 1, - arg_types[idx] - )); + if mismatch { + return Err(format!("arg {} expected to be {}", idx+1, arg_types[idx])); } - if idx == (arg_types.len() - 1) { + if idx > (arg_types.len() - 1) { return Err("too many arguments".to_string()); } + if idx < (arg_types.len() - 1) { + return Err("too few arguments".to_string()); + } } } } diff --git a/tests/test_func.rs b/tests/test_func.rs index 52204af..6f18029 100644 --- a/tests/test_func.rs +++ b/tests/test_func.rs @@ -177,35 +177,131 @@ mod func_tests { } } - /* - // TODO: These tests need completion! #[test] - fn eval_lazy_func_call() { + fn arg_type_mismatch() { + let mut syms = SymTable::new(); + let test_internal_func: Symbol = Symbol { + name: String::from("test_func_in"), + conditional_branches: false, + args: Args::Strict(vec![Type::Bool]), + value: ValueType::Internal(Box::new( + |a: &Seg, _: &mut SymTable| -> Ctr { + let inner = a; + let mut is_bool = false; + if let Ctr::Bool(_) = *inner.car { + is_bool = true; + } + Ctr::Bool(is_bool) + }, + )), + }; + let args = Seg::from( + Box::new(Ctr::Integer(1)), + Box::new(Ctr::None) + ); - } - - #[test] - fn sym_loose_func_call() { + syms.insert(String::from("test_func_in"), test_internal_func); + if let Err(s) = syms.call_symbol(&"test_func_in".to_string(), &args, true) { + assert_eq!(s, "failure to call test_func_in: arg 1 expected to be bool"); + } else { + print!("call to function succeeded (shouldnt have)"); + assert!(false); + } } #[test] fn too_many_args() { + let mut syms = SymTable::new(); + match lex(&"((input))".to_string()) { + Err(e) => panic!("{}", e), + Ok(finner) => { + let test_external_func: Symbol = Symbol { + name: String::from("echo"), + conditional_branches: false, + args: Args::Lazy(1), + value: ValueType::FuncForm(UserFn{ + arg_syms: vec!["input".to_string()], + ast: finner, + }), + }; + let args = Seg::from( + Box::new(Ctr::String("test".to_string())), + Box::new(Ctr::Seg(Seg::from_mono(Box::new(Ctr::Integer(1))))) + ); + + syms.insert(String::from("test_func_in"), test_external_func); + + if let Err(s) = syms.call_symbol(&"test_func_in".to_string(), &args, true) { + assert_eq!(s, "failure to call echo: expected 1 args. Got 2."); + } else { + print!("call to function succeeded (shouldnt have)"); + assert!(false); + } + } + } } #[test] - fn not_enough_args() { + fn too_few_args() { + let mut syms = SymTable::new(); + match lex(&"((input))".to_string()) { + Err(e) => panic!("{}", e), + Ok(finner) => { + let test_external_func: Symbol = Symbol { + name: String::from("echo"), + conditional_branches: false, + args: Args::Lazy(1), + value: ValueType::FuncForm(UserFn{ + arg_syms: vec!["input".to_string()], + ast: finner, + }), + }; + let args = Seg::new(); + syms.insert(String::from("test_func_in"), test_external_func); + + if let Err(s) = syms.call_symbol(&"test_func_in".to_string(), &args, true) { + assert_eq!(s, "failure to call echo: expected 1 args. Got 2."); + } else { + print!("call to function succeeded (shouldnt have)"); + assert!(false); + } + } + } } #[test] - fn bad_eval_arg() { + fn arg_cant_eval() { + let mut syms = SymTable::new(); + let test_internal_func: Symbol = Symbol { + name: String::from("test_func_in"), + conditional_branches: false, + args: Args::Strict(vec![Type::Bool]), + value: ValueType::Internal(Box::new( + |a: &Seg, _: &mut SymTable| -> Ctr { + let inner = a; + let mut is_bool = false; + if let Ctr::Bool(_) = *inner.car { + is_bool = true; + } + Ctr::Bool(is_bool) + }, + )), + }; + let args = Seg::from( + Box::new(Ctr::Symbol("undefined-symbol".to_string())), + Box::new(Ctr::None) + ); + syms.insert(String::from("test_func_in"), test_internal_func); + + if let Err(s) = syms.call_symbol(&"test_func_in".to_string(), &args, true) { + assert_eq!(s, "failure to call echo: expected 1 args. Got 2."); + } else { + print!("call to function succeeded (shouldnt have)"); + assert!(false); + } } - - #[test] - fn bad_eval_fn_body() { - - }*/ }