#![allow(clippy::cyclomatic_complexity)]
use crate::error::OverError;
use crate::types::Type;
use crate::value::Value;
macro_rules! test_eq {
($left:expr, $right:expr) => {{
if $left != $right {
panic!(format!(
"Left did not equal right.\nLeft: {}\nRight: {}\n",
$left, $right
));
}
}};
}
#[test]
fn set_and_get() {
let obj = obj! {
"null" => Value::Null,
"bool" => true,
"int" => -5,
"frac" => frac!(1, 1),
"char" => 'x',
"str1" => "hello",
"str2" => "yo",
"arr" => arr![-5, 0, 1],
};
test_eq!(obj.get("null").unwrap(), Value::Null);
assert!(obj.get("null").unwrap().is_null());
test_eq!(obj.get_bool("bool").unwrap(), true);
assert_eq!(obj.get_bool("bool"), Ok(true));
assert_eq!(obj.get_int("int"), Ok((-5).into()));
assert_eq!(obj.get_frac("frac"), Ok(frac!(1, 1)));
assert_eq!(obj.get_char("char"), Ok('x'));
let yo = String::from("yo");
test_eq!(obj.get("str1").unwrap(), "hello");
test_eq!(obj.get("str2").unwrap(), yo);
test_eq!(obj.get("arr").unwrap(), arr![-5, 0, 1]);
let res = obj.get("bool").unwrap().get_str();
assert_eq!(res, Err(OverError::TypeMismatch(Type::Str, Type::Bool)));
assert_eq!(obj.get(""), None);
assert_eq!(obj.get("cool"), None);
}
#[test]
fn parents() {
let def2 = obj! {
"bool2" => true,
"bool3" => true
};
let def1 = obj! {
"^" => def2.clone(),
"bool1" => true,
"bool2" => false,
"test2" => "bye",
};
let obj = obj! {
"^" => def1.clone(),
"bool1" => true,
"test1" => "hi",
};
assert_ne!(obj, def1);
assert_ne!(def1, def2);
assert_ne!(obj, def2);
let obj2 = obj! { "^" => def1.clone() };
assert_ne!(obj, obj2);
let obj2 = obj! { "^" => def1.clone(), "test1" => "hi", "bool1" => true };
test_eq!(obj, obj2);
let (v, o) = obj.get_with_source("bool1").unwrap();
test_eq!(v, true);
assert!(o.ptr_eq(&obj));
let (v, o) = obj.get_with_source("bool2").unwrap();
test_eq!(v, false);
assert!(o.ptr_eq(&def1));
let (v, o) = obj.get_with_source("bool3").unwrap();
test_eq!(v, true);
assert!(o.ptr_eq(&def2));
test_eq!(obj.get("test1").unwrap(), "hi");
test_eq!(obj.get("test2").unwrap(), "bye");
}
#[test]
fn types() {
let obj = obj! {
"bool" => true,
"str" => "",
"arr_char" => arr!['w', 'o', 'w'],
"arr_arr" => try_arr![arr![], arr![true, false]].unwrap(),
"tup" => tup!('!', tup!(-1), try_arr!["test", "heya"].unwrap()),
};
let null = Value::Null;
test_eq!(null.get_type(), Type::Null);
test_eq!(obj.get("bool").unwrap().get_type(), Type::Bool);
test_eq!(obj.get("str").unwrap().get_type(), Type::Str);
test_eq!(
obj.get("arr_char").unwrap().get_type(),
Type::Arr(Box::new(Type::Char))
);
test_eq!(
obj.get("arr_arr").unwrap().get_type(),
Type::Arr(Box::new(Type::Arr(Box::new(Type::Bool))))
);
assert_ne!(
Type::Arr(Box::new(Type::Arr(Box::new(Type::Int)))),
Type::Arr(Box::new(Type::Int))
);
let tup_type = Type::Tup(vec![
Type::Char,
Type::Tup(vec![Type::Int]),
Type::Arr(Box::new(Type::Str)),
]);
test_eq!(obj.get("tup").unwrap().get_type(), tup_type);
assert_ne!(obj.get("bool").unwrap().get_type(), null.get_type());
assert_ne!(
obj.get("bool").unwrap().get_type(),
obj.get("str").unwrap().get_type()
)
}