base.py 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. import textwrap
  2. import markdown
  3. import os
  4. from functools import wraps
  5. from tempfile import TemporaryDirectory
  6. from mkdocs import config
  7. from mkdocs import utils
  8. def dedent(text):
  9. return textwrap.dedent(text).strip()
  10. def get_markdown_toc(markdown_source):
  11. """ Return TOC generated by Markdown parser from Markdown source text. """
  12. md = markdown.Markdown(extensions=['toc'])
  13. md.convert(markdown_source)
  14. return md.toc_tokens
  15. def load_config(**cfg):
  16. """ Helper to build a simple config for testing. """
  17. path_base = os.path.join(
  18. os.path.abspath(os.path.dirname(__file__)), 'integration', 'minimal'
  19. )
  20. cfg = cfg or {}
  21. if 'site_name' not in cfg:
  22. cfg['site_name'] = 'Example'
  23. if 'config_file_path' not in cfg:
  24. cfg['config_file_path'] = os.path.join(path_base, 'mkdocs.yml')
  25. if 'docs_dir' not in cfg:
  26. # Point to an actual dir to avoid a 'does not exist' error on validation.
  27. cfg['docs_dir'] = os.path.join(path_base, 'docs')
  28. conf = config.Config(schema=config.DEFAULT_SCHEMA, config_file_path=cfg['config_file_path'])
  29. conf.load_dict(cfg)
  30. errors_warnings = conf.validate()
  31. assert(errors_warnings == ([], [])), errors_warnings
  32. return conf
  33. def tempdir(files=None, **kw):
  34. """
  35. A decorator for building a temporary directory with prepopulated files.
  36. The temporary directory and files are created just before the wrapped function is called and are destroyed
  37. immediately after the wrapped function returns.
  38. The `files` keyword should be a dict of file paths as keys and strings of file content as values.
  39. If `files` is a list, then each item is assumed to be a path of an empty file. All other
  40. keywords are passed to `tempfile.TemporaryDirectory` to create the parent directory.
  41. In the following example, two files are created in the temporary directory and then are destroyed when
  42. the function exits:
  43. @tempdir(files={
  44. 'foo.txt': 'foo content',
  45. 'bar.txt': 'bar content'
  46. })
  47. def example(self, tdir):
  48. assert os.path.isfile(os.path.join(tdir, 'foo.txt'))
  49. pth = os.path.join(tdir, 'bar.txt')
  50. assert os.path.isfile(pth)
  51. with open(pth, 'r', encoding='utf-8') as f:
  52. assert f.read() == 'bar content'
  53. """
  54. files = {f: '' for f in files} if isinstance(files, (list, tuple)) else files or {}
  55. if 'prefix' not in kw:
  56. kw['prefix'] = 'mkdocs_test-'
  57. def decorator(fn):
  58. @wraps(fn)
  59. def wrapper(self, *args):
  60. with TemporaryDirectory(**kw) as td:
  61. for path, content in files.items():
  62. pth = os.path.join(td, path)
  63. utils.write_file(content.encode(encoding='utf-8'), pth)
  64. return fn(self, td, *args)
  65. return wrapper
  66. return decorator
  67. class PathAssertionMixin:
  68. """
  69. Assertion methods for testing paths.
  70. Each method accepts one or more strings, which are first joined using os.path.join.
  71. """
  72. def assertPathsEqual(self, a, b, msg=None):
  73. self.assertEqual(a.replace('\\', '/'), b.replace('\\', '/'))
  74. def assertPathExists(self, *parts):
  75. path = os.path.join(*parts)
  76. if not os.path.exists(path):
  77. msg = self._formatMessage(None, "The path '{}' does not exist".format(path))
  78. raise self.failureException(msg)
  79. def assertPathNotExists(self, *parts):
  80. path = os.path.join(*parts)
  81. if os.path.exists(path):
  82. msg = self._formatMessage(None, "The path '{}' does exist".format(path))
  83. raise self.failureException(msg)
  84. def assertPathIsFile(self, *parts):
  85. path = os.path.join(*parts)
  86. if not os.path.isfile(path):
  87. msg = self._formatMessage(None, "The path '{}' is not a file that exists".format(path))
  88. raise self.failureException(msg)
  89. def assertPathNotFile(self, *parts):
  90. path = os.path.join(*parts)
  91. if os.path.isfile(path):
  92. msg = self._formatMessage(None, "The path '{}' is a file that exists".format(path))
  93. raise self.failureException(msg)
  94. def assertPathIsDir(self, *parts):
  95. path = os.path.join(*parts)
  96. if not os.path.isdir(path):
  97. msg = self._formatMessage(None, "The path '{}' is not a directory that exists".format(path))
  98. raise self.failureException(msg)
  99. def assertPathNotDir(self, *parts):
  100. path = os.path.join(*parts)
  101. if os.path.isfile(path):
  102. msg = self._formatMessage(None, "The path '{}' is a directory that exists".format(path))
  103. raise self.failureException(msg)