use crate::errors::InputError;
use crate::Float;
use float_cmp::assert_approx_eq;
use std::mem::discriminant;
#[derive(Copy, Clone, Debug, Default)]
pub struct Argument {
pub name: &'static str,
pub def_val: Float,
pub range: [Float; 2],
}
#[allow(dead_code)]
pub fn test_with_2args(
tested_function: &dyn Fn(Float, Float) -> Result<Float, InputError>,
arg1: Argument,
arg2: Argument,
expected_result: Float,
) -> bool {
let result = tested_function(arg1.def_val, arg2.def_val).unwrap();
assert_approx_eq!(Float, result, expected_result, epsilon = 0.01);
let results = vec![
tested_function(0.0, arg2.def_val),
tested_function(arg1.def_val, 0.0),
tested_function(0.0, 0.0),
];
for result in results {
if result.is_ok() {
assert!(result.unwrap().is_finite());
}
}
for arg1_itr in 0..=100 {
for arg2_itr in 0..=100 {
let arg1_tmp =
(((arg1.range[1] - arg1.range[0]) / 100.0) * arg1_itr as Float) + arg1.range[0];
let arg2_tmp =
(((arg2.range[1] - arg2.range[0]) / 100.0) * arg2_itr as Float) + arg2.range[0];
let result = tested_function(arg1_tmp, arg2_tmp);
if result.is_err() {
assert!(
discriminant(&InputError::IncorrectArgumentSet(String::from("")))
== discriminant(&result.unwrap_err())
);
} else {
assert!(result.unwrap().is_finite());
}
}
}
let expected = InputError::OutOfRange(String::from(arg1.name));
let result = tested_function(arg1.range[0] - 0.1, arg2.def_val).unwrap_err();
assert_eq!(result, expected);
let result = tested_function(arg1.range[1] + 0.1, arg2.def_val).unwrap_err();
assert_eq!(result, expected);
let expected = InputError::OutOfRange(String::from(arg2.name));
let result = tested_function(arg1.def_val, arg2.range[0] - 0.1).unwrap_err();
assert_eq!(result, expected);
let result = tested_function(arg1.def_val, arg2.range[1] + 0.1).unwrap_err();
assert_eq!(result, expected);
true
}
#[allow(dead_code)]
pub fn test_with_1arg(
tested_function: &dyn Fn(Float) -> Result<Float, InputError>,
arg1: Argument,
expected_result: Float,
) -> bool {
let result = tested_function(arg1.def_val).unwrap();
assert_approx_eq!(Float, result, expected_result, epsilon = 0.01);
let results = vec![tested_function(0.0)];
for result in results {
if result.is_ok() {
assert!(result.unwrap().is_finite());
}
}
for arg1_itr in 0..=100 {
let arg1_tmp =
(((arg1.range[1] - arg1.range[0]) / 100.0) * arg1_itr as Float) + arg1.range[0];
let result = tested_function(arg1_tmp);
if result.is_err() {
assert!(
discriminant(&InputError::IncorrectArgumentSet(String::from("")))
== discriminant(&result.unwrap_err())
);
} else {
assert!(result.unwrap().is_finite());
}
}
let expected = InputError::OutOfRange(String::from(arg1.name));
let result = tested_function(arg1.range[0] - 0.1).unwrap_err();
assert_eq!(result, expected);
let result = tested_function(arg1.range[1] + 0.1).unwrap_err();
assert_eq!(result, expected);
true
}
#[allow(dead_code)]
pub fn test_with_3args(
tested_function: &dyn Fn(Float, Float, Float) -> Result<Float, InputError>,
arg1: Argument,
arg2: Argument,
arg3: Argument,
expected_result: Float,
) -> bool {
let result = tested_function(arg1.def_val, arg2.def_val, arg3.def_val).unwrap();
assert_approx_eq!(Float, result, expected_result, epsilon = 0.01);
let results = vec![
tested_function(0.0, arg2.def_val, arg3.def_val),
tested_function(arg1.def_val, 0.0, arg3.def_val),
tested_function(arg1.def_val, arg2.def_val, 0.0),
tested_function(0.0, 0.0, 0.0),
];
for result in results {
if result.is_ok() {
assert!(result.unwrap().is_finite());
}
}
for arg1_itr in 0..=100 {
for arg2_itr in 0..=100 {
for arg3_itr in 0..=100 {
let arg1_tmp =
(((arg1.range[1] - arg1.range[0]) / 100.0) * arg1_itr as Float) + arg1.range[0];
let arg2_tmp =
(((arg2.range[1] - arg2.range[0]) / 100.0) * arg2_itr as Float) + arg2.range[0];
let arg3_tmp =
(((arg3.range[1] - arg3.range[0]) / 100.0) * arg3_itr as Float) + arg3.range[0];
let result = tested_function(arg1_tmp, arg2_tmp, arg3_tmp);
if result.is_err() {
assert!(
discriminant(&InputError::IncorrectArgumentSet(String::from("")))
== discriminant(&result.unwrap_err())
);
} else {
println!("{} {} {} {:?}", arg1_tmp, arg2_tmp, arg3_tmp, result);
assert!(result.unwrap().is_finite());
}
}
}
}
let expected = InputError::OutOfRange(String::from(arg1.name));
let result = tested_function(arg1.range[0] - 0.1, arg2.def_val, arg3.def_val).unwrap_err();
assert_eq!(result, expected);
let result = tested_function(arg1.range[1] + 0.1, arg2.def_val, arg3.def_val).unwrap_err();
assert_eq!(result, expected);
let expected = InputError::OutOfRange(String::from(arg2.name));
let result = tested_function(arg1.def_val, arg2.range[0] - 0.1, arg3.def_val).unwrap_err();
assert_eq!(result, expected);
let result = tested_function(arg1.def_val, arg2.range[1] + 0.1, arg3.def_val).unwrap_err();
assert_eq!(result, expected);
let expected = InputError::OutOfRange(String::from(arg3.name));
let result = tested_function(arg1.def_val, arg2.def_val, arg3.range[0] - 0.1).unwrap_err();
assert_eq!(result, expected);
let result = tested_function(arg1.def_val, arg2.def_val, arg3.range[1] + 0.1).unwrap_err();
assert_eq!(result, expected);
true
}