1818
1919namespace Microsoft . VisualStudio . TestPlatform . CommandLine . Internal ;
2020
21- // Not using FriendlyName because it
2221[ ExtensionUri ( ExtensionUri ) ]
2322[ FriendlyName ( FriendlyName ) ]
2423internal class MSBuildLogger : ITestLoggerWithParameters
@@ -100,72 +99,83 @@ private void TestResultHandler(object? sender, TestResultEventArgs e)
10099 TPDebug . Assert ( Output != null , "Initialize should have been called." ) ;
101100 switch ( e . Result . Outcome )
102101 {
102+ case TestOutcome . Passed :
103+ case TestOutcome . Skipped :
104+
105+ var test = e . Result . TestCase . DisplayName ;
106+ var outcome = e . Result . Outcome == TestOutcome . Passed
107+ ? CommandLineResources . PassedTestIndicator
108+ : CommandLineResources . SkippedTestIndicator ;
109+ var info = $ "++++{ outcome } ++++{ ReplacePlusSeparator ( test ) } ";
110+
111+ Debug . WriteLine ( ">>>>MESSAGE:" + info ) ;
112+ Output . Information ( false , info ) ;
113+ break ;
103114 case TestOutcome . Failed :
115+
116+ var result = e . Result ;
117+ if ( ! StringUtils . IsNullOrWhiteSpace ( result . ErrorStackTrace ) )
104118 {
105- var result = e . Result ;
106- if ( ! StringUtils . IsNullOrWhiteSpace ( result . ErrorStackTrace ) )
119+ var maxLength = 1000 ;
120+ string ? error = null ;
121+ if ( result . ErrorMessage != null )
107122 {
108- var maxLength = 1000 ;
109- string ? error = null ;
110- if ( result . ErrorMessage != null )
111- {
112- var oneLineMessage = result . ErrorMessage . Replace ( Environment . NewLine , " " ) ;
113- error = oneLineMessage . Length > maxLength ? oneLineMessage . Substring ( 0 , maxLength ) : oneLineMessage ;
114- }
123+ // Do not use environment.newline here, we want to replace also \n on Windows.
124+ var oneLineMessage = result . ErrorMessage . Replace ( "\n " , " " ) . Replace ( "\r " , " " ) ;
125+ error = oneLineMessage . Length > maxLength ? oneLineMessage . Substring ( 0 , maxLength ) : oneLineMessage ;
126+ }
115127
116- string ? stackFrame = null ;
117- var stackFrames = Regex . Split ( result . ErrorStackTrace , Environment . NewLine ) ;
118- string ? line = null ;
119- string ? file = null ;
120- string ? place = null ;
121- if ( stackFrames . Length > 0 )
128+ string ? stackFrame = null ;
129+ var stackFrames = Regex . Split ( result . ErrorStackTrace , Environment . NewLine ) ;
130+ string ? line = null ;
131+ string ? file = null ;
132+ string ? place = null ;
133+ if ( stackFrames . Length > 0 )
134+ {
135+ foreach ( var frame in stackFrames . Take ( 20 ) )
122136 {
123- foreach ( var frame in stackFrames . Take ( 20 ) )
137+ if ( TryGetStackFrameLocation ( frame , out line , out file , out place ) )
124138 {
125- if ( TryGetStackFrameLocation ( frame , out line , out file , out place ) )
126- {
127- break ;
128- }
139+ break ;
129140 }
130141 }
142+ }
131143
132- // We did not find any stack frame with location in the first 20 frames.
133- // Try getting location of the test.
134- if ( file == null )
144+ // We did not find any stack frame with location in the first 20 frames.
145+ // Try getting location of the test.
146+ if ( file == null )
147+ {
148+ if ( ! StringUtils . IsNullOrEmpty ( result . TestCase . CodeFilePath ) )
135149 {
136- if ( ! StringUtils . IsNullOrEmpty ( result . TestCase . CodeFilePath ) )
137- {
138- // if there are no symbols but we collect source info, us the source info.
139- file = result . TestCase . CodeFilePath ;
140- line = result . TestCase . LineNumber > 0 ? result . TestCase . LineNumber . ToString ( CultureInfo . InvariantCulture ) : null ;
141- place = stackFrame ;
142- }
143- else
144- {
145- // if there are no symbols and no source info use the dll
146- place = result . TestCase . DisplayName ;
147- file = result . TestCase . Source ;
148- }
150+ // if there are no symbols but we collect source info, us the source info.
151+ file = result . TestCase . CodeFilePath ;
152+ line = result . TestCase . LineNumber > 0 ? result . TestCase . LineNumber . ToString ( CultureInfo . InvariantCulture ) : null ;
153+ place = stackFrame ;
154+ }
155+ else
156+ {
157+ // if there are no symbols and no source info use the dll
158+ place = result . TestCase . DisplayName ;
159+ file = result . TestCase . Source ;
149160 }
150-
151- place = $ "({ result . TestCase . DisplayName } ) { place } ";
152- var message = $ "||||{ ReplacePipeSeparator ( file ) } ||||{ line } ||||{ ReplacePipeSeparator ( place ) } ||||{ ReplacePipeSeparator ( error ) } ";
153-
154- Trace . WriteLine ( ">>>>MESSAGE:" + message ) ;
155- Output . Error ( false , message ) ;
156-
157- var fullError = $ "~~~~{ ReplaceTildaSeparator ( result . ErrorMessage ) } ~~~~{ ReplaceTildaSeparator ( result . ErrorStackTrace ) } ";
158- Output . Information ( false , fullError ) ;
159- return ;
160- }
161- else
162- {
163- Output . Error ( false , result . DisplayName ? . Replace ( Environment . NewLine , " " ) ?? string . Empty ) ;
164161 }
165162
163+ place = $ "({ result . TestCase . DisplayName } ) { place } ";
164+ var message = $ "||||{ ReplacePipeSeparator ( file ) } ||||{ line } ||||{ ReplacePipeSeparator ( place ) } ||||{ ReplacePipeSeparator ( error ) } ";
166165
167- break ;
166+ Debug . WriteLine ( ">>>>MESSAGE:" + message ) ;
167+ Output . Error ( false , message ) ;
168+
169+ var fullError = $ "~~~~{ ReplaceTildaSeparator ( result . ErrorMessage ) } ~~~~{ ReplaceTildaSeparator ( result . ErrorStackTrace ) } ";
170+ Output . Information ( false , fullError ) ;
171+ return ;
172+ }
173+ else
174+ {
175+ Output . Error ( false , result . DisplayName ? . Replace ( Environment . NewLine , " " ) ?? string . Empty ) ;
168176 }
177+
178+ break ;
169179 }
170180 }
171181
@@ -186,7 +196,7 @@ private static bool TryGetStackFrameLocation(string stackFrame, out string? line
186196 line = match . Groups [ "line" ] . Value ;
187197 }
188198
189- Trace . WriteLine ( $ ">>>> { ( match . Success ? "MATCH" : "NOMATCH" ) } { stackFrame } ") ;
199+ Debug . WriteLine ( $ ">>>> { ( match . Success ? "MATCH" : "NOMATCH" ) } { stackFrame } ") ;
190200
191201 return match . Success ;
192202 }
@@ -203,6 +213,17 @@ private static bool TryGetStackFrameLocation(string stackFrame, out string? line
203213 return text . Replace ( "||||" , "____" ) ;
204214 }
205215
216+ private static string ? ReplacePlusSeparator ( string ? text )
217+ {
218+ if ( text == null )
219+ {
220+ return null ;
221+ }
222+
223+ // Remove any occurrence of message splitter.
224+ return text . Replace ( "++++" , "____" ) ;
225+ }
226+
206227 private static string ? ReplaceTildaSeparator ( string ? text )
207228 {
208229 if ( text == null )
0 commit comments