@@ -94,9 +94,12 @@ const textDecoder = new TextDecoder();
9494const ANSI_RESET = "\u001b[0m" ;
9595const ANSI_RED = "\u001b[31m" ;
9696const ANSI_GREEN = "\u001b[32m" ;
97+ const ANSI_YELLOW = "\u001b[33m" ;
98+ const ANSI_BOLD = "\u001b[1m" ;
9799
98100const LEGACY_FAIL_MARKER = "<<====== FAILED ======>>" ;
99101const LEGACY_PASS_REGEX = / \b p a s s e d \b / i;
102+ const LEGACY_STATUS_REGEX = / S t a t u s : \s * ( \w + ) / i;
100103
101104const GLOB_PATTERN = / [ * ? ] / ;
102105
@@ -200,11 +203,12 @@ function deriveMethodResultsFromClassSummary(
200203 }
201204
202205 const hasSpecificFailures = Array . from ( summaries . values ( ) ) . some ( ( summary ) => summary . status === TestStatus . Failed ) ;
206+ const hasAssertionData = Array . isArray ( classResult . assertions ) && classResult . assertions . length > 0 ;
203207 const fallbackMethods = requestedMethods && requestedMethods . size ? Array . from ( requestedMethods ) : availableMethods ;
204208 const fallbackStatus =
205- classResult . status === TestStatus . Failed && ! hasSpecificFailures && ! classResult . assertions ?. length
209+ classResult . status === TestStatus . Failed && ! hasSpecificFailures && ! hasAssertionData
206210 ? TestStatus . Failed
207- : ( classResult . status ?? TestStatus . Passed ) ;
211+ : TestStatus . Passed ;
208212
209213 for ( const methodName of fallbackMethods ) {
210214 const normalized = normalizeLegacyMethodName ( methodName ) ?? methodName ;
@@ -342,11 +346,20 @@ function colorizeLegacyConsoleLine(line: string): string {
342346 if ( ! line ) {
343347 return line ;
344348 }
349+ if ( line . includes ( ANSI_RESET ) ) {
350+ return line ;
351+ }
345352 if ( line . includes ( LEGACY_FAIL_MARKER ) ) {
346- return ` ${ ANSI_RED } ${ line } ${ ANSI_RESET } ` ;
353+ return line . replace ( LEGACY_FAIL_MARKER , `${ ANSI_RED } ${ LEGACY_FAIL_MARKER } ${ ANSI_RESET } ` ) ;
354+ }
355+ const statusMatch = line . match ( LEGACY_STATUS_REGEX ) ;
356+ if ( statusMatch ?. [ 1 ] ) {
357+ const statusText = statusMatch [ 1 ] ;
358+ const coloredStatus = `${ LEGACY_PASS_REGEX . test ( statusText ) ? ANSI_GREEN : ANSI_RED } ${ statusText } ${ ANSI_RESET } ` ;
359+ return line . replace ( statusText , coloredStatus ) ;
347360 }
348361 if ( LEGACY_PASS_REGEX . test ( line ) ) {
349- return ` ${ ANSI_GREEN } ${ line } ${ ANSI_RESET } `;
362+ return line . replace ( LEGACY_PASS_REGEX , ( match ) => ` ${ ANSI_GREEN } ${ match } ${ ANSI_RESET } `) ;
350363 }
351364 return line ;
352365}
@@ -359,7 +372,15 @@ function normalizeLegacyMethodName(method?: string): string | undefined {
359372 if ( ! trimmed ) {
360373 return undefined ;
361374 }
362- return trimmed . startsWith ( "Test" ) ? trimmed . slice ( 4 ) : trimmed ;
375+ let working = trimmed ;
376+ if ( / ^ z t e s t / i. test ( working ) ) {
377+ working = working . slice ( 1 ) ;
378+ }
379+ if ( / ^ t e s t / i. test ( working ) ) {
380+ working = working . slice ( 4 ) ;
381+ }
382+ const normalized = working . trim ( ) ;
383+ return normalized ? normalized : undefined ;
363384}
364385
365386function parseLegacyLabelFromText ( text ?: string ) : string | undefined {
@@ -840,7 +861,7 @@ async function addItemForClassUri(testController: vscode.TestController, uri: vs
840861
841862function groupConsoleByMethod ( lines : string [ ] ) : Map < string , string [ ] > {
842863 const map = new Map < string , string [ ] > ( ) ;
843- const headerRegex = / M é t o d o : \s * ( \S + ) / i;
864+ const headerRegex = / M e t [ ó o ] d o : \s * ( [ ^ \r \n - ] + ) / i;
844865
845866 let currentMethodName : string | undefined ;
846867
@@ -850,7 +871,7 @@ function groupConsoleByMethod(lines: string[]): Map<string, string[]> {
850871
851872 const headerMatch = line . match ( headerRegex ) ;
852873 if ( headerMatch ) {
853- currentMethodName = headerMatch [ 1 ] ;
874+ currentMethodName = headerMatch [ 1 ] . trim ( ) ;
854875 if ( ! map . has ( currentMethodName ) ) {
855876 map . set ( currentMethodName , [ ] ) ;
856877 }
@@ -870,6 +891,46 @@ function groupConsoleByMethod(lines: string[]): Map<string, string[]> {
870891 return map ;
871892}
872893
894+ function groupAssertionsByMethod ( classResult : TestResult ) : Map < string , LegacyAssertion [ ] > {
895+ const map = new Map < string , LegacyAssertion [ ] > ( ) ;
896+ if ( ! Array . isArray ( classResult . assertions ) ) {
897+ return map ;
898+ }
899+
900+ for ( const assertion of classResult . assertions ) {
901+ const label = labelFromAssertion ( assertion ) ;
902+ const normalized = normalizeLegacyMethodName ( label ?? "" ) ;
903+ if ( ! normalized ) {
904+ continue ;
905+ }
906+ const group = map . get ( normalized ) ?? [ ] ;
907+ group . push ( assertion ) ;
908+ map . set ( normalized , group ) ;
909+ }
910+
911+ return map ;
912+ }
913+
914+ function formatLegacyAssertions ( summaryLine : string , assertions : LegacyAssertion [ ] ) : string [ ] {
915+ const lines : string [ ] = [ summaryLine ] ;
916+
917+ for ( const assertion of assertions ) {
918+ const statusText =
919+ assertion . status === TestStatus . Passed
920+ ? `${ ANSI_GREEN } Passed${ ANSI_RESET } `
921+ : assertion . status === TestStatus . Skipped
922+ ? `${ ANSI_YELLOW } Skipped${ ANSI_RESET } `
923+ : `${ ANSI_RED } ${ LEGACY_FAIL_MARKER } ${ ANSI_RESET } ` ;
924+
925+ const typePrefix = assertion . type ? `${ assertion . type } - ` : "" ;
926+ lines . push ( ` ${ typePrefix } ${ assertion . message } >> ${ statusText } ` ) ;
927+ }
928+
929+ lines . push ( "" ) ;
930+
931+ return lines ;
932+ }
933+
873934async function promptGenerateLegacyBase ( rootUri : vscode . Uri ) : Promise < boolean | undefined > {
874935 const options : ( vscode . QuickPickItem & { value : boolean } ) [ ] = [
875936 {
@@ -1017,6 +1078,7 @@ async function executeLegacyRunner(
10171078 continue ;
10181079 }
10191080 const durationsByMethod = extractMethodDurations ( testResult ) ;
1081+ const assertionsByMethod = groupAssertionsByMethod ( testResult ) ;
10201082 const methodResultsToApply : {
10211083 item : vscode . TestItem ;
10221084 result : TestResult ;
@@ -1065,11 +1127,8 @@ async function executeLegacyRunner(
10651127 knownStatuses . set ( methodItem , methodResult . status ) ;
10661128 const legacyMethodName = `Test${ methodItem . label } ` ;
10671129 const methodConsoleLines = consoleByMethod . get ( legacyMethodName ) ?? [ ] ;
1068-
1069- for ( const line of methodConsoleLines ) {
1070- const colored = colorizeLegacyConsoleLine ( line ) ;
1071- testRun . appendOutput ( colored + "\r\n" , undefined , methodItem ) ;
1072- }
1130+ const normalizedMethodName = normalizeLegacyMethodName ( methodItem . label ) ?? methodItem . label ;
1131+ const methodAssertions = assertionsByMethod . get ( normalizedMethodName ) ?? [ ] ;
10731132 const statusText =
10741133 methodResult . status === TestStatus . Passed
10751134 ? "passed"
@@ -1083,8 +1142,39 @@ async function executeLegacyRunner(
10831142 ? `Duration of execution: ${ methodResult . duration } ms`
10841143 : "Duration not available" ) ;
10851144
1086- const summaryLine = ` Método: ${ methodItem . label } | Status: ${ statusText } | ${ durationInfo } ` ;
1087- testRun . appendOutput ( summaryLine + "\r\n" , undefined , methodItem ) ;
1145+ const statusColor =
1146+ methodResult . status === TestStatus . Passed
1147+ ? ANSI_GREEN
1148+ : methodResult . status === TestStatus . Failed
1149+ ? ANSI_RED
1150+ : ANSI_YELLOW ;
1151+
1152+ const summaryLine = `Método: ${ ANSI_BOLD } ${ methodItem . label } ${ ANSI_RESET } | Status: ${ statusColor } ${ statusText } ${ ANSI_RESET } | ${ durationInfo } ` ;
1153+ const fallbackAssertionLines = formatLegacyAssertions ( summaryLine , methodAssertions ) ;
1154+
1155+ let linesToOutput : string [ ] ;
1156+ if ( methodAssertions . length > 0 ) {
1157+ linesToOutput = fallbackAssertionLines ;
1158+ } else if ( methodConsoleLines . length > 0 ) {
1159+ const consoleAssertions = methodConsoleLines
1160+ . filter ( ( line ) => {
1161+ const clean = stripAnsiSequences ( line ) ;
1162+ return ! / M e t [ ó o ] d o : / i. test ( clean ) && ! / F i m d a e x e c u [ c ç ] [ a ã ] o / i. test ( clean ) ;
1163+ } )
1164+ . map ( ( line ) => {
1165+ const clean = line . trimStart ( ) ;
1166+ return clean ? ` ${ clean } ` : clean ;
1167+ } ) ;
1168+
1169+ linesToOutput = [ summaryLine , ...consoleAssertions , "" ] ;
1170+ } else {
1171+ linesToOutput = fallbackAssertionLines ;
1172+ }
1173+
1174+ for ( const line of linesToOutput ) {
1175+ const colored = colorizeLegacyConsoleLine ( line ) ;
1176+ testRun . appendOutput ( colored + "\r\n" , undefined , methodItem ) ;
1177+ }
10881178 switch ( methodResult . status ) {
10891179 case TestStatus . Failed : {
10901180 const messages : vscode . TestMessage [ ] = [ ] ;
0 commit comments