expand func call tests

Signed-off-by: Ava Hahn <ava@aidanis.online>
This commit is contained in:
Ava Hahn 2023-02-24 16:05:10 -08:00
parent d640c815a8
commit 82854a58f8
Signed by untrusted user who does not match committer: affine
GPG key ID: 3A4645B8CF806069
2 changed files with 118 additions and 21 deletions

View file

@ -149,6 +149,7 @@ impl Args {
Args::Strict(ref arg_types) => { Args::Strict(ref arg_types) => {
let mut idx: usize = 0; let mut idx: usize = 0;
let mut mismatch = false;
let passes = args.circuit(&mut |c: &Ctr| -> bool { let passes = args.circuit(&mut |c: &Ctr| -> bool {
if idx >= arg_types.len() { if idx >= arg_types.len() {
return false; return false;
@ -160,6 +161,7 @@ impl Args {
idx += 1; idx += 1;
return true; return true;
} }
mismatch = true;
false false
}); });
@ -171,16 +173,15 @@ impl Args {
} }
if !passes { if !passes {
if idx < (arg_types.len() - 1) { if mismatch {
return Err(format!( return Err(format!("arg {} expected to be {}", idx+1, arg_types[idx]));
"argument {} is of wrong type (expected {})",
idx + 1,
arg_types[idx]
));
} }
if idx == (arg_types.len() - 1) { if idx > (arg_types.len() - 1) {
return Err("too many arguments".to_string()); return Err("too many arguments".to_string());
} }
if idx < (arg_types.len() - 1) {
return Err("too few arguments".to_string());
}
} }
} }
} }

View file

@ -177,35 +177,131 @@ mod func_tests {
} }
} }
/*
// TODO: These tests need completion!
#[test] #[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] syms.insert(String::from("test_func_in"), test_internal_func);
fn sym_loose_func_call() {
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] #[test]
fn too_many_args() { 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] #[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] #[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)
);
#[test] syms.insert(String::from("test_func_in"), test_internal_func);
fn bad_eval_fn_body() {
}*/ 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);
}
}
} }