From 46fc0a4b3dccce58c429f408c04cf5cda3af9fb5 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Thu, 19 Sep 2024 06:57:07 +0200 Subject: Adding upstream version 7.4.7. Signed-off-by: Daniel Baumann --- tests/js/fixtures/cpp/searchindex.js | 1 + tests/js/fixtures/multiterm/searchindex.js | 1 + tests/js/fixtures/partial/searchindex.js | 1 + tests/js/fixtures/titles/searchindex.js | 1 + tests/js/language_data.js | 26 +++ tests/js/roots/cpp/conf.py | 0 tests/js/roots/cpp/index.rst | 10 + tests/js/roots/multiterm/conf.py | 0 tests/js/roots/multiterm/index.rst | 13 ++ tests/js/roots/partial/conf.py | 0 tests/js/roots/partial/index.rst | 9 + tests/js/roots/titles/conf.py | 6 + tests/js/roots/titles/index.rst | 20 ++ tests/js/roots/titles/relevance.py | 7 + tests/js/roots/titles/relevance.rst | 13 ++ tests/js/searchtools.js | 166 +++++++++++---- .../conf.py | 5 +- tests/roots/test-add_source_parser/conf.py | 1 - tests/roots/test-autosummary/conf.py | 2 - tests/roots/test-build-text/conf.py | 4 +- .../index.rst | 13 ++ tests/roots/test-domain-py/index.rst | 1 + tests/roots/test-domain-py/module.rst | 3 + tests/roots/test-domain-py/roles.rst | 6 + tests/roots/test-domain-py/type_alias.rst | 15 ++ tests/roots/test-ext-autodoc/conf.py | 3 - tests/roots/test-ext-autodoc/target/annotated.py | 36 +++- .../test-ext-autosummary-import_cycle/conf.py | 7 + .../test-ext-autosummary-import_cycle/index.rst | 6 + .../spam/__init__.py | 1 + .../test-ext-autosummary-import_cycle/spam/eggs.py | 10 + .../test-ext-autosummary-module_prefix/conf.py | 8 + .../test-ext-autosummary-module_prefix/index.rst | 5 + .../pkg/__init__.py | 0 .../pkg/mod0/__init__.py | 0 .../pkg/mod1/__init__.py | 0 tests/roots/test-ext-autosummary/conf.py | 3 - tests/roots/test-ext-coverage/conf.py | 5 +- tests/roots/test-ext-coverage/coverage_ignored.py | 22 -- .../test-ext-coverage/coverage_not_ignored.py | 22 -- tests/roots/test-ext-coverage/grog/__init__.py | 0 .../test-ext-coverage/grog/coverage_ignored.py | 22 ++ .../test-ext-coverage/grog/coverage_missing.py | 7 + .../test-ext-coverage/grog/coverage_not_ignored.py | 22 ++ tests/roots/test-ext-coverage/index.rst | 4 +- tests/roots/test-ext-doctest-skipif/conf.py | 4 +- tests/roots/test-ext-doctest/conf.py | 4 +- tests/roots/test-html_assets/extra/API.html.jinja | 1 + tests/roots/test-html_assets/extra/API.html_t | 1 - tests/roots/test-html_assets/static/API.html.jinja | 1 + tests/roots/test-html_assets/static/API.html_t | 1 - tests/roots/test-images/index.rst | 5 + tests/roots/test-inheritance/conf.py | 1 - tests/roots/test-intl/conf.py | 4 +- .../test-intl/glossary_terms_inconsistency.txt | 1 + tests/roots/test-intl/index.txt | 1 + tests/roots/test-intl/markup.txt | 6 + tests/roots/test-intl/role_xref.txt | 3 + .../xx/LC_MESSAGES/glossary_terms_inconsistency.po | 3 + .../roots/test-intl/xx/LC_MESSAGES/literalblock.po | 32 ++- tests/roots/test-intl/xx/LC_MESSAGES/markup.po | 25 +++ .../roots/test-latex-figure-in-admonition/conf.py | 2 + .../test-latex-figure-in-admonition/index.rst | 19 +- .../_mytemplates/latex/longtable.tex.jinja | 1 + .../_mytemplates/latex/longtable.tex_t | 1 - .../_mytemplates/latex/tabulary.tex_t | 1 + .../index.rst | 1 + tests/roots/test-markup-rubric/conf.py | 1 + tests/roots/test-markup-rubric/index.rst | 32 +++ tests/roots/test-root/conf.py | 7 +- tests/roots/test-root/images.txt | 8 + tests/roots/test-root/markup.txt | 13 ++ tests/roots/test-templating/conf.py | 4 +- .../staticfiles/static/legacytmpl.html_t | 2 + .../staticfiles/static/statictmpl.html.jinja | 2 + .../staticfiles/static/statictmpl.html_t | 2 - .../document_scoping.rst | 23 ++ tests/roots/test-toctree-domain-objects/index.rst | 1 + tests/roots/test-util-copyasset_overwrite/conf.py | 7 + .../roots/test-util-copyasset_overwrite/index.rst | 0 tests/roots/test-util-copyasset_overwrite/myext.py | 22 ++ .../myext_static/custom-styles.css | 1 + .../user_static/custom-styles.css | 1 + tests/roots/test-versioning/conf.py | 4 +- tests/test_addnodes.py | 2 +- tests/test_application.py | 2 +- tests/test_builders/test_build.py | 2 +- tests/test_builders/test_build_dirhtml.py | 8 +- tests/test_builders/test_build_epub.py | 11 +- tests/test_builders/test_build_gettext.py | 51 ++++- tests/test_builders/test_build_html.py | 77 ++++++- tests/test_builders/test_build_html_5_output.py | 33 ++- tests/test_builders/test_build_html_assets.py | 2 +- tests/test_builders/test_build_html_download.py | 1 - tests/test_builders/test_build_html_image.py | 5 +- tests/test_builders/test_build_latex.py | 166 +++++++++------ tests/test_builders/test_build_linkcheck.py | 235 +++++++++++++++------ tests/test_builders/test_build_manpage.py | 10 +- tests/test_builders/test_build_texinfo.py | 10 +- tests/test_config/test_config.py | 18 +- tests/test_directives/test_directive_code.py | 16 +- tests/test_directives/test_directive_other.py | 12 ++ tests/test_domains/test_domain_cpp.py | 108 +++++----- tests/test_domains/test_domain_py.py | 80 +++++-- tests/test_domains/test_domain_py_pyobject.py | 71 +++++++ tests/test_environment/test_environment.py | 2 +- .../test_environment_indexentries.py | 86 ++++---- tests/test_environment/test_environment_toctree.py | 37 +++- tests/test_extensions/test_ext_apidoc.py | 25 ++- tests/test_extensions/test_ext_autodoc.py | 54 ++++- .../test_extensions/test_ext_autodoc_automodule.py | 16 ++ tests/test_extensions/test_ext_autodoc_configs.py | 31 ++- tests/test_extensions/test_ext_autosummary.py | 38 +++- .../test_ext_autosummary_imports.py | 49 +++++ tests/test_extensions/test_ext_coverage.py | 40 ++-- tests/test_extensions/test_ext_graphviz.py | 2 +- tests/test_extensions/test_ext_imgconverter.py | 4 +- tests/test_extensions/test_ext_imgmockconverter.py | 2 +- .../test_ext_inheritance_diagram.py | 2 +- tests/test_extensions/test_ext_intersphinx.py | 33 ++- tests/test_extensions/test_ext_math.py | 22 +- tests/test_extensions/test_ext_todo.py | 2 +- tests/test_extensions/test_ext_viewcode.py | 4 + tests/test_intl/test_catalogs.py | 2 +- tests/test_intl/test_intl.py | 61 +++++- tests/test_markup/test_markup.py | 18 +- tests/test_markup/test_smartquotes.py | 6 +- tests/test_search.py | 60 +++++- tests/test_theming/test_theming.py | 7 +- .../test_transforms_post_transforms.py | 6 +- .../test_transforms_post_transforms_code.py | 2 +- .../test_transforms_post_transforms_images.py | 46 ++++ tests/test_util/intersphinx_data.py | 12 ++ .../test_util_docutils_sphinx_directive.py | 139 ++++++++++++ tests/test_util/test_util_fileutil.py | 43 +++- tests/test_util/test_util_i18n.py | 10 +- tests/test_util/test_util_inspect.py | 6 +- tests/test_util/test_util_inventory.py | 19 ++ tests/test_util/test_util_typing.py | 197 +++++++++++++---- tests/test_util/typing_test_data.py | 6 +- 140 files changed, 2205 insertions(+), 559 deletions(-) create mode 100644 tests/js/fixtures/cpp/searchindex.js create mode 100644 tests/js/fixtures/multiterm/searchindex.js create mode 100644 tests/js/fixtures/partial/searchindex.js create mode 100644 tests/js/fixtures/titles/searchindex.js create mode 100644 tests/js/language_data.js create mode 100644 tests/js/roots/cpp/conf.py create mode 100644 tests/js/roots/cpp/index.rst create mode 100644 tests/js/roots/multiterm/conf.py create mode 100644 tests/js/roots/multiterm/index.rst create mode 100644 tests/js/roots/partial/conf.py create mode 100644 tests/js/roots/partial/index.rst create mode 100644 tests/js/roots/titles/conf.py create mode 100644 tests/js/roots/titles/index.rst create mode 100644 tests/js/roots/titles/relevance.py create mode 100644 tests/js/roots/titles/relevance.rst create mode 100644 tests/roots/test-domain-py/type_alias.rst create mode 100644 tests/roots/test-ext-autosummary-import_cycle/conf.py create mode 100644 tests/roots/test-ext-autosummary-import_cycle/index.rst create mode 100644 tests/roots/test-ext-autosummary-import_cycle/spam/__init__.py create mode 100644 tests/roots/test-ext-autosummary-import_cycle/spam/eggs.py create mode 100644 tests/roots/test-ext-autosummary-module_prefix/conf.py create mode 100644 tests/roots/test-ext-autosummary-module_prefix/index.rst create mode 100644 tests/roots/test-ext-autosummary-module_prefix/pkg/__init__.py create mode 100644 tests/roots/test-ext-autosummary-module_prefix/pkg/mod0/__init__.py create mode 100644 tests/roots/test-ext-autosummary-module_prefix/pkg/mod1/__init__.py delete mode 100644 tests/roots/test-ext-coverage/coverage_ignored.py delete mode 100644 tests/roots/test-ext-coverage/coverage_not_ignored.py create mode 100644 tests/roots/test-ext-coverage/grog/__init__.py create mode 100644 tests/roots/test-ext-coverage/grog/coverage_ignored.py create mode 100644 tests/roots/test-ext-coverage/grog/coverage_missing.py create mode 100644 tests/roots/test-ext-coverage/grog/coverage_not_ignored.py create mode 100644 tests/roots/test-html_assets/extra/API.html.jinja delete mode 100644 tests/roots/test-html_assets/extra/API.html_t create mode 100644 tests/roots/test-html_assets/static/API.html.jinja delete mode 100644 tests/roots/test-html_assets/static/API.html_t create mode 100644 tests/roots/test-intl/markup.txt create mode 100644 tests/roots/test-intl/xx/LC_MESSAGES/markup.po create mode 100644 tests/roots/test-latex-table/_mytemplates/latex/longtable.tex.jinja delete mode 100644 tests/roots/test-latex-table/_mytemplates/latex/longtable.tex_t create mode 100644 tests/roots/test-latex-table/_mytemplates/latex/tabulary.tex_t create mode 100644 tests/roots/test-theming/test_theme/staticfiles/static/legacytmpl.html_t create mode 100644 tests/roots/test-theming/test_theme/staticfiles/static/statictmpl.html.jinja delete mode 100644 tests/roots/test-theming/test_theme/staticfiles/static/statictmpl.html_t create mode 100644 tests/roots/test-toctree-domain-objects/document_scoping.rst create mode 100644 tests/roots/test-util-copyasset_overwrite/conf.py create mode 100644 tests/roots/test-util-copyasset_overwrite/index.rst create mode 100644 tests/roots/test-util-copyasset_overwrite/myext.py create mode 100644 tests/roots/test-util-copyasset_overwrite/myext_static/custom-styles.css create mode 100644 tests/roots/test-util-copyasset_overwrite/user_static/custom-styles.css create mode 100644 tests/test_extensions/test_ext_autosummary_imports.py create mode 100644 tests/test_transforms/test_transforms_post_transforms_images.py create mode 100644 tests/test_util/test_util_docutils_sphinx_directive.py (limited to 'tests') diff --git a/tests/js/fixtures/cpp/searchindex.js b/tests/js/fixtures/cpp/searchindex.js new file mode 100644 index 0000000..46f4824 --- /dev/null +++ b/tests/js/fixtures/cpp/searchindex.js @@ -0,0 +1 @@ +Search.setIndex({"alltitles": {}, "docnames": ["index"], "envversion": {"sphinx": 62, "sphinx.domains.c": 3, "sphinx.domains.changeset": 1, "sphinx.domains.citation": 1, "sphinx.domains.cpp": 9, "sphinx.domains.index": 1, "sphinx.domains.javascript": 3, "sphinx.domains.math": 2, "sphinx.domains.python": 4, "sphinx.domains.rst": 2, "sphinx.domains.std": 2}, "filenames": ["index.rst"], "indexentries": {"sphinx (c++ class)": [[0, "_CPPv46Sphinx", false]]}, "objects": {"": [[0, 0, 1, "_CPPv46Sphinx", "Sphinx"]]}, "objnames": {"0": ["cpp", "class", "C++ class"]}, "objtypes": {"0": "cpp:class"}, "terms": {"The": 0, "becaus": 0, "c": 0, "can": 0, "cardin": 0, "challeng": 0, "charact": 0, "class": 0, "descript": 0, "drop": 0, "engin": 0, "fixtur": 0, "frequent": 0, "gener": 0, "i": 0, "index": 0, "inflat": 0, "mathemat": 0, "occur": 0, "often": 0, "project": 0, "punctuat": 0, "queri": 0, "relat": 0, "sampl": 0, "search": 0, "size": 0, "sphinx": 0, "term": 0, "thei": 0, "thi": 0, "token": 0, "us": 0, "web": 0, "would": 0}, "titles": ["<no title>"], "titleterms": {}}) \ No newline at end of file diff --git a/tests/js/fixtures/multiterm/searchindex.js b/tests/js/fixtures/multiterm/searchindex.js new file mode 100644 index 0000000..a868eb6 --- /dev/null +++ b/tests/js/fixtures/multiterm/searchindex.js @@ -0,0 +1 @@ +Search.setIndex({"alltitles": {"Main Page": [[0, null]]}, "docnames": ["index"], "envversion": {"sphinx": 62, "sphinx.domains.c": 3, "sphinx.domains.changeset": 1, "sphinx.domains.citation": 1, "sphinx.domains.cpp": 9, "sphinx.domains.index": 1, "sphinx.domains.javascript": 3, "sphinx.domains.math": 2, "sphinx.domains.python": 4, "sphinx.domains.rst": 2, "sphinx.domains.std": 2}, "filenames": ["index.rst"], "indexentries": {}, "objects": {}, "objnames": {}, "objtypes": {}, "terms": {"At": 0, "adjac": 0, "all": 0, "an": 0, "appear": 0, "applic": 0, "ar": 0, "built": 0, "can": 0, "check": 0, "contain": 0, "do": 0, "document": 0, "doesn": 0, "each": 0, "fixtur": 0, "format": 0, "function": 0, "futur": 0, "html": 0, "i": 0, "includ": 0, "match": 0, "messag": 0, "multipl": 0, "multiterm": 0, "order": 0, "other": 0, "output": 0, "perform": 0, "perhap": 0, "phrase": 0, "project": 0, "queri": 0, "requir": 0, "same": 0, "search": 0, "successfulli": 0, "support": 0, "t": 0, "term": 0, "test": 0, "thi": 0, "time": 0, "us": 0, "when": 0, "write": 0}, "titles": ["Main Page"], "titleterms": {"main": 0, "page": 0}}) \ No newline at end of file diff --git a/tests/js/fixtures/partial/searchindex.js b/tests/js/fixtures/partial/searchindex.js new file mode 100644 index 0000000..356386a --- /dev/null +++ b/tests/js/fixtures/partial/searchindex.js @@ -0,0 +1 @@ +Search.setIndex({"alltitles": {"sphinx_utils module": [[0, null]]}, "docnames": ["index"], "envversion": {"sphinx": 62, "sphinx.domains.c": 3, "sphinx.domains.changeset": 1, "sphinx.domains.citation": 1, "sphinx.domains.cpp": 9, "sphinx.domains.index": 1, "sphinx.domains.javascript": 3, "sphinx.domains.math": 2, "sphinx.domains.python": 4, "sphinx.domains.rst": 2, "sphinx.domains.std": 2}, "filenames": ["index.rst"], "indexentries": {}, "objects": {}, "objnames": {}, "objtypes": {}, "terms": {"also": 0, "ar": 0, "built": 0, "confirm": 0, "document": 0, "function": 0, "html": 0, "i": 0, "includ": 0, "input": 0, "javascript": 0, "known": 0, "match": 0, "partial": 0, "possibl": 0, "prefix": 0, "project": 0, "provid": 0, "restructuredtext": 0, "sampl": 0, "search": 0, "should": 0, "thi": 0, "titl": 0, "us": 0, "when": 0}, "titles": ["sphinx_utils module"], "titleterms": {"modul": 0, "sphinx_util": 0}}) \ No newline at end of file diff --git a/tests/js/fixtures/titles/searchindex.js b/tests/js/fixtures/titles/searchindex.js new file mode 100644 index 0000000..9a229d0 --- /dev/null +++ b/tests/js/fixtures/titles/searchindex.js @@ -0,0 +1 @@ +Search.setIndex({"alltitles": {"Main Page": [[0, null]], "Relevance": [[0, "relevance"], [1, null]]}, "docnames": ["index", "relevance"], "envversion": {"sphinx": 62, "sphinx.domains.c": 3, "sphinx.domains.changeset": 1, "sphinx.domains.citation": 1, "sphinx.domains.cpp": 9, "sphinx.domains.index": 1, "sphinx.domains.javascript": 3, "sphinx.domains.math": 2, "sphinx.domains.python": 4, "sphinx.domains.rst": 2, "sphinx.domains.std": 2}, "filenames": ["index.rst", "relevance.rst"], "indexentries": {"example (class in relevance)": [[0, "relevance.Example", false]], "module": [[0, "module-relevance", false]], "relevance": [[0, "module-relevance", false]], "relevance (relevance.example attribute)": [[0, "relevance.Example.relevance", false]]}, "objects": {"": [[0, 0, 0, "-", "relevance"]], "relevance": [[0, 1, 1, "", "Example"]], "relevance.Example": [[0, 2, 1, "", "relevance"]]}, "objnames": {"0": ["py", "module", "Python module"], "1": ["py", "class", "Python class"], "2": ["py", "attribute", "Python attribute"]}, "objtypes": {"0": "py:module", "1": "py:class", "2": "py:attribute"}, "terms": {"": [0, 1], "A": 1, "For": 1, "In": [0, 1], "against": 0, "also": 1, "an": 0, "answer": 0, "appear": 1, "ar": 1, "area": 0, "ask": 0, "attribut": 0, "built": 1, "can": [0, 1], "class": 0, "code": [0, 1], "consid": 1, "contain": 0, "context": 0, "corpu": 1, "could": 1, "demonstr": 0, "describ": 1, "detail": 1, "determin": 1, "docstr": 0, "document": [0, 1], "domain": 1, "engin": 0, "exampl": [0, 1], "extract": 0, "find": 0, "found": 0, "from": 0, "function": 1, "ha": 1, "handl": 0, "happen": 1, "head": 0, "help": 0, "highli": 1, "how": 0, "i": [0, 1], "improv": 0, "inform": 0, "intend": 0, "issu": 1, "itself": 1, "knowledg": 0, "languag": 1, "less": 1, "like": [0, 1], "match": 0, "mention": 1, "name": [0, 1], "object": 0, "one": 1, "onli": 1, "other": 0, "page": 1, "part": 1, "particular": 0, "printf": 1, "program": 1, "project": 0, "queri": [0, 1], "question": 0, "re": 0, "rel": 0, "research": 0, "result": 1, "sai": 0, "same": 1, "score": 0, "search": [0, 1], "seem": 0, "softwar": 1, "some": 1, "sphinx": 0, "straightforward": 1, "subject": 0, "subsect": 0, "term": [0, 1], "test": 0, "text": 0, "than": 1, "thei": 0, "them": 0, "thi": 0, "titl": 0, "user": [0, 1], "we": [0, 1], "when": 0, "whether": 1, "within": 0, "would": 1}, "titles": ["Main Page", "Relevance"], "titleterms": {"main": 0, "page": 0, "relev": [0, 1]}}) \ No newline at end of file diff --git a/tests/js/language_data.js b/tests/js/language_data.js new file mode 100644 index 0000000..89083d9 --- /dev/null +++ b/tests/js/language_data.js @@ -0,0 +1,26 @@ +/* + * language_data.js + * ~~~~~~~~~~~~~~~~ + * + * This script contains the language-specific data used by searchtools.js, + * namely the list of stopwords, stemmer, scorer and splitter. + * + * :copyright: Copyright 2007-2024 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +var stopwords = []; + + +/* Non-minified version is copied as a separate JS file, if available */ + +/** + * Dummy stemmer for languages without stemming rules. + */ +var Stemmer = function() { + this.stemWord = function(w) { + return w; + } +} + diff --git a/tests/js/roots/cpp/conf.py b/tests/js/roots/cpp/conf.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/js/roots/cpp/index.rst b/tests/js/roots/cpp/index.rst new file mode 100644 index 0000000..d731343 --- /dev/null +++ b/tests/js/roots/cpp/index.rst @@ -0,0 +1,10 @@ +This is a sample C++ project used to generate a search engine index fixture. + +.. cpp:class:: public Sphinx + + The description of Sphinx class. + +Indexing and querying the term C++ can be challenging, because search-related +tokenization often drops punctuation and mathematical characters (they occur +frequently on the web and would inflate the cardinality and size of web search +indexes). diff --git a/tests/js/roots/multiterm/conf.py b/tests/js/roots/multiterm/conf.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/js/roots/multiterm/index.rst b/tests/js/roots/multiterm/index.rst new file mode 100644 index 0000000..495e5ce --- /dev/null +++ b/tests/js/roots/multiterm/index.rst @@ -0,0 +1,13 @@ +Main Page +========= + +This is the main page of the ``multiterm`` test project. + +This document is used as a test fixture to check that the search functionality +included when projects are built into an HTML output format can successfully +match this document when a search query containing multiple terms is performed. + +At the time-of-writing this message, the application doesn't support "phrase +queries" -- queries that require all of the contained terms to appear adjacent +to each other and in the same order in the document as in the query; perhaps it +will do in future? diff --git a/tests/js/roots/partial/conf.py b/tests/js/roots/partial/conf.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/js/roots/partial/index.rst b/tests/js/roots/partial/index.rst new file mode 100644 index 0000000..6a9561b --- /dev/null +++ b/tests/js/roots/partial/index.rst @@ -0,0 +1,9 @@ +sphinx_utils module +=================== + +Partial (also known as "prefix") matches on document titles should be possible +using the JavaScript search functionality included when HTML documentation +projects are built. + +This document provides a sample reStructuredText input to confirm that partial +title matching is possible. diff --git a/tests/js/roots/titles/conf.py b/tests/js/roots/titles/conf.py new file mode 100644 index 0000000..e5f6bb9 --- /dev/null +++ b/tests/js/roots/titles/conf.py @@ -0,0 +1,6 @@ +import os +import sys + +sys.path.insert(0, os.path.abspath('.')) + +extensions = ['sphinx.ext.autodoc'] diff --git a/tests/js/roots/titles/index.rst b/tests/js/roots/titles/index.rst new file mode 100644 index 0000000..464cd95 --- /dev/null +++ b/tests/js/roots/titles/index.rst @@ -0,0 +1,20 @@ +Main Page +========= + +This is the main page of the ``titles`` test project. + +In particular, this test project is intended to demonstrate how Sphinx +can handle scoring of query matches against document titles and subsection +heading titles relative to other document matches such as terms found within +document text and object names extracted from code. + +Relevance +--------- + +In the context of search engines, we can say that a document is **relevant** +to a user's query when it contains information that seems likely to help them +find an answer to a question they're asking, or to improve their knowledge of +the subject area they're researching. + +.. automodule:: relevance + :members: diff --git a/tests/js/roots/titles/relevance.py b/tests/js/roots/titles/relevance.py new file mode 100644 index 0000000..c4d0eec --- /dev/null +++ b/tests/js/roots/titles/relevance.py @@ -0,0 +1,7 @@ +class Example: + """Example class""" + num_attribute = 5 + text_attribute = "string" + + relevance = "testing" + """attribute docstring""" diff --git a/tests/js/roots/titles/relevance.rst b/tests/js/roots/titles/relevance.rst new file mode 100644 index 0000000..18f494f --- /dev/null +++ b/tests/js/roots/titles/relevance.rst @@ -0,0 +1,13 @@ +Relevance +========= + +In some domains, it can be straightforward to determine whether a search result +is relevant to the user's query. + +For example, if we are in a software programming language domain, and a user +has issued a query for the term ``printf``, then we could consider a document +in the corpus that describes a built-in language function with the same name +as (highly) relevant. A document that only happens to mention the ``printf`` +function name as part of some example code that appears on the page would +also be relevant, but likely less relevant than the one that describes the +function itself in detail. diff --git a/tests/js/searchtools.js b/tests/js/searchtools.js index 4f9984d..ebf37e5 100644 --- a/tests/js/searchtools.js +++ b/tests/js/searchtools.js @@ -1,20 +1,38 @@ describe('Basic html theme search', function() { + function loadFixture(name) { + req = new XMLHttpRequest(); + req.open("GET", `base/tests/js/fixtures/${name}`, false); + req.send(null); + return req.responseText; + } + + function checkRanking(expectedRanking, results) { + let [nextExpected, ...remainingItems] = expectedRanking; + + for (result of results.reverse()) { + if (!nextExpected) break; + + let [expectedPage, expectedTitle, expectedTarget] = nextExpected; + let [page, title, target] = result; + + if (page == expectedPage && title == expectedTitle && target == expectedTarget) { + [nextExpected, ...remainingItems] = remainingItems; + } + } + + expect(remainingItems.length).toEqual(0); + expect(nextExpected).toEqual(undefined); + } + describe('terms search', function() { it('should find "C++" when in index', function() { - index = { - docnames:["index"], - filenames:["index.rst"], - terms:{'c++':0}, - titles:["<no title>"], - titleterms:{} - } - Search.setIndex(index); - searchterms = ['c++']; - excluded = []; - terms = index.terms; - titleterms = index.titleterms; + eval(loadFixture("cpp/searchindex.js")); + + [_searchQuery, searchterms, excluded, ..._remainingItems] = Search._parseQuery('C++'); + terms = Search._index.terms; + titleterms = Search._index.titleterms; hits = [[ "index", @@ -28,22 +46,11 @@ describe('Basic html theme search', function() { }); it('should be able to search for multiple terms', function() { - index = { - alltitles: { - 'Main Page': [[0, 'main-page']], - }, - docnames:["index"], - filenames:["index.rst"], - terms:{main:0, page:0}, - titles:["Main Page"], - titleterms:{ main:0, page:0 } - } - Search.setIndex(index); + eval(loadFixture("multiterm/searchindex.js")); - searchterms = ['main', 'page']; - excluded = []; - terms = index.terms; - titleterms = index.titleterms; + [_searchQuery, searchterms, excluded, ..._remainingItems] = Search._parseQuery('main page'); + terms = Search._index.terms; + titleterms = Search._index.titleterms; hits = [[ 'index', 'Main Page', @@ -55,18 +62,11 @@ describe('Basic html theme search', function() { }); it('should partially-match "sphinx" when in title index', function() { - index = { - docnames:["index"], - filenames:["index.rst"], - terms:{'useful': 0, 'utilities': 0}, - titles:["sphinx_utils module"], - titleterms:{'sphinx_utils': 0} - } - Search.setIndex(index); - searchterms = ['sphinx']; - excluded = []; - terms = index.terms; - titleterms = index.titleterms; + eval(loadFixture("partial/searchindex.js")); + + [_searchQuery, searchterms, excluded, ..._remainingItems] = Search._parseQuery('sphinx'); + terms = Search._index.terms; + titleterms = Search._index.titleterms; hits = [[ "index", @@ -81,6 +81,88 @@ describe('Basic html theme search', function() { }); + describe('aggregation of search results', function() { + + it('should combine document title and document term matches', function() { + eval(loadFixture("multiterm/searchindex.js")); + + searchParameters = Search._parseQuery('main page'); + + hits = [ + [ + 'index', + 'Main Page', + '', + null, + 16, + 'index.rst' + ] + ]; + expect(Search._performSearch(...searchParameters)).toEqual(hits); + }); + + }); + + describe('search result ranking', function() { + + /* + * These tests should not proscribe precise expected ordering of search + * results; instead each test case should describe a single relevance rule + * that helps users to locate relevant information efficiently. + * + * If you think that one of the rules seems to be poorly-defined or is + * limiting the potential for search algorithm improvements, please check + * for existing discussion/bugreports related to it on GitHub[1] before + * creating one yourself. Suggestions for possible improvements are also + * welcome. + * + * [1] - https://github.com/sphinx-doc/sphinx.git/ + */ + + it('should score a code module match above a page-title match', function() { + eval(loadFixture("titles/searchindex.js")); + + expectedRanking = [ + ['index', 'relevance', '#module-relevance'], /* py:module documentation */ + ['relevance', 'Relevance', ''], /* main title */ + ]; + + searchParameters = Search._parseQuery('relevance'); + results = Search._performSearch(...searchParameters); + + checkRanking(expectedRanking, results); + }); + + it('should score a main-title match above an object member match', function() { + eval(loadFixture("titles/searchindex.js")); + + expectedRanking = [ + ['relevance', 'Relevance', ''], /* main title */ + ['index', 'relevance.Example.relevance', '#relevance.Example.relevance'], /* py:class attribute */ + ]; + + searchParameters = Search._parseQuery('relevance'); + results = Search._performSearch(...searchParameters); + + checkRanking(expectedRanking, results); + }); + + it('should score a main-title match above a subheading-title match', function() { + eval(loadFixture("titles/searchindex.js")); + + expectedRanking = [ + ['relevance', 'Relevance', ''], /* main title */ + ['index', 'Main Page > Relevance', '#relevance'], /* subsection heading title */ + ]; + + searchParameters = Search._parseQuery('relevance'); + results = Search._performSearch(...searchParameters); + + checkRanking(expectedRanking, results); + }); + + }); + }); describe("htmlToText", function() { @@ -100,15 +182,15 @@ describe("htmlToText", function() {
-

Getting Started

+

Getting Started

Some text

-

Other Section

+

Other Section

Other text

-

Yet Another Section

+

Yet Another Section

More text

diff --git a/tests/roots/test-add_source_parser-conflicts-with-users-setting/conf.py b/tests/roots/test-add_source_parser-conflicts-with-users-setting/conf.py index 3ad5491..5e57901 100644 --- a/tests/roots/test-add_source_parser-conflicts-with-users-setting/conf.py +++ b/tests/roots/test-add_source_parser-conflicts-with-users-setting/conf.py @@ -11,7 +11,10 @@ class DummyTestParser(Parser): extensions = ['source_parser'] -source_suffix = ['.rst', '.test'] +source_suffix = { + '.rst': 'restructuredtext', + '.test': 'restructuredtext', +} source_parsers = { '.test': DummyTestParser } diff --git a/tests/roots/test-add_source_parser/conf.py b/tests/roots/test-add_source_parser/conf.py index 2acd4d2..ef85560 100644 --- a/tests/roots/test-add_source_parser/conf.py +++ b/tests/roots/test-add_source_parser/conf.py @@ -5,4 +5,3 @@ sys.path.insert(0, os.path.abspath('.')) extensions = ['source_parser'] -source_suffix = ['.rst'] diff --git a/tests/roots/test-autosummary/conf.py b/tests/roots/test-autosummary/conf.py index 46cf4fa..f459017 100644 --- a/tests/roots/test-autosummary/conf.py +++ b/tests/roots/test-autosummary/conf.py @@ -5,8 +5,6 @@ sys.path.insert(0, os.path.abspath('.')) extensions = ['sphinx.ext.autosummary'] -# The suffix of source filenames. -source_suffix = '.rst' autosummary_generate = True exclude_patterns = ['_build'] diff --git a/tests/roots/test-build-text/conf.py b/tests/roots/test-build-text/conf.py index fd9eefb..b0fdaf8 100644 --- a/tests/roots/test-build-text/conf.py +++ b/tests/roots/test-build-text/conf.py @@ -1,2 +1,4 @@ -source_suffix = '.txt' +source_suffix = { + '.txt': 'restructuredtext' +} exclude_patterns = ['_build'] diff --git a/tests/roots/test-domain-py-python_maximum_signature_line_length/index.rst b/tests/roots/test-domain-py-python_maximum_signature_line_length/index.rst index 75e4683..9715500 100644 --- a/tests/roots/test-domain-py-python_maximum_signature_line_length/index.rst +++ b/tests/roots/test-domain-py-python_maximum_signature_line_length/index.rst @@ -4,3 +4,16 @@ domain-py-maximum_signature_line_length .. py:function:: hello(name: str) -> str .. py:function:: foo([a, [b, ]]c, d[, e, f]) + +.. py:function:: generic_arg[T] + +.. py:function:: generic_foo[T]() + +.. py:function:: generic_bar[T](x: list[T]) + +.. py:function:: generic_ret[R]() -> R + +.. py:class:: MyGenericClass[X] + +.. py:class:: MyList[T](list[T]) + diff --git a/tests/roots/test-domain-py/index.rst b/tests/roots/test-domain-py/index.rst index b24bbea..71e45f7 100644 --- a/tests/roots/test-domain-py/index.rst +++ b/tests/roots/test-domain-py/index.rst @@ -8,3 +8,4 @@ test-domain-py module_option abbr canonical + type_alias diff --git a/tests/roots/test-domain-py/module.rst b/tests/roots/test-domain-py/module.rst index 70098f6..307e786 100644 --- a/tests/roots/test-domain-py/module.rst +++ b/tests/roots/test-domain-py/module.rst @@ -64,3 +64,6 @@ module .. py:data:: test2 :type: typing.Literal[-2] + +.. py:type:: MyType1 + :canonical: list[int | str] diff --git a/tests/roots/test-domain-py/roles.rst b/tests/roots/test-domain-py/roles.rst index 6bff2d2..d3492ce 100644 --- a/tests/roots/test-domain-py/roles.rst +++ b/tests/roots/test-domain-py/roles.rst @@ -5,14 +5,19 @@ roles .. py:method:: top_level +.. py:type:: TopLevelType + * :py:class:`TopLevel` * :py:meth:`top_level` +* :py:type:`TopLevelType` .. py:class:: NestedParentA * Link to :py:meth:`child_1` + .. py:type:: NestedTypeA + .. py:method:: child_1() * Link to :py:meth:`NestedChildA.subchild_2` @@ -46,3 +51,4 @@ roles * Link to :py:class:`NestedParentB` * :py:class:`NestedParentA.NestedChildA` +* :py:type:`NestedParentA.NestedTypeA` diff --git a/tests/roots/test-domain-py/type_alias.rst b/tests/roots/test-domain-py/type_alias.rst new file mode 100644 index 0000000..6a3df44 --- /dev/null +++ b/tests/roots/test-domain-py/type_alias.rst @@ -0,0 +1,15 @@ +Type Alias +========== + +.. py:module:: module_two + + .. py:class:: SomeClass + +:py:type:`.MyAlias` +:any:`MyAlias` +:any:`module_one.MyAlias` + +.. py:module:: module_one + + .. py:type:: MyAlias + :canonical: list[int | module_two.SomeClass] diff --git a/tests/roots/test-ext-autodoc/conf.py b/tests/roots/test-ext-autodoc/conf.py index 979a709..9d1cdc7 100644 --- a/tests/roots/test-ext-autodoc/conf.py +++ b/tests/roots/test-ext-autodoc/conf.py @@ -5,9 +5,6 @@ sys.path.insert(0, os.path.abspath('.')) extensions = ['sphinx.ext.autodoc'] -# The suffix of source filenames. -source_suffix = '.rst' - autodoc_mock_imports = [ 'dummy' ] diff --git a/tests/roots/test-ext-autodoc/target/annotated.py b/tests/roots/test-ext-autodoc/target/annotated.py index 5b87518..7adc3e0 100644 --- a/tests/roots/test-ext-autodoc/target/annotated.py +++ b/tests/roots/test-ext-autodoc/target/annotated.py @@ -1,8 +1,42 @@ -from __future__ import annotations +# from __future__ import annotations +import dataclasses +import types from typing import Annotated +@dataclasses.dataclass(frozen=True) +class FuncValidator: + func: types.FunctionType + + +@dataclasses.dataclass(frozen=True) +class MaxLen: + max_length: int + whitelisted_words: list[str] + + +def validate(value: str) -> str: + return value + + +#: Type alias for a validated string. +ValidatedString = Annotated[str, FuncValidator(validate)] + + def hello(name: Annotated[str, "attribute"]) -> None: """docstring""" pass + + +class AnnotatedAttributes: + """docstring""" + + #: Docstring about the ``name`` attribute. + name: Annotated[str, "attribute"] + + #: Docstring about the ``max_len`` attribute. + max_len: list[Annotated[str, MaxLen(10, ['word_one', 'word_two'])]] + + #: Docstring about the ``validated`` attribute. + validated: ValidatedString diff --git a/tests/roots/test-ext-autosummary-import_cycle/conf.py b/tests/roots/test-ext-autosummary-import_cycle/conf.py new file mode 100644 index 0000000..5e889f9 --- /dev/null +++ b/tests/roots/test-ext-autosummary-import_cycle/conf.py @@ -0,0 +1,7 @@ +import os +import sys + +sys.path.insert(0, os.path.abspath('.')) + +extensions = ['sphinx.ext.autosummary'] +autosummary_generate = False diff --git a/tests/roots/test-ext-autosummary-import_cycle/index.rst b/tests/roots/test-ext-autosummary-import_cycle/index.rst new file mode 100644 index 0000000..14e7266 --- /dev/null +++ b/tests/roots/test-ext-autosummary-import_cycle/index.rst @@ -0,0 +1,6 @@ +.. automodule:: spam.eggs + :members: + + .. autosummary:: + + spam.eggs.Ham diff --git a/tests/roots/test-ext-autosummary-import_cycle/spam/__init__.py b/tests/roots/test-ext-autosummary-import_cycle/spam/__init__.py new file mode 100644 index 0000000..e94cf4b --- /dev/null +++ b/tests/roots/test-ext-autosummary-import_cycle/spam/__init__.py @@ -0,0 +1 @@ +"""``spam`` module docstring.""" diff --git a/tests/roots/test-ext-autosummary-import_cycle/spam/eggs.py b/tests/roots/test-ext-autosummary-import_cycle/spam/eggs.py new file mode 100644 index 0000000..12122e8 --- /dev/null +++ b/tests/roots/test-ext-autosummary-import_cycle/spam/eggs.py @@ -0,0 +1,10 @@ +"""``spam.eggs`` module docstring.""" + +import spam # Required for test. + + +class Ham: + """``spam.eggs.Ham`` class docstring.""" + a = 1 + b = 2 + c = 3 diff --git a/tests/roots/test-ext-autosummary-module_prefix/conf.py b/tests/roots/test-ext-autosummary-module_prefix/conf.py new file mode 100644 index 0000000..1065b91 --- /dev/null +++ b/tests/roots/test-ext-autosummary-module_prefix/conf.py @@ -0,0 +1,8 @@ +import os +import sys + +sys.path.insert(0, os.path.abspath('.')) + +extensions = [ + 'sphinx.ext.autosummary', +] diff --git a/tests/roots/test-ext-autosummary-module_prefix/index.rst b/tests/roots/test-ext-autosummary-module_prefix/index.rst new file mode 100644 index 0000000..fe0b13c --- /dev/null +++ b/tests/roots/test-ext-autosummary-module_prefix/index.rst @@ -0,0 +1,5 @@ +.. autosummary:: + :toctree: docs/pkg + :recursive: + + pkg diff --git a/tests/roots/test-ext-autosummary-module_prefix/pkg/__init__.py b/tests/roots/test-ext-autosummary-module_prefix/pkg/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/roots/test-ext-autosummary-module_prefix/pkg/mod0/__init__.py b/tests/roots/test-ext-autosummary-module_prefix/pkg/mod0/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/roots/test-ext-autosummary-module_prefix/pkg/mod1/__init__.py b/tests/roots/test-ext-autosummary-module_prefix/pkg/mod1/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/roots/test-ext-autosummary/conf.py b/tests/roots/test-ext-autosummary/conf.py index 55c769c..1c0d022 100644 --- a/tests/roots/test-ext-autosummary/conf.py +++ b/tests/roots/test-ext-autosummary/conf.py @@ -5,6 +5,3 @@ sys.path.insert(0, os.path.abspath('.')) extensions = ['sphinx.ext.autosummary'] autosummary_generate = True - -# The suffix of source filenames. -source_suffix = '.rst' diff --git a/tests/roots/test-ext-coverage/conf.py b/tests/roots/test-ext-coverage/conf.py index d3ec6e8..70fd03e 100644 --- a/tests/roots/test-ext-coverage/conf.py +++ b/tests/roots/test-ext-coverage/conf.py @@ -5,8 +5,11 @@ sys.path.insert(0, os.path.abspath('.')) extensions = ['sphinx.ext.autodoc', 'sphinx.ext.coverage'] +coverage_modules = [ + 'grog', +] coverage_ignore_pyobjects = [ - r'^coverage_ignored(\..*)?$', + r'^grog\.coverage_ignored(\..*)?$', r'\.Ignored$', r'\.Documented\.ignored\d$', ] diff --git a/tests/roots/test-ext-coverage/coverage_ignored.py b/tests/roots/test-ext-coverage/coverage_ignored.py deleted file mode 100644 index b762955..0000000 --- a/tests/roots/test-ext-coverage/coverage_ignored.py +++ /dev/null @@ -1,22 +0,0 @@ -class Documented: - """Documented""" - - def ignored1(self): - pass - - def ignored2(self): - pass - - def not_ignored1(self): - pass - - def not_ignored2(self): - pass - - -class Ignored: - pass - - -class NotIgnored: - pass diff --git a/tests/roots/test-ext-coverage/coverage_not_ignored.py b/tests/roots/test-ext-coverage/coverage_not_ignored.py deleted file mode 100644 index b762955..0000000 --- a/tests/roots/test-ext-coverage/coverage_not_ignored.py +++ /dev/null @@ -1,22 +0,0 @@ -class Documented: - """Documented""" - - def ignored1(self): - pass - - def ignored2(self): - pass - - def not_ignored1(self): - pass - - def not_ignored2(self): - pass - - -class Ignored: - pass - - -class NotIgnored: - pass diff --git a/tests/roots/test-ext-coverage/grog/__init__.py b/tests/roots/test-ext-coverage/grog/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/roots/test-ext-coverage/grog/coverage_ignored.py b/tests/roots/test-ext-coverage/grog/coverage_ignored.py new file mode 100644 index 0000000..b762955 --- /dev/null +++ b/tests/roots/test-ext-coverage/grog/coverage_ignored.py @@ -0,0 +1,22 @@ +class Documented: + """Documented""" + + def ignored1(self): + pass + + def ignored2(self): + pass + + def not_ignored1(self): + pass + + def not_ignored2(self): + pass + + +class Ignored: + pass + + +class NotIgnored: + pass diff --git a/tests/roots/test-ext-coverage/grog/coverage_missing.py b/tests/roots/test-ext-coverage/grog/coverage_missing.py new file mode 100644 index 0000000..2fe4433 --- /dev/null +++ b/tests/roots/test-ext-coverage/grog/coverage_missing.py @@ -0,0 +1,7 @@ +"""This module is intentionally not documented.""" + +class Missing: + """An undocumented class.""" + + def missing_a(self): + """An undocumented method.""" diff --git a/tests/roots/test-ext-coverage/grog/coverage_not_ignored.py b/tests/roots/test-ext-coverage/grog/coverage_not_ignored.py new file mode 100644 index 0000000..b762955 --- /dev/null +++ b/tests/roots/test-ext-coverage/grog/coverage_not_ignored.py @@ -0,0 +1,22 @@ +class Documented: + """Documented""" + + def ignored1(self): + pass + + def ignored2(self): + pass + + def not_ignored1(self): + pass + + def not_ignored2(self): + pass + + +class Ignored: + pass + + +class NotIgnored: + pass diff --git a/tests/roots/test-ext-coverage/index.rst b/tests/roots/test-ext-coverage/index.rst index b846898..85dccf9 100644 --- a/tests/roots/test-ext-coverage/index.rst +++ b/tests/roots/test-ext-coverage/index.rst @@ -1,6 +1,6 @@ -.. automodule:: coverage_ignored +.. automodule:: grog.coverage_ignored :members: -.. automodule:: coverage_not_ignored +.. automodule:: grog.coverage_not_ignored :members: diff --git a/tests/roots/test-ext-doctest-skipif/conf.py b/tests/roots/test-ext-doctest-skipif/conf.py index cd8f3eb..ae00e35 100644 --- a/tests/roots/test-ext-doctest-skipif/conf.py +++ b/tests/roots/test-ext-doctest-skipif/conf.py @@ -2,7 +2,9 @@ extensions = ['sphinx.ext.doctest'] project = 'test project for the doctest :skipif: directive' root_doc = 'skipif' -source_suffix = '.txt' +source_suffix = { + '.txt': 'restructuredtext' +} exclude_patterns = ['_build'] doctest_global_setup = ''' diff --git a/tests/roots/test-ext-doctest/conf.py b/tests/roots/test-ext-doctest/conf.py index d0e8b10..57fc406 100644 --- a/tests/roots/test-ext-doctest/conf.py +++ b/tests/roots/test-ext-doctest/conf.py @@ -2,5 +2,7 @@ extensions = ['sphinx.ext.doctest'] project = 'test project for doctest' root_doc = 'doctest' -source_suffix = '.txt' +source_suffix = { + '.txt': 'restructuredtext' +} exclude_patterns = ['_build'] diff --git a/tests/roots/test-html_assets/extra/API.html.jinja b/tests/roots/test-html_assets/extra/API.html.jinja new file mode 100644 index 0000000..34ecd9d --- /dev/null +++ b/tests/roots/test-html_assets/extra/API.html.jinja @@ -0,0 +1 @@ +{{ project }}-{{ version }} diff --git a/tests/roots/test-html_assets/extra/API.html_t b/tests/roots/test-html_assets/extra/API.html_t deleted file mode 100644 index 34ecd9d..0000000 --- a/tests/roots/test-html_assets/extra/API.html_t +++ /dev/null @@ -1 +0,0 @@ -{{ project }}-{{ version }} diff --git a/tests/roots/test-html_assets/static/API.html.jinja b/tests/roots/test-html_assets/static/API.html.jinja new file mode 100644 index 0000000..34ecd9d --- /dev/null +++ b/tests/roots/test-html_assets/static/API.html.jinja @@ -0,0 +1 @@ +{{ project }}-{{ version }} diff --git a/tests/roots/test-html_assets/static/API.html_t b/tests/roots/test-html_assets/static/API.html_t deleted file mode 100644 index 34ecd9d..0000000 --- a/tests/roots/test-html_assets/static/API.html_t +++ /dev/null @@ -1 +0,0 @@ -{{ project }}-{{ version }} diff --git a/tests/roots/test-images/index.rst b/tests/roots/test-images/index.rst index 9b9aac1..f6d7160 100644 --- a/tests/roots/test-images/index.rst +++ b/tests/roots/test-images/index.rst @@ -27,3 +27,8 @@ test-image .. non-exist remote image .. image:: http://localhost:7777/NOT_EXIST.PNG + +.. a self-contained image within a data URI + This image was generated using ImageMagick 6.9 with the command ``convert -pointsize 32 -font Noto-Sans-Egyptian-Hieroglyphs-Regular caption:$(printf '\U13080') -trim -border 2 -monochrome eoh.png`` +.. image:: data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACoAAAAjAQAAAADKt6U+AAAAAmJLR0QAAd2KE6QAAAAHdElNRQfoBQIVBgOBlOMTAAAAEGNhTnYAAAAtAAAAOwAAAAEAAAATst46RgAAAJtJREFUCNdNz70KwkAMAOA8iOhjuGh9HB9BCtoTHHwMH0Mc7KWTmx0dHDpovUk6HCil3sUmATHLR/4IAeJA+LEWPmbEeHJMWbTMZDA0CNFn8x1COFPaIHQ55R7hlZGdIjwj2aovRjJbhPvMLNN+r0g2vB7ByIWbHqqVh3LR3lhZWM0qYV8qjU6+lc4J7ZVx4SjEINBKOSinv/+YL1xvsJE6ztdqAAAADHRFWHRjYXB0aW9uAPCTgoD4hdKUAAAAD3RFWHRjYXB0aW9uOmxpbmVzADGoBz2RAAAAAElFTkSuQmCC + :alt: The Eye of Horus in a black font on a white background. diff --git a/tests/roots/test-inheritance/conf.py b/tests/roots/test-inheritance/conf.py index 26cadca..9953494 100644 --- a/tests/roots/test-inheritance/conf.py +++ b/tests/roots/test-inheritance/conf.py @@ -4,4 +4,3 @@ import sys sys.path.insert(0, os.path.abspath('.')) extensions = ['sphinx.ext.inheritance_diagram'] -source_suffix = '.rst' diff --git a/tests/roots/test-intl/conf.py b/tests/roots/test-intl/conf.py index 96ac664..09c47bb 100644 --- a/tests/roots/test-intl/conf.py +++ b/tests/roots/test-intl/conf.py @@ -1,5 +1,7 @@ project = 'Sphinx intl ' -source_suffix = '.txt' +source_suffix = { + '.txt': 'restructuredtext' +} keep_warnings = True templates_path = ['_templates'] html_additional_pages = {'contents': 'contents.html'} diff --git a/tests/roots/test-intl/glossary_terms_inconsistency.txt b/tests/roots/test-intl/glossary_terms_inconsistency.txt index 837411b..0de1e7e 100644 --- a/tests/roots/test-intl/glossary_terms_inconsistency.txt +++ b/tests/roots/test-intl/glossary_terms_inconsistency.txt @@ -4,3 +4,4 @@ i18n with glossary terms inconsistency ====================================== 1. link to :term:`Some term` and :term:`Some other term`. +2. link to :term:`Some term`. diff --git a/tests/roots/test-intl/index.txt b/tests/roots/test-intl/index.txt index 9de15d5..ac68314 100644 --- a/tests/roots/test-intl/index.txt +++ b/tests/roots/test-intl/index.txt @@ -31,6 +31,7 @@ CONTENTS section translation_progress topic + markup .. toctree:: :maxdepth: 2 diff --git a/tests/roots/test-intl/markup.txt b/tests/roots/test-intl/markup.txt new file mode 100644 index 0000000..d167a04 --- /dev/null +++ b/tests/roots/test-intl/markup.txt @@ -0,0 +1,6 @@ +i18n with strange markup +======================== + +1. title starting with 1. +------------------------- + diff --git a/tests/roots/test-intl/role_xref.txt b/tests/roots/test-intl/role_xref.txt index 2919b5c..f39e752 100644 --- a/tests/roots/test-intl/role_xref.txt +++ b/tests/roots/test-intl/role_xref.txt @@ -7,6 +7,9 @@ i18n role xref link to :term:`Some term`, :ref:`i18n-role-xref`, :doc:`index`. +link to :term:`Some term`, :ref:`i18n-role-xref`, :doc:`index`. +--------------------------------------------------------------- + .. _same-type-links: same type links diff --git a/tests/roots/test-intl/xx/LC_MESSAGES/glossary_terms_inconsistency.po b/tests/roots/test-intl/xx/LC_MESSAGES/glossary_terms_inconsistency.po index ef2bf30..048b81f 100644 --- a/tests/roots/test-intl/xx/LC_MESSAGES/glossary_terms_inconsistency.po +++ b/tests/roots/test-intl/xx/LC_MESSAGES/glossary_terms_inconsistency.po @@ -21,3 +21,6 @@ msgstr "I18N WITH GLOSSARY TERMS INCONSISTENCY" msgid "link to :term:`Some term` and :term:`Some other term`." msgstr "LINK TO :term:`SOME NEW TERM`." + +msgid "link to :term:`Some term`." +msgstr "LINK TO :term:`TERM NOT IN GLOSSARY`." diff --git a/tests/roots/test-intl/xx/LC_MESSAGES/literalblock.po b/tests/roots/test-intl/xx/LC_MESSAGES/literalblock.po index 8d3e5d8..d320d95 100644 --- a/tests/roots/test-intl/xx/LC_MESSAGES/literalblock.po +++ b/tests/roots/test-intl/xx/LC_MESSAGES/literalblock.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: sphinx 1.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2012-11-22 08:28+0000\n" +"POT-Creation-Date: 2024-04-14 15:05+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -22,6 +22,11 @@ msgstr "I18N WITH LITERAL BLOCK" msgid "Correct literal block::" msgstr "CORRECT LITERAL BLOCK::" +msgid "" +"this is\n" +"literal block" +msgstr "THIS IS\nLITERAL BLOCK" + msgid "Missing literal block::" msgstr "MISSING LITERAL BLOCK::" @@ -31,6 +36,25 @@ msgstr "THAT'S ALL." msgid "included raw.txt" msgstr "INCLUDED RAW.TXT" +msgid "" +"===\n" +"Raw\n" +"===\n" +"\n" +".. raw:: html\n" +"\n" +" \n" +"\n" +msgstr "" +"===\n" +"RAW\n" +"===\n" +"\n" +".. raw:: html\n" +"\n" +" \n" +"\n" + msgid "code blocks" msgstr "CODE-BLOCKS" @@ -43,9 +67,6 @@ msgstr "" " 'RESULT'\n" "end" -msgid "example of C language" -msgstr "EXAMPLE OF C LANGUAGE" - msgid "" "#include \n" "int main(int argc, char** argv)\n" @@ -59,6 +80,9 @@ msgstr "" " return 0;\n" "}" +msgid "example of C language" +msgstr "EXAMPLE OF C LANGUAGE" + msgid "" "#include \n" "int main(int argc, char** argv)\n" diff --git a/tests/roots/test-intl/xx/LC_MESSAGES/markup.po b/tests/roots/test-intl/xx/LC_MESSAGES/markup.po new file mode 100644 index 0000000..ad6de9b --- /dev/null +++ b/tests/roots/test-intl/xx/LC_MESSAGES/markup.po @@ -0,0 +1,25 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2018, dev +# This file is distributed under the same license as the sphinx package. +# FIRST AUTHOR , 2018. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: sphinx 1.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2018-05-06 16:44+0900\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 2.4.0\n" + +msgid "i18n with strange markup" +msgstr "I18N WITH STRANGE MARKUP" + +msgid "1. title starting with 1." +msgstr "1. TITLE STARTING WITH 1." + diff --git a/tests/roots/test-latex-figure-in-admonition/conf.py b/tests/roots/test-latex-figure-in-admonition/conf.py index a45d22e..3d8b7b5 100644 --- a/tests/roots/test-latex-figure-in-admonition/conf.py +++ b/tests/roots/test-latex-figure-in-admonition/conf.py @@ -1 +1,3 @@ +extensions = ['sphinx.ext.todo'] +todo_include_todos = True exclude_patterns = ['_build'] diff --git a/tests/roots/test-latex-figure-in-admonition/index.rst b/tests/roots/test-latex-figure-in-admonition/index.rst index e3d39d3..c3fcaab 100644 --- a/tests/roots/test-latex-figure-in-admonition/index.rst +++ b/tests/roots/test-latex-figure-in-admonition/index.rst @@ -3,7 +3,24 @@ Test Figure in Admonition .. caution:: - This uses a figure in an admonition. + This uses a figure in a caution directive. .. figure:: img.png +.. note:: + + This uses a figure in a note directive. + + .. figure:: img.png + +.. seealso:: + + This uses a figure in a seealso directive. + + .. figure:: img.png + +.. todo:: + + This uses a figure in a todo directive. + + .. figure:: img.png diff --git a/tests/roots/test-latex-table/_mytemplates/latex/longtable.tex.jinja b/tests/roots/test-latex-table/_mytemplates/latex/longtable.tex.jinja new file mode 100644 index 0000000..e2cb1db --- /dev/null +++ b/tests/roots/test-latex-table/_mytemplates/latex/longtable.tex.jinja @@ -0,0 +1 @@ +SALUT LES COPAINS diff --git a/tests/roots/test-latex-table/_mytemplates/latex/longtable.tex_t b/tests/roots/test-latex-table/_mytemplates/latex/longtable.tex_t deleted file mode 100644 index e2cb1db..0000000 --- a/tests/roots/test-latex-table/_mytemplates/latex/longtable.tex_t +++ /dev/null @@ -1 +0,0 @@ -SALUT LES COPAINS diff --git a/tests/roots/test-latex-table/_mytemplates/latex/tabulary.tex_t b/tests/roots/test-latex-table/_mytemplates/latex/tabulary.tex_t new file mode 100644 index 0000000..7e6d425 --- /dev/null +++ b/tests/roots/test-latex-table/_mytemplates/latex/tabulary.tex_t @@ -0,0 +1 @@ +AU REVOIR, KANIGGETS diff --git a/tests/roots/test-linkcheck-anchors-ignore-for-url/index.rst b/tests/roots/test-linkcheck-anchors-ignore-for-url/index.rst index df287b4..02969b6 100644 --- a/tests/roots/test-linkcheck-anchors-ignore-for-url/index.rst +++ b/tests/roots/test-linkcheck-anchors-ignore-for-url/index.rst @@ -1,5 +1,6 @@ * `Example valid url, no anchor `_ * `Example valid url, valid anchor `_ +* `Example valid url, valid quotable anchor `_ * `Example valid url, invalid anchor `_ * `Example ignored url, no anchor `_ * `Example ignored url, invalid anchor `_ diff --git a/tests/roots/test-markup-rubric/conf.py b/tests/roots/test-markup-rubric/conf.py index e274bde..eccdbf7 100644 --- a/tests/roots/test-markup-rubric/conf.py +++ b/tests/roots/test-markup-rubric/conf.py @@ -1,3 +1,4 @@ latex_documents = [ ('index', 'test.tex', 'The basic Sphinx documentation for testing', 'Sphinx', 'report') ] +latex_toplevel_sectioning = 'section' diff --git a/tests/roots/test-markup-rubric/index.rst b/tests/roots/test-markup-rubric/index.rst index c2ae68a..f91b0f7 100644 --- a/tests/roots/test-markup-rubric/index.rst +++ b/tests/roots/test-markup-rubric/index.rst @@ -5,3 +5,35 @@ test-markup-rubric .. rubric:: This is a multiline rubric + +.. rubric:: A rubric with a class + :class: myclass + +.. rubric:: A rubric with a heading level 1 + :heading-level: 1 + :class: myclass + +.. rubric:: A rubric with a heading level 2 + :heading-level: 2 + :class: myclass + +.. rubric:: A rubric with a heading level 3 + :heading-level: 3 + :class: myclass + +.. rubric:: A rubric with a heading level 4 + :heading-level: 4 + :class: myclass + +.. rubric:: A rubric with a heading level 5 + :heading-level: 5 + :class: myclass + +.. rubric:: A rubric with a heading level 6 + :heading-level: 6 + :class: myclass + +.. rubric:: A rubric with a heading level 7 + :heading-level: 7 + :class: myclass + diff --git a/tests/roots/test-root/conf.py b/tests/roots/test-root/conf.py index a14ffaf..25c723b 100644 --- a/tests/roots/test-root/conf.py +++ b/tests/roots/test-root/conf.py @@ -17,7 +17,10 @@ jsmath_path = 'dummy.js' templates_path = ['_templates'] -source_suffix = ['.txt', '.add', '.foo'] +source_suffix = { + '.txt': 'restructuredtext', + '.foo': 'foo', +} project = 'Sphinx ' copyright = '1234-6789, copyright text credits' @@ -68,7 +71,7 @@ latex_elements = { shadowrule=1pt, shadowsep=10pt, shadowsize=10pt, - div.topic_border-width=2pt,% alias to shadowrule + div.topic_border-width=2pt,% alias to shadowrule div.topic_padding=6pt,% alias to shadowsep div.topic_box-shadow=5pt,% overrides/alias shadowsize % diff --git a/tests/roots/test-root/images.txt b/tests/roots/test-root/images.txt index 5a096dc..a07429a 100644 --- a/tests/roots/test-root/images.txt +++ b/tests/roots/test-root/images.txt @@ -18,5 +18,13 @@ Sphinx image handling .. an SVG image (for HTML at least) .. image:: svgimg.* +.. an SVG image using width with units +.. image:: svgimg.* + :width: 2cm + +.. an SVG image using height with units +.. image:: svgimg.* + :height: 2cm + .. an image with more than 1 dot in its file name .. image:: img.foo.png diff --git a/tests/roots/test-root/markup.txt b/tests/roots/test-root/markup.txt index ff677eb..91f4194 100644 --- a/tests/roots/test-root/markup.txt +++ b/tests/roots/test-root/markup.txt @@ -230,6 +230,19 @@ Tables with multirow and multicol: figure in table + * - .. warning:: + + warning in table + + * - .. seealso:: + + figure in a seealso in a table + + .. figure:: img.png + + with a caption + + and a legend Figures ------- diff --git a/tests/roots/test-templating/conf.py b/tests/roots/test-templating/conf.py index e03eaf1..7a2baed 100644 --- a/tests/roots/test-templating/conf.py +++ b/tests/roots/test-templating/conf.py @@ -1,5 +1,7 @@ project = 'Sphinx templating ' -source_suffix = '.txt' +source_suffix = { + '.txt': 'restructuredtext' +} keep_warnings = True templates_path = ['_templates'] release = version = '2013.120' diff --git a/tests/roots/test-theming/test_theme/staticfiles/static/legacytmpl.html_t b/tests/roots/test-theming/test_theme/staticfiles/static/legacytmpl.html_t new file mode 100644 index 0000000..8b505e2 --- /dev/null +++ b/tests/roots/test-theming/test_theme/staticfiles/static/legacytmpl.html_t @@ -0,0 +1,2 @@ + +{{ project | lower | escape }} diff --git a/tests/roots/test-theming/test_theme/staticfiles/static/statictmpl.html.jinja b/tests/roots/test-theming/test_theme/staticfiles/static/statictmpl.html.jinja new file mode 100644 index 0000000..4ab292b --- /dev/null +++ b/tests/roots/test-theming/test_theme/staticfiles/static/statictmpl.html.jinja @@ -0,0 +1,2 @@ + +{{ project|e }} diff --git a/tests/roots/test-theming/test_theme/staticfiles/static/statictmpl.html_t b/tests/roots/test-theming/test_theme/staticfiles/static/statictmpl.html_t deleted file mode 100644 index 4ab292b..0000000 --- a/tests/roots/test-theming/test_theme/staticfiles/static/statictmpl.html_t +++ /dev/null @@ -1,2 +0,0 @@ - -{{ project|e }} diff --git a/tests/roots/test-toctree-domain-objects/document_scoping.rst b/tests/roots/test-toctree-domain-objects/document_scoping.rst new file mode 100644 index 0000000..49aba9e --- /dev/null +++ b/tests/roots/test-toctree-domain-objects/document_scoping.rst @@ -0,0 +1,23 @@ +Level 1 +======= + +.. py:class:: ClassLevel1a + ClassLevel1b + + .. py:method:: f() + +.. py:method:: ClassLevel1a.g() + +.. py:method:: ClassLevel1b.g() + +Level 2 +------- + +.. py:class:: ClassLevel2a + ClassLevel2b + + .. py:method:: f() + +.. py:method:: ClassLevel2a.g() + +.. py:method:: ClassLevel2b.g() diff --git a/tests/roots/test-toctree-domain-objects/index.rst b/tests/roots/test-toctree-domain-objects/index.rst index 77ee010..5f04172 100644 --- a/tests/roots/test-toctree-domain-objects/index.rst +++ b/tests/roots/test-toctree-domain-objects/index.rst @@ -4,3 +4,4 @@ :name: mastertoc domains + document_scoping diff --git a/tests/roots/test-util-copyasset_overwrite/conf.py b/tests/roots/test-util-copyasset_overwrite/conf.py new file mode 100644 index 0000000..bb91f31 --- /dev/null +++ b/tests/roots/test-util-copyasset_overwrite/conf.py @@ -0,0 +1,7 @@ +import os +import sys +sys.path.insert(0, os.path.abspath('.')) + +extensions = ['myext'] +html_static_path = ['user_static'] +html_theme = 'basic' diff --git a/tests/roots/test-util-copyasset_overwrite/index.rst b/tests/roots/test-util-copyasset_overwrite/index.rst new file mode 100644 index 0000000..e69de29 diff --git a/tests/roots/test-util-copyasset_overwrite/myext.py b/tests/roots/test-util-copyasset_overwrite/myext.py new file mode 100644 index 0000000..544057c --- /dev/null +++ b/tests/roots/test-util-copyasset_overwrite/myext.py @@ -0,0 +1,22 @@ +from pathlib import Path + +from sphinx.util.fileutil import copy_asset + + +def _copy_asset_overwrite_hook(app): + css = app.outdir / '_static' / 'custom-styles.css' + # html_static_path is copied by default + assert css.read_text() == '/* html_static_path */\n', 'invalid default text' + # warning generated by here + copy_asset( + Path(__file__).parent.joinpath('myext_static', 'custom-styles.css'), + app.outdir / '_static', + ) + # This demonstrates the overwriting + assert css.read_text() == '/* extension styles */\n', 'overwriting failed' + return [] + + +def setup(app): + app.connect('html-collect-pages', _copy_asset_overwrite_hook) + app.add_css_file('custom-styles.css') diff --git a/tests/roots/test-util-copyasset_overwrite/myext_static/custom-styles.css b/tests/roots/test-util-copyasset_overwrite/myext_static/custom-styles.css new file mode 100644 index 0000000..9509354 --- /dev/null +++ b/tests/roots/test-util-copyasset_overwrite/myext_static/custom-styles.css @@ -0,0 +1 @@ +/* extension styles */ diff --git a/tests/roots/test-util-copyasset_overwrite/user_static/custom-styles.css b/tests/roots/test-util-copyasset_overwrite/user_static/custom-styles.css new file mode 100644 index 0000000..1b892b9 --- /dev/null +++ b/tests/roots/test-util-copyasset_overwrite/user_static/custom-styles.css @@ -0,0 +1 @@ +/* html_static_path */ diff --git a/tests/roots/test-versioning/conf.py b/tests/roots/test-versioning/conf.py index 6344cb0..d52d1f2 100644 --- a/tests/roots/test-versioning/conf.py +++ b/tests/roots/test-versioning/conf.py @@ -1,3 +1,5 @@ project = 'versioning test root' -source_suffix = '.txt' +source_suffix = { + '.txt': 'restructuredtext' +} exclude_patterns = ['_build'] diff --git a/tests/test_addnodes.py b/tests/test_addnodes.py index aa99343..b3f77ad 100644 --- a/tests/test_addnodes.py +++ b/tests/test_addnodes.py @@ -12,7 +12,7 @@ if TYPE_CHECKING: from collections.abc import Iterator -@pytest.fixture() +@pytest.fixture def sig_elements() -> Iterator[set[type[addnodes.desc_sig_element]]]: """Fixture returning the current ``addnodes.SIG_ELEMENTS`` set.""" original = addnodes.SIG_ELEMENTS.copy() # safe copy of the current nodes diff --git a/tests/test_application.py b/tests/test_application.py index 1fc49d6..9326ba5 100644 --- a/tests/test_application.py +++ b/tests/test_application.py @@ -96,7 +96,7 @@ def test_add_source_parser(app, status, warning): # .rst; only in :confval:`source_suffix` assert '.rst' not in app.registry.get_source_parsers() - assert app.registry.source_suffix['.rst'] is None + assert app.registry.source_suffix['.rst'] == 'restructuredtext' # .test; configured by API assert app.registry.source_suffix['.test'] == 'test' diff --git a/tests/test_builders/test_build.py b/tests/test_builders/test_build.py index 3f6d12c..0e649f7 100644 --- a/tests/test_builders/test_build.py +++ b/tests/test_builders/test_build.py @@ -21,7 +21,7 @@ def request_session_head(url, **kwargs): return response -@pytest.fixture() +@pytest.fixture def nonascii_srcdir(request, rootdir, sphinx_test_tempdir): # Build in a non-ASCII source dir test_name = '\u65e5\u672c\u8a9e' diff --git a/tests/test_builders/test_build_dirhtml.py b/tests/test_builders/test_build_dirhtml.py index dc5ab86..93609e3 100644 --- a/tests/test_builders/test_build_dirhtml.py +++ b/tests/test_builders/test_build_dirhtml.py @@ -28,13 +28,13 @@ def test_dirhtml(app, status, warning): invdata = InventoryFile.load(f, 'path/to', posixpath.join) assert 'index' in invdata.get('std:doc') - assert invdata['std:doc']['index'] == ('Python', '', 'path/to/', '-') + assert invdata['std:doc']['index'] == ('Project name not set', '', 'path/to/', '-') assert 'foo/index' in invdata.get('std:doc') - assert invdata['std:doc']['foo/index'] == ('Python', '', 'path/to/foo/', '-') + assert invdata['std:doc']['foo/index'] == ('Project name not set', '', 'path/to/foo/', '-') assert 'index' in invdata.get('std:label') - assert invdata['std:label']['index'] == ('Python', '', 'path/to/#index', '-') + assert invdata['std:label']['index'] == ('Project name not set', '', 'path/to/#index', '-') assert 'foo' in invdata.get('std:label') - assert invdata['std:label']['foo'] == ('Python', '', 'path/to/foo/#foo', 'foo/index') + assert invdata['std:label']['foo'] == ('Project name not set', '', 'path/to/foo/#foo', 'foo/index') diff --git a/tests/test_builders/test_build_epub.py b/tests/test_builders/test_build_epub.py index 6829f22..691ffcc 100644 --- a/tests/test_builders/test_build_epub.py +++ b/tests/test_builders/test_build_epub.py @@ -67,7 +67,7 @@ def test_build_epub(app): # toc.ncx toc = EPUBElementTree.fromstring((app.outdir / 'toc.ncx').read_text(encoding='utf8')) - assert toc.find("./ncx:docTitle/ncx:text").text == 'Python' + assert toc.find("./ncx:docTitle/ncx:text").text == 'Project name not set' # toc.ncx / head meta = list(toc.find("./ncx:head")) @@ -91,11 +91,11 @@ def test_build_epub(app): # content.opf / metadata metadata = opf.find("./idpf:metadata") assert metadata.find("./dc:language").text == 'en' - assert metadata.find("./dc:title").text == 'Python' + assert metadata.find("./dc:title").text == 'Project name not set' assert metadata.find("./dc:description").text == 'unknown' - assert metadata.find("./dc:creator").text == 'unknown' + assert metadata.find("./dc:creator").text == 'Author name not set' assert metadata.find("./dc:contributor").text == 'unknown' - assert metadata.find("./dc:publisher").text == 'unknown' + assert metadata.find("./dc:publisher").text == 'Author name not set' assert metadata.find("./dc:rights").text is None assert metadata.find("./idpf:meta[@property='ibooks:version']").text is None assert metadata.find("./idpf:meta[@property='ibooks:specified-fonts']").text == 'true' @@ -171,7 +171,7 @@ def test_nested_toc(app): # toc.ncx toc = EPUBElementTree.fromstring((app.outdir / 'toc.ncx').read_bytes()) - assert toc.find("./ncx:docTitle/ncx:text").text == 'Python' + assert toc.find("./ncx:docTitle/ncx:text").text == 'Project name not set' # toc.ncx / navPoint def navinfo(elem): @@ -409,6 +409,7 @@ def test_copy_images(app, status, warning): images = {image.name for image in images_dir.rglob('*')} images.discard('python-logo.png') assert images == { + # 'ba30773957c3fe046897111afd65a80b81cad089.png', # epub: image from data:image/png URI in source 'img.png', 'rimg.png', 'rimg1.png', diff --git a/tests/test_builders/test_build_gettext.py b/tests/test_builders/test_build_gettext.py index ddc6d30..dc8f4c9 100644 --- a/tests/test_builders/test_build_gettext.py +++ b/tests/test_builders/test_build_gettext.py @@ -16,13 +16,12 @@ if sys.version_info[:2] >= (3, 11): else: from sphinx.util.osutil import _chdir as chdir -_MSGID_PATTERN = re.compile(r'msgid "(.*)"') +_MSGID_PATTERN = re.compile(r'msgid "((?:\n|.)*?)"\nmsgstr', re.MULTILINE) -def msgid_getter(msgid): - if m := _MSGID_PATTERN.search(msgid): - return m[1] - return None +def get_msgids(pot): + matches = _MSGID_PATTERN.findall(pot) + return [m.replace('"\n"', '') for m in matches[1:]] def test_Catalog_duplicated_message(): @@ -105,7 +104,7 @@ def test_gettext_index_entries(app): app.build(filenames=[app.srcdir / 'index_entries.txt']) pot = (app.outdir / 'index_entries.pot').read_text(encoding='utf8') - msg_ids = list(filter(None, map(msgid_getter, pot.splitlines()))) + msg_ids = get_msgids(pot) assert msg_ids == [ "i18n with index entries", @@ -134,7 +133,7 @@ def test_gettext_disable_index_entries(app): app.build(filenames=[app.srcdir / 'index_entries.txt']) pot = (app.outdir / 'index_entries.pot').read_text(encoding='utf8') - msg_ids = list(filter(None, map(msgid_getter, pot.splitlines()))) + msg_ids = get_msgids(pot) assert msg_ids == [ "i18n with index entries", @@ -200,7 +199,7 @@ def test_gettext_prolog_epilog_substitution(app): assert (app.outdir / 'prolog_epilog_substitution.pot').is_file() pot = (app.outdir / 'prolog_epilog_substitution.pot').read_text(encoding='utf8') - msg_ids = list(filter(None, map(msgid_getter, pot.splitlines()))) + msg_ids = get_msgids(pot) assert msg_ids == [ "i18n with prologue and epilogue substitutions", @@ -227,9 +226,43 @@ def test_gettext_prolog_epilog_substitution_excluded(app): assert (app.outdir / 'prolog_epilog_substitution_excluded.pot').is_file() pot = (app.outdir / 'prolog_epilog_substitution_excluded.pot').read_text(encoding='utf8') - msg_ids = list(filter(None, map(msgid_getter, pot.splitlines()))) + msg_ids = get_msgids(pot) assert msg_ids == [ "i18n without prologue and epilogue substitutions", "This is content that does not include prologue and epilogue substitutions.", ] + + +@pytest.mark.sphinx( + 'gettext', srcdir='gettext', + confoverrides={'gettext_compact': False, + 'gettext_additional_targets': ['literal-block', 'doctest-block']}) +def test_gettext_literalblock_additional(app): + app.build(force_all=True) + + assert (app.outdir / 'literalblock.pot').is_file() + pot = (app.outdir / 'literalblock.pot').read_text(encoding='utf8') + msg_ids = get_msgids(pot) + + assert msg_ids == [ + 'i18n with literal block', + 'Correct literal block::', + 'this is\\nliteral block', + 'Missing literal block::', + "That's all.", + 'included raw.txt', + '===\\nRaw\\n===\\n\\n.. raw:: html\\n\\n \\n\\n', + 'code blocks', + "def main\\n 'result'\\nend", + '#include \\nint main(int argc, char** argv)\\n{\\n return 0;\\n}', + 'example of C language', + '#include \\nint main(int argc, char** argv)\\n{\\n return 0;\\n}', + 'literal-block\\nin list', + 'test_code_for_noqa()\\ncontinued()', + 'doctest blocks', + '>>> import sys # sys importing\\n>>> def main(): # define main ' + "function\\n... sys.stdout.write('hello') # call write method of " + "stdout object\\n>>>\\n>>> if __name__ == '__main__': # if run this py " + 'file as python script\\n... main() # call main', + ] diff --git a/tests/test_builders/test_build_html.py b/tests/test_builders/test_build_html.py index 1fa3ba4..8db0790 100644 --- a/tests/test_builders/test_build_html.py +++ b/tests/test_builders/test_build_html.py @@ -1,5 +1,6 @@ """Test the HTML builder and check output against XPath.""" +import contextlib import os import posixpath import re @@ -8,7 +9,7 @@ import pytest from sphinx.builders.html import validate_html_extra_path, validate_html_static_path from sphinx.deprecation import RemovedInSphinx80Warning -from sphinx.errors import ConfigError +from sphinx.errors import ConfigError, ThemeError from sphinx.util.console import strip_colors from sphinx.util.inventory import InventoryFile @@ -16,6 +17,31 @@ from tests.test_builders.xpath_data import FIGURE_CAPTION from tests.test_builders.xpath_util import check_xpath +def test_html_sidebars_error(make_app, tmp_path): + (tmp_path / 'conf.py').touch() + (tmp_path / 'index.rst').touch() + app = make_app( + buildername='html', + srcdir=tmp_path, + confoverrides={'html_sidebars': {'index': 'searchbox.html'}}, + ) + + # Test that the error is logged + warnings = app.warning.getvalue() + assert ("ERROR: Values in 'html_sidebars' must be a list of strings. " + "At least one pattern has a string value: 'index'. " + "Change to `html_sidebars = {'index': ['searchbox.html']}`.") in warnings + + # But that the value is unchanged. + # (Remove this bit of the test in Sphinx 8) + def _html_context_hook(app, pagename, templatename, context, doctree): + assert context["sidebars"] == 'searchbox.html' + app.connect('html-page-context', _html_context_hook) + with contextlib.suppress(ThemeError): + # ignore template rendering issues (ThemeError). + app.build() + + def test_html4_error(make_app, tmp_path): (tmp_path / 'conf.py').write_text('', encoding='utf-8') with pytest.raises( @@ -131,24 +157,24 @@ def test_html_inventory(app): 'py-modindex', 'genindex', 'search'} - assert invdata['std:label']['modindex'] == ('Python', + assert invdata['std:label']['modindex'] == ('Project name not set', '', 'https://www.google.com/py-modindex.html', 'Module Index') - assert invdata['std:label']['py-modindex'] == ('Python', + assert invdata['std:label']['py-modindex'] == ('Project name not set', '', 'https://www.google.com/py-modindex.html', 'Python Module Index') - assert invdata['std:label']['genindex'] == ('Python', + assert invdata['std:label']['genindex'] == ('Project name not set', '', 'https://www.google.com/genindex.html', 'Index') - assert invdata['std:label']['search'] == ('Python', + assert invdata['std:label']['search'] == ('Project name not set', '', 'https://www.google.com/search.html', 'Search Page') assert set(invdata['std:doc'].keys()) == {'index'} - assert invdata['std:doc']['index'] == ('Python', + assert invdata['std:doc']['index'] == ('Project name not set', '', 'https://www.google.com/index.html', 'The basic Sphinx documentation for testing') @@ -222,8 +248,8 @@ def test_html_sidebar(app, status, warning): app.build(force_all=True) result = (app.outdir / 'index.html').read_text(encoding='utf8') assert ('