141 lines
4.7 KiB
Python
141 lines
4.7 KiB
Python
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(**cfg) -> MkDocsConfig:
|
|
"""Helper to build a simple config for testing."""
|
|
path_base = os.path.join(os.path.abspath(os.path.dirname(__file__)), 'integration', 'minimal')
|
|
cfg = cfg or {}
|
|
if 'site_name' not in cfg:
|
|
cfg['site_name'] = 'Example'
|
|
if 'config_file_path' not in cfg:
|
|
cfg['config_file_path'] = os.path.join(path_base, 'mkdocs.yml')
|
|
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')
|
|
conf = MkDocsConfig(config_file_path=cfg['config_file_path'])
|
|
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, '/'))
|
|
|
|
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 assertPathNotFile(self, *parts):
|
|
path = os.path.join(*parts)
|
|
if os.path.isfile(path):
|
|
msg = self._formatMessage(None, f"The path '{path}' is 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)
|
|
|
|
def assertPathNotDir(self, *parts):
|
|
path = os.path.join(*parts)
|
|
if os.path.isfile(path):
|
|
msg = self._formatMessage(None, f"The path '{path}' is a directory that exists")
|
|
raise self.failureException(msg)
|