#[cfg(test)]
mod tests {
use petgraph::graph::DiGraph;
use crate::graph::{XmlNode, XmlTag, XmlWay, XmlNodeRef};
use crate::utils::{calculate_distance, calculate_travel_time};
use crate::overpass::bbox_from_point;
fn make_node(id: i64, lat: f64, lon: f64) -> XmlNode {
XmlNode { id, lat, lon, tags: vec![], geohash: None }
}
fn make_way(id: i64, tags: Vec<(&str, &str)>) -> XmlWay {
XmlWay {
id,
nodes: vec![],
tags: tags.into_iter().map(|(k, v)| XmlTag {
key: k.to_string(),
value: v.to_string(),
}).collect(),
length: 100.0,
speed_kph: 50.0,
walk_travel_time: 72.0,
bike_travel_time: 24.0,
drive_travel_time: 7.2,
}
}
#[test]
fn test_distance_same_point() {
let d = calculate_distance(48.0, 11.0, 48.0, 11.0);
assert_eq!(d, 0.0);
}
#[test]
fn test_distance_known_value() {
let d = calculate_distance(48.0, 11.0, 48.009, 11.0);
assert!((d - 1000.0).abs() < 10.0, "Expected ~1000m, got {}", d);
}
#[test]
fn test_distance_is_symmetric() {
let d1 = calculate_distance(48.0, 11.0, 52.0, 13.0);
let d2 = calculate_distance(52.0, 13.0, 48.0, 11.0);
assert!((d1 - d2).abs() < 1e-6);
}
#[test]
fn test_travel_time_basic() {
let t = calculate_travel_time(1000.0, 36.0);
assert!((t - 100.0).abs() < 1e-6, "Expected 100s, got {}", t);
}
#[test]
fn test_travel_time_walking() {
let t = calculate_travel_time(500.0, 5.0);
assert!((t - 360.0).abs() < 1e-6);
}
#[test]
fn test_bbox_is_symmetric() {
let bbox = bbox_from_point(48.0, 11.0, 1000.0);
let parts: Vec<f64> = bbox.split(',').map(|s| s.parse().unwrap()).collect();
let (south, west, north, east) = (parts[0], parts[1], parts[2], parts[3]);
assert!((48.0 - south - (north - 48.0)).abs() < 1e-6);
assert!((11.0 - west - (east - 11.0)).abs() < 1e-6);
}
#[test]
fn test_bbox_larger_dist_gives_larger_box() {
let small = bbox_from_point(48.0, 11.0, 1_000.0);
let large = bbox_from_point(48.0, 11.0, 10_000.0);
let small_parts: Vec<f64> = small.split(',').map(|s| s.parse().unwrap()).collect();
let large_parts: Vec<f64> = large.split(',').map(|s| s.parse().unwrap()).collect();
assert!(large_parts[2] > small_parts[2]);
}
#[test]
fn test_graph_respects_maxspeed_tag() {
let nodes = vec![make_node(1, 0.0, 0.0), make_node(2, 0.001, 0.0)];
let way = XmlWay {
id: 1,
nodes: vec![
XmlNodeRef { node_id: 1 },
XmlNodeRef { node_id: 2 },
],
tags: vec![
XmlTag { key: "highway".to_string(), value: "residential".to_string() },
XmlTag { key: "maxspeed".to_string(), value: "30".to_string() },
],
length: 0.0,
speed_kph: 0.0,
walk_travel_time: 0.0,
bike_travel_time: 0.0,
drive_travel_time: 0.0,
};
let graph = crate::graph::create_graph(vec![nodes[0].clone(), nodes[1].clone()], vec![way], true, false);
let speed = graph.edge_weights().next().unwrap().speed_kph;
assert_eq!(speed, 30.0);
}
#[test]
fn test_oneway_produces_single_edge() {
let nodes = vec![make_node(1, 0.0, 0.0), make_node(2, 0.001, 0.0)];
let way = XmlWay {
id: 1,
nodes: vec![XmlNodeRef { node_id: 1 }, XmlNodeRef { node_id: 2 }],
tags: vec![
XmlTag { key: "highway".to_string(), value: "residential".to_string() },
XmlTag { key: "oneway".to_string(), value: "yes".to_string() },
],
length: 0.0, speed_kph: 0.0,
walk_travel_time: 0.0, bike_travel_time: 0.0, drive_travel_time: 0.0,
};
let graph = crate::graph::create_graph(vec![nodes[0].clone(), nodes[1].clone()], vec![way], true, false);
assert_eq!(graph.edge_count(), 1);
}
#[test]
fn test_bidirectional_produces_two_edges() {
let nodes = vec![make_node(1, 0.0, 0.0), make_node(2, 0.001, 0.0)];
let way = XmlWay {
id: 1,
nodes: vec![XmlNodeRef { node_id: 1 }, XmlNodeRef { node_id: 2 }],
tags: vec![
XmlTag { key: "highway".to_string(), value: "residential".to_string() },
],
length: 0.0, speed_kph: 0.0,
walk_travel_time: 0.0, bike_travel_time: 0.0, drive_travel_time: 0.0,
};
let graph = crate::graph::create_graph(vec![nodes[0].clone(), nodes[1].clone()], vec![way], true, false);
assert_eq!(graph.edge_count(), 2);
}
#[test]
fn test_deduplicate_keeps_fastest_edge() {
let mut graph = DiGraph::new();
let a = graph.add_node(make_node(1, 0.0, 0.0));
let b = graph.add_node(make_node(2, 0.001, 0.0));
let mut slow = make_way(1, vec![]);
slow.drive_travel_time = 100.0;
let mut fast = make_way(2, vec![]);
fast.drive_travel_time = 50.0;
graph.add_edge(a, b, slow);
graph.add_edge(a, b, fast);
assert_eq!(graph.edge_count(), 2); let deduped = crate::simplify::simplify_graph(&graph);
let edge_count = deduped.edge_count();
assert!(edge_count <= 1, "Expected at most 1 edge, got {}", edge_count);
}
#[test]
fn test_nearest_node_finds_closest() {
let mut graph = DiGraph::new();
graph.add_node(make_node(1, 48.0, 11.0));
graph.add_node(make_node(2, 52.0, 13.0)); let sg = crate::graph::SpatialGraph::new(graph);
let idx = sg.nearest_node(48.001, 11.001).unwrap();
let node = &sg.graph[idx];
assert_eq!(node.id, 1);
}
}