11using System . Text . Json ;
22using System . Text . Json . Nodes ;
3- using System . Text . Json . Serialization ;
4- using System . Xml . Linq ;
5- using AStar . Dev . Testing . Dashboard . Server . Controllers ;
6- using AStar . Dev . Testing . Dashboard . Server . Models ;
73
84namespace AStar . Dev . Testing . Dashboard . Server . TestCoverage ;
95
@@ -18,87 +14,87 @@ public static WebApplication MapCodeCoverageEndpoints(this WebApplication app)
1814
1915// IMPORTANT: Update this to the root directory where your projects are located.
2016// This is the starting point for the script to find the test results.
21- string path = Directory . GetCurrentDirectory ( ) ;
22- string rootDirectoryToScan = Path . Combine ( path , "../../../" ) ;
17+ var path = Directory . GetCurrentDirectory ( ) ;
18+ var rootDirectoryToScan = Path . Combine ( path , "../../../" ) ;
2319 Console . WriteLine ( rootDirectoryToScan ) ;
2420
25-
2621// ------------------------------------------------------------------------------------------------
2722// API Endpoints
2823// ------------------------------------------------------------------------------------------------
2924
3025// Endpoint for Code Coverage Results
31- IResult FindAndProcessFiles ( string filePattern , Func < string , JsonNode > processFile )
32- {
33- // Check if the root directory exists
34- if ( ! Directory . Exists ( rootDirectoryToScan ) )
35- {
36- return Results . NotFound ( $ "The root directory '{ rootDirectoryToScan } ' does not exist.") ;
37- }
38-
39- // Find all test result files recursively.
40- // The `testresults.trx` and `coverage.json` files are nested within
41- // a GUID-named folder inside the `TestResults` directory.
42- var files = Directory . EnumerateFiles (
43- rootDirectoryToScan ,
44- filePattern ,
45- SearchOption . AllDirectories ) . ToList ( ) ;
26+ IResult FindAndProcessFiles ( string filePattern , Func < string , JsonNode > processFile )
27+ {
28+ // Check if the root directory exists
29+ if ( ! Directory . Exists ( rootDirectoryToScan ) )
30+ {
31+ return Results . NotFound ( $ "The root directory '{ rootDirectoryToScan } ' does not exist.") ;
32+ }
4633
47- if ( files . Count == 0 )
48- {
49- return Results . NotFound ( $ "No files matching '{ filePattern } ' were found in '{ rootDirectoryToScan } '.") ;
50- }
34+ // Find all test result files recursively.
35+ // The `testresults.trx` and `coverage.json` files are nested within
36+ // a GUID-named folder inside the `TestResults` directory.
37+ var files = Directory . EnumerateFiles (
38+ rootDirectoryToScan ,
39+ filePattern ,
40+ SearchOption . AllDirectories ) . ToList ( ) ;
5141
52- var groupedData = new Dictionary < string , JsonNode > ( ) ;
42+ if ( files . Count == 0 )
43+ {
44+ return Results . NotFound ( $ "No files matching '{ filePattern } ' were found in '{ rootDirectoryToScan } '.") ;
45+ }
5346
54- foreach ( var file in files )
55- {
56- try
57- {
58- // Infer the project name from the file path.
59- // A common pattern is that the project directory is two levels up from the file itself.
60- var projectDirectory = Path . GetDirectoryName ( Path . GetDirectoryName ( Path . GetDirectoryName ( file ) ) ) ;
47+ var groupedData = new Dictionary < string , JsonNode > ( ) ;
6148
62- if ( projectDirectory == null )
49+ foreach ( var file in files )
6350 {
64- continue ;
65- }
51+ try
52+ {
53+ // Infer the project name from the file path.
54+ // A common pattern is that the project directory is two levels up from the file itself.
55+ var projectDirectory = Path . GetDirectoryName ( Path . GetDirectoryName ( Path . GetDirectoryName ( file ) ) ) ;
6656
67- var projectName = Path . GetFileName ( projectDirectory ) ;
57+ if ( projectDirectory == null )
58+ {
59+ continue ;
60+ }
6861
69- // Process the file and add to the dictionary.
70- groupedData [ projectName ] = processFile ( file ) ;
71- }
72- catch ( Exception ex )
73- {
74- Console . WriteLine ( $ "Error processing file '{ file } ': { ex . Message } ") ;
62+ var projectName = Path . GetFileName ( projectDirectory ) ;
63+
64+ // Process the file and add to the dictionary.
65+ groupedData [ projectName ] = processFile ( file ) ;
66+ }
67+ catch ( Exception ex )
68+ {
69+ Console . WriteLine ( $ "Error processing file '{ file } ': { ex . Message } ") ;
70+ }
71+ }
72+
73+ return Results . Ok ( groupedData ) ;
7574 }
76- }
7775
78- return Results . Ok ( groupedData ) ;
79- }
76+ app . MapGet ( "/api/coverage" , ( ) =>
77+ {
78+ return FindAndProcessFiles ( "coverage.json" , file =>
79+ {
80+ var jsonContent = File . ReadAllText ( file ) ;
81+ var jsonObject = JsonNode . Parse ( jsonContent ) ;
8082
81- app . MapGet ( "/api/coverage" , ( ) =>
82- {
83- return FindAndProcessFiles ( "coverage.json" , file =>
84- {
85- var jsonContent = File . ReadAllText ( file ) ;
86- var jsonObject = JsonNode . Parse ( jsonContent ) ;
83+ if ( jsonObject ? [ "files" ] is not JsonObject filesNode )
84+ {
85+ return JsonNode . Parse ( "{}" ) ! ;
86+ }
8787
88- if ( jsonObject ? [ "files" ] is not JsonObject filesNode )
89- {
90- return JsonNode . Parse ( "{}" ) ! ;
91- }
88+ var summary = new Dictionary < string , FileCoverageSummary > ( ) ;
9289
93- var summary = new Dictionary < string , FileCoverageSummary > ( ) ;
90+ CalculateFileCoverageSummary ( filesNode , summary ) ;
9491
95- CalculateFileCoverageSummary ( filesNode , summary ) ;
92+ return JsonNode . Parse ( JsonSerializer . Serialize ( summary ) ) ! ;
93+ } ) ;
94+ } )
95+ . WithName ( "GetCoverageResults" )
96+ . WithOpenApi ( ) ;
9697
97- return JsonNode . Parse ( JsonSerializer . Serialize ( summary ) ) ! ;
98- } ) ;
99- } )
100- . WithName ( "GetCoverageResults" )
101- . WithOpenApi ( ) ;
10298 return app ;
10399 }
104100
@@ -135,6 +131,7 @@ private static void CalculateFileCoverageSummary(JsonObject filesNode, Dictionar
135131 if ( branch is JsonArray branchData && branchData . Count >= 2 )
136132 {
137133 var coverageCount = branchData [ 1 ] ? . GetValue < int > ( ) ?? 0 ;
134+
138135 if ( coverageCount > 0 )
139136 {
140137 branchesCovered ++ ;
@@ -152,13 +149,13 @@ private static void CalculateFileCoverageSummary(JsonObject filesNode, Dictionar
152149 var totalBranches = branchesCovered + branchesNotCovered ;
153150 var branchPercentage = totalBranches > 0 ? ( double ) branchesCovered / totalBranches * 100 : 100.0 ;
154151
155- summary [ filePathKey ] = new FileCoverageSummary (
156- linesCovered ,
157- linesNotCovered ,
158- branchesCovered ,
159- branchesNotCovered ,
160- linePercentage ,
161- branchPercentage ) ;
152+ summary [ filePathKey ] = new (
153+ linesCovered ,
154+ linesNotCovered ,
155+ branchesCovered ,
156+ branchesNotCovered ,
157+ linePercentage ,
158+ branchPercentage ) ;
162159 }
163160 }
164161}
0 commit comments