| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268 |
- #!/usr/bin/env python
- import os
- import tempfile
- import unittest
- from tempfile import TemporaryDirectory
- import mkdocs
- from mkdocs import config
- from mkdocs.config import config_options
- from mkdocs.exceptions import ConfigurationError
- from mkdocs.tests.base import dedent
- class ConfigTests(unittest.TestCase):
- def test_missing_config_file(self):
- def load_missing_config():
- config.load_config(config_file='bad_filename.yaml')
- self.assertRaises(ConfigurationError, load_missing_config)
- def test_missing_site_name(self):
- c = config.Config(schema=config.DEFAULT_SCHEMA)
- c.load_dict({})
- errors, warnings = c.validate()
- self.assertEqual(len(errors), 1)
- self.assertEqual(errors[0][0], 'site_name')
- self.assertEqual(str(errors[0][1]), 'Required configuration not provided.')
- self.assertEqual(len(warnings), 0)
- def test_empty_config(self):
- def load_empty_config():
- config.load_config(config_file='/dev/null')
- self.assertRaises(ConfigurationError, load_empty_config)
- def test_nonexistant_config(self):
- def load_empty_config():
- config.load_config(config_file='/path/that/is/not/real')
- self.assertRaises(ConfigurationError, load_empty_config)
- def test_invalid_config(self):
- file_contents = dedent("""
- - ['index.md', 'Introduction']
- - ['index.md', 'Introduction']
- - ['index.md', 'Introduction']
- """)
- config_file = tempfile.NamedTemporaryFile('w', delete=False)
- try:
- config_file.write(file_contents)
- config_file.flush()
- config_file.close()
- self.assertRaises(
- ConfigurationError,
- config.load_config, config_file=open(config_file.name, 'rb')
- )
- finally:
- os.remove(config_file.name)
- def test_config_option(self):
- """
- Users can explicitly set the config file using the '--config' option.
- Allows users to specify a config other than the default `mkdocs.yml`.
- """
- expected_result = {
- 'site_name': 'Example',
- 'pages': [
- {'Introduction': 'index.md'}
- ],
- }
- file_contents = dedent("""
- site_name: Example
- pages:
- - 'Introduction': 'index.md'
- """)
- with TemporaryDirectory() as temp_path:
- os.mkdir(os.path.join(temp_path, 'docs'))
- config_path = os.path.join(temp_path, 'mkdocs.yml')
- config_file = open(config_path, 'w')
- config_file.write(file_contents)
- config_file.flush()
- config_file.close()
- result = config.load_config(config_file=config_file.name)
- self.assertEqual(result['site_name'], expected_result['site_name'])
- self.assertEqual(result['pages'], expected_result['pages'])
- def test_theme(self):
- with TemporaryDirectory() as mytheme, TemporaryDirectory() as custom:
- configs = [
- dict(), # default theme
- {"theme": "readthedocs"}, # builtin theme
- {"theme": {'name': 'readthedocs'}}, # builtin as complex
- {"theme": {'name': None, 'custom_dir': mytheme}}, # custom only as complex
- {"theme": {'name': 'readthedocs', 'custom_dir': custom}}, # builtin and custom as complex
- { # user defined variables
- 'theme': {
- 'name': 'mkdocs',
- 'static_templates': ['foo.html'],
- 'show_sidebar': False,
- 'some_var': 'bar'
- }
- }
- ]
- mkdocs_dir = os.path.abspath(os.path.dirname(mkdocs.__file__))
- mkdocs_templates_dir = os.path.join(mkdocs_dir, 'templates')
- theme_dir = os.path.abspath(os.path.join(mkdocs_dir, 'themes'))
- results = (
- {
- 'dirs': [os.path.join(theme_dir, 'mkdocs'), mkdocs_templates_dir],
- 'static_templates': ['404.html', 'sitemap.xml'],
- 'vars': {
- 'include_search_page': False,
- 'search_index_only': False,
- 'highlightjs': True,
- 'hljs_style': 'github',
- 'hljs_languages': [],
- 'navigation_depth': 2,
- 'nav_style': 'primary',
- 'shortcuts': {'help': 191, 'next': 78, 'previous': 80, 'search': 83}
- }
- }, {
- 'dirs': [os.path.join(theme_dir, 'readthedocs'), mkdocs_templates_dir],
- 'static_templates': ['404.html', 'sitemap.xml'],
- 'vars': {
- 'include_search_page': True,
- 'search_index_only': False,
- 'highlightjs': True,
- 'hljs_languages': [],
- 'include_homepage_in_sidebar': True,
- 'prev_next_buttons_location': 'bottom',
- 'navigation_depth': 4,
- 'sticky_navigation': True,
- 'titles_only': False,
- 'collapse_navigation': True
- }
- }, {
- 'dirs': [os.path.join(theme_dir, 'readthedocs'), mkdocs_templates_dir],
- 'static_templates': ['404.html', 'sitemap.xml'],
- 'vars': {
- 'include_search_page': True,
- 'search_index_only': False,
- 'highlightjs': True,
- 'hljs_languages': [],
- 'include_homepage_in_sidebar': True,
- 'prev_next_buttons_location': 'bottom',
- 'navigation_depth': 4,
- 'sticky_navigation': True,
- 'titles_only': False,
- 'collapse_navigation': True
- }
- }, {
- 'dirs': [mytheme, mkdocs_templates_dir],
- 'static_templates': ['sitemap.xml'],
- 'vars': {}
- }, {
- 'dirs': [custom, os.path.join(theme_dir, 'readthedocs'), mkdocs_templates_dir],
- 'static_templates': ['404.html', 'sitemap.xml'],
- 'vars': {
- 'include_search_page': True,
- 'search_index_only': False,
- 'highlightjs': True,
- 'hljs_languages': [],
- 'include_homepage_in_sidebar': True,
- 'prev_next_buttons_location': 'bottom',
- 'navigation_depth': 4,
- 'sticky_navigation': True,
- 'titles_only': False,
- 'collapse_navigation': True
- }
- }, {
- 'dirs': [os.path.join(theme_dir, 'mkdocs'), mkdocs_templates_dir],
- 'static_templates': ['404.html', 'sitemap.xml', 'foo.html'],
- 'vars': {
- 'show_sidebar': False,
- 'some_var': 'bar',
- 'include_search_page': False,
- 'search_index_only': False,
- 'highlightjs': True,
- 'hljs_style': 'github',
- 'hljs_languages': [],
- 'navigation_depth': 2,
- 'nav_style': 'primary',
- 'shortcuts': {'help': 191, 'next': 78, 'previous': 80, 'search': 83}
- }
- }
- )
- for config_contents, result in zip(configs, results):
- c = config.Config(schema=(('theme', config_options.Theme(default='mkdocs')),))
- c.load_dict(config_contents)
- errors, warnings = c.validate()
- self.assertEqual(len(errors), 0)
- self.assertEqual(c['theme'].dirs, result['dirs'])
- self.assertEqual(c['theme'].static_templates, set(result['static_templates']))
- self.assertEqual({k: c['theme'][k] for k in iter(c['theme'])}, result['vars'])
- def test_empty_nav(self):
- conf = config.Config(schema=config.DEFAULT_SCHEMA)
- conf.load_dict({
- 'site_name': 'Example',
- 'config_file_path': os.path.join(os.path.abspath('.'), 'mkdocs.yml')
- })
- conf.validate()
- self.assertEqual(conf['nav'], None)
- def test_copy_pages_to_nav(self):
- # TODO: remove this when pages config setting is fully deprecated.
- conf = config.Config(schema=config.DEFAULT_SCHEMA)
- conf.load_dict({
- 'site_name': 'Example',
- 'pages': ['index.md', 'about.md'],
- 'config_file_path': os.path.join(os.path.abspath('.'), 'mkdocs.yml')
- })
- conf.validate()
- self.assertEqual(conf['nav'], ['index.md', 'about.md'])
- def test_dont_overwrite_nav_with_pages(self):
- # TODO: remove this when pages config setting is fully deprecated.
- conf = config.Config(schema=config.DEFAULT_SCHEMA)
- conf.load_dict({
- 'site_name': 'Example',
- 'pages': ['index.md', 'about.md'],
- 'nav': ['foo.md', 'bar.md'],
- 'config_file_path': os.path.join(os.path.abspath('.'), 'mkdocs.yml')
- })
- conf.validate()
- self.assertEqual(conf['nav'], ['foo.md', 'bar.md'])
- def test_doc_dir_in_site_dir(self):
- j = os.path.join
- test_configs = (
- {'docs_dir': j('site', 'docs'), 'site_dir': 'site'},
- {'docs_dir': 'docs', 'site_dir': '.'},
- {'docs_dir': '.', 'site_dir': '.'},
- {'docs_dir': 'docs', 'site_dir': ''},
- {'docs_dir': '', 'site_dir': ''},
- {'docs_dir': 'docs', 'site_dir': 'docs'},
- )
- conf = {
- 'config_file_path': j(os.path.abspath('..'), 'mkdocs.yml')
- }
- for test_config in test_configs:
- patch = conf.copy()
- patch.update(test_config)
- # Same as the default schema, but don't verify the docs_dir exists.
- c = config.Config(schema=(
- ('docs_dir', config_options.Dir(default='docs')),
- ('site_dir', config_options.SiteDir(default='site')),
- ('config_file_path', config_options.Type(str))
- ))
- c.load_dict(patch)
- errors, warnings = c.validate()
- self.assertEqual(len(errors), 1)
- self.assertEqual(warnings, [])
|