tests.sphinx package¶
Submodules¶
tests.sphinx.conftest module¶
Fixtures and helpers for Sphinx tests.
Separated from the root tests/conftest.py so that the Sphinx dependency
(and its ecosystem: myst-parser, docutils, etc.) is only imported when running
the tests in this subdirectory. Downstream packagers can skip these tests with
--ignore=tests/sphinx without affecting the rest of the test suite.
- tests.sphinx.conftest.MYST_HAS_NATIVE_ALERTS = True¶
Flip-switch reused by tests to branch between the two alert rendering paths:
click_extra’s regex converter (pre-5.1) andmyst-parser’s native"alert"extension (>=5.1). Both paths must produce the same admonition HTML.
- class tests.sphinx.conftest.FormatType(*values)[source]¶
Bases:
EnumSphinx document format types and their file extensions.
- RST = '.rst'¶
- MYST = '.md'¶
- class tests.sphinx.conftest.SphinxAppWrapper(app, format_type)[source]¶
Bases:
objectWrapper around Sphinx application with additional testing methods.
- classmethod create(format_type, tmp_path, return_srcdir=False, enable_exec_directives=True)[source]¶
Factory method to create a SphinxAppWrapper with given format.
enable_exec_directivesopts the test app into theclick:*andpython:*directive families. Defaults toTruefor every fixture-built app because the test suite primarily exercises those directives. Tests that verify the off-by-default production gate flip the flag back toFalseexplicitly.- Return type:
Generator[SphinxAppWrapper|tuple[SphinxAppWrapper,Path],None,None]
- tests.sphinx.conftest.sphinx_app(request, tmp_path)[source]¶
Create a Sphinx application for testing.
- tests.sphinx.conftest.sphinx_app_for_format(request, tmp_path)[source]¶
sphinx_appvariant whose format is supplied by the caller.Identical to
sphinx_app()but without the defaultparams: theFormatTypeis taken from the test’s indirect parametrization. Aparams-bearing fixture cannot also be parametrized by a test (pytest rejects it as a duplicate parametrization), so a test that drives the format per case parametrizes this variant instead.
- tests.sphinx.conftest.sphinx_app_rst(tmp_path)[source]¶
Create a Sphinx application for testing RST format only.
The
click:*andpython:*directive families are enabled so tests can exercise them. Tests that explicitly verify the off-by- default opt-in gate construct their own app viaSphinxAppWrapper.create()withenable_exec_directives=False.
- tests.sphinx.conftest.sphinx_app_myst(tmp_path)[source]¶
Create a Sphinx application for testing MyST format only.
The
click:*andpython:*directive families are enabled: seesphinx_app_rst()for the rationale.
- tests.sphinx.conftest.sphinx_app_myst_with_include(tmp_path)[source]¶
Create a Sphinx application for testing MyST format with include files.
- class tests.sphinx.conftest.DirectiveTestCase(name, format_type=None, source_block=None, run_block=None, document=None, html_matches=None)[source]¶
Bases:
objectTest case data for directive tests.
- format_type: FormatType | None = None¶
- tests.sphinx.conftest.python_block(*lines)[source]¶
Build expected Python highlight block.
- Return type:
tests.sphinx.test_sphinx module¶
Fixtures and utilities for Sphinx testing.
tests.sphinx.test_sphinx_alerts module¶
Tests for GitHub alert syntax conversion in Sphinx with MyST parser.
- tests.sphinx.test_sphinx_alerts.test_all_alert_types(alert_type)[source]¶
Test all supported alert types are converted correctly.
- tests.sphinx.test_sphinx_alerts.test_alert_conversion(text, expected)[source]¶
Test GitHub alerts are converted to MyST admonitions.
When expected is None, no conversion should occur.
- tests.sphinx.test_sphinx_alerts.test_sphinx_integration(sphinx_app, test_case)[source]¶
Integration-critical tests that verify Sphinx rendering behavior.
tests.sphinx.test_sphinx_click module¶
Tests for Sphinx directives click:source and click:run in rST and MyST formats.
- tests.sphinx.test_sphinx_click.test_directive_functionality(sphinx_app, test_case)[source]¶
Test standard directive functionalities in both rST and MyST.
- tests.sphinx.test_sphinx_click.test_directive_option_format(sphinx_app_rst)[source]¶
rST will fail to render if an
:option:is not followed by an empty line.
- tests.sphinx.test_sphinx_click.test_directive_option_language_override(sphinx_app)[source]¶
Test that language override works for click:run directive.
- tests.sphinx.test_sphinx_click.test_sphinx_directive_state_persistence(sphinx_app)[source]¶
Test that state persists between declare and run directives in real Sphinx.
- tests.sphinx.test_sphinx_click.test_directive_variable_conflict(var_name, sphinx_app_for_format, content, directive_lineno, error_lineno)[source]¶
Test that variable conflicts are properly detected in real Sphinx environment.
- tests.sphinx.test_sphinx_click.test_exit_exception_percolate(sphinx_app)[source]¶
Test directives that handle command errors and exit codes.
- tests.sphinx.test_sphinx_click.test_clickrunner_forces_color(monkeypatch)[source]¶
ClickRunnerforcesFORCE_COLORso Rich-based CLIs colorize underNO_COLOR.The runner already passes
color=True(Click’s color system). But rich-click renders help through Rich’sConsole, gated onFORCE_COLOR, whichcolor=Truenever reaches. The runner therefore also forcesFORCE_COLOR(clearing the disabling vars) around the executed command, then restores the environment.
- tests.sphinx.test_sphinx_click.test_clickrunner_capture_mode_controls_fileno(capture, renders)[source]¶
ClickRunner(capture=...)decides whether a fileno-writing CLI renders.Click’s
"sys"mode backs the captured stream with an in-memory buffer whosefileno()raisesio.UnsupportedOperation, so a documented command that re-opens its descriptor (a common UTF-8-on-Windows guard) aborts."fd"(the default on Unix, also exposed as theclick_extra_run_captureconf.py value) backs it with a real descriptor, so the command renders. On Windows, where fd-backed streams are not supported, the default falls back to"sys".
tests.sphinx.test_sphinx_click_tree module¶
Tests for the click:tree Sphinx directive.
- tests.sphinx.test_sphinx_click_tree.KITCHEN_CLI = '```{click:source}\n:hide-source:\nfrom click import command, echo, group, option\n\n@group\ndef kitchen():\n """Manage kitchen tools and recipes."""\n\n@kitchen.command\n@option("--minutes", type=int, default=5)\ndef boil(minutes):\n """Boil water for tea."""\n echo(f"Boiling for {minutes} minutes.")\n\n@kitchen.group\ndef pantry():\n """Inspect pantry contents."""\n\n@pantry.command\ndef jars():\n """List jars on the shelf."""\n echo("Olives, honey, pickles.")\n```\n'¶
Toy CLI reused across tests. Defines a multi-level group so the walk exercises the recursive descent into nested
click.Groupcommands.
- tests.sphinx.test_sphinx_click_tree.test_click_tree_renders_summary_table_and_help_blocks(sphinx_app_myst)[source]¶
The directive expands into a GFM table + one help capture per command.
- tests.sphinx.test_sphinx_click_tree.test_click_tree_inline_import_in_body(sphinx_app_myst)[source]¶
The directive body runs as a preamble, so a seed
click:sourceis optional.
- tests.sphinx.test_sphinx_click_tree.test_click_tree_no_table_and_no_root(sphinx_app_myst)[source]¶
:no-table:and:no-root:drop the summary table and root block.
- tests.sphinx.test_sphinx_click_tree.test_click_tree_max_depth_truncates_walk(sphinx_app_myst)[source]¶
:max-depth: 1stops the walk at one level below the root.
- tests.sphinx.test_sphinx_click_tree.test_click_tree_label_and_anchor_prefix_override(sphinx_app_myst)[source]¶
:label-prefix:and:anchor-prefix:override the defaults.
- tests.sphinx.test_sphinx_click_tree.test_click_tree_errors_on_non_command(sphinx_app_myst)[source]¶
Resolving the argument to a non-Command raises a clear directive error.
- tests.sphinx.test_sphinx_click_tree.test_click_tree_errors_on_unknown_name(sphinx_app_myst)[source]¶
An expression that can’t be evaluated raises a clear directive error.
- tests.sphinx.test_sphinx_click_tree.test_click_tree_errors_in_rst(sphinx_app_rst)[source]¶
click:treeraises a clear error when used in an rST document.
- tests.sphinx.test_sphinx_click_tree.test_click_tree_heading_offset_defaults_to_top_level(sphinx_app_myst)[source]¶
Below a single
# Doc titlethe root renders ath2.Preserves the historical default behavior: a directive at the document body (inside the title’s h1 section) emits its root one level below.
- tests.sphinx.test_sphinx_click_tree.test_click_tree_heading_offset_adapts_to_surrounding_section(sphinx_app_myst)[source]¶
Nested inside an
h3section, the root renders ath4.The default heading offset is computed from
state.memo.section_levelso the document outline stays consistent regardless of where the directive is placed.
- tests.sphinx.test_sphinx_click_tree.test_click_tree_heading_offset_explicit_override(sphinx_app_myst)[source]¶
An explicit
:heading-offset:wins over the auto-detected default.Surrounding headings establish a deep level so the override’s effect is clearly observable in the rendered HTML (without MyST normalizing skipped heading levels).
tests.sphinx.test_sphinx_manpages module¶
Tests for click_extra.sphinx.manpages.
- tests.sphinx.test_sphinx_manpages.test_manpages_hook_writes_tree_into_outdir(tmp_path)[source]¶
An entry with just
scriptwrites the whole tree underman/.
- tests.sphinx.test_sphinx_manpages.test_manpages_hook_honors_prog_name_and_output_dir(tmp_path)[source]¶
An entry can override both the basename and the subdirectory.
- tests.sphinx.test_sphinx_manpages.test_manpages_hook_skips_non_html_builder(tmp_path)[source]¶
Non-HTML builders (like
linkcheck) must not emit man pages.
- tests.sphinx.test_sphinx_manpages.test_manpages_hook_empty_config_is_noop(tmp_path)[source]¶
An empty list leaves the build untouched.
- tests.sphinx.test_sphinx_manpages.test_manpages_hook_skips_entry_without_script(tmp_path)[source]¶
An entry missing
scriptis skipped (logged as a warning) instead of aborting the build.
- tests.sphinx.test_sphinx_manpages.test_manpages_module_help_documents_config_shape()[source]¶
The module docstring spells out every supported key.
A safety net against silent removal: distributors and downstream projects depend on the docstring as the canonical reference, since it is what
help(click_extra.sphinx.manpages)prints.
- tests.sphinx.test_sphinx_manpages.test_manpages_hook_emits_html_siblings(tmp_path)[source]¶
When a renderer is available, every
.1gets a.1.htmlnext to it whose body carries the section headings from the source roff.
- tests.sphinx.test_sphinx_manpages.test_manpages_hook_respects_render_html_opt_out(tmp_path)[source]¶
render_html=Falseskips the HTML pass even when a renderer is present, keeping the build to roff only.
- tests.sphinx.test_sphinx_manpages.test_manpages_directive_renders_one_link_per_command(tmp_path)[source]¶
The directive emits a bullet list with one entry per (sub)command of every script declared in
click_extra_manpages.
tests.sphinx.test_sphinx_python module¶
Tests for the python:* Sphinx directive family.
Covers python:source, python:run, and the three render variants:
python:render(host parser)python:render-myst(forced MyST, regardless of host)python:render-rst(forced reST, regardless of host)
- tests.sphinx.test_sphinx_python.test_python_run_renders_stdout(sphinx_app_myst)[source]¶
python:runcapturesprintoutput and renders it in a code block.
- tests.sphinx.test_sphinx_python.test_python_source_seeds_namespace_for_python_run(sphinx_app_myst)[source]¶
python:sourceruns silently; a follow-uppython:runreuses its imports.
- tests.sphinx.test_sphinx_python.test_python_run_language_override(sphinx_app_myst)[source]¶
:language:overrides the defaulttextlexer for the result block.
- tests.sphinx.test_sphinx_python.test_python_run_emphasize_lines_split(sphinx_app_myst)[source]¶
:emphasize-lines:highlights source only;:emphasize-result-lines:highlights result only: independently, on the same block.
- tests.sphinx.test_sphinx_python.test_python_render_passes_block_level_html(sphinx_app_myst)[source]¶
python:renderpasses block-level raw HTML through unchanged.A naked
print('<div>...</div>')should reach the rendered page without any{raw} htmlwrapping. Locks down the natural-form pattern so a future MyST upgrade or extension reordering can’t silently regress it.
- tests.sphinx.test_sphinx_python.test_python_render_host_myst_injects_table(sphinx_app_myst)[source]¶
python:renderparses captured stdout with the host (MyST) parser.
- tests.sphinx.test_sphinx_python.test_python_render_host_myst_injects_heading(sphinx_app_myst)[source]¶
A heading printed by
python:renderbecomes a real heading node.
- tests.sphinx.test_sphinx_python.test_python_render_host_rst_injects_admonition(sphinx_app_rst)[source]¶
python:renderin an rST host: stdout is parsed as reST.
- tests.sphinx.test_sphinx_python.test_python_render_myst_in_rst_host(sphinx_app_rst)[source]¶
python:render-mystforces MyST parsing inside an rST host document.This is the headline use case: an rST file embeds Python that prints MyST markup and the directive parses it as MyST regardless of host.
- tests.sphinx.test_sphinx_python.test_python_render_rst_in_myst_host(sphinx_app_myst)[source]¶
python:render-rstforces reST parsing inside a MyST host document.
- tests.sphinx.test_sphinx_python.test_python_render_myst_in_myst_host_still_works(sphinx_app_myst)[source]¶
python:render-mystworks in MyST hosts too; it always picks MyST.
- tests.sphinx.test_sphinx_python.test_python_render_rst_in_rst_host_still_works(sphinx_app_rst)[source]¶
python:render-rstworks in rST hosts too; it always picks reST.
- tests.sphinx.test_sphinx_python.test_exec_directives_disabled_by_default(tmp_path)[source]¶
Without the opt-in flag,
click:*andpython:*are not registered.The Sphinx build still succeeds but neither family’s directive body is ever executed. This is the desired security default: a project that adds
click_extra.sphinxto its extensions list does not silently gain build-time arbitrary Python execution.The exact rendering of an unrecognized directive is parser-dependent (MyST silently swallows it; reST emits a system message), so the assertion focuses on the security-relevant invariant: the directive body’s
printoutput never reaches the rendered HTML.