mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Spring-clean `sphinx.testing.utils
` (#11534)
This commit is contained in:
parent
1cfb68d8be
commit
629b862cde
@ -1,7 +1,6 @@
|
|||||||
"""Sphinx test suite utilities"""
|
"""Sphinx test suite utilities"""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import functools
|
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
@ -20,24 +19,7 @@ if TYPE_CHECKING:
|
|||||||
from io import StringIO
|
from io import StringIO
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
__all__ = [
|
__all__ = 'SphinxTestApp', 'SphinxTestAppWrapperForSkipBuilding'
|
||||||
'Struct', 'SphinxTestApp', 'SphinxTestAppWrapperForSkipBuilding',
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
def assert_re_search(regex: re.Pattern, text: str, flags: int = 0) -> None:
|
|
||||||
if not re.search(regex, text, flags):
|
|
||||||
raise AssertionError(f'{regex!r} did not match {text!r}')
|
|
||||||
|
|
||||||
|
|
||||||
def assert_not_re_search(regex: re.Pattern, text: str, flags: int = 0) -> None:
|
|
||||||
if re.search(regex, text, flags):
|
|
||||||
raise AssertionError(f'{regex!r} did match {text!r}')
|
|
||||||
|
|
||||||
|
|
||||||
def assert_startswith(thing: str, prefix: str) -> None:
|
|
||||||
if not thing.startswith(prefix):
|
|
||||||
raise AssertionError(f'{thing!r} does not start with {prefix!r}')
|
|
||||||
|
|
||||||
|
|
||||||
def assert_node(node: Node, cls: Any = None, xpath: str = "", **kwargs: Any) -> None:
|
def assert_node(node: Node, cls: Any = None, xpath: str = "", **kwargs: Any) -> None:
|
||||||
@ -86,11 +68,6 @@ def etree_parse(path: str) -> Any:
|
|||||||
return ElementTree.parse(path) # NoQA: S314 # using known data in tests
|
return ElementTree.parse(path) # NoQA: S314 # using known data in tests
|
||||||
|
|
||||||
|
|
||||||
class Struct:
|
|
||||||
def __init__(self, **kwargs: Any) -> None:
|
|
||||||
self.__dict__.update(kwargs)
|
|
||||||
|
|
||||||
|
|
||||||
class SphinxTestApp(application.Sphinx):
|
class SphinxTestApp(application.Sphinx):
|
||||||
"""
|
"""
|
||||||
A subclass of :class:`Sphinx` that runs on the test root, with some
|
A subclass of :class:`Sphinx` that runs on the test root, with some
|
||||||
@ -190,18 +167,5 @@ class SphinxTestAppWrapperForSkipBuilding:
|
|||||||
# otherwise, we can use built cache
|
# otherwise, we can use built cache
|
||||||
|
|
||||||
|
|
||||||
_unicode_literals_re = re.compile(r'u(".*?")|u(\'.*?\')')
|
|
||||||
|
|
||||||
|
|
||||||
def strip_escseq(text: str) -> str:
|
def strip_escseq(text: str) -> str:
|
||||||
return re.sub('\x1b.*?m', '', text)
|
return re.sub('\x1b.*?m', '', text)
|
||||||
|
|
||||||
|
|
||||||
def simple_decorator(f):
|
|
||||||
"""
|
|
||||||
A simple decorator that does nothing, for tests to use.
|
|
||||||
"""
|
|
||||||
@functools.wraps(f)
|
|
||||||
def wrapper(*args, **kwargs):
|
|
||||||
return f(*args, **kwargs)
|
|
||||||
return wrapper
|
|
||||||
|
@ -5,6 +5,7 @@ source file translated by test_build.
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
|
from types import SimpleNamespace
|
||||||
from unittest.mock import Mock
|
from unittest.mock import Mock
|
||||||
from warnings import catch_warnings
|
from warnings import catch_warnings
|
||||||
|
|
||||||
@ -14,7 +15,6 @@ from docutils.statemachine import ViewList
|
|||||||
from sphinx import addnodes
|
from sphinx import addnodes
|
||||||
from sphinx.ext.autodoc import ALL, ModuleLevelDocumenter, Options
|
from sphinx.ext.autodoc import ALL, ModuleLevelDocumenter, Options
|
||||||
from sphinx.ext.autodoc.directive import DocumenterBridge, process_documenter_options
|
from sphinx.ext.autodoc.directive import DocumenterBridge, process_documenter_options
|
||||||
from sphinx.testing.util import SphinxTestApp, Struct # noqa: F401
|
|
||||||
from sphinx.util.docutils import LoggingReporter
|
from sphinx.util.docutils import LoggingReporter
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@ -59,7 +59,7 @@ def make_directive_bridge(env):
|
|||||||
ignore_module_all = False,
|
ignore_module_all = False,
|
||||||
)
|
)
|
||||||
|
|
||||||
directive = Struct(
|
directive = SimpleNamespace(
|
||||||
env = env,
|
env = env,
|
||||||
genopt = options,
|
genopt = options,
|
||||||
result = ViewList(),
|
result = ViewList(),
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
"""Tests for :mod:`sphinx.ext.napoleon.__init__` module."""
|
"""Tests for :mod:`sphinx.ext.napoleon.__init__` module."""
|
||||||
|
|
||||||
|
import functools
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
from unittest import mock
|
from unittest import mock
|
||||||
|
|
||||||
@ -7,7 +8,16 @@ import pytest
|
|||||||
|
|
||||||
from sphinx.application import Sphinx
|
from sphinx.application import Sphinx
|
||||||
from sphinx.ext.napoleon import Config, _process_docstring, _skip_member, setup
|
from sphinx.ext.napoleon import Config, _process_docstring, _skip_member, setup
|
||||||
from sphinx.testing.util import simple_decorator
|
|
||||||
|
|
||||||
|
def simple_decorator(f):
|
||||||
|
"""
|
||||||
|
A simple decorator that does nothing, for tests to use.
|
||||||
|
"""
|
||||||
|
@functools.wraps(f)
|
||||||
|
def wrapper(*args, **kwargs):
|
||||||
|
return f(*args, **kwargs)
|
||||||
|
return wrapper
|
||||||
|
|
||||||
|
|
||||||
def _private_doc():
|
def _private_doc():
|
||||||
|
@ -17,14 +17,7 @@ from babel.messages.catalog import Catalog
|
|||||||
from docutils import nodes
|
from docutils import nodes
|
||||||
|
|
||||||
from sphinx import locale
|
from sphinx import locale
|
||||||
from sphinx.testing.util import (
|
from sphinx.testing.util import assert_node, etree_parse, strip_escseq
|
||||||
assert_node,
|
|
||||||
assert_not_re_search,
|
|
||||||
assert_re_search,
|
|
||||||
assert_startswith,
|
|
||||||
etree_parse,
|
|
||||||
strip_escseq,
|
|
||||||
)
|
|
||||||
from sphinx.util.nodes import NodeMatcher
|
from sphinx.util.nodes import NodeMatcher
|
||||||
|
|
||||||
sphinx_intl = pytest.mark.sphinx(
|
sphinx_intl = pytest.mark.sphinx(
|
||||||
@ -105,7 +98,7 @@ def test_text_emit_warnings(app, warning):
|
|||||||
warnings = getwarning(warning)
|
warnings = getwarning(warning)
|
||||||
warning_expr = ('.*/warnings.txt:4:<translated>:1: '
|
warning_expr = ('.*/warnings.txt:4:<translated>:1: '
|
||||||
'WARNING: Inline literal start-string without end-string.\n')
|
'WARNING: Inline literal start-string without end-string.\n')
|
||||||
assert_re_search(warning_expr, warnings)
|
assert re.search(warning_expr, warnings), f'{warning_expr!r} did not match {warnings!r}'
|
||||||
|
|
||||||
|
|
||||||
@sphinx_intl
|
@sphinx_intl
|
||||||
@ -142,7 +135,7 @@ def test_text_subdirs(app):
|
|||||||
app.build()
|
app.build()
|
||||||
# --- check translation in subdirs
|
# --- check translation in subdirs
|
||||||
result = (app.outdir / 'subdir' / 'index.txt').read_text(encoding='utf8')
|
result = (app.outdir / 'subdir' / 'index.txt').read_text(encoding='utf8')
|
||||||
assert_startswith(result, "1. subdir contents\n******************\n")
|
assert result.startswith('1. subdir contents\n******************\n')
|
||||||
|
|
||||||
|
|
||||||
@sphinx_intl
|
@sphinx_intl
|
||||||
@ -187,12 +180,12 @@ def test_text_inconsistency_warnings(app, warning):
|
|||||||
'original': "\\[\\]",
|
'original': "\\[\\]",
|
||||||
'translated': "\\['`I18N WITH REFS INCONSISTENCY`_'\\]",
|
'translated': "\\['`I18N WITH REFS INCONSISTENCY`_'\\]",
|
||||||
})
|
})
|
||||||
assert_re_search(expected_warning_expr, warnings)
|
assert re.search(expected_warning_expr, warnings), f'{expected_warning_expr!r} did not match {warnings!r}'
|
||||||
|
|
||||||
expected_citation_warning_expr = (
|
expected_citation_warning_expr = (
|
||||||
'.*/refs_inconsistency.txt:\\d+: WARNING: Citation \\[ref2\\] is not referenced.\n' +
|
'.*/refs_inconsistency.txt:\\d+: WARNING: Citation \\[ref2\\] is not referenced.\n' +
|
||||||
'.*/refs_inconsistency.txt:\\d+: WARNING: citation not found: ref3')
|
'.*/refs_inconsistency.txt:\\d+: WARNING: citation not found: ref3')
|
||||||
assert_re_search(expected_citation_warning_expr, warnings)
|
assert re.search(expected_citation_warning_expr, warnings), f'{expected_citation_warning_expr!r} did not match {warnings!r}'
|
||||||
|
|
||||||
|
|
||||||
@sphinx_intl
|
@sphinx_intl
|
||||||
@ -235,12 +228,12 @@ def test_text_literalblock_warnings(app, warning):
|
|||||||
"\n literal block\n"
|
"\n literal block\n"
|
||||||
"\nMISSING LITERAL BLOCK:\n"
|
"\nMISSING LITERAL BLOCK:\n"
|
||||||
"\n<SYSTEM MESSAGE:")
|
"\n<SYSTEM MESSAGE:")
|
||||||
assert_startswith(result, expect)
|
assert result.startswith(expect)
|
||||||
|
|
||||||
warnings = getwarning(warning)
|
warnings = getwarning(warning)
|
||||||
expected_warning_expr = ('.*/literalblock.txt:\\d+: '
|
expected_warning_expr = ('.*/literalblock.txt:\\d+: '
|
||||||
'WARNING: Literal block expected; none found.')
|
'WARNING: Literal block expected; none found.')
|
||||||
assert_re_search(expected_warning_expr, warnings)
|
assert re.search(expected_warning_expr, warnings), f'{expected_warning_expr!r} did not match {warnings!r}'
|
||||||
|
|
||||||
|
|
||||||
@sphinx_intl
|
@sphinx_intl
|
||||||
@ -316,7 +309,7 @@ def test_text_glossary_term_inconsistencies(app, warning):
|
|||||||
'WARNING: inconsistent term references in translated message.'
|
'WARNING: inconsistent term references in translated message.'
|
||||||
" original: \\[':term:`Some term`', ':term:`Some other term`'\\],"
|
" original: \\[':term:`Some term`', ':term:`Some other term`'\\],"
|
||||||
" translated: \\[':term:`SOME NEW TERM`'\\]\n")
|
" translated: \\[':term:`SOME NEW TERM`'\\]\n")
|
||||||
assert_re_search(expected_warning_expr, warnings)
|
assert re.search(expected_warning_expr, warnings), f'{expected_warning_expr!r} did not match {warnings!r}'
|
||||||
|
|
||||||
|
|
||||||
@sphinx_intl
|
@sphinx_intl
|
||||||
@ -798,7 +791,7 @@ def test_html_index_entries(app):
|
|||||||
wrap_nest('li', 'ul', 'SEE'),
|
wrap_nest('li', 'ul', 'SEE'),
|
||||||
]
|
]
|
||||||
for expr in expected_exprs:
|
for expr in expected_exprs:
|
||||||
assert_re_search(expr, result, re.M)
|
assert re.search(expr, result, re.MULTILINE), f'{expr!r} did not match {result!r}'
|
||||||
|
|
||||||
|
|
||||||
@sphinx_intl
|
@sphinx_intl
|
||||||
@ -927,7 +920,7 @@ def test_xml_footnotes(app, warning):
|
|||||||
|
|
||||||
warnings = getwarning(warning)
|
warnings = getwarning(warning)
|
||||||
warning_expr = '.*/footnote.xml:\\d*: SEVERE: Duplicate ID: ".*".\n'
|
warning_expr = '.*/footnote.xml:\\d*: SEVERE: Duplicate ID: ".*".\n'
|
||||||
assert_not_re_search(warning_expr, warnings)
|
assert not re.search(warning_expr, warnings), f'{warning_expr!r} did match {warnings!r}'
|
||||||
|
|
||||||
|
|
||||||
@sphinx_intl
|
@sphinx_intl
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
import re
|
import re
|
||||||
import warnings
|
import warnings
|
||||||
|
from types import SimpleNamespace
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from docutils import frontend, nodes, utils
|
from docutils import frontend, nodes, utils
|
||||||
@ -12,7 +13,7 @@ from sphinx.builders.html.transforms import KeyboardTransform
|
|||||||
from sphinx.builders.latex import LaTeXBuilder
|
from sphinx.builders.latex import LaTeXBuilder
|
||||||
from sphinx.environment import default_settings
|
from sphinx.environment import default_settings
|
||||||
from sphinx.roles import XRefRole
|
from sphinx.roles import XRefRole
|
||||||
from sphinx.testing.util import Struct, assert_node
|
from sphinx.testing.util import assert_node
|
||||||
from sphinx.transforms import SphinxSmartQuotes
|
from sphinx.transforms import SphinxSmartQuotes
|
||||||
from sphinx.util import texescape
|
from sphinx.util import texescape
|
||||||
from sphinx.util.docutils import sphinx_domains
|
from sphinx.util.docutils import sphinx_domains
|
||||||
@ -55,7 +56,7 @@ def new_document(settings):
|
|||||||
def inliner(new_document):
|
def inliner(new_document):
|
||||||
document = new_document()
|
document = new_document()
|
||||||
document.reporter.get_source_and_line = lambda line=1: ('dummy.rst', line)
|
document.reporter.get_source_and_line = lambda line=1: ('dummy.rst', line)
|
||||||
return Struct(document=document, reporter=document.reporter)
|
return SimpleNamespace(document=document, reporter=document.reporter)
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture()
|
@pytest.fixture()
|
||||||
|
Loading…
Reference in New Issue
Block a user