Skip to content
Open
Next Next commit
Tests: Refactor test_build_changes to use BeautifulSoup
  • Loading branch information
dariomesic committed Oct 28, 2025
commit 87254e35892440c40026b8955ab2c6d4d7246e77
57 changes: 41 additions & 16 deletions tests/test_builders/test_build_changes.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,28 +9,53 @@
if TYPE_CHECKING:
from sphinx.testing.util import SphinxTestApp

import re # <--- IMPORT ADDED

from bs4 import BeautifulSoup # <--- IMPORT ADDED

Check failure on line 14 in tests/test_builders/test_build_changes.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (I001)

tests/test_builders/test_build_changes.py:12:1: I001 Import block is un-sorted or un-formatted


@pytest.mark.sphinx('changes', testroot='changes')
def test_build(app: SphinxTestApp) -> None:
"""Test the 'changes' builder and resolve TODO for better HTML checking."""
app.build()

# TODO: Use better checking of html content
htmltext = (app.outdir / 'changes.html').read_text(encoding='utf8')
assert 'Added in version 0.6: Some funny stuff.' in htmltext
assert 'Changed in version 0.6: Even more funny stuff.' in htmltext
assert 'Deprecated since version 0.6: Boring stuff.' in htmltext

path_html = (
'<b>Path</b>: <i>deprecated:</i> Deprecated since version 0.6:'
' So, that was a bad idea it turns out.'
)
assert path_html in htmltext

malloc_html = (
'<b>void *Test_Malloc(size_t n)</b>: <i>changed:</i> Changed in version 0.6:'
' Can now be replaced with a different allocator.</a>'
)
assert malloc_html in htmltext
soup = BeautifulSoup(htmltext, 'html.parser')

def find_change_item(type_text: str, version: str, content: str) -> dict:
"""Helper to find and validate change items."""
# Use regex to find text content, ignoring surrounding whitespace/newlines
item = soup.find('li', string=re.compile(r'\s*' + re.escape(content) + r'\s*'))
assert item is not None, f"Could not find change item containing '{content}'"

type_elem = item.find('i')
assert type_elem is not None, f"Missing type indicator for '{content}'"
assert type_text in type_elem.text, f"Expected type '{type_text}' for '{content}'"

assert f"version {version}" in item.text, f"Version {version} not found in '{content}'"

Check failure on line 35 in tests/test_builders/test_build_changes.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (Q000)

tests/test_builders/test_build_changes.py:35:16: Q000 Double quotes found but single quotes preferred

return {'item': item, 'type': type_elem}

# Test simple changes
changes = [
('added', '0.6', 'Some funny stuff.'),
('changed', '0.6', 'Even more funny stuff.'),
('deprecated', '0.6', 'Boring stuff.')
]

for change_type, version, content in changes:
find_change_item(change_type, version, content)

# Test Path deprecation (Search by unique text)
path_change = find_change_item('deprecated', '0.6', 'So, that was a bad idea it turns out.')
assert path_change['item'].find('b').text == 'Path'

# Test Malloc function change (Search by unique text)
malloc_change = find_change_item('changed', '0.6', 'Can now be replaced with a different allocator.')
assert malloc_change['item'].find('b').text == 'void *Test_Malloc(size_t n)'

# Test the other test function still works
assert len(soup.find_all('li')) >= 5 # Make sure we found all items


@pytest.mark.sphinx(
Expand Down
Loading