use crate::suite::mark_fail;
use mumu::{
parser::interpreter::Interpreter,
parser::types::{FunctionValue, Value},
};
fn call_any_function(
interp: &mut Interpreter,
func: Box<FunctionValue>,
args: Vec<Value>,
) -> Result<Value, String> {
match *func {
FunctionValue::Named(ref name) => {
if let Some(df) = interp.get_dynamic_function(name) {
(df.lock().unwrap())(interp, args)
} else {
mumu::parser::interpreter::apply::apply_function_value(
interp,
Box::new(FunctionValue::Named(name.clone())),
args,
)
}
}
other => {
mumu::parser::interpreter::apply::apply_function_value(
interp,
Box::new(other),
args,
)
}
}
}
pub fn expect_error_bridge_fn(
interp: &mut Interpreter,
mut args: Vec<Value>,
) -> Result<Value, String> {
if args.is_empty() || args.len() > 2 {
return Err(format!(
"test:expect_error => expected 1 or 2 args (function, optional string), got {}",
args.len()
));
}
let user_fn_value = args.remove(0);
let user_fn = match user_fn_value {
Value::Function(fb) => fb,
other => {
mark_fail(&format!(
"test:expect_error => first arg must be a function, got {:?}",
other
));
return Ok(Value::Bool(true));
}
};
let mut expected_substring: Option<String> = None;
if !args.is_empty() {
let maybe_str = args.remove(0);
match maybe_str {
Value::SingleString(s) => expected_substring = Some(s),
Value::StrArray(arr) if arr.len() == 1 => expected_substring = Some(arr[0].clone()),
other => {
mark_fail(&format!(
"test:expect_error => second arg must be a single string, got {:?}",
other
));
return Ok(Value::Bool(true));
}
}
}
match call_any_function(interp, user_fn, vec![]) {
Ok(_val) => {
mark_fail("test:expect_error => function did NOT raise an error");
}
Err(e) => {
if let Some(sub) = expected_substring {
if !e.contains(&sub) {
mark_fail(&format!(
"test:expect_error => error found, but it does not contain {:?}. Full error => {}",
sub, e
));
}
}
}
}
Ok(Value::Bool(true))
}