| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274 |
- import os
- import tempfile
- import unittest
- from tempfile import TemporaryDirectory
- from mkdocs import exceptions
- from mkdocs.config import base, defaults
- from mkdocs.config.config_options import BaseConfigOption
- class ConfigBaseTests(unittest.TestCase):
- def test_unrecognised_keys(self):
- c = base.Config(schema=defaults.DEFAULT_SCHEMA)
- c.load_dict({
- 'not_a_valid_config_option': "test"
- })
- failed, warnings = c.validate()
- self.assertEqual(warnings, [
- ('not_a_valid_config_option',
- 'Unrecognised configuration name: not_a_valid_config_option')
- ])
- def test_missing_required(self):
- c = base.Config(schema=defaults.DEFAULT_SCHEMA)
- 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_load_from_file(self):
- """
- Users can explicitly set the config file using the '--config' option.
- Allows users to specify a config other than the default `mkdocs.yml`.
- """
- temp_dir = TemporaryDirectory()
- config_file = open(os.path.join(temp_dir.name, 'mkdocs.yml'), 'w')
- os.mkdir(os.path.join(temp_dir.name, 'docs'))
- try:
- config_file.write("site_name: MkDocs Test\n")
- config_file.flush()
- config_file.close()
- cfg = base.load_config(config_file=config_file.name)
- self.assertTrue(isinstance(cfg, base.Config))
- self.assertEqual(cfg['site_name'], 'MkDocs Test')
- finally:
- os.remove(config_file.name)
- temp_dir.cleanup()
- def test_load_from_missing_file(self):
- self.assertRaises(exceptions.ConfigurationError,
- base.load_config, config_file='missing_file.yml')
- def test_load_from_open_file(self):
- """
- `load_config` can accept an open file descriptor.
- """
- temp_dir = TemporaryDirectory()
- temp_path = temp_dir.name
- config_fname = os.path.join(temp_path, 'mkdocs.yml')
- config_file = open(config_fname, 'w+')
- os.mkdir(os.path.join(temp_path, 'docs'))
- try:
- config_file.write("site_name: MkDocs Test\n")
- config_file.flush()
- cfg = base.load_config(config_file=config_file)
- self.assertTrue(isinstance(cfg, base.Config))
- self.assertEqual(cfg['site_name'], 'MkDocs Test')
- # load_config will always close the file
- self.assertTrue(config_file.closed)
- finally:
- temp_dir.cleanup()
- def test_load_from_closed_file(self):
- """
- The `serve` command with auto-reload may pass in a closed file descriptor.
- Ensure `load_config` reloads the closed file.
- """
- temp_dir = TemporaryDirectory()
- config_file = open(os.path.join(temp_dir.name, 'mkdocs.yml'), 'w')
- os.mkdir(os.path.join(temp_dir.name, 'docs'))
- try:
- config_file.write("site_name: MkDocs Test\n")
- config_file.flush()
- config_file.close()
- cfg = base.load_config(config_file=config_file)
- self.assertTrue(isinstance(cfg, base.Config))
- self.assertEqual(cfg['site_name'], 'MkDocs Test')
- finally:
- temp_dir.cleanup()
- def test_load_from_deleted_file(self):
- """
- Deleting the config file could trigger a server reload.
- """
- config_file = tempfile.NamedTemporaryFile('w', delete=False)
- try:
- config_file.write("site_name: MkDocs Test\n")
- config_file.flush()
- config_file.close()
- finally:
- os.remove(config_file.name)
- self.assertRaises(exceptions.ConfigurationError,
- base.load_config, config_file=config_file)
- def test_load_missing_required(self):
- """
- `site_name` is a required setting.
- """
- config_file = tempfile.NamedTemporaryFile('w', delete=False)
- try:
- config_file.write(
- "site_dir: output\nsite_uri: https://www.mkdocs.org\n")
- config_file.flush()
- config_file.close()
- self.assertRaises(exceptions.ConfigurationError,
- base.load_config, config_file=config_file.name)
- finally:
- os.remove(config_file.name)
- def test_pre_validation_error(self):
- class InvalidConfigOption(BaseConfigOption):
- def pre_validation(self, config, key_name):
- raise base.ValidationError('pre_validation error')
- c = base.Config(schema=(('invalid_option', InvalidConfigOption()), ))
- errors, warnings = c.validate()
- self.assertEqual(len(errors), 1)
- self.assertEqual(errors[0][0], 'invalid_option')
- self.assertEqual(str(errors[0][1]), 'pre_validation error')
- self.assertTrue(isinstance(errors[0][1], base.ValidationError))
- self.assertEqual(len(warnings), 0)
- def test_run_validation_error(self):
- class InvalidConfigOption(BaseConfigOption):
- def run_validation(self, value):
- raise base.ValidationError('run_validation error')
- c = base.Config(schema=(('invalid_option', InvalidConfigOption()), ))
- errors, warnings = c.validate()
- self.assertEqual(len(errors), 1)
- self.assertEqual(errors[0][0], 'invalid_option')
- self.assertEqual(str(errors[0][1]), 'run_validation error')
- self.assertTrue(isinstance(errors[0][1], base.ValidationError))
- self.assertEqual(len(warnings), 0)
- def test_post_validation_error(self):
- class InvalidConfigOption(BaseConfigOption):
- def post_validation(self, config, key_name):
- raise base.ValidationError('post_validation error')
- c = base.Config(schema=(('invalid_option', InvalidConfigOption()), ))
- errors, warnings = c.validate()
- self.assertEqual(len(errors), 1)
- self.assertEqual(errors[0][0], 'invalid_option')
- self.assertEqual(str(errors[0][1]), 'post_validation error')
- self.assertTrue(isinstance(errors[0][1], base.ValidationError))
- self.assertEqual(len(warnings), 0)
- def test_pre_and_run_validation_errors(self):
- """ A pre_validation error does not stop run_validation from running. """
- class InvalidConfigOption(BaseConfigOption):
- def pre_validation(self, config, key_name):
- raise base.ValidationError('pre_validation error')
- def run_validation(self, value):
- raise base.ValidationError('run_validation error')
- c = base.Config(schema=(('invalid_option', InvalidConfigOption()), ))
- errors, warnings = c.validate()
- self.assertEqual(len(errors), 2)
- self.assertEqual(errors[0][0], 'invalid_option')
- self.assertEqual(str(errors[0][1]), 'pre_validation error')
- self.assertTrue(isinstance(errors[0][1], base.ValidationError))
- self.assertEqual(errors[1][0], 'invalid_option')
- self.assertEqual(str(errors[1][1]), 'run_validation error')
- self.assertTrue(isinstance(errors[1][1], base.ValidationError))
- self.assertEqual(len(warnings), 0)
- def test_run_and_post_validation_errors(self):
- """ A run_validation error stops post_validation from running. """
- class InvalidConfigOption(BaseConfigOption):
- def run_validation(self, value):
- raise base.ValidationError('run_validation error')
- def post_validation(self, config, key_name):
- raise base.ValidationError('post_validation error')
- c = base.Config(schema=(('invalid_option', InvalidConfigOption()), ))
- errors, warnings = c.validate()
- self.assertEqual(len(errors), 1)
- self.assertEqual(errors[0][0], 'invalid_option')
- self.assertEqual(str(errors[0][1]), 'run_validation error')
- self.assertTrue(isinstance(errors[0][1], base.ValidationError))
- self.assertEqual(len(warnings), 0)
- def test_validation_warnings(self):
- class InvalidConfigOption(BaseConfigOption):
- def pre_validation(self, config, key_name):
- self.warnings.append('pre_validation warning')
- def run_validation(self, value):
- self.warnings.append('run_validation warning')
- def post_validation(self, config, key_name):
- self.warnings.append('post_validation warning')
- c = base.Config(schema=(('invalid_option', InvalidConfigOption()), ))
- errors, warnings = c.validate()
- self.assertEqual(len(errors), 0)
- self.assertEqual(warnings, [
- ('invalid_option', 'pre_validation warning'),
- ('invalid_option', 'run_validation warning'),
- ('invalid_option', 'post_validation warning'),
- ])
- def test_load_from_file_with_relative_paths(self):
- """
- When explicitly setting a config file, paths should be relative to the
- config file, not the working directory.
- """
- config_dir = TemporaryDirectory()
- config_fname = os.path.join(config_dir.name, 'mkdocs.yml')
- docs_dir = os.path.join(config_dir.name, 'src')
- os.mkdir(docs_dir)
- config_file = open(config_fname, 'w')
- try:
- config_file.write("docs_dir: src\nsite_name: MkDocs Test\n")
- config_file.flush()
- config_file.close()
- cfg = base.load_config(config_file=config_file)
- self.assertTrue(isinstance(cfg, base.Config))
- self.assertEqual(cfg['site_name'], 'MkDocs Test')
- self.assertEqual(cfg['docs_dir'], docs_dir)
- self.assertEqual(cfg.config_file_path, config_fname)
- self.assertIsInstance(cfg.config_file_path, str)
- finally:
- config_dir.cleanup()
|