pax_global_header00006660000000000000000000000064145025446600014520gustar00rootroot0000000000000052 comment=276e66b31efb688a87a1001f2bc0e1553cc61e56 sphinx-pytest-0.2.0/000077500000000000000000000000001450254466000143565ustar00rootroot00000000000000sphinx-pytest-0.2.0/.github/000077500000000000000000000000001450254466000157165ustar00rootroot00000000000000sphinx-pytest-0.2.0/.github/dependabot.yml000066400000000000000000000011261450254466000205460ustar00rootroot00000000000000# To get started with Dependabot version updates, you'll need to specify which # package ecosystems to update and where the package manifests are located. # Please see the documentation for all configuration options: # https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates version: 2 updates: - package-ecosystem: github-actions directory: / commit-message: prefix: ⬆️ schedule: interval: weekly - package-ecosystem: pip directory: / commit-message: prefix: ⬆️ schedule: interval: weekly sphinx-pytest-0.2.0/.github/workflows/000077500000000000000000000000001450254466000177535ustar00rootroot00000000000000sphinx-pytest-0.2.0/.github/workflows/ci.yml000066400000000000000000000027731450254466000211020ustar00rootroot00000000000000name: ci on: push: branches: [main] tags: - "v[0-9]+.[0-9]+.[0-9]+*" pull_request: jobs: pre-commit: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: Set up Python 3.8 uses: actions/setup-python@v4 with: python-version: "3.8" - uses: pre-commit/action@v3.0.0 tests: strategy: fail-fast: false matrix: python-version: ["3.7", "3.8", "3.9", "3.10"] os: [ubuntu-latest] include: - os: windows-latest python-version: "3.8" runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v3 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v4 with: python-version: ${{ matrix.python-version }} - name: Install dependencies run: | python -m pip install --upgrade pip pip install -e . - name: Run pytest run: pytest publish: name: Publish to PyPi needs: [pre-commit, tests] if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags') runs-on: ubuntu-latest steps: - name: Checkout source uses: actions/checkout@v3 - name: Set up Python uses: actions/setup-python@v4 with: python-version: "3.8" - name: install flit run: | pip install flit~=3.4 - name: Build and publish run: | flit publish env: FLIT_USERNAME: __token__ FLIT_PASSWORD: ${{ secrets.PYPI_TOKEN }} sphinx-pytest-0.2.0/.gitignore000066400000000000000000000034211450254466000163460ustar00rootroot00000000000000# Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] *$py.class # C extensions *.so # Distribution / packaging .Python build/ develop-eggs/ dist/ downloads/ eggs/ .eggs/ lib/ lib64/ parts/ sdist/ var/ wheels/ pip-wheel-metadata/ share/python-wheels/ *.egg-info/ .installed.cfg *.egg MANIFEST # PyInstaller # Usually these files are written by a python script from a template # before PyInstaller builds the exe, so as to inject date/other infos into it. *.manifest *.spec # Installer logs pip-log.txt pip-delete-this-directory.txt # Unit test / coverage reports htmlcov/ .tox/ .nox/ .coverage .coverage.* .cache nosetests.xml coverage.xml *.cover *.py,cover .hypothesis/ .pytest_cache/ # Translations *.mo *.pot # Django stuff: *.log local_settings.py db.sqlite3 db.sqlite3-journal # Flask stuff: instance/ .webassets-cache # Scrapy stuff: .scrapy # Sphinx documentation docs/_build/ # PyBuilder target/ # Jupyter Notebook .ipynb_checkpoints # IPython profile_default/ ipython_config.py # pyenv .python-version # pipenv # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. # However, in case of collaboration, if having platform-specific dependencies or dependencies # having no cross-platform support, pipenv may install dependencies that don't work, or not # install all needed dependencies. #Pipfile.lock # PEP 582; used by e.g. github.com/David-OConnor/pyflow __pypackages__/ # Celery stuff celerybeat-schedule celerybeat.pid # SageMath parsed files *.sage.py # Environments .env .venv env/ venv/ ENV/ env.bak/ venv.bak/ # Spyder project settings .spyderproject .spyproject # Rope project settings .ropeproject # mkdocs documentation /site # mypy .mypy_cache/ .dmypy.json dmypy.json # Pyre type checker .pyre/ .vscode/ sphinx-pytest-0.2.0/.pre-commit-config.yaml000066400000000000000000000017521450254466000206440ustar00rootroot00000000000000# See https://pre-commit.com for more information # See https://pre-commit.com/hooks.html for more hooks repos: - repo: https://github.com/pre-commit/pre-commit-hooks rev: v4.4.0 hooks: - id: trailing-whitespace - id: end-of-file-fixer - id: check-yaml - id: check-added-large-files - repo: https://github.com/asottile/pyupgrade rev: v3.4.0 hooks: - id: pyupgrade args: [--py37-plus] - repo: https://github.com/PyCQA/isort rev: 5.12.0 hooks: - id: isort - repo: https://github.com/psf/black rev: 23.3.0 hooks: - id: black - repo: https://github.com/PyCQA/flake8 rev: 6.0.0 hooks: - id: flake8 additional_dependencies: - flake8-comprehensions - flake8-bugbear - repo: https://github.com/pre-commit/mirrors-mypy rev: v1.3.0 hooks: - id: mypy args: [--config-file=pyproject.toml] additional_dependencies: - types-docutils - sphinx~=7.0 - pytest sphinx-pytest-0.2.0/.vscode/000077500000000000000000000000001450254466000157175ustar00rootroot00000000000000sphinx-pytest-0.2.0/.vscode/settings.json000066400000000000000000000005131450254466000204510ustar00rootroot00000000000000{ "files.exclude": { "**/.git": true, "**/.svn": true, "**/.hg": true, "**/CVS": true, "**/.DS_Store": true, "**/Thumbs.db": true, "**/__pycache__": true, "**/.pytest_cache": true, "**/.mypy_cache": true }, "python.formatting.provider": "black" } sphinx-pytest-0.2.0/LICENSE000066400000000000000000000020551450254466000153650ustar00rootroot00000000000000MIT License Copyright (c) 2022 Chris Sewell Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. sphinx-pytest-0.2.0/README.md000066400000000000000000000030641450254466000156400ustar00rootroot00000000000000# sphinx-pytest [![PyPI][pypi-badge]][pypi-link] Helpful pytest fixtures for sphinx extensions. Sphinx is annoying, because the modularity is not great, meaning that there is no real way just to convert single documents in isolation, etc. This extension mainly provides some pytest fixtures to "simulate" converting some source text to docutils AST at different stages; before transforms, after transforms, etc. ## Installation ``` pip install sphinx-pytest ``` ## Examples ```python from sphinx_pytest.plugin import CreateDoctree def test_no_transforms(sphinx_doctree_no_tr: CreateDoctree): """Return the doctree, before any transforms have been applied.""" sphinx_doctree_no_tr.set_conf({"language": "en"}) result = sphinx_doctree_no_transforms(".. _target:\n\nheader\n------\n") assert ( result.pformat() == """\
header """.rstrip() ) ``` ```python def test_with_transforms(sphinx_doctree: CreateDoctree): """Return the doctree, after transforms (but not post-transforms).""" result = sphinx_doctree(".. _target:\n\nheader\n------\n") assert ( result.pformat() == """\ <document source="<src>/index.rst"> <target refid="target"> <section ids="header target" names="header target"> <title> header """.rstrip() ) ``` [pypi-badge]: https://img.shields.io/pypi/v/sphinx_pytest.svg [pypi-link]: https://pypi.org/project/sphinx_pytest ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������sphinx-pytest-0.2.0/pyproject.toml������������������������������������������������������������������0000664�0000000�0000000�00000002070�14502544660�0017271�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������[build-system] requires = ["flit_core >=3.2,<4"] build-backend = "flit_core.buildapi" [project] name = "sphinx_pytest" dynamic = ["version", "description"] authors = [{name = "Chris Sewell", email = "chrisj_sewell@hotmail.com"}] readme = "README.md" license = {file = "LICENSE"} classifiers = [ "License :: OSI Approved :: MIT License", "Programming Language :: Python :: 3", "Programming Language :: Python :: Implementation :: CPython", "Topic :: Software Development :: Libraries :: Python Modules", "Framework :: Pytest", ] keywords = ["sphinx", "pytest"] requires-python = ">=3.7" dependencies = ["sphinx", "pytest"] [project.urls] Homepage = "https://github.com/sphinx-extensions2/sphinx-pytest" [project.entry-points."pytest11"] sphinx_test = "sphinx_pytest.plugin" [project.entry-points."sphinx.builders"] doctree = "sphinx_pytest.builders" [tool.isort] profile = "black" force_sort_within_sections = true [tool.mypy] show_error_codes = true check_untyped_defs = true strict_equality = true no_implicit_optional = true warn_unused_ignores = true ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������sphinx-pytest-0.2.0/src/����������������������������������������������������������������������������0000775�0000000�0000000�00000000000�14502544660�0015145�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������sphinx-pytest-0.2.0/src/sphinx_pytest/��������������������������������������������������������������0000775�0000000�0000000�00000000000�14502544660�0020066�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������sphinx-pytest-0.2.0/src/sphinx_pytest/__init__.py���������������������������������������������������0000664�0000000�0000000�00000000114�14502544660�0022173�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������"""Helpful pytest fixtures for sphinx extensions.""" __version__ = "0.2.0" ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������sphinx-pytest-0.2.0/src/sphinx_pytest/builders.py���������������������������������������������������0000664�0000000�0000000�00000002035�14502544660�0022251�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������"""Sphinx builders for pytest.""" from __future__ import annotations from docutils import nodes from sphinx.application import Sphinx from sphinx.builders.dummy import DummyBuilder class DoctreeBuilder(DummyBuilder): """A builder that only builds the the initial doctrees, without subsequent events or post-transforms. The doctrees are stored in the `doctrees` attribute, rather than saved to disk. """ name = "doctree" def init(self) -> None: self.doctrees: dict[str, nodes.document] = {} def write_doctree( self, docname: str, doctree: nodes.document, *, _cache: bool = True ) -> None: # save the doctree instead of pickling to disk self.doctrees[docname] = doctree def build(self, *args, **kwargs) -> None: # don't run anything after the initial doctree reads self.read() def setup(app: Sphinx) -> dict: app.add_builder(DoctreeBuilder) return { "version": "1", "parallel_read_safe": True, "parallel_write_safe": True, } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������sphinx-pytest-0.2.0/src/sphinx_pytest/plugin.py�����������������������������������������������������0000664�0000000�0000000�00000013465�14502544660�0021747�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������"""The pytest plugin.""" from __future__ import annotations from collections.abc import Mapping import os from pathlib import Path from typing import Any, Iterator from docutils import nodes from docutils.core import Publisher import pytest from sphinx import version_info as sphinx_version_info from sphinx.environment import BuildEnvironment from sphinx.testing.util import SphinxTestApp from .builders import DoctreeBuilder pytest_plugins = ("sphinx.testing.fixtures",) @pytest.fixture def sphinx_doctree(make_app: type[SphinxTestApp], tmp_path: Path): """Create a sphinx doctree (before post-transforms).""" yield CreateDoctree(app_cls=make_app, srcdir=tmp_path / "src") @pytest.fixture def sphinx_doctree_no_tr(make_app: type[SphinxTestApp], tmp_path: Path, monkeypatch): """Create a sphinx doctree with no transforms.""" def _apply_transforms(self): pass monkeypatch.setattr(Publisher, "apply_transforms", _apply_transforms) yield CreateDoctree(app_cls=make_app, srcdir=tmp_path / "src") class Doctrees(Mapping): """A mapping of doctree names to doctrees.""" def __init__(self, env: BuildEnvironment): self._env = env def __getitem__(self, key: str) -> nodes.document: try: return self._env.get_doctree(key) except FileNotFoundError: raise KeyError(key) def __iter__(self) -> Iterator[str]: return iter(self._env.found_docs) def __len__(self) -> int: return len(self._env.found_docs) class AppWrapper: """Wrapper for SphinxTestApp to make it easier to use.""" def __init__(self, app: SphinxTestApp) -> None: self._app = app @property def app(self) -> SphinxTestApp: return self._app @property def env(self) -> BuildEnvironment: assert self._app.env is not None return self._app.env @property def builder(self) -> DoctreeBuilder: return self._app.builder # type: ignore def build(self) -> AppWrapper: self._app.build() return self @property def warnings(self) -> str: text = self._app._warning.getvalue() return text.replace(str(self._app.srcdir), "<src>") @property def doctrees(self) -> dict[str, nodes.document] | Doctrees: """The built doctrees (before post-transforms).""" try: return self.builder.doctrees except AttributeError: return Doctrees(self.env) def pformat( self, docname: str = "index", pop_doc_attrs=("translation_progress",) ) -> str: """Return an indented pseudo-XML representation. The src directory is replaced with <src>, for reproducibility. :param pop_doc_attrs: Remove these attributes of the doctree node, before converting to text. By default, ``translation_progress`` is removed for compatibility (added in sphinx 7.1). """ doctree = self.doctrees[docname].deepcopy() for attr_name in pop_doc_attrs: doctree.attributes.pop(attr_name, None) text = doctree.pformat() return text.replace(str(self._app.srcdir) + os.sep, "<src>/").rstrip() def get_resolved_doctree(self, docname: str = "index") -> nodes.document: """Return the doctree after post-transforms. Note only builder agnostic post-transforms will be applied, e.g. not ones for 'html' etc. """ doctree = self.doctrees[docname].deepcopy() self.env.apply_post_transforms(doctree, docname) # note, this does not resolve toctrees, as in: # https://github.com/sphinx-doc/sphinx/blob/05a898ecb4ff8e654a053a1ba5131715a4514812/sphinx/environment/__init__.py#L538 return doctree def get_resolved_pformat( self, docname: str = "index", pop_doc_attrs=("translation_progress",) ) -> str: """Return an indented pseudo-XML representation, after post-transforms. The src directory is replaced with <src>, for reproducibility. :param pop_doc_attrs: Remove these attributes of the doctree node, before converting to text. By default, ``translation_progress`` is removed for compatibility (added in sphinx 7.1). """ doctree = self.get_resolved_doctree(docname) for attr_name in pop_doc_attrs: doctree.attributes.pop(attr_name, None) text = doctree.pformat() return text.replace(str(self._app.srcdir) + os.sep, "<src>/").rstrip() class CreateDoctree: def __init__(self, app_cls: type[SphinxTestApp], srcdir: Path) -> None: self._app_cls = app_cls self.srcdir = srcdir self.srcdir.mkdir(parents=True, exist_ok=True) # the test app always sets `confdir = srcdir`, as opposed to None, # which means a conf.py is required self.srcdir.joinpath("conf.py").write_text("", encoding="utf8") self.buildername = "doctree" self._confoverrides: dict[str, Any] = {} def set_conf(self, conf: dict[str, Any]) -> CreateDoctree: self._confoverrides = conf return self def __call__( self, content: str, filename: str = "index.rst", **kwargs, ) -> AppWrapper: """Create doctrees for a set of files.""" self.srcdir.joinpath(filename).parent.mkdir(parents=True, exist_ok=True) self.srcdir.joinpath(filename).write_text(content, encoding="utf8") srcdir: Any if sphinx_version_info >= (7, 2): srcdir = self.srcdir else: from sphinx.testing.path import path srcdir = path(str(self.srcdir)) return AppWrapper( self._app_cls( srcdir=srcdir, buildername=self.buildername, confoverrides=self._confoverrides, **kwargs, ) ).build() �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������sphinx-pytest-0.2.0/tests/��������������������������������������������������������������������������0000775�0000000�0000000�00000000000�14502544660�0015520�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������sphinx-pytest-0.2.0/tests/test_basic.py�������������������������������������������������������������0000664�0000000�0000000�00000002525�14502544660�0020216�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������def test_basic(sphinx_doctree): result = sphinx_doctree("abc") assert ( result.pformat() == '<document source="<src>/index.rst">\n <paragraph>\n abc' ) def test_no_transforms(sphinx_doctree_no_tr): """Return the doctree, before any transforms have been applied.""" result = sphinx_doctree_no_tr(".. _target:\n\nheader\n------\n") assert ( result.pformat() == """\ <document source="<src>/index.rst"> <target ids="target" names="target"> <section ids="header" names="header"> <title> header """.rstrip() ) def test_with_transforms(sphinx_doctree): """Return the doctree, after transforms (but not post-transforms).""" result = sphinx_doctree(".. _target:\n\nheader\n------\n") assert ( result.pformat() == """\ <document source="<src>/index.rst"> <target refid="target"> <section ids="header target" names="header target"> <title> header """.rstrip() ) def test_html_builder(sphinx_doctree): sphinx_doctree.buildername = "html" result = sphinx_doctree(".. only:: html\n\n abc\n\n.. only:: latex\n\n xyz\n") assert ( result.get_resolved_pformat() == '<document source="<src>/index.rst">\n <paragraph>\n abc' '\n <comment xml:space="preserve">' ) ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������sphinx-pytest-0.2.0/tox.ini�������������������������������������������������������������������������0000664�0000000�0000000�00000000315�14502544660�0015670�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# To use tox, see https://tox.readthedocs.io [tox] envlist = py38 [testenv] usedevelop = true [testenv:py{37,38,39,310}] commands = pytest {posargs} [flake8] max-line-length = 100 extend-ignore = E203 ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������