@@ -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