use delaunay::prelude::geometry::*;
fn assert_invalid_coordinate<const D: usize>(
coords: [f64; D],
coordinate_index: usize,
coordinate_value: InvalidCoordinateValue,
) {
assert_eq!(
Point::<D>::try_new(coords),
Err(CoordinateValidationError::InvalidCoordinate {
coordinate_index,
coordinate_value,
dimension: D,
})
);
}
#[test]
fn test_point_try_new_rejects_non_finite_coordinates() {
assert_invalid_coordinate([f64::NAN, 0.5, 0.5], 0, InvalidCoordinateValue::Nan);
assert_invalid_coordinate(
[f64::INFINITY, 0.5, 0.5],
0,
InvalidCoordinateValue::PositiveInfinity,
);
assert_invalid_coordinate([f64::NAN, 1.0], 0, InvalidCoordinateValue::Nan);
assert_invalid_coordinate(
[f64::NEG_INFINITY, 1.0],
0,
InvalidCoordinateValue::NegativeInfinity,
);
assert_invalid_coordinate(
[0.0, f64::INFINITY],
1,
InvalidCoordinateValue::PositiveInfinity,
);
}
#[test]
fn test_hypot_distance_with_mixed_problematic_coordinates() {
let point1_coords: [f64; 2] = [f64::NAN, 1.0];
let point2_coords: [f64; 2] = [1.0, f64::INFINITY];
let diff_coords = [
point1_coords[0] - point2_coords[0],
point1_coords[1] - point2_coords[1],
];
let result = hypot(&diff_coords);
assert!(
!result.is_finite(),
"Expected non-finite result from hypot with NaN/infinity coordinates"
);
}
#[test]
fn test_hypot_with_nan_values() {
let result = hypot(&[f64::NAN, 1.0]);
assert!(
result.is_nan(),
"Expected NaN result from hypot with NaN input"
);
}
#[test]
fn test_hypot_with_infinity_values() {
let result = hypot(&[f64::INFINITY, 1.0]);
assert!(
result.is_infinite() || result.is_nan(),
"Expected infinite or NaN result from hypot with infinity input"
);
}
#[test]
fn test_error_message_contains_context() {
let Err(error) = Point::<2>::try_new([f64::NAN, 1.0]) else {
panic!("Expected an error, but got Ok");
};
let error_msg = error.to_string();
assert!(error_msg.contains("NaN") || error_msg.contains("non-finite"));
assert!(error_msg.contains("coordinate") || error_msg.contains("value"));
}
#[test]
fn test_infinity_error_message_contains_context() {
let Err(error) = Point::<2>::try_new([f64::INFINITY, 1.0]) else {
panic!("Expected an error, but got Ok");
};
let error_msg = error.to_string();
assert!(
error_msg.contains("inf")
|| error_msg.contains("infinite")
|| error_msg.contains("non-finite")
);
}
#[test]
fn test_subnormal_values_handling() {
let subnormal = f64::MIN_POSITIVE / 2.0;
let points = vec![
Point::try_new([0.0, 0.0]).expect("finite point coordinates"),
Point::try_new([1.0, 0.0]).expect("finite point coordinates"),
Point::try_new([subnormal, 1.0]).expect("finite point coordinates"), ];
let result = circumcenter(&points);
match result {
Ok(_) => {
}
Err(error) => panic!("Subnormal values should not cause errors: {error:?}"),
}
}
#[test]
fn test_zero_and_negative_zero() {
let points = vec![
Point::try_new([0.0, 0.0]).expect("finite point coordinates"),
Point::try_new([1.0, 0.0]).expect("finite point coordinates"),
Point::try_new([-0.0, 1.0]).expect("finite point coordinates"), ];
let result = circumcenter(&points);
match result {
Ok(_) => {
}
Err(error) => panic!("Zero values should not cause errors: {error:?}"),
}
}
#[test]
fn test_very_large_finite_values() {
let large_value = 1e100; let points = vec![
Point::try_new([0.0, 0.0]).expect("finite point coordinates"),
Point::try_new([1.0, 0.0]).expect("finite point coordinates"),
Point::try_new([large_value, 1.0]).expect("finite point coordinates"), ];
let result = circumcenter(&points);
match result {
Ok(_)
| Err(CircumcenterError::CoordinateConversion {
source: CoordinateConversionError::NonFiniteValue { .. },
}) => {}
Err(other_error) => {
panic!("Unexpected error with large finite values: {other_error:?}");
}
}
}
#[test]
fn test_very_small_finite_values() {
let points = vec![
Point::try_new([0.0, 0.0]).expect("finite point coordinates"),
Point::try_new([1.0, 0.0]).expect("finite point coordinates"),
Point::try_new([f64::MIN_POSITIVE, 1.0]).expect("finite point coordinates"), ];
let result = circumcenter(&points);
match result {
Ok(_) => {
}
Err(error) => panic!("Small finite values should not cause errors: {error:?}"),
}
}