1+ using System . Xml . Linq ;
2+ using ModularPipelines . DotNet . Enums ;
3+
4+ namespace ModularPipelines . DotNet . Parsers . Trx ;
5+
6+ public class TrxParser : ITrxParser
7+ {
8+ public DotNetTestResult ParseTrxContents ( string input )
9+ {
10+ var xDocument = XDocument . Load ( new StringReader ( input ) ) ;
11+ return new DotNetTestResult ( GetUnitTestResults ( xDocument ) , GetResultSummary ( xDocument ) ) ;
12+ }
13+
14+ private ResultSummary GetResultSummary ( XDocument document )
15+ {
16+ return ParseResultSummary ( document
17+ . Descendants ( )
18+ . First ( e => e . Name . LocalName == "ResultSummary" ) ) ;
19+ }
20+
21+ private ResultSummary ParseResultSummary ( XElement element )
22+ {
23+ var outcome = element . Attribute ( "outcome" ) ! . Value ;
24+
25+ var counters = ParseCounters ( element . Descendants ( ) . First ( e => e . Name . LocalName == "Counters" ) ) ;
26+
27+ return new ResultSummary ( outcome , counters ) ;
28+ }
29+
30+ private Counters ParseCounters ( XElement element )
31+ {
32+ return new Counters (
33+ int . Parse ( element . Attribute ( "total" ) ! . Value ) ,
34+ int . Parse ( element . Attribute ( "executed" ) ! . Value ) ,
35+ int . Parse ( element . Attribute ( "passed" ) ! . Value ) ,
36+ int . Parse ( element . Attribute ( "failed" ) ! . Value ) ,
37+ int . Parse ( element . Attribute ( "error" ) ! . Value ) ,
38+ int . Parse ( element . Attribute ( "timeout" ) ! . Value ) ,
39+ int . Parse ( element . Attribute ( "aborted" ) ! . Value ) ,
40+ int . Parse ( element . Attribute ( "inconclusive" ) ! . Value ) ,
41+ int . Parse ( element . Attribute ( "passedButRunAborted" ) ! . Value ) ,
42+ int . Parse ( element . Attribute ( "notRunnable" ) ! . Value ) ,
43+ int . Parse ( element . Attribute ( "notExecuted" ) ! . Value ) ,
44+ int . Parse ( element . Attribute ( "disconnected" ) ! . Value ) ,
45+ int . Parse ( element . Attribute ( "warning" ) ! . Value ) ,
46+ int . Parse ( element . Attribute ( "completed" ) ! . Value ) ,
47+ int . Parse ( element . Attribute ( "inProgress" ) ! . Value ) ,
48+ int . Parse ( element . Attribute ( "pending" ) ! . Value )
49+ ) ;
50+ }
51+
52+ private List < UnitTestResult > GetUnitTestResults ( XDocument xDocument )
53+ {
54+ return xDocument . Descendants ( )
55+ . Where ( d => d . Name . LocalName == "UnitTestResult" )
56+ . Select ( ParseUnitTestResult )
57+ . ToList ( ) ;
58+ }
59+
60+ private UnitTestResult ParseUnitTestResult ( XElement element )
61+ {
62+ var errorInfo = element . Descendants ( ) . FirstOrDefault ( x => x . Name . LocalName == "ErrorInfo" ) ;
63+
64+ return new UnitTestResult
65+ {
66+ ExecutionId = element . Attribute ( "executionId" ) ! . Value ,
67+ TestId = element . Attribute ( "testId" ) ! . Value ,
68+ TestName = element . Attribute ( "testName" ) ! . Value ,
69+ ComputerName = element . Attribute ( "computerName" ) ! . Value ,
70+ Duration = TimeSpan . Parse ( element . Attribute ( "duration" ) ! . Value ) ,
71+ StartTime = DateTimeOffset . Parse ( element . Attribute ( "startTime" ) ! . Value ) ,
72+ EndTime = DateTimeOffset . Parse ( element . Attribute ( "endTime" ) ! . Value ) ,
73+ TestType = element . Attribute ( "testType" ) ! . Value ,
74+ Outcome = Enum . Parse < TestOutcome > ( element . Attribute ( "outcome" ) ! . Value ) ,
75+ TestListId = element . Attribute ( "testListId" ) ! . Value ,
76+ RelativeResultsDirectory = element . Attribute ( "relativeResultsDirectory" ) ! . Value ,
77+ Output = new TestOutput
78+ {
79+ StdOut = element . Descendants ( ) . FirstOrDefault ( x => x . Name . LocalName == "StdOut" ) ? . Value ,
80+ ErrorInfo = errorInfo == null ? null : new ErrorInfo
81+ {
82+ Message = errorInfo . Descendants ( ) . FirstOrDefault ( x => x . Name . LocalName == "Message" ) ? . Value ,
83+ StackTrace = errorInfo . Descendants ( ) . FirstOrDefault ( x => x . Name . LocalName == "StackTrace" ) ? . Value ,
84+ } ,
85+ } ,
86+ } ;
87+ }
88+ }
0 commit comments