Skip to content

Commit 8ac400e

Browse files
committed
chore: fix dashboard displaying failed cases
1 parent b17085e commit 8ac400e

1 file changed

Lines changed: 23 additions & 46 deletions

File tree

tools/render_coverage_dashboard.py

Lines changed: 23 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,9 @@ def total(self) -> int:
216216
.status-fail { color: #c52b2f; font-weight: 700; }
217217
.status-skip { color: #8b5a00; font-weight: 700; }
218218
219+
.failure-list { margin: 0; padding-left: 22px; }
220+
.failure-list li + li { margin-top: 6px; }
221+
219222
.metadata {
220223
display: grid;
221224
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
@@ -298,6 +301,10 @@ def detail_from_element(element: ElementTree.Element) -> str:
298301
return "\n".join(part for part in (message, body) if part)
299302

300303

304+
def normalize_test_name(value: str) -> str:
305+
return value.split(" # GetParam() = ", 1)[0].strip()
306+
307+
301308
def parse_junit(path: Path) -> TestSummary:
302309
if not path.exists():
303310
return TestSummary([], "CTest did not produce a JUnit XML file.")
@@ -312,9 +319,13 @@ def parse_junit(path: Path) -> TestSummary:
312319
if local_name(element.tag) != "testcase":
313320
continue
314321

315-
class_name = element.attrib.get("classname", "").strip()
316-
case_name = element.attrib.get("name", "unnamed test").strip()
317-
name = f"{class_name}.{case_name}" if class_name else case_name
322+
class_name = normalize_test_name(element.attrib.get("classname", "").strip())
323+
case_name = normalize_test_name(element.attrib.get("name", "unnamed test").strip())
324+
name = (
325+
f"{class_name}.{case_name}"
326+
if class_name and case_name and class_name != case_name
327+
else case_name or class_name or "unnamed test"
328+
)
318329
status = "PASS"
319330
detail = ""
320331
for child in element:
@@ -447,14 +458,6 @@ def metric_detail(metric: Metric) -> str:
447458
return f"{metric.covered:,} / {metric.total:,} covered"
448459

449460

450-
def format_duration(value: float | None) -> str:
451-
if value is None:
452-
return "n/a"
453-
if value >= 1:
454-
return f"{value:.2f} s"
455-
return f"{value * 1000:.0f} ms"
456-
457-
458461
def navigation(active: str) -> str:
459462
items = (("overview", "index.html", "Overview"), ("tests", "tests.html", "Tests"), ("coverage", "coverage/index.html", "Coverage"))
460463
links = []
@@ -588,40 +591,19 @@ def overview_page(
588591

589592

590593
def tests_page(args: argparse.Namespace, tests: TestSummary, generated_at: str) -> str:
591-
failure_details = ""
592594
failures = [case for case in tests.cases if case.status == "FAIL"]
593595
if failures:
594-
failure_details = "".join(
595-
f""" <details open>
596-
<summary>{escape(case.name)}</summary>
597-
<pre>{escape(case.detail or 'CTest did not include failure output.')}</pre>
598-
</details>"""
596+
failure_list = "\n".join(
597+
f" <li><code>{escape(case.name)}</code></li>"
599598
for case in failures
600599
)
600+
failure_section = f""" <ul class="failure-list">
601+
{failure_list}
602+
</ul>"""
601603
elif tests.unavailable_reason:
602-
failure_details = f'<p class="empty">{escape(tests.unavailable_reason)}</p>'
604+
failure_section = f'<p class="empty">{escape(tests.unavailable_reason)}</p>'
603605
else:
604-
failure_details = '<p class="empty">No failing CTest cases were reported.</p>'
605-
606-
order = {"FAIL": 0, "SKIP": 1, "PASS": 2}
607-
test_rows = "".join(
608-
"<tr>"
609-
f"<td><code>{escape(case.name)}</code></td>"
610-
f"<td class=\"status-{case.status.lower()}\">{escape(case.status)}</td>"
611-
f"<td>{format_duration(case.duration)}</td>"
612-
"</tr>"
613-
for case in sorted(tests.cases, key=lambda case: (order[case.status], case.name))
614-
)
615-
result_table = (
616-
f""" <div class="table-wrap">
617-
<table>
618-
<thead><tr><th>CTest case</th><th>Result</th><th>Duration</th></tr></thead>
619-
<tbody>{test_rows}</tbody>
620-
</table>
621-
</div>"""
622-
if test_rows
623-
else f'<p class="empty">{escape(tests.unavailable_reason or "No CTest cases were reported.")}</p>'
624-
)
606+
failure_section = '<p class="empty">No failing CTest cases were reported.</p>'
625607
return page(
626608
"AviSynthPlus-UT Test Results",
627609
"tests",
@@ -637,13 +619,8 @@ def tests_page(args: argparse.Namespace, tests: TestSummary, generated_at: str)
637619
</div>
638620
639621
<section class="section">
640-
<h2>Failure output</h2>
641-
{failure_details}
642-
</section>
643-
644-
<section class="section">
645-
<h2>All CTest cases</h2>
646-
{result_table}
622+
<h2>Failed tests</h2>
623+
{failure_section}
647624
</section>
648625
649626
<section class="section">

0 commit comments

Comments
 (0)