use aerocontext_core::geo;
use super::*;
fn p(lat: f64, lon: f64) -> GeoPoint {
GeoPoint { lat, lon }
}
fn dogleg() -> Corridor {
Corridor::around_points(&[p(0.0, 0.0), p(2.0, 0.0), p(3.5, 1.5)], 25.0).unwrap()
}
#[test]
fn construction_validates_inputs() {
assert!(matches!(
Corridor::around_points(&[p(0.0, 0.0)], 25.0),
Err(CorridorError::TooFewPoints { got: 1 })
));
assert!(matches!(
Corridor::around_points(&[p(0.0, 0.0), p(1.0, 0.0)], 0.0),
Err(CorridorError::InvalidWidth { .. })
));
assert!(matches!(
Corridor::around_points(&[p(0.0, 0.0), p(1.0, 0.0)], f64::NAN),
Err(CorridorError::InvalidWidth { .. })
));
}
#[test]
fn every_centerline_point_is_contained() {
let corridor = dogleg();
for vertex in &corridor.centerline {
assert!(corridor.contains(*vertex));
assert!(corridor.distance_to_centerline_nm(*vertex) < 1e-6);
}
}
#[test]
fn probes_abeam_each_leg_classify_by_width() {
let corridor = dogleg();
let inside = geo::destination(p(1.0, 0.0), 90.0, 0.9 * 25.0);
let outside = geo::destination(p(1.0, 0.0), 90.0, 1.1 * 25.0);
assert!(corridor.contains(inside));
assert!(!corridor.contains(outside));
let mid = p(2.75, 0.75);
let leg_bearing = geo::initial_bearing_deg(p(2.0, 0.0), p(3.5, 1.5));
let inside2 = geo::destination(mid, leg_bearing - 90.0, 0.9 * 25.0);
let outside2 = geo::destination(mid, leg_bearing - 90.0, 1.1 * 25.0);
assert!(corridor.contains(inside2));
assert!(!corridor.contains(outside2));
}
#[test]
fn endpoint_caps_round_the_ends() {
let corridor = dogleg();
let behind_inside = geo::destination(p(0.0, 0.0), 180.0, 0.9 * 25.0);
let behind_outside = geo::destination(p(0.0, 0.0), 180.0, 1.1 * 25.0);
assert!(corridor.contains(behind_inside));
assert!(!corridor.contains(behind_outside));
}
#[test]
fn polygon_ring_encloses_the_centerline_bbox() {
let corridor = dogleg();
assert!(
corridor.polygon.len() >= 2 * corridor.centerline.len() + 2 * (CAP_SEGMENTS as usize - 1),
"ring carries both sides plus caps: {}",
corridor.polygon.len()
);
let area = corridor.area();
let (sw, ne) = area.enclosing_bbox().unwrap();
for vertex in &corridor.centerline {
assert!(vertex.lat >= sw.lat && vertex.lat <= ne.lat);
assert!(vertex.lon >= sw.lon && vertex.lon <= ne.lon);
}
assert_eq!(area.contains(p(1.0, 0.1)), Some(true));
}
#[test]
fn hairpin_truth_stays_legwise() {
let corridor = Corridor::around_points(&[p(0.0, 0.0), p(2.0, 0.2), p(0.2, 0.5)], 10.0).unwrap();
let on_first_leg = p(1.0, 0.1);
assert!(corridor.contains(on_first_leg));
let far_away = p(1.0, 3.0);
assert!(!corridor.contains(far_away));
}