Source code for tests.mkdocs.test_mkdocs
# Copyright Kevin Deldycke <kevin@deldycke.com> and contributors.
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
"""Tests for the MkDocs ANSI color plugin."""
from __future__ import annotations
import click
import pytest
from pygments.formatters.html import HtmlFormatter
from click_extra.mkdocs import (
ANSI_OUTPUT_FENCE,
TEXT_FENCE,
AnsiColorPlugin,
_patch_mkdocs_click,
)
from click_extra.pygments import AnsiHtmlFormatter
@pytest.fixture()
def _clean_pymdownx():
"""Save and restore pymdownx.highlight formatter classes around each test."""
import pymdownx.highlight
orig_block = pymdownx.highlight.BlockHtmlFormatter
orig_inline = pymdownx.highlight.InlineHtmlFormatter
yield
pymdownx.highlight.BlockHtmlFormatter = orig_block
pymdownx.highlight.InlineHtmlFormatter = orig_inline
@pytest.fixture()
def _clean_mkdocs_click():
"""Save and restore mkdocs-click functions around each test."""
from mkdocs_click import _docs
orig_usage = _docs._make_usage
orig_plain = _docs._make_plain_options
orig_patched = getattr(_docs, "_click_extra_patched", False)
yield
_docs._make_usage = orig_usage
_docs._make_plain_options = orig_plain
_docs._click_extra_patched = orig_patched # type: ignore[attr-defined]
[docs]
@pytest.mark.once
def test_mkdocs_entry_point():
"""Verify the ``mkdocs.plugins`` entry point is declared in ``pyproject.toml``."""
import sys
if sys.version_info >= (3, 11):
import tomllib
else:
import tomli as tomllib # type: ignore[import-not-found]
from pathlib import Path
toml_path = Path(__file__).parent.parent.parent / "pyproject.toml"
config = tomllib.loads(toml_path.read_text(encoding="utf-8"))
ep = config["project"]["entry-points"]["mkdocs.plugins"]
assert ep == {"click-extra": "click_extra.mkdocs:AnsiColorPlugin"}
[docs]
@pytest.mark.usefixtures("_clean_pymdownx", "_clean_mkdocs_click")
def test_on_config_idempotent():
"""Calling ``on_config`` twice does not create a new class each time."""
import pymdownx.highlight
plugin = AnsiColorPlugin()
plugin.on_config({}) # type: ignore[arg-type]
block_cls = pymdownx.highlight.BlockHtmlFormatter
inline_cls = pymdownx.highlight.InlineHtmlFormatter
plugin.on_config({}) # type: ignore[arg-type]
assert pymdownx.highlight.BlockHtmlFormatter is block_cls
assert pymdownx.highlight.InlineHtmlFormatter is inline_cls
@click.command()
@click.option("--name", help="The person to greet.")
def _hello_cmd(name):
"""Greet someone."""
[docs]
@pytest.mark.usefixtures("_clean_mkdocs_click")
def test_patch_mkdocs_click_usage():
"""After patching, ``_make_usage`` yields ``ansi-output`` fences."""
from mkdocs_click import _docs
ctx = click.Context(_hello_cmd, info_name="hello")
lines_before = list(_docs._make_usage(ctx))
assert TEXT_FENCE in lines_before
assert ANSI_OUTPUT_FENCE not in lines_before
_patch_mkdocs_click()
lines_after = list(_docs._make_usage(ctx))
assert ANSI_OUTPUT_FENCE in lines_after
assert TEXT_FENCE not in lines_after
[docs]
@pytest.mark.usefixtures("_clean_mkdocs_click")
def test_patch_mkdocs_click_plain_options():
"""After patching, ``_make_plain_options`` yields ``ansi-output`` fences."""
from mkdocs_click import _docs
ctx = click.Context(_hello_cmd, info_name="hello")
lines_before = list(_docs._make_plain_options(ctx))
assert TEXT_FENCE in lines_before
assert ANSI_OUTPUT_FENCE not in lines_before
_patch_mkdocs_click()
lines_after = list(_docs._make_plain_options(ctx))
assert ANSI_OUTPUT_FENCE in lines_after
assert TEXT_FENCE not in lines_after
[docs]
@pytest.mark.usefixtures("_clean_mkdocs_click")
def test_patch_mkdocs_click_idempotent():
"""Calling ``_patch_mkdocs_click`` twice does not double-wrap."""
from mkdocs_click import _docs
_patch_mkdocs_click()
usage_fn = _docs._make_usage
plain_fn = _docs._make_plain_options
_patch_mkdocs_click()
assert _docs._make_usage is usage_fn
assert _docs._make_plain_options is plain_fn
[docs]
@pytest.mark.usefixtures("_clean_pymdownx", "_clean_mkdocs_click")
def test_on_config_patches_mkdocs_click():
"""``on_config`` patches mkdocs-click alongside pymdownx.highlight."""
from mkdocs_click import _docs
assert not getattr(_docs, "_click_extra_patched", False)
plugin = AnsiColorPlugin()
plugin.on_config({}) # type: ignore[arg-type]
assert _docs._click_extra_patched is True # type: ignore[attr-defined]
ctx = click.Context(_hello_cmd, info_name="hello")
lines = list(_docs._make_usage(ctx))
assert ANSI_OUTPUT_FENCE in lines