@@ -985,3 +985,129 @@ mod process_changes {
985985 ) ;
986986 }
987987}
988+
989+ mod blame_ranges {
990+ use crate :: { BlameRanges , Error } ;
991+
992+ #[ test]
993+ fn create_with_invalid_range ( ) {
994+ let ranges = BlameRanges :: from_one_based_inclusive_range ( 0 ..=10 ) ;
995+
996+ assert ! ( matches!( ranges, Err ( Error :: InvalidOneBasedLineRange ) ) ) ;
997+ }
998+
999+ #[ test]
1000+ fn create_from_single_range ( ) {
1001+ let ranges = BlameRanges :: from_one_based_inclusive_range ( 20 ..=40 ) . unwrap ( ) ;
1002+
1003+ assert_eq ! ( ranges. to_zero_based_exclusive_ranges( 100 ) , vec![ 19 ..40 ] ) ;
1004+ }
1005+
1006+ #[ test]
1007+ fn create_from_multiple_ranges ( ) {
1008+ let ranges = BlameRanges :: from_one_based_inclusive_ranges ( vec ! [ 1 ..=4 , 10 ..=14 ] ) . unwrap ( ) ;
1009+
1010+ assert_eq ! ( ranges. to_zero_based_exclusive_ranges( 100 ) , vec![ 0 ..4 , 9 ..14 ] ) ;
1011+ }
1012+
1013+ #[ test]
1014+ fn create_with_empty_ranges ( ) {
1015+ let ranges = BlameRanges :: from_one_based_inclusive_ranges ( vec ! [ ] ) . unwrap ( ) ;
1016+
1017+ assert_eq ! ( ranges. to_zero_based_exclusive_ranges( 100 ) , vec![ 0 ..100 ] ) ;
1018+ }
1019+
1020+ #[ test]
1021+ fn add_range_merges_overlapping ( ) {
1022+ let mut ranges = BlameRanges :: from_one_based_inclusive_range ( 1 ..=5 ) . unwrap ( ) ;
1023+ ranges. add_one_based_inclusive_range ( 3 ..=7 ) . unwrap ( ) ;
1024+
1025+ assert_eq ! ( ranges. to_zero_based_exclusive_ranges( 100 ) , vec![ 0 ..7 ] ) ;
1026+ }
1027+
1028+ #[ test]
1029+ fn add_range_merges_overlapping_both ( ) {
1030+ let mut ranges = BlameRanges :: from_one_based_inclusive_range ( 1 ..=3 ) . unwrap ( ) ;
1031+ ranges. add_one_based_inclusive_range ( 5 ..=7 ) . unwrap ( ) ;
1032+ ranges. add_one_based_inclusive_range ( 2 ..=6 ) . unwrap ( ) ;
1033+
1034+ assert_eq ! ( ranges. to_zero_based_exclusive_ranges( 100 ) , vec![ 0 ..7 ] ) ;
1035+ }
1036+
1037+ #[ test]
1038+ fn add_range_non_sorted ( ) {
1039+ let mut ranges = BlameRanges :: from_one_based_inclusive_range ( 5 ..=7 ) . unwrap ( ) ;
1040+ ranges. add_one_based_inclusive_range ( 1 ..=3 ) . unwrap ( ) ;
1041+
1042+ assert_eq ! ( ranges. to_zero_based_exclusive_ranges( 100 ) , vec![ 0 ..3 , 4 ..7 ] ) ;
1043+ }
1044+
1045+ #[ test]
1046+ fn add_range_merges_adjacent ( ) {
1047+ let mut ranges = BlameRanges :: from_one_based_inclusive_range ( 1 ..=5 ) . unwrap ( ) ;
1048+ ranges. add_one_based_inclusive_range ( 6 ..=10 ) . unwrap ( ) ;
1049+
1050+ assert_eq ! ( ranges. to_zero_based_exclusive_ranges( 100 ) , vec![ 0 ..10 ] ) ;
1051+ }
1052+
1053+ #[ test]
1054+ fn non_sorted_ranges ( ) {
1055+ let ranges = BlameRanges :: from_one_based_inclusive_ranges ( vec ! [ 10 ..=15 , 1 ..=5 ] ) . unwrap ( ) ;
1056+
1057+ assert_eq ! ( ranges. to_zero_based_exclusive_ranges( 100 ) , vec![ 0 ..5 , 9 ..15 ] ) ;
1058+ }
1059+
1060+ #[ test]
1061+ fn convert_to_zero_based_exclusive ( ) {
1062+ let ranges = BlameRanges :: from_one_based_inclusive_ranges ( vec ! [ 1 ..=5 , 10 ..=15 ] ) . unwrap ( ) ;
1063+
1064+ assert_eq ! ( ranges. to_zero_based_exclusive_ranges( 100 ) , vec![ 0 ..5 , 9 ..15 ] ) ;
1065+ }
1066+
1067+ #[ test]
1068+ fn convert_full_file_to_zero_based ( ) {
1069+ let ranges = BlameRanges :: WholeFile ;
1070+
1071+ assert_eq ! ( ranges. to_zero_based_exclusive_ranges( 100 ) , vec![ 0 ..100 ] ) ;
1072+ }
1073+
1074+ #[ test]
1075+ fn adding_a_range_turns_whole_file_into_partial_file ( ) {
1076+ let mut ranges = BlameRanges :: default ( ) ;
1077+
1078+ ranges. add_one_based_inclusive_range ( 1 ..=10 ) . unwrap ( ) ;
1079+
1080+ assert_eq ! ( ranges. to_zero_based_exclusive_ranges( 100 ) , vec![ 0 ..10 ] ) ;
1081+ }
1082+
1083+ #[ test]
1084+ fn to_zero_based_exclusive_ignores_range_past_max_lines ( ) {
1085+ let mut ranges = BlameRanges :: from_one_based_inclusive_range ( 1 ..=5 ) . unwrap ( ) ;
1086+ ranges. add_one_based_inclusive_range ( 16 ..=20 ) . unwrap ( ) ;
1087+
1088+ assert_eq ! ( ranges. to_zero_based_exclusive_ranges( 7 ) , vec![ 0 ..5 ] ) ;
1089+ }
1090+
1091+ #[ test]
1092+ fn to_zero_based_exclusive_range_doesnt_exceed_max_lines ( ) {
1093+ let mut ranges = BlameRanges :: from_one_based_inclusive_range ( 1 ..=5 ) . unwrap ( ) ;
1094+ ranges. add_one_based_inclusive_range ( 6 ..=10 ) . unwrap ( ) ;
1095+
1096+ assert_eq ! ( ranges. to_zero_based_exclusive_ranges( 7 ) , vec![ 0 ..7 ] ) ;
1097+ }
1098+
1099+ #[ test]
1100+ fn to_zero_based_exclusive_merged_ranges_dont_exceed_max_lines ( ) {
1101+ let mut ranges = BlameRanges :: from_one_based_inclusive_range ( 1 ..=4 ) . unwrap ( ) ;
1102+ ranges. add_one_based_inclusive_range ( 6 ..=10 ) . unwrap ( ) ;
1103+
1104+ assert_eq ! ( ranges. to_zero_based_exclusive_ranges( 7 ) , vec![ 0 ..4 , 5 ..7 ] ) ;
1105+ }
1106+
1107+ #[ test]
1108+ fn default_is_full_file ( ) {
1109+ let ranges = BlameRanges :: default ( ) ;
1110+
1111+ assert ! ( matches!( ranges, BlameRanges :: WholeFile ) ) ;
1112+ }
1113+ }
0 commit comments