@@ -785,4 +785,178 @@ private static TaskResult ExecuteTaskInvalidSolutionPath(SetupState setup)
785785 var success = task . Execute ( ) ;
786786 return new TaskResult ( setup , task , success ) ;
787787 }
788+
789+ // ========== Malformed Solution File Tests ==========
790+
791+ [ Scenario ( "Gracefully handles malformed project lines in .sln file with missing name" ) ]
792+ [ Fact ]
793+ public async Task Handles_malformed_sln_missing_name ( )
794+ {
795+ await Given ( "solution file with malformed project line (missing name)" , SetupMalformedSlnMissingName )
796+ . When ( "execute task with solution scan" , ExecuteTaskSolutionScan )
797+ . Then ( "task succeeds without exception" , r => r . Success )
798+ . And ( "sql project path resolved from valid line" , r => r . Task . SqlProjPath == Path . GetFullPath ( r . Setup . SqlProj ) )
799+ . Finally ( r => r . Setup . Folder . Dispose ( ) )
800+ . AssertPassed ( ) ;
801+ }
802+
803+ [ Scenario ( "Gracefully handles malformed project lines in .sln file with missing path" ) ]
804+ [ Fact ]
805+ public async Task Handles_malformed_sln_missing_path ( )
806+ {
807+ await Given ( "solution file with malformed project line (missing path)" , SetupMalformedSlnMissingPath )
808+ . When ( "execute task with solution scan" , ExecuteTaskSolutionScan )
809+ . Then ( "task succeeds without exception" , r => r . Success )
810+ . And ( "sql project path resolved from valid line" , r => r . Task . SqlProjPath == Path . GetFullPath ( r . Setup . SqlProj ) )
811+ . Finally ( r => r . Setup . Folder . Dispose ( ) )
812+ . AssertPassed ( ) ;
813+ }
814+
815+ [ Scenario ( "Gracefully handles .sln file with empty project name" ) ]
816+ [ Fact ]
817+ public async Task Handles_sln_with_empty_project_name ( )
818+ {
819+ await Given ( "solution file with empty project name" , SetupSlnEmptyProjectName )
820+ . When ( "execute task with solution scan" , ExecuteTaskSolutionScan )
821+ . Then ( "task succeeds without exception" , r => r . Success )
822+ . And ( "sql project path resolved from valid line" , r => r . Task . SqlProjPath == Path . GetFullPath ( r . Setup . SqlProj ) )
823+ . Finally ( r => r . Setup . Folder . Dispose ( ) )
824+ . AssertPassed ( ) ;
825+ }
826+
827+ [ Scenario ( "Gracefully handles .sln file with empty project path" ) ]
828+ [ Fact ]
829+ public async Task Handles_sln_with_empty_project_path ( )
830+ {
831+ await Given ( "solution file with empty project path" , SetupSlnEmptyProjectPath )
832+ . When ( "execute task with solution scan" , ExecuteTaskSolutionScan )
833+ . Then ( "task succeeds without exception" , r => r . Success )
834+ . And ( "sql project path resolved from valid line" , r => r . Task . SqlProjPath == Path . GetFullPath ( r . Setup . SqlProj ) )
835+ . Finally ( r => r . Setup . Folder . Dispose ( ) )
836+ . AssertPassed ( ) ;
837+ }
838+
839+ [ Scenario ( "Gracefully handles .sln file with only malformed lines" ) ]
840+ [ Fact ]
841+ public async Task Handles_sln_with_only_malformed_lines ( )
842+ {
843+ await Given ( "solution file with only malformed project lines" , SetupSlnOnlyMalformedLines )
844+ . When ( "execute task with solution scan" , ExecuteTaskSolutionScan )
845+ . Then ( "task fails due to no sql project found" , r => ! r . Success )
846+ . And ( "no null reference exceptions occur" , r => ! r . Setup . Engine . Warnings . Any ( w =>
847+ w . Message ? . Contains ( "Object reference not set" ) == true ) )
848+ . Finally ( r => r . Setup . Folder . Dispose ( ) )
849+ . AssertPassed ( ) ;
850+ }
851+
852+ private static SolutionScanSetup SetupMalformedSlnMissingName ( )
853+ {
854+ var folder = new TestFolder ( ) ;
855+ var projectDir = folder . CreateDir ( "src" ) ;
856+ folder . WriteFile ( "src/App.csproj" , "<Project />" ) ;
857+
858+ var sqlproj = folder . WriteFile ( "db/Db.csproj" , "<Project Sdk=\" MSBuild.Sdk.SqlProj/3.0.0\" />" ) ;
859+ // First line is malformed (missing closing quote for name), second line is valid
860+ var solutionPath = folder . WriteFile ( "Sample.sln" ,
861+ """
862+ Microsoft Visual Studio Solution File, Format Version 12.00
863+ # Visual Studio Version 17
864+ Project("{11111111-1111-1111-1111-111111111111}") = "MalformedApp, "src\App.csproj", "{22222222-2222-2222-2222-222222222222}"
865+ EndProject
866+ Project("{11111111-1111-1111-1111-111111111111}") = "Db", "db\Db.csproj", "{33333333-3333-3333-3333-333333333333}"
867+ EndProject
868+ """ ) ;
869+
870+ var engine = new TestBuildEngine ( ) ;
871+ return new SolutionScanSetup ( folder , projectDir , sqlproj , solutionPath , engine ) ;
872+ }
873+
874+ private static SolutionScanSetup SetupMalformedSlnMissingPath ( )
875+ {
876+ var folder = new TestFolder ( ) ;
877+ var projectDir = folder . CreateDir ( "src" ) ;
878+ folder . WriteFile ( "src/App.csproj" , "<Project />" ) ;
879+
880+ var sqlproj = folder . WriteFile ( "db/Db.csproj" , "<Project Sdk=\" MSBuild.Sdk.SqlProj/3.0.0\" />" ) ;
881+ // First line is malformed (missing closing quote for path), second line is valid
882+ var solutionPath = folder . WriteFile ( "Sample.sln" ,
883+ """
884+ Microsoft Visual Studio Solution File, Format Version 12.00
885+ # Visual Studio Version 17
886+ Project("{11111111-1111-1111-1111-111111111111}") = "App", "src\App.csproj, "{22222222-2222-2222-2222-222222222222}"
887+ EndProject
888+ Project("{11111111-1111-1111-1111-111111111111}") = "Db", "db\Db.csproj", "{33333333-3333-3333-3333-333333333333}"
889+ EndProject
890+ """ ) ;
891+
892+ var engine = new TestBuildEngine ( ) ;
893+ return new SolutionScanSetup ( folder , projectDir , sqlproj , solutionPath , engine ) ;
894+ }
895+
896+ private static SolutionScanSetup SetupSlnEmptyProjectName ( )
897+ {
898+ var folder = new TestFolder ( ) ;
899+ var projectDir = folder . CreateDir ( "src" ) ;
900+ folder . WriteFile ( "src/App.csproj" , "<Project />" ) ;
901+
902+ var sqlproj = folder . WriteFile ( "db/Db.csproj" , "<Project Sdk=\" MSBuild.Sdk.SqlProj/3.0.0\" />" ) ;
903+ // First line has empty name, second line is valid
904+ var solutionPath = folder . WriteFile ( "Sample.sln" ,
905+ """
906+ Microsoft Visual Studio Solution File, Format Version 12.00
907+ # Visual Studio Version 17
908+ Project("{11111111-1111-1111-1111-111111111111}") = "", "src\App.csproj", "{22222222-2222-2222-2222-222222222222}"
909+ EndProject
910+ Project("{11111111-1111-1111-1111-111111111111}") = "Db", "db\Db.csproj", "{33333333-3333-3333-3333-333333333333}"
911+ EndProject
912+ """ ) ;
913+
914+ var engine = new TestBuildEngine ( ) ;
915+ return new SolutionScanSetup ( folder , projectDir , sqlproj , solutionPath , engine ) ;
916+ }
917+
918+ private static SolutionScanSetup SetupSlnEmptyProjectPath ( )
919+ {
920+ var folder = new TestFolder ( ) ;
921+ var projectDir = folder . CreateDir ( "src" ) ;
922+ folder . WriteFile ( "src/App.csproj" , "<Project />" ) ;
923+
924+ var sqlproj = folder . WriteFile ( "db/Db.csproj" , "<Project Sdk=\" MSBuild.Sdk.SqlProj/3.0.0\" />" ) ;
925+ // First line has empty path, second line is valid
926+ var solutionPath = folder . WriteFile ( "Sample.sln" ,
927+ """
928+ Microsoft Visual Studio Solution File, Format Version 12.00
929+ # Visual Studio Version 17
930+ Project("{11111111-1111-1111-1111-111111111111}") = "App", "", "{22222222-2222-2222-2222-222222222222}"
931+ EndProject
932+ Project("{11111111-1111-1111-1111-111111111111}") = "Db", "db\Db.csproj", "{33333333-3333-3333-3333-333333333333}"
933+ EndProject
934+ """ ) ;
935+
936+ var engine = new TestBuildEngine ( ) ;
937+ return new SolutionScanSetup ( folder , projectDir , sqlproj , solutionPath , engine ) ;
938+ }
939+
940+ private static SolutionScanSetup SetupSlnOnlyMalformedLines ( )
941+ {
942+ var folder = new TestFolder ( ) ;
943+ var projectDir = folder . CreateDir ( "src" ) ;
944+ folder . WriteFile ( "src/App.csproj" , "<Project />" ) ;
945+
946+ // Create the SQL project file but don't add it to solution properly
947+ folder . WriteFile ( "db/Db.csproj" , "<Project Sdk=\" MSBuild.Sdk.SqlProj/3.0.0\" />" ) ;
948+ // All project lines are malformed or empty
949+ var solutionPath = folder . WriteFile ( "Sample.sln" ,
950+ """
951+ Microsoft Visual Studio Solution File, Format Version 12.00
952+ # Visual Studio Version 17
953+ Project("{11111111-1111-1111-1111-111111111111}") = "", "", "{22222222-2222-2222-2222-222222222222}"
954+ EndProject
955+ Project("{11111111-1111-1111-1111-111111111111}") = "MissingPath, "src\App.csproj", "{33333333-3333-3333-3333-333333333333}"
956+ EndProject
957+ """ ) ;
958+
959+ var engine = new TestBuildEngine ( ) ;
960+ return new SolutionScanSetup ( folder , projectDir , "" , solutionPath , engine ) ;
961+ }
788962}
0 commit comments