@@ -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 {
@@ -839,7 +860,7 @@ async function addItemForClassUri(testController: vscode.TestController, uri: vs
839860
840861function groupConsoleByMethod ( lines : string [ ] ) : Map < string , string [ ] > {
841862 const map = new Map < string , string [ ] > ( ) ;
842- const headerRegex = / M é t o d o : \s * ( \S + ) / i;
863+ const headerRegex = / M e t [ ó o ] d o : \s * ( [ ^ \r \n - ] + ) / i;
843864
844865 let currentMethodName : string | undefined ;
845866
@@ -849,7 +870,7 @@ function groupConsoleByMethod(lines: string[]): Map<string, string[]> {
849870
850871 const headerMatch = line . match ( headerRegex ) ;
851872 if ( headerMatch ) {
852- currentMethodName = headerMatch [ 1 ] ;
873+ currentMethodName = headerMatch [ 1 ] . trim ( ) ;
853874 if ( ! map . has ( currentMethodName ) ) {
854875 map . set ( currentMethodName , [ ] ) ;
855876 }
@@ -869,6 +890,46 @@ function groupConsoleByMethod(lines: string[]): Map<string, string[]> {
869890 return map ;
870891}
871892
893+ function groupAssertionsByMethod ( classResult : TestResult ) : Map < string , LegacyAssertion [ ] > {
894+ const map = new Map < string , LegacyAssertion [ ] > ( ) ;
895+ if ( ! Array . isArray ( classResult . assertions ) ) {
896+ return map ;
897+ }
898+
899+ for ( const assertion of classResult . assertions ) {
900+ const label = labelFromAssertion ( assertion ) ;
901+ const normalized = normalizeLegacyMethodName ( label ?? "" ) ;
902+ if ( ! normalized ) {
903+ continue ;
904+ }
905+ const group = map . get ( normalized ) ?? [ ] ;
906+ group . push ( assertion ) ;
907+ map . set ( normalized , group ) ;
908+ }
909+
910+ return map ;
911+ }
912+
913+ function formatLegacyAssertions ( summaryLine : string , assertions : LegacyAssertion [ ] ) : string [ ] {
914+ const lines : string [ ] = [ summaryLine ] ;
915+
916+ for ( const assertion of assertions ) {
917+ const statusText =
918+ assertion . status === TestStatus . Passed
919+ ? `${ ANSI_GREEN } Passed${ ANSI_RESET } `
920+ : assertion . status === TestStatus . Skipped
921+ ? `${ ANSI_YELLOW } Skipped${ ANSI_RESET } `
922+ : `${ ANSI_RED } ${ LEGACY_FAIL_MARKER } ${ ANSI_RESET } ` ;
923+
924+ const typePrefix = assertion . type ? `${ assertion . type } - ` : "" ;
925+ lines . push ( ` ${ typePrefix } ${ assertion . message } >> ${ statusText } ` ) ;
926+ }
927+
928+ lines . push ( "" ) ;
929+
930+ return lines ;
931+ }
932+
872933async function promptGenerateLegacyBase ( rootUri : vscode . Uri ) : Promise < boolean | undefined > {
873934 const options : ( vscode . QuickPickItem & { value : boolean } ) [ ] = [
874935 {
@@ -1016,6 +1077,7 @@ async function executeLegacyRunner(
10161077 continue ;
10171078 }
10181079 const durationsByMethod = extractMethodDurations ( testResult ) ;
1080+ const assertionsByMethod = groupAssertionsByMethod ( testResult ) ;
10191081 const methodResultsToApply : {
10201082 item : vscode . TestItem ;
10211083 result : TestResult ;
@@ -1064,11 +1126,8 @@ async function executeLegacyRunner(
10641126 knownStatuses . set ( methodItem , methodResult . status ) ;
10651127 const legacyMethodName = `Test${ methodItem . label } ` ;
10661128 const methodConsoleLines = consoleByMethod . get ( legacyMethodName ) ?? [ ] ;
1067-
1068- for ( const line of methodConsoleLines ) {
1069- const colored = colorizeLegacyConsoleLine ( line ) ;
1070- testRun . appendOutput ( colored + "\r\n" , undefined , methodItem ) ;
1071- }
1129+ const normalizedMethodName = normalizeLegacyMethodName ( methodItem . label ) ?? methodItem . label ;
1130+ const methodAssertions = assertionsByMethod . get ( normalizedMethodName ) ?? [ ] ;
10721131 const statusText =
10731132 methodResult . status === TestStatus . Passed
10741133 ? "passed"
@@ -1082,8 +1141,39 @@ async function executeLegacyRunner(
10821141 ? `Duration of execution: ${ methodResult . duration } ms`
10831142 : "Duration not available" ) ;
10841143
1085- const summaryLine = ` Método: ${ methodItem . label } | Status: ${ statusText } | ${ durationInfo } ` ;
1086- testRun . appendOutput ( summaryLine + "\r\n" , undefined , methodItem ) ;
1144+ const statusColor =
1145+ methodResult . status === TestStatus . Passed
1146+ ? ANSI_GREEN
1147+ : methodResult . status === TestStatus . Failed
1148+ ? ANSI_RED
1149+ : ANSI_YELLOW ;
1150+
1151+ const summaryLine = `Método: ${ ANSI_BOLD } ${ methodItem . label } ${ ANSI_RESET } | Status: ${ statusColor } ${ statusText } ${ ANSI_RESET } | ${ durationInfo } ` ;
1152+ const fallbackAssertionLines = formatLegacyAssertions ( summaryLine , methodAssertions ) ;
1153+
1154+ let linesToOutput : string [ ] ;
1155+ if ( methodAssertions . length > 0 ) {
1156+ linesToOutput = fallbackAssertionLines ;
1157+ } else if ( methodConsoleLines . length > 0 ) {
1158+ const consoleAssertions = methodConsoleLines
1159+ . filter ( ( line ) => {
1160+ const clean = stripAnsiSequences ( line ) ;
1161+ 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 ) ;
1162+ } )
1163+ . map ( ( line ) => {
1164+ const clean = line . trimStart ( ) ;
1165+ return clean ? ` ${ clean } ` : clean ;
1166+ } ) ;
1167+
1168+ linesToOutput = [ summaryLine , ...consoleAssertions , "" ] ;
1169+ } else {
1170+ linesToOutput = fallbackAssertionLines ;
1171+ }
1172+
1173+ for ( const line of linesToOutput ) {
1174+ const colored = colorizeLegacyConsoleLine ( line ) ;
1175+ testRun . appendOutput ( colored + "\r\n" , undefined , methodItem ) ;
1176+ }
10871177 switch ( methodResult . status ) {
10881178 case TestStatus . Failed : {
10891179 const messages : vscode . TestMessage [ ] = [ ] ;
0 commit comments