11using System ;
2+ using System . Collections . Concurrent ;
23using System . Collections . Generic ;
34using System . Diagnostics ;
45using System . Globalization ;
@@ -25,9 +26,17 @@ public class PrettyLogger : ITestLogger
2526 private readonly List < string > _disableSkipNamespaces = new List < string > ( ) ;
2627 public static Uri RootUri { get ; } = new Uri ( Environment . CurrentDirectory + Path . DirectorySeparatorChar , UriKind . Absolute ) ;
2728
29+ private readonly ConcurrentQueue < TestResult > _failedTests = new ConcurrentQueue < TestResult > ( ) ;
30+
2831 public void Initialize ( TestLoggerEvents events , string testRunDirectory )
2932 {
30- events . TestResult += TestResultHandler ;
33+ events . TestResult += ( s , e ) =>
34+ {
35+ if ( e . Result . Outcome != TestOutcome . Failed ) return ;
36+ _failedTests . Enqueue ( e . Result ) ;
37+ } ;
38+
39+ //events.TestResult += TestResultHandler;
3140 events . TestRunComplete += TestRunCompleteHandler ;
3241 events . TestRunStart += ( sender , args ) =>
3342 {
@@ -49,7 +58,6 @@ public void Initialize(TestLoggerEvents events, string testRunDirectory)
4958 . Where ( s => ! string . IsNullOrWhiteSpace ( s ) )
5059 ) ;
5160 }
52- foreach ( var a in StartUpActions ) a ( ) ;
5361 } ;
5462 }
5563
@@ -77,37 +85,44 @@ public void TestResultHandler(object sender, TestResultEventArgs e)
7785
7886 break ;
7987 default :
80- if ( _writtenPassed > 0 )
81- {
82- Console . WriteLine ( ) ;
83- _writtenPassed = 0 ;
84- }
85- PrintTestOutcomeHeader ( e . Result . Outcome , testCase . FullyQualifiedName ) ;
86- switch ( e . Result . Outcome )
87- {
88- case TestOutcome . NotFound : break ;
89- case TestOutcome . None : break ;
90- case TestOutcome . Passed :
91- PrintLocation ( testCase ) ;
92- PrintDuration ( e . Result . Duration ) ;
93- break ;
94- case TestOutcome . Skipped :
95- foreach ( var p in e . Result . Messages )
96- p . Text . WriteWordWrapped ( ) ;
97-
98- break ;
99- case TestOutcome . Failed :
100- PrintLocation ( testCase ) ;
101- PrintDuration ( e . Result . Duration ) ;
102- e . Result . ErrorMessage . WriteWordWrapped ( WordWrapper . WriteWithExceptionHighlighted ) ;
103- PrintStackTrace ( e . Result . ErrorStackTrace ) ;
104- break ;
105- }
88+ WriteTestResult ( e . Result ) ;
10689
10790 break ;
10891 }
10992 }
11093
94+ private void WriteTestResult ( TestResult result , bool longForm = true )
95+ {
96+ if ( _writtenPassed > 0 )
97+ {
98+ Console . WriteLine ( ) ;
99+ _writtenPassed = 0 ;
100+ }
101+ var testCase = result . TestCase ;
102+ PrintTestOutcomeHeader ( result . Outcome , result . TestCase . FullyQualifiedName ) ;
103+ switch ( result . Outcome )
104+ {
105+ case TestOutcome . NotFound : break ;
106+ case TestOutcome . None : break ;
107+ case TestOutcome . Passed :
108+ PrintLocation ( testCase ) ;
109+ PrintDuration ( result . Duration ) ;
110+ break ;
111+ case TestOutcome . Skipped :
112+ foreach ( var p in result . Messages )
113+ p . Text . WriteWordWrapped ( ) ;
114+
115+ break ;
116+ case TestOutcome . Failed :
117+ PrintLocation ( testCase ) ;
118+ PrintDuration ( result . Duration ) ;
119+ result . ErrorMessage . WriteWordWrapped ( WordWrapper . WriteWithExceptionHighlighted , longForm ) ;
120+ if ( longForm )
121+ PrintStackTrace ( result . ErrorStackTrace ) ;
122+ break ;
123+ }
124+ }
125+
111126 private static int _slowTests = 0 ;
112127 private static void PrintDuration ( TimeSpan duration )
113128 {
@@ -144,20 +159,19 @@ private static void PrintStackTrace(string stackTrace)
144159 var atIn = line . Split ( new [ ] { ") in " } , StringSplitOptions . RemoveEmptyEntries ) ;
145160 var at = atIn [ 0 ] + ")" ;
146161 Console . WriteLine ( at ) ;
147- if ( atIn . Length > 1 )
148- {
149- var @in = atIn [ 1 ] . Split ( ':' ) ;
150- var file = @in [ 0 ] ;
151- var lineNumber = @in [ 1 ] ;
152- Console . ForegroundColor = ConsoleColor . Gray ;
153- Console . Write ( " in " ) ;
154- Console . ForegroundColor = ConsoleColor . Blue ;
155- Console . Write ( lineNumber ) ;
156- Console . Write ( " " ) ;
157- Console . ForegroundColor = ConsoleColor . DarkGray ;
158- Console . WriteLine ( file . CreateRelativePath ( ) ) ;
159- Console . ResetColor ( ) ;
160- }
162+ if ( atIn . Length <= 1 ) continue ;
163+
164+ var @in = atIn [ 1 ] . Split ( ':' ) ;
165+ var file = @in [ 0 ] ;
166+ var lineNumber = @in [ 1 ] ;
167+ Console . ForegroundColor = ConsoleColor . Gray ;
168+ Console . Write ( " in " ) ;
169+ Console . ForegroundColor = ConsoleColor . Blue ;
170+ Console . Write ( lineNumber ) ;
171+ Console . Write ( " " ) ;
172+ Console . ForegroundColor = ConsoleColor . DarkGray ;
173+ Console . WriteLine ( file . CreateRelativePath ( ) ) ;
174+ Console . ResetColor ( ) ;
161175 }
162176 Console . WriteLine ( ) ;
163177 }
@@ -172,9 +186,9 @@ private static void PrintLocation(TestCase testCase)
172186 Console . ResetColor ( ) ;
173187 }
174188
175- public void TestRunCompleteHandler ( object sender , TestRunCompleteEventArgs e )
189+ private void TestRunCompleteHandler ( object sender , TestRunCompleteEventArgs e )
176190 {
177- void WriteBox ( string boxString , ConsoleColor boxColor , string metric )
191+ static void WriteBox ( string boxString , ConsoleColor boxColor , string metric )
178192 {
179193 boxString = " " + boxString . PadRight ( 5 ) ;
180194 Console . ForegroundColor = ConsoleColor . White ;
@@ -188,23 +202,17 @@ void WriteBox(string boxString, ConsoleColor boxColor, string metric)
188202 Console . WriteLine ( ) ;
189203 }
190204
191- Console . WriteLine ( ) ;
192- Console . BackgroundColor = ConsoleColor . White ;
193- Console . ForegroundColor = ConsoleColor . Black ;
194- Console . Write ( " " ) ;
195- Console . ResetColor ( ) ;
196- Console . WriteLine ( ) ;
197- Console . BackgroundColor = ConsoleColor . White ;
198- Console . ForegroundColor = ConsoleColor . Black ;
199- Console . Write ( " 🌈 SUMMARY RESULTS 🌈 " ) ;
200- Console . ResetColor ( ) ;
201- Console . WriteLine ( ) ;
202- Console . BackgroundColor = ConsoleColor . White ;
203- Console . ForegroundColor = ConsoleColor . Black ;
204- Console . Write ( " " ) ;
205- Console . ResetColor ( ) ;
206- Console . WriteLine ( ) ;
207- Console . WriteLine ( ) ;
205+
206+ //Reprint first 20 test failures at the bottom for convenience
207+ Announce ( $ "SEEN { _failedTests . Count } FAILURE{ ( _failedTests . Count > 1 ? "S" : "" ) } ") ;
208+
209+ for ( var expanded = 0 ; _failedTests . TryDequeue ( out var testResult ) ; expanded ++ )
210+ {
211+ WriteTestResult ( testResult , expanded <= 20 ) ;
212+ }
213+
214+
215+ Announce ( " 🌈 SUMMARY RESULTS 🌈 " ) ;
208216
209217 WriteBox ( "ALL" , ConsoleColor . DarkGray , e . TestRunStatistics . ExecutedTests . ToString ( ) ) ;
210218
@@ -228,6 +236,27 @@ void WriteBox(string boxString, ConsoleColor boxColor, string metric)
228236
229237 Console . WriteLine ( ) ;
230238 Console . WriteLine ( ) ;
239+ }
240+
241+ private static void Announce ( string text )
242+ {
243+ Console . WriteLine ( ) ;
244+ var padding = new string ( ' ' , text . Length + 4 ) ;
245+ Console . BackgroundColor = ConsoleColor . White ;
246+ Console . ForegroundColor = ConsoleColor . Black ;
247+ Console . Write ( padding ) ;
248+ Console . ResetColor ( ) ;
249+ Console . WriteLine ( ) ;
250+ Console . BackgroundColor = ConsoleColor . White ;
251+ Console . ForegroundColor = ConsoleColor . Black ;
252+ Console . Write ( $ " { text } ") ;
253+ Console . ResetColor ( ) ;
254+ Console . WriteLine ( ) ;
255+ Console . BackgroundColor = ConsoleColor . White ;
256+ Console . ForegroundColor = ConsoleColor . Black ;
257+ Console . Write ( padding ) ;
258+ Console . ResetColor ( ) ;
259+ Console . WriteLine ( ) ;
231260 Console . WriteLine ( ) ;
232261 }
233262
@@ -303,7 +332,5 @@ private static string ToStringFromMilliseconds(double milliseconds, bool @fixed
303332 return ( milliseconds / 60_000d ) . ToString ( "N0" , Provider ) + " m" ;
304333 }
305334
306- public static void AddStartupAction ( Action action ) => StartUpActions . Add ( action ) ;
307- private static List < Action > StartUpActions { get ; } = new List < Action > ( ) ;
308335 }
309336}
0 commit comments