Parse error details section to extract error messages for each test.
(test_results: TestResult, lines: list[str])
| 173 | |
| 174 | |
| 175 | def _parse_error_details(test_results: TestResult, lines: list[str]) -> None: |
| 176 | """Parse error details section to extract error messages for each test.""" |
| 177 | # Build a lookup dict for tests by (name, path) |
| 178 | test_lookup: dict[tuple[str, str], Test] = {} |
| 179 | for test in test_results.tests: |
| 180 | test_lookup[(test.name, test.path)] = test |
| 181 | |
| 182 | # Parse error detail blocks |
| 183 | # Format: |
| 184 | # ====================================================================== |
| 185 | # FAIL: test_name (path) |
| 186 | # ---------------------------------------------------------------------- |
| 187 | # Traceback (most recent call last): |
| 188 | # ... |
| 189 | # AssertionError: message |
| 190 | # |
| 191 | # ====================================================================== |
| 192 | i = 0 |
| 193 | while i < len(lines): |
| 194 | line = lines[i] |
| 195 | # Look for FAIL: or ERROR: header |
| 196 | if line.startswith(("FAIL: ", "ERROR: ")): |
| 197 | # Parse: "FAIL: test_name (path)" or "ERROR: test_name (path)" |
| 198 | header = line.split(": ", 1)[1] if ": " in line else "" |
| 199 | first_space = header.find(" ") |
| 200 | if first_space > 0: |
| 201 | test_name = header[:first_space] |
| 202 | path_part = header[first_space:].strip() |
| 203 | if path_part.startswith("(") and path_part.endswith(")"): |
| 204 | test_path = path_part[1:-1] |
| 205 | |
| 206 | # Find the last non-empty line before the next separator or end |
| 207 | error_lines = [] |
| 208 | i += 1 |
| 209 | # Skip the separator line |
| 210 | if i < len(lines) and lines[i].startswith("-----"): |
| 211 | i += 1 |
| 212 | |
| 213 | # Collect lines until the next separator or end |
| 214 | while i < len(lines): |
| 215 | current = lines[i] |
| 216 | if current.startswith("=====") or current.startswith("-----"): |
| 217 | break |
| 218 | error_lines.append(current) |
| 219 | i += 1 |
| 220 | |
| 221 | # Find the last non-empty line (the error message) |
| 222 | error_message = "" |
| 223 | for err_line in reversed(error_lines): |
| 224 | stripped = err_line.strip() |
| 225 | if stripped: |
| 226 | error_message = stripped |
| 227 | break |
| 228 | |
| 229 | # Update the test with the error message |
| 230 | if (test_name, test_path) in test_lookup: |
| 231 | test_lookup[ |
| 232 | (test_name, test_path) |
no test coverage detected