Skip to content

Commit a537d07

Browse files
committed
Show dedicated-test counts in coverage pages
1 parent e0df1b0 commit a537d07

1 file changed

Lines changed: 56 additions & 4 deletions

File tree

test-packages/render_all.py

Lines changed: 56 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@
103103

104104
# Package names explicitly referenced in test_gdg_rendered.py (dedicated tests)
105105
_DEDICATED_PACKAGES: set[str] = set()
106+
_DEDICATED_COUNTS: dict[str, int] = {}
106107

107108

108109
def _load_dedicated_packages() -> set[str]:
@@ -116,6 +117,37 @@ def _load_dedicated_packages() -> set[str]:
116117
return _DEDICATED_PACKAGES
117118

118119

120+
def _count_dedicated_tests(name: str) -> int:
121+
"""Count dedicated test functions that reference a given package.
122+
123+
Looks for functions decorated with ``@pytest.mark.dedicated`` and counts
124+
how many reference the package name in their decorator block + body.
125+
"""
126+
global _DEDICATED_COUNTS # noqa: PLW0603
127+
if not _DEDICATED_COUNTS:
128+
test_file = _PROJECT_ROOT / "tests" / "test_gdg_rendered.py"
129+
if not test_file.exists():
130+
return 0
131+
content = test_file.read_text()
132+
# Split into function blocks
133+
fn_positions = [
134+
(m.start(), m.group(1))
135+
for m in re.finditer(r"\ndef (test_\w+)", content)
136+
]
137+
for idx, (pos, _fn_name) in enumerate(fn_positions):
138+
# Look for @pytest.mark.dedicated in the decorator block
139+
decorator_block = content[max(0, pos - 1500) : pos]
140+
if "@pytest.mark.dedicated" not in decorator_block:
141+
continue
142+
# Get function body
143+
end = fn_positions[idx + 1][0] if idx + 1 < len(fn_positions) else len(content)
144+
fn_body = content[pos:end]
145+
search_text = decorator_block + fn_body
146+
for pkg in set(re.findall(r"gdtest_[a-z0-9_]+", search_text)):
147+
_DEDICATED_COUNTS[pkg] = _DEDICATED_COUNTS.get(pkg, 0) + 1
148+
return _DEDICATED_COUNTS.get(name, 0)
149+
150+
119151
def _compute_coverage(name: str) -> dict[str, bool]:
120152
"""Compute test coverage levels for a single package.
121153
@@ -1062,6 +1094,7 @@ def _create_test_coverage_page(name: str) -> str:
10621094
color = "#f38ba8"
10631095

10641096
# Build the coverage table rows
1097+
ded_count = _count_dedicated_tests(name)
10651098
rows = []
10661099
for level in _COVERAGE_LEVELS:
10671100
covered = coverage.get(level, False)
@@ -1077,10 +1110,18 @@ def _create_test_coverage_page(name: str) -> str:
10771110
else:
10781111
icon = "❌"
10791112
row_class = "cov-miss"
1113+
# For DED, show the count badge
1114+
level_display = html.escape(level)
1115+
if level == "DED" and ded_count > 0:
1116+
level_display = (
1117+
f'{html.escape(level)}'
1118+
f' <span class="ded-count">×{ded_count}</span>'
1119+
)
1120+
desc = f"{ded_count} dedicated test{'s' if ded_count != 1 else ''} for this package"
10801121
rows.append(
10811122
f'<tr class="{row_class}">'
10821123
f"<td>{icon}</td>"
1083-
f'<td class="cov-level">{html.escape(level)}</td>'
1124+
f'<td class="cov-level">{level_display}</td>'
10841125
f'<td class="cov-fn">{html.escape(test_fn)}</td>'
10851126
f'<td class="cov-desc">{html.escape(desc)}</td>'
10861127
f"</tr>"
@@ -1197,6 +1238,11 @@ def _create_test_coverage_page(name: str) -> str:
11971238
.cov-miss .cov-fn {{ color: #484e58; }}
11981239
.cov-excluded .cov-fn {{ color: #484e58; }}
11991240
.cov-desc {{ max-width: 300px; }}
1241+
.ded-count {{
1242+
display: inline-block; padding: 1px 6px; margin-left: 4px;
1243+
border-radius: 10px; font-size: 10px; font-weight: 700;
1244+
background: #a6e3a120; color: #a6e3a1; border: 1px solid #a6e3a140;
1245+
}}
12001246
.counter {{ display: flex; gap: 16px; margin-bottom: 16px; }}
12011247
.counter-item {{
12021248
padding: 4px 12px; border-radius: 4px; font-size: 13px; font-weight: 600;
@@ -1528,7 +1574,8 @@ def _create_test_coverage_summary_page(results: list[dict]) -> str:
15281574
else:
15291575
color = "#f38ba8"
15301576
num = ALL_PACKAGES.index(name) + 1 if name in ALL_PACKAGES else 0
1531-
ded_icon = "✓" if p["coverage"].get("DED") else ""
1577+
ded_n = _count_dedicated_tests(name)
1578+
ded_cell = f'<span class="ded-badge">{ded_n}</span>' if ded_n > 0 else "—"
15321579

15331580
# Level dots (pass/miss/excluded)
15341581
dots = []
@@ -1550,7 +1597,7 @@ def _create_test_coverage_summary_page(results: list[dict]) -> str:
15501597
f'<td class="pkg-score">{p["score"]}/{p["max"]}</td>'
15511598
f'<td class="pkg-excl">{p["excluded"]}</td>'
15521599
f'<td class="dot-row">{dots_html}</td>'
1553-
f'<td class="ded-icon">{ded_icon}</td>'
1600+
f'<td class="ded-icon">{ded_cell}</td>'
15541601
f"</tr>"
15551602
)
15561603
pkg_table = "\n ".join(pkg_rows)
@@ -1648,7 +1695,12 @@ def _create_test_coverage_summary_page(results: list[dict]) -> str:
16481695
.dot-pass {{ color: #a6e3a1; }}
16491696
.dot-miss {{ color: #f38ba8; }}
16501697
.dot-excl {{ color: #30363d; }}
1651-
.ded-icon {{ color: #a6e3a1; font-weight: 700; text-align: center; }}
1698+
.ded-icon {{ text-align: center; }}
1699+
.ded-badge {{
1700+
display: inline-block; padding: 2px 7px; border-radius: 10px;
1701+
font-size: 11px; font-weight: 700; font-family: "SF Mono", monospace;
1702+
background: #a6e3a118; color: #a6e3a1; border: 1px solid #a6e3a140;
1703+
}}
16521704
.hist-container {{
16531705
display: flex; align-items: flex-end; gap: 6px;
16541706
padding: 0 4px;

0 commit comments

Comments
 (0)