Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 729f6df

Browse files
test: add comprehensive test coverage for improved shortest path algorithms
- Add tests for Zero trait implementations - Add tests for VertexDistance ordering behavior - Add edge case tests for empty graphs and disconnected vertices - Add tests for bucket algorithm with weight limits - Add tests for adaptive algorithm threshold behavior - Add tests for priority queue behavior and visited vertex skipping - Add tests for different numeric types (u32, i64) - Add tests for bucket algorithm with empty buckets - Increase test coverage from 90.31% to target coverage
1 parent 2d4e506 commit 729f6df

File tree

1 file changed

+190
-2
lines changed

1 file changed

+190
-2
lines changed

‎src/graph/improved_shortest_path.rs‎

Lines changed: 190 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -494,7 +494,195 @@ mod tests {
494494
assert_eq!(bucket_result, improved_result);
495495

496496
// Bucket approach should be faster for small integer weights
497-
println!("Bucket duration: {:?}", bucket_duration);
498-
println!("Improved duration: {:?}", improved_duration);
497+
println!("Bucket duration: {bucket_duration:?}");
498+
println!("Improved duration: {improved_duration:?}");
499+
}
500+
501+
#[test]
502+
fn test_zero_trait_implementations() {
503+
use super::Zero;
504+
// Test all Zero trait implementations
505+
assert_eq!(usize::zero(), 0);
506+
assert_eq!(isize::zero(), 0);
507+
assert_eq!(u32::zero(), 0);
508+
assert_eq!(i32::zero(), 0);
509+
assert_eq!(u64::zero(), 0);
510+
assert_eq!(i64::zero(), 0);
511+
assert_eq!(f32::zero(), 0.0);
512+
assert_eq!(f64::zero(), 0.0);
513+
}
514+
515+
#[test]
516+
fn test_vertex_distance_ordering() {
517+
use super::VertexDistance;
518+
519+
// Test ordering behavior for min-heap (reverse ordering)
520+
let vd1 = VertexDistance {
521+
vertex: 1,
522+
distance: 5,
523+
};
524+
let vd2 = VertexDistance {
525+
vertex: 2,
526+
distance: 3,
527+
};
528+
529+
// vd2 should be "greater" (comes first in min-heap) due to smaller distance
530+
assert!(vd2 > vd1);
531+
532+
// Test equality
533+
let vd3 = VertexDistance {
534+
vertex: 1,
535+
distance: 5,
536+
};
537+
assert_eq!(vd1.cmp(&vd3), std::cmp::Ordering::Equal);
538+
539+
// Test same distance, different vertices
540+
let vd4 = VertexDistance {
541+
vertex: 3,
542+
distance: 5,
543+
};
544+
assert_ne!(vd1.cmp(&vd4), std::cmp::Ordering::Equal);
545+
}
546+
547+
#[test]
548+
fn test_improved_shortest_path_edge_cases() {
549+
// Test empty graph
550+
let empty_graph: Graph<i32, i32> = BTreeMap::new();
551+
let result = improved_shortest_path(&empty_graph, 0);
552+
assert_eq!(result.len(), 1);
553+
assert_eq!(result[&0], None);
554+
555+
// Test graph with only one vertex and no edges
556+
let mut single_vertex: Graph<i32, i32> = BTreeMap::new();
557+
single_vertex.insert(0, BTreeMap::new());
558+
let result = improved_shortest_path(&single_vertex, 0);
559+
assert_eq!(result.len(), 1);
560+
assert_eq!(result[&0], None);
561+
562+
// Test disconnected vertices
563+
let mut disconnected: Graph<i32, i32> = BTreeMap::new();
564+
disconnected.insert(0, BTreeMap::new());
565+
disconnected.insert(1, BTreeMap::new());
566+
disconnected.insert(2, BTreeMap::new());
567+
let result = improved_shortest_path(&disconnected, 0);
568+
assert_eq!(result.len(), 1);
569+
assert_eq!(result[&0], None);
570+
}
571+
572+
#[test]
573+
fn test_bucket_shortest_path_edge_cases() {
574+
// Test with max_weight = 0
575+
let mut graph = BTreeMap::new();
576+
add_edge(&mut graph, 0, 1, 0);
577+
578+
let result = bucket_shortest_path(&graph, 0, 0);
579+
assert_eq!(result[&0], None);
580+
assert_eq!(result[&1], Some((0, 0)));
581+
582+
// Test with weights exceeding max_weight
583+
let mut graph = BTreeMap::new();
584+
add_edge(&mut graph, 0, 1, 5);
585+
add_edge(&mut graph, 1, 2, 3);
586+
587+
let result = bucket_shortest_path(&graph, 0, 3);
588+
// Should still work but may not find optimal path for vertex 2
589+
assert_eq!(result[&0], None);
590+
assert_eq!(result[&1], Some((0, 5)));
591+
}
592+
593+
#[test]
594+
fn test_adaptive_shortest_path_edge_cases() {
595+
// Test with empty graph
596+
let empty_graph: Graph<i32, usize> = BTreeMap::new();
597+
let result = adaptive_shortest_path(&empty_graph, 0, 10);
598+
assert_eq!(result.len(), 1);
599+
assert_eq!(result[&0], None);
600+
601+
// Test threshold behavior - should choose bucket for small weights
602+
let mut small_weights = BTreeMap::new();
603+
add_edge(&mut small_weights, 0, 1, 2);
604+
add_edge(&mut small_weights, 1, 2, 1);
605+
606+
let result = adaptive_shortest_path(&small_weights, 0, 5);
607+
assert_eq!(result[&0], None);
608+
assert_eq!(result[&1], Some((0, 2)));
609+
assert_eq!(result[&2], Some((1, 3)));
610+
611+
// Test threshold behavior - should choose improved for large weights
612+
let mut large_weights = BTreeMap::new();
613+
add_edge(&mut large_weights, 0, 1, 10);
614+
add_edge(&mut large_weights, 1, 2, 15);
615+
616+
let result = adaptive_shortest_path(&large_weights, 0, 5);
617+
assert_eq!(result[&0], None);
618+
assert_eq!(result[&1], Some((0, 10)));
619+
assert_eq!(result[&2], Some((1, 25)));
620+
}
621+
622+
#[test]
623+
fn test_priority_queue_behavior() {
624+
// Test that priority queue correctly handles duplicate vertices
625+
let mut graph = BTreeMap::new();
626+
add_edge(&mut graph, 0, 1, 5);
627+
add_edge(&mut graph, 0, 2, 3);
628+
add_edge(&mut graph, 2, 1, 1); // This creates a shorter path to 1
629+
630+
let result = improved_shortest_path(&graph, 0);
631+
632+
// Should find shortest path: 0 -> 2 -> 1 (distance 4)
633+
assert_eq!(result[&0], None);
634+
assert_eq!(result[&2], Some((0, 3)));
635+
assert_eq!(result[&1].unwrap().1, 4); // Distance should be 4, not 5
636+
}
637+
638+
#[test]
639+
fn test_bucket_algorithm_empty_buckets() {
640+
// Test bucket algorithm with gaps in distances
641+
let mut graph = BTreeMap::new();
642+
add_edge(&mut graph, 0, 1, 2);
643+
add_edge(&mut graph, 1, 2, 5); // Creates gap in bucket indices
644+
645+
let result = bucket_shortest_path(&graph, 0, 10);
646+
647+
assert_eq!(result[&0], None);
648+
assert_eq!(result[&1], Some((0, 2)));
649+
assert_eq!(result[&2], Some((1, 7)));
650+
}
651+
652+
#[test]
653+
fn test_visited_vertex_skipping() {
654+
// Test that already visited vertices are properly skipped
655+
let mut graph = BTreeMap::new();
656+
add_edge(&mut graph, 0, 1, 1);
657+
add_edge(&mut graph, 0, 2, 2);
658+
add_edge(&mut graph, 1, 2, 1); // Creates multiple paths to vertex 2
659+
660+
let result = improved_shortest_path(&graph, 0);
661+
662+
// Should find optimal path: 0 -> 1 -> 2 (distance 2)
663+
assert_eq!(result[&0], None);
664+
assert_eq!(result[&1], Some((0, 1)));
665+
assert_eq!(result[&2].unwrap().1, 2);
666+
}
667+
668+
#[test]
669+
fn test_different_numeric_types() {
670+
// Test with different numeric types to ensure trait implementations work
671+
let mut graph_u32: Graph<u32, u32> = BTreeMap::new();
672+
graph_u32.insert(0, BTreeMap::new());
673+
graph_u32.insert(1, BTreeMap::new());
674+
graph_u32.entry(0).or_default().insert(1, 5);
675+
676+
let result_u32 = improved_shortest_path(&graph_u32, 0);
677+
assert_eq!(result_u32[&1], Some((0, 5)));
678+
679+
// Test with i64 (which implements Ord)
680+
let mut graph_i64: Graph<i64, i64> = BTreeMap::new();
681+
graph_i64.insert(0, BTreeMap::new());
682+
graph_i64.insert(1, BTreeMap::new());
683+
graph_i64.entry(0).or_default().insert(1, 314);
684+
685+
let result_i64 = improved_shortest_path(&graph_i64, 0);
686+
assert_eq!(result_i64[&1], Some((0, 314)));
499687
}
500688
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /