File: base.py

package info (click to toggle)
python-mkdocs 1.6.1%2Bdfsg1-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 7,812 kB
  • sloc: python: 14,346; javascript: 10,535; perl: 143; sh: 57; makefile: 30; xml: 11
file content (129 lines) | stat: -rw-r--r-- 4,374 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
from __future__ import annotations

import contextlib
import os
import textwrap
from functools import wraps
from tempfile import TemporaryDirectory

import markdown

from mkdocs import utils
from mkdocs.config.defaults import MkDocsConfig


def dedent(text):
    return textwrap.dedent(text).strip()


def get_markdown_toc(markdown_source):
    """Return TOC generated by Markdown parser from Markdown source text."""
    md = markdown.Markdown(extensions=['toc'])
    md.convert(markdown_source)
    return md.toc_tokens


def load_config(config_file_path: str | None = None, **cfg) -> MkDocsConfig:
    """Helper to build a simple config for testing."""
    path_base = os.path.join(os.path.abspath(os.path.dirname(__file__)), 'integration', 'minimal')
    if 'site_name' not in cfg:
        cfg['site_name'] = 'Example'
    if 'docs_dir' not in cfg:
        # Point to an actual dir to avoid a 'does not exist' error on validation.
        cfg['docs_dir'] = os.path.join(path_base, 'docs')
    if 'plugins' not in cfg:
        cfg['plugins'] = []
    conf = MkDocsConfig(config_file_path=config_file_path or os.path.join(path_base, 'mkdocs.yml'))
    conf.load_dict(cfg)

    errors_warnings = conf.validate()
    assert errors_warnings == ([], []), errors_warnings
    return conf


def tempdir(files=None, **kw):
    """
    A decorator for building a temporary directory with prepopulated files.

    The temporary directory and files are created just before the wrapped function is called and are destroyed
    immediately after the wrapped function returns.

    The `files` keyword should be a dict of file paths as keys and strings of file content as values.
    If `files` is a list, then each item is assumed to be a path of an empty file. All other
    keywords are passed to `tempfile.TemporaryDirectory` to create the parent directory.

    In the following example, two files are created in the temporary directory and then are destroyed when
    the function exits:

        @tempdir(files={
            'foo.txt': 'foo content',
            'bar.txt': 'bar content'
        })
        def example(self, tdir):
            assert os.path.isfile(os.path.join(tdir, 'foo.txt'))
            pth = os.path.join(tdir, 'bar.txt')
            assert os.path.isfile(pth)
            with open(pth, 'r', encoding='utf-8') as f:
                assert f.read() == 'bar content'
    """
    files = {f: '' for f in files} if isinstance(files, (list, tuple)) else files or {}

    kw['prefix'] = 'mkdocs_test-' + kw.get('prefix', '')

    def decorator(fn):
        @wraps(fn)
        def wrapper(self, *args):
            with TemporaryDirectory(**kw) as td:
                for path, content in files.items():
                    pth = os.path.join(td, path)
                    utils.write_file(content.encode(encoding='utf-8'), pth)
                return fn(self, td, *args)

        return wrapper

    return decorator


@contextlib.contextmanager
def change_dir(path):
    old_cwd = os.getcwd()
    os.chdir(path)
    try:
        yield
    finally:
        os.chdir(old_cwd)


class PathAssertionMixin:
    """
    Assertion methods for testing paths.

    Each method accepts one or more strings, which are first joined using os.path.join.
    """

    def assertPathsEqual(self, a, b, msg=None):
        self.assertEqual(a.replace(os.sep, '/'), b.replace(os.sep, '/'), msg=msg)

    def assertPathExists(self, *parts):
        path = os.path.join(*parts)
        if not os.path.exists(path):
            msg = self._formatMessage(None, f"The path '{path}' does not exist")
            raise self.failureException(msg)

    def assertPathNotExists(self, *parts):
        path = os.path.join(*parts)
        if os.path.exists(path):
            msg = self._formatMessage(None, f"The path '{path}' does exist")
            raise self.failureException(msg)

    def assertPathIsFile(self, *parts):
        path = os.path.join(*parts)
        if not os.path.isfile(path):
            msg = self._formatMessage(None, f"The path '{path}' is not a file that exists")
            raise self.failureException(msg)

    def assertPathIsDir(self, *parts):
        path = os.path.join(*parts)
        if not os.path.isdir(path):
            msg = self._formatMessage(None, f"The path '{path}' is not a directory that exists")
            raise self.failureException(msg)