use decy_hir::{HirParameter, HirType};
use proptest::prelude::*;
fn simple_hir_type() -> impl Strategy<Value = HirType> {
prop_oneof![
Just(HirType::Int),
Just(HirType::Float),
Just(HirType::Double),
Just(HirType::Char),
Just(HirType::Void),
]
}
fn valid_identifier() -> impl Strategy<Value = String> {
"[a-zA-Z_][a-zA-Z0-9_]{0,30}".prop_map(|s| s.to_string())
}
proptest! {
#![proptest_config(ProptestConfig::with_cases(256))]
#[test]
fn prop_function_pointer_creation_never_panics(
param_type in simple_hir_type(),
return_type in simple_hir_type(),
) {
let _ = HirType::FunctionPointer {
param_types: vec![param_type],
return_type: Box::new(return_type),
};
}
#[test]
fn prop_function_pointer_equality(
param_type in simple_hir_type(),
return_type in simple_hir_type(),
) {
let fp1 = HirType::FunctionPointer {
param_types: vec![param_type.clone()],
return_type: Box::new(return_type.clone()),
};
let fp2 = HirType::FunctionPointer {
param_types: vec![param_type],
return_type: Box::new(return_type),
};
prop_assert_eq!(fp1, fp2);
}
#[test]
fn prop_function_pointer_inequality_params(
param1 in simple_hir_type(),
param2 in simple_hir_type(),
return_type in simple_hir_type(),
) {
prop_assume!(param1 != param2);
let fp1 = HirType::FunctionPointer {
param_types: vec![param1],
return_type: Box::new(return_type.clone()),
};
let fp2 = HirType::FunctionPointer {
param_types: vec![param2],
return_type: Box::new(return_type),
};
prop_assert_ne!(fp1, fp2);
}
#[test]
fn prop_function_pointer_inequality_return(
param_type in simple_hir_type(),
return1 in simple_hir_type(),
return2 in simple_hir_type(),
) {
prop_assume!(return1 != return2);
let fp1 = HirType::FunctionPointer {
param_types: vec![param_type.clone()],
return_type: Box::new(return1),
};
let fp2 = HirType::FunctionPointer {
param_types: vec![param_type],
return_type: Box::new(return2),
};
prop_assert_ne!(fp1, fp2);
}
#[test]
fn prop_function_pointer_preserves_param_count(
param_count in 0usize..5,
return_type in simple_hir_type(),
) {
let param_types = vec![HirType::Int; param_count];
let fp = HirType::FunctionPointer {
param_types: param_types.clone(),
return_type: Box::new(return_type),
};
match fp {
HirType::FunctionPointer { param_types: params, .. } => {
prop_assert_eq!(params.len(), param_count);
}
_ => prop_assert!(false, "Expected FunctionPointer type"),
}
}
#[test]
fn prop_function_pointer_preserves_return_type(
return_type in simple_hir_type(),
) {
let fp = HirType::FunctionPointer {
param_types: vec![HirType::Int],
return_type: Box::new(return_type.clone()),
};
match fp {
HirType::FunctionPointer { return_type: ret, .. } => {
prop_assert_eq!(*ret, return_type);
}
_ => prop_assert!(false, "Expected FunctionPointer type"),
}
}
#[test]
fn prop_function_pointer_as_parameter(
param_name in valid_identifier(),
return_type in simple_hir_type(),
) {
let fp_type = HirType::FunctionPointer {
param_types: vec![HirType::Int],
return_type: Box::new(return_type),
};
let param = HirParameter::new(param_name.clone(), fp_type.clone());
prop_assert_eq!(param.name(), param_name.as_str());
prop_assert_eq!(param.param_type(), &fp_type);
}
#[test]
fn prop_function_pointer_void_return(
param_type in simple_hir_type(),
) {
let fp = HirType::FunctionPointer {
param_types: vec![param_type],
return_type: Box::new(HirType::Void),
};
match fp {
HirType::FunctionPointer { return_type, .. } => {
prop_assert_eq!(*return_type, HirType::Void);
}
_ => prop_assert!(false, "Expected FunctionPointer type"),
}
}
#[test]
fn prop_function_pointer_no_params(
return_type in simple_hir_type(),
) {
let fp = HirType::FunctionPointer {
param_types: vec![],
return_type: Box::new(return_type),
};
match fp {
HirType::FunctionPointer { param_types, .. } => {
prop_assert_eq!(param_types.len(), 0);
}
_ => prop_assert!(false, "Expected FunctionPointer type"),
}
}
#[test]
fn prop_function_pointer_clone_preserves(
param_type in simple_hir_type(),
return_type in simple_hir_type(),
) {
let fp1 = HirType::FunctionPointer {
param_types: vec![param_type],
return_type: Box::new(return_type),
};
let fp2 = fp1.clone();
prop_assert_eq!(fp1, fp2);
}
}