@@ -1008,3 +1008,113 @@ This project is open source and available for use.
10081008 "This project is open source and available for use." . ai( ) ,
10091009 ] ) ;
10101010}
1011+
1012+ #[ test]
1013+ fn test_deletion_within_a_single_line_attribution ( ) {
1014+ // Regression test for bug where removing a constructor parameter
1015+ // doesn't get attributed to AI when using mock_ai checkpoint
1016+ // This replicates the scenario where:
1017+ // - constructor(_config: Config, enabled: boolean = true) { [no-data]
1018+ // + constructor(enabled: boolean = true) { [no-data]
1019+ // The constructor line should be attributed to AI
1020+ use std:: fs;
1021+
1022+ let repo = TestRepo :: new ( ) ;
1023+ let file_path = repo. path ( ) . join ( "git-ai-integration-service.ts" ) ;
1024+
1025+ // Initial commit: File with old constructor signature (all human)
1026+ fs:: write (
1027+ & file_path,
1028+ "/**\n * Service for integrating git-ai hooks into the hook system.\n */\n export class GitAiIntegrationService {\n private readonly commandPath: string;\n private registered = false;\n \n constructor(_config: Config, enabled: boolean = true) {\n this.enabled = enabled;\n this.commandPath = 'git-ai';\n }\n }\n " ,
1029+ )
1030+ . unwrap ( ) ;
1031+
1032+ repo. git_ai ( & [ "checkpoint" ] ) . unwrap ( ) ;
1033+ repo. stage_all_and_commit ( "Initial commit with old constructor" ) . unwrap ( ) ;
1034+
1035+ // Second commit: AI removes the _config parameter
1036+ fs:: write (
1037+ & file_path,
1038+ "/**\n * Service for integrating git-ai hooks into the hook system.\n */\n export class GitAiIntegrationService {\n private readonly commandPath: string;\n private registered = false;\n \n constructor(enabled: boolean = true) {\n this.enabled = enabled;\n this.commandPath = 'git-ai';\n }\n }\n " ,
1039+ )
1040+ . unwrap ( ) ;
1041+
1042+ // Mark the change as AI-authored
1043+ repo. git_ai ( & [ "checkpoint" , "mock_ai" , "git-ai-integration-service.ts" ] )
1044+ . unwrap ( ) ;
1045+
1046+ repo. stage_all_and_commit ( "AI removes constructor parameter" )
1047+ . unwrap ( ) ;
1048+
1049+ // Verify line-by-line attribution - the constructor line should be AI
1050+ let mut file = repo. filename ( "git-ai-integration-service.ts" ) ;
1051+ file. assert_lines_and_blame ( lines ! [
1052+ "/**" . human( ) ,
1053+ " * Service for integrating git-ai hooks into the hook system." . human( ) ,
1054+ " */" . human( ) ,
1055+ "export class GitAiIntegrationService {" . human( ) ,
1056+ " private readonly commandPath: string;" . human( ) ,
1057+ " private registered = false;" . human( ) ,
1058+ "" . human( ) ,
1059+ " constructor(enabled: boolean = true) {" . ai( ) , // Should be AI, not [no-data]
1060+ " this.enabled = enabled;" . human( ) ,
1061+ " this.commandPath = 'git-ai';" . human( ) ,
1062+ " }" . human( ) ,
1063+ "}" . human( ) ,
1064+ ] ) ;
1065+ }
1066+
1067+ #[ test]
1068+ fn test_deletion_of_multiple_lines_by_ai ( ) {
1069+ // Regression test for bug where removing a constructor parameter
1070+ // doesn't get attributed to AI when using mock_ai checkpoint
1071+ // This replicates the scenario where:
1072+ // - constructor(_config: Config, enabled: boolean = true) { [no-data]
1073+ // + constructor(enabled: boolean = true) { [no-data]
1074+ // The constructor line should be attributed to AI
1075+ use std:: fs;
1076+
1077+ let repo = TestRepo :: new ( ) ;
1078+ let file_path = repo. path ( ) . join ( "git-ai-integration-service.ts" ) ;
1079+
1080+ // Initial commit: File with old constructor signature (all human)
1081+ fs:: write (
1082+ & file_path,
1083+ "/**\n * Service for integrating git-ai hooks into the hook system.\n */\n export class GitAiIntegrationService {\n private readonly commandPath: string;\n private registered = false;\n \n constructor(_config: Config, enabled: boolean = true) {\n this.enabled = enabled;\n this.commandPath = 'git-ai';\n }\n }\n " ,
1084+ )
1085+ . unwrap ( ) ;
1086+
1087+ repo. git_ai ( & [ "checkpoint" ] ) . unwrap ( ) ;
1088+ repo. stage_all_and_commit ( "Initial commit with old constructor" ) . unwrap ( ) ;
1089+
1090+ // Second commit: AI removes the _config parameter
1091+ fs:: write (
1092+ & file_path,
1093+ "/**\n * Service for integrating git-ai hooks into the hook system.\n */\n export class GitAiIntegrationService {\n private readonly commandPath: string;\n constructor(_config: Config, enabled: boolean = true) {\n this.commandPath = 'git-ai';\n }\n }\n " ,
1094+ )
1095+ . unwrap ( ) ;
1096+
1097+ // Mark the change as AI-authored
1098+ repo. git_ai ( & [ "checkpoint" , "mock_ai" , "git-ai-integration-service.ts" ] )
1099+ . unwrap ( ) ;
1100+
1101+ repo. stage_all_and_commit ( "AI removes constructor parameter" )
1102+ . unwrap ( ) ;
1103+
1104+ // Verify line-by-line attribution - the constructor line should be AI
1105+ let mut file = repo. filename ( "git-ai-integration-service.ts" ) ;
1106+ file. assert_lines_and_blame ( lines ! [
1107+ "/**" . human( ) ,
1108+ " * Service for integrating git-ai hooks into the hook system." . human( ) ,
1109+ " */" . human( ) ,
1110+ "export class GitAiIntegrationService {" . human( ) ,
1111+ " private readonly commandPath: string;" . human( ) ,
1112+ // " private registered = false;".human(),
1113+ // "".human(),
1114+ " constructor(_config: Config, enabled: boolean = true) {" . human( ) ,
1115+ // " this.enabled = enabled;".human(),
1116+ " this.commandPath = 'git-ai';" . human( ) ,
1117+ " }" . human( ) ,
1118+ "}" . human( ) ,
1119+ ] ) ;
1120+ }
0 commit comments