Skip to content

Commit 0bd0f5a

Browse files
committed
Fix unit test failure (#73)
1 parent 495d2de commit 0bd0f5a

File tree

1 file changed

+104
-14
lines changed

1 file changed

+104
-14
lines changed

src/commands/unitTest.ts

Lines changed: 104 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -94,9 +94,12 @@ const textDecoder = new TextDecoder();
9494
const ANSI_RESET = "\u001b[0m";
9595
const ANSI_RED = "\u001b[31m";
9696
const ANSI_GREEN = "\u001b[32m";
97+
const ANSI_YELLOW = "\u001b[33m";
98+
const ANSI_BOLD = "\u001b[1m";
9799

98100
const LEGACY_FAIL_MARKER = "<<====== FAILED ======>>";
99101
const LEGACY_PASS_REGEX = /\bpassed\b/i;
102+
const LEGACY_STATUS_REGEX = /Status:\s*(\w+)/i;
100103

101104
const 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 (/^ztest/i.test(working)) {
377+
working = working.slice(1);
378+
}
379+
if (/^test/i.test(working)) {
380+
working = working.slice(4);
381+
}
382+
const normalized = working.trim();
383+
return normalized ? normalized : undefined;
363384
}
364385

365386
function parseLegacyLabelFromText(text?: string): string | undefined {
@@ -840,7 +861,7 @@ async function addItemForClassUri(testController: vscode.TestController, uri: vs
840861

841862
function groupConsoleByMethod(lines: string[]): Map<string, string[]> {
842863
const map = new Map<string, string[]>();
843-
const headerRegex = /Método:\s*(\S+)/i;
864+
const headerRegex = /Met[óo]do:\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+
873934
async 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 !/Met[óo]do:/i.test(clean) && !/Fim da execu[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

Comments
 (0)