1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
|
"""Test sphinx.ext.todo extension."""
from __future__ import annotations
import re
from typing import TYPE_CHECKING
import pytest
if TYPE_CHECKING:
from sphinx.testing.util import SphinxTestApp
@pytest.mark.sphinx(
'html',
testroot='ext-todo',
freshenv=True,
confoverrides={'todo_include_todos': True, 'todo_emit_warnings': True},
)
def test_todo(app: SphinxTestApp) -> None:
todos = []
def on_todo_defined(app, node):
todos.append(node)
app.connect('todo-defined', on_todo_defined)
app.build(force_all=True)
# check todolist
content = (app.outdir / 'index.html').read_text(encoding='utf8')
assert '<p class="admonition-title">Todo</p>\n<p>todo in foo</p>' in content
assert '<p class="admonition-title">Todo</p>\n<p>todo in bar</p>' in content
# check todo
content = (app.outdir / 'foo.html').read_text(encoding='utf8')
assert '<p class="admonition-title">Todo</p>\n<p>todo in foo</p>' in content
assert (
'<p class="admonition-title">Todo</p>\n<p>todo in param field</p>'
) in content
# check emitted warnings
assert 'WARNING: TODO entry found: todo in foo' in app.warning.getvalue()
assert 'WARNING: TODO entry found: todo in bar' in app.warning.getvalue()
# check handled event
assert len(todos) == 3
assert {todo[1].astext() for todo in todos} == {
'todo in foo',
'todo in bar',
'todo in param field',
}
@pytest.mark.sphinx(
'html',
testroot='ext-todo',
freshenv=True,
confoverrides={'todo_include_todos': False, 'todo_emit_warnings': True},
)
def test_todo_not_included(app: SphinxTestApp) -> None:
todos = []
def on_todo_defined(app, node):
todos.append(node)
app.connect('todo-defined', on_todo_defined)
app.build(force_all=True)
# check todolist
content = (app.outdir / 'index.html').read_text(encoding='utf8')
assert '<p class="admonition-title">Todo</p>\n<p>todo in foo</p>' not in content
assert '<p class="admonition-title">Todo</p>\n<p>todo in bar</p>' not in content
# check todo
content = (app.outdir / 'foo.html').read_text(encoding='utf8')
assert '<p class="admonition-title">Todo</p>\n<p>todo in foo</p>' not in content
# check emitted warnings
assert 'WARNING: TODO entry found: todo in foo' in app.warning.getvalue()
assert 'WARNING: TODO entry found: todo in bar' in app.warning.getvalue()
# check handled event
assert len(todos) == 3
assert {todo[1].astext() for todo in todos} == {
'todo in foo',
'todo in bar',
'todo in param field',
}
@pytest.mark.sphinx(
'latex',
testroot='ext-todo',
freshenv=True,
confoverrides={'todo_include_todos': True},
)
def test_todo_valid_link(app: SphinxTestApp) -> None:
"""Test that the inserted "original entry" links for todo items have a target
that exists in the LaTeX output. The target was previously incorrectly omitted.
https://github.com/sphinx-doc/sphinx/issues/1020
"""
# Ensure the LaTeX output is built.
app.build(force_all=True)
content = (app.outdir / 'projectnamenotset.tex').read_text(encoding='utf8')
# Look for the link to foo. Note that there are two of them because the
# source document uses todolist twice. We could equally well look for links
# to bar.
link = (
r'{\\hyperref\[\\detokenize{(.*?foo.*?)}]{\\sphinxcrossref{'
r'\\sphinxstyleemphasis{original entry}}}}'
)
m = re.findall(link, content)
assert len(m) == 4
target = m[0]
# Look for the targets of this link.
labels = re.findall(r'\\label{\\detokenize{([^}]*)}}', content)
matched = [l for l in labels if l == target]
# If everything is correct we should have exactly one target.
assert len(matched) == 1
|