Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ test = [
"defusedxml>=0.7.1", # for secure XML/HTML parsing
"setuptools>=70.0", # for Cython compilation
"typing_extensions>=4.9", # for typing_extensions.Unpack
"beautifulsoup4>=4.12", # for HTML parsing in tests
]
translations = [
"babel>=2.13",
Expand Down
71 changes: 59 additions & 12 deletions tests/test_builders/test_build_changes.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,35 +2,82 @@

from __future__ import annotations

import re
from typing import TYPE_CHECKING

import pytest
from bs4 import BeautifulSoup

if TYPE_CHECKING:
from typing import Any

from sphinx.testing.util import SphinxTestApp


@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
soup = BeautifulSoup(htmltext, 'html.parser')

# Get all <li> items up front
all_items = soup.find_all('li')
assert len(all_items) >= 5, 'Did not find all 5 change items'

def find_change_item(type_text: str, version: str, content: str) -> dict[str, Any]:
"""Helper to find and validate change items."""
found_item = None
# Loop through all <li> tags
for item in all_items:
# Check if the content is in the item's *full text*
if re.search(re.escape(content), item.text):
found_item = item
break # Found it!

# This is the assertion that was failing
assert found_item is not None, (
f"Could not find change item containing '{content}'"
)

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

assert f'version {version}' in found_item.text, (
f'Version {version} not found in {content!r}'
)

return {'item': found_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)

path_html = (
'<b>Path</b>: <i>deprecated:</i> Deprecated since version 0.6:'
' So, that was a bad idea it turns out.'
# 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_html in htmltext
assert path_change['item'].find('b').text == 'Path'

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>'
# 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_html in htmltext
assert malloc_change['item'].find('b').text == 'void *Test_Malloc(size_t n)'


@pytest.mark.sphinx(
Expand Down
Loading