added podman, json and yaml
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,284 @@
|
||||
import os
|
||||
import unittest
|
||||
|
||||
from mkdocs import exceptions
|
||||
from mkdocs.config import base
|
||||
from mkdocs.config import config_options as c
|
||||
from mkdocs.config import defaults
|
||||
from mkdocs.config.base import ValidationError
|
||||
from mkdocs.tests.base import change_dir, tempdir
|
||||
|
||||
|
||||
class ConfigBaseTests(unittest.TestCase):
|
||||
def test_unrecognised_keys(self):
|
||||
conf = defaults.MkDocsConfig()
|
||||
conf.load_dict(
|
||||
{
|
||||
'not_a_valid_config_option': "test",
|
||||
}
|
||||
)
|
||||
|
||||
failed, warnings = conf.validate()
|
||||
|
||||
self.assertEqual(
|
||||
warnings,
|
||||
[
|
||||
(
|
||||
'not_a_valid_config_option',
|
||||
'Unrecognised configuration name: not_a_valid_config_option',
|
||||
)
|
||||
],
|
||||
)
|
||||
|
||||
def test_missing_required(self):
|
||||
conf = defaults.MkDocsConfig()
|
||||
|
||||
errors, warnings = conf.validate()
|
||||
|
||||
self.assertEqual(
|
||||
errors, [('site_name', ValidationError('Required configuration not provided.'))]
|
||||
)
|
||||
self.assertEqual(warnings, [])
|
||||
|
||||
@tempdir()
|
||||
def test_load_from_file(self, temp_dir):
|
||||
"""
|
||||
Users can explicitly set the config file using the '--config' option.
|
||||
Allows users to specify a config other than the default `mkdocs.yml`.
|
||||
"""
|
||||
with open(os.path.join(temp_dir, 'mkdocs.yml'), 'w') as config_file:
|
||||
config_file.write("site_name: MkDocs Test\n")
|
||||
os.mkdir(os.path.join(temp_dir, 'docs'))
|
||||
|
||||
cfg = base.load_config(config_file=config_file.name)
|
||||
self.assertTrue(isinstance(cfg, defaults.MkDocsConfig))
|
||||
self.assertEqual(cfg['site_name'], 'MkDocs Test')
|
||||
|
||||
@tempdir()
|
||||
def test_load_default_file(self, temp_dir):
|
||||
"""
|
||||
test that `mkdocs.yml` will be loaded when '--config' is not set.
|
||||
"""
|
||||
with open(os.path.join(temp_dir, 'mkdocs.yml'), 'w') as config_file:
|
||||
config_file.write("site_name: MkDocs Test\n")
|
||||
os.mkdir(os.path.join(temp_dir, 'docs'))
|
||||
with change_dir(temp_dir):
|
||||
cfg = base.load_config(config_file=None)
|
||||
self.assertTrue(isinstance(cfg, defaults.MkDocsConfig))
|
||||
self.assertEqual(cfg['site_name'], 'MkDocs Test')
|
||||
|
||||
@tempdir
|
||||
def test_load_default_file_with_yaml(self, temp_dir):
|
||||
"""
|
||||
test that `mkdocs.yml` will be loaded when '--config' is not set.
|
||||
"""
|
||||
with open(os.path.join(temp_dir, 'mkdocs.yaml'), 'w') as config_file:
|
||||
config_file.write("site_name: MkDocs Test\n")
|
||||
os.mkdir(os.path.join(temp_dir, 'docs'))
|
||||
with change_dir(temp_dir):
|
||||
cfg = base.load_config(config_file=None)
|
||||
self.assertTrue(isinstance(cfg, defaults.MkDocsConfig))
|
||||
self.assertEqual(cfg['site_name'], 'MkDocs Test')
|
||||
|
||||
@tempdir()
|
||||
def test_load_default_file_prefer_yml(self, temp_dir):
|
||||
"""
|
||||
test that `mkdocs.yml` will be loaded when '--config' is not set.
|
||||
"""
|
||||
with open(os.path.join(temp_dir, 'mkdocs.yml'), 'w') as config_file1:
|
||||
config_file1.write("site_name: MkDocs Test1\n")
|
||||
with open(os.path.join(temp_dir, 'mkdocs.yaml'), 'w') as config_file2:
|
||||
config_file2.write("site_name: MkDocs Test2\n")
|
||||
|
||||
os.mkdir(os.path.join(temp_dir, 'docs'))
|
||||
with change_dir(temp_dir):
|
||||
cfg = base.load_config(config_file=None)
|
||||
self.assertTrue(isinstance(cfg, defaults.MkDocsConfig))
|
||||
self.assertEqual(cfg['site_name'], 'MkDocs Test1')
|
||||
|
||||
def test_load_from_missing_file(self):
|
||||
with self.assertRaisesRegex(
|
||||
exceptions.ConfigurationError, "Config file 'missing_file.yml' does not exist."
|
||||
):
|
||||
base.load_config(config_file='missing_file.yml')
|
||||
|
||||
@tempdir()
|
||||
def test_load_from_open_file(self, temp_path):
|
||||
"""
|
||||
`load_config` can accept an open file descriptor.
|
||||
"""
|
||||
config_fname = os.path.join(temp_path, 'mkdocs.yml')
|
||||
config_file = open(config_fname, 'w+')
|
||||
config_file.write("site_name: MkDocs Test\n")
|
||||
config_file.flush()
|
||||
os.mkdir(os.path.join(temp_path, 'docs'))
|
||||
|
||||
cfg = base.load_config(config_file=config_file)
|
||||
self.assertTrue(isinstance(cfg, defaults.MkDocsConfig))
|
||||
self.assertEqual(cfg['site_name'], 'MkDocs Test')
|
||||
# load_config will always close the file
|
||||
self.assertTrue(config_file.closed)
|
||||
|
||||
@tempdir()
|
||||
def test_load_from_closed_file(self, temp_dir):
|
||||
"""
|
||||
The `serve` command with auto-reload may pass in a closed file descriptor.
|
||||
Ensure `load_config` reloads the closed file.
|
||||
"""
|
||||
with open(os.path.join(temp_dir, 'mkdocs.yml'), 'w') as config_file:
|
||||
config_file.write("site_name: MkDocs Test\n")
|
||||
os.mkdir(os.path.join(temp_dir, 'docs'))
|
||||
|
||||
cfg = base.load_config(config_file=config_file)
|
||||
self.assertTrue(isinstance(cfg, defaults.MkDocsConfig))
|
||||
self.assertEqual(cfg['site_name'], 'MkDocs Test')
|
||||
|
||||
@tempdir
|
||||
def test_load_missing_required(self, temp_dir):
|
||||
"""
|
||||
`site_name` is a required setting.
|
||||
"""
|
||||
with open(os.path.join(temp_dir, 'mkdocs.yml'), 'w') as config_file:
|
||||
config_file.write("site_dir: output\nsite_url: https://www.mkdocs.org\n")
|
||||
os.mkdir(os.path.join(temp_dir, 'docs'))
|
||||
|
||||
with self.assertLogs('mkdocs') as cm:
|
||||
with self.assertRaises(exceptions.Abort):
|
||||
base.load_config(config_file=config_file.name)
|
||||
self.assertEqual(
|
||||
'\n'.join(cm.output),
|
||||
"ERROR:mkdocs.config:Config value 'site_name': Required configuration not provided.",
|
||||
)
|
||||
|
||||
def test_pre_validation_error(self):
|
||||
class InvalidConfigOption(c.BaseConfigOption):
|
||||
def pre_validation(self, config, key_name):
|
||||
raise ValidationError('pre_validation error')
|
||||
|
||||
conf = base.Config(schema=(('invalid_option', InvalidConfigOption()),))
|
||||
|
||||
errors, warnings = conf.validate()
|
||||
|
||||
self.assertEqual(errors, [('invalid_option', ValidationError('pre_validation error'))])
|
||||
self.assertEqual(warnings, [])
|
||||
|
||||
def test_run_validation_error(self):
|
||||
class InvalidConfigOption(c.BaseConfigOption):
|
||||
def run_validation(self, value):
|
||||
raise ValidationError('run_validation error')
|
||||
|
||||
conf = base.Config(schema=(('invalid_option', InvalidConfigOption()),))
|
||||
|
||||
errors, warnings = conf.validate()
|
||||
|
||||
self.assertEqual(errors, [('invalid_option', ValidationError('run_validation error'))])
|
||||
self.assertEqual(warnings, [])
|
||||
|
||||
def test_post_validation_error(self):
|
||||
class InvalidConfigOption(c.BaseConfigOption):
|
||||
def post_validation(self, config, key_name):
|
||||
raise ValidationError('post_validation error')
|
||||
|
||||
conf = base.Config(schema=(('invalid_option', InvalidConfigOption()),))
|
||||
|
||||
errors, warnings = conf.validate()
|
||||
|
||||
self.assertEqual(errors, [('invalid_option', ValidationError('post_validation error'))])
|
||||
self.assertEqual(warnings, [])
|
||||
|
||||
def test_pre_and_run_validation_errors(self):
|
||||
"""A pre_validation error does not stop run_validation from running."""
|
||||
|
||||
class InvalidConfigOption(c.BaseConfigOption):
|
||||
def pre_validation(self, config, key_name):
|
||||
raise ValidationError('pre_validation error')
|
||||
|
||||
def run_validation(self, value):
|
||||
raise ValidationError('run_validation error')
|
||||
|
||||
conf = base.Config(schema=(('invalid_option', InvalidConfigOption()),))
|
||||
|
||||
errors, warnings = conf.validate()
|
||||
|
||||
self.assertEqual(
|
||||
errors,
|
||||
[
|
||||
('invalid_option', ValidationError('pre_validation error')),
|
||||
('invalid_option', ValidationError('run_validation error')),
|
||||
],
|
||||
)
|
||||
self.assertEqual(warnings, [])
|
||||
|
||||
def test_run_and_post_validation_errors(self):
|
||||
"""A run_validation error stops post_validation from running."""
|
||||
|
||||
class InvalidConfigOption(c.BaseConfigOption):
|
||||
def run_validation(self, value):
|
||||
raise ValidationError('run_validation error')
|
||||
|
||||
def post_validation(self, config, key_name):
|
||||
raise ValidationError('post_validation error')
|
||||
|
||||
conf = base.Config(schema=(('invalid_option', InvalidConfigOption()),))
|
||||
|
||||
errors, warnings = conf.validate()
|
||||
|
||||
self.assertEqual(errors, [('invalid_option', ValidationError('run_validation error'))])
|
||||
self.assertEqual(warnings, [])
|
||||
|
||||
def test_validation_warnings(self):
|
||||
class InvalidConfigOption(c.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')
|
||||
|
||||
conf = base.Config(schema=(('invalid_option', InvalidConfigOption()),))
|
||||
|
||||
errors, warnings = conf.validate()
|
||||
|
||||
self.assertEqual(errors, [])
|
||||
self.assertEqual(
|
||||
warnings,
|
||||
[
|
||||
('invalid_option', 'pre_validation warning'),
|
||||
('invalid_option', 'run_validation warning'),
|
||||
('invalid_option', 'post_validation warning'),
|
||||
],
|
||||
)
|
||||
|
||||
@tempdir()
|
||||
def test_load_from_file_with_relative_paths(self, config_dir):
|
||||
"""
|
||||
When explicitly setting a config file, paths should be relative to the
|
||||
config file, not the working directory.
|
||||
"""
|
||||
config_fname = os.path.join(config_dir, 'mkdocs.yml')
|
||||
with open(config_fname, 'w') as config_file:
|
||||
config_file.write("docs_dir: src\nsite_name: MkDocs Test\n")
|
||||
docs_dir = os.path.join(config_dir, 'src')
|
||||
os.mkdir(docs_dir)
|
||||
|
||||
cfg = base.load_config(config_file=config_file)
|
||||
self.assertTrue(isinstance(cfg, defaults.MkDocsConfig))
|
||||
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)
|
||||
|
||||
def test_get_schema(self):
|
||||
class FooConfig:
|
||||
z = c.URL()
|
||||
aa = c.Type(int)
|
||||
|
||||
self.assertEqual(
|
||||
base.get_schema(FooConfig),
|
||||
(
|
||||
('z', FooConfig.z),
|
||||
('aa', FooConfig.aa),
|
||||
),
|
||||
)
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,278 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import os
|
||||
import unittest
|
||||
|
||||
import mkdocs
|
||||
from mkdocs import config
|
||||
from mkdocs.config import config_options as c
|
||||
from mkdocs.config import defaults
|
||||
from mkdocs.config.base import ValidationError
|
||||
from mkdocs.exceptions import ConfigurationError
|
||||
from mkdocs.localization import parse_locale
|
||||
from mkdocs.tests.base import dedent, tempdir
|
||||
|
||||
|
||||
class ConfigTests(unittest.TestCase):
|
||||
def test_missing_config_file(self):
|
||||
with self.assertRaises(ConfigurationError):
|
||||
config.load_config(config_file='bad_filename.yaml')
|
||||
|
||||
def test_missing_site_name(self):
|
||||
conf = defaults.MkDocsConfig()
|
||||
conf.load_dict({})
|
||||
errors, warnings = conf.validate()
|
||||
self.assertEqual(
|
||||
errors, [('site_name', ValidationError("Required configuration not provided."))]
|
||||
)
|
||||
self.assertEqual(warnings, [])
|
||||
|
||||
def test_empty_config(self):
|
||||
with self.assertRaises(ConfigurationError):
|
||||
config.load_config(config_file='/dev/null')
|
||||
|
||||
def test_nonexistant_config(self):
|
||||
with self.assertRaises(ConfigurationError):
|
||||
config.load_config(config_file='/path/that/is/not/real')
|
||||
|
||||
@tempdir()
|
||||
def test_invalid_config(self, temp_path):
|
||||
file_contents = dedent(
|
||||
"""
|
||||
- ['index.md', 'Introduction']
|
||||
- ['index.md', 'Introduction']
|
||||
- ['index.md', 'Introduction']
|
||||
"""
|
||||
)
|
||||
config_path = os.path.join(temp_path, 'foo.yml')
|
||||
with open(config_path, 'w') as config_file:
|
||||
config_file.write(file_contents)
|
||||
|
||||
with self.assertRaises(ConfigurationError):
|
||||
config.load_config(config_file=open(config_file.name, 'rb'))
|
||||
|
||||
@tempdir()
|
||||
def test_config_option(self, temp_path):
|
||||
"""
|
||||
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',
|
||||
'nav': [{'Introduction': 'index.md'}],
|
||||
}
|
||||
file_contents = dedent(
|
||||
"""
|
||||
site_name: Example
|
||||
nav:
|
||||
- 'Introduction': 'index.md'
|
||||
"""
|
||||
)
|
||||
config_path = os.path.join(temp_path, 'mkdocs.yml')
|
||||
with open(config_path, 'w') as config_file:
|
||||
config_file.write(file_contents)
|
||||
os.mkdir(os.path.join(temp_path, 'docs'))
|
||||
|
||||
result = config.load_config(config_file=config_file.name)
|
||||
self.assertEqual(result['site_name'], expected_result['site_name'])
|
||||
self.assertEqual(result['nav'], expected_result['nav'])
|
||||
|
||||
@tempdir()
|
||||
@tempdir()
|
||||
def test_theme(self, mytheme, 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',
|
||||
'locale': 'fr',
|
||||
'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': {
|
||||
'name': 'mkdocs',
|
||||
'locale': parse_locale('en'),
|
||||
'include_search_page': False,
|
||||
'search_index_only': False,
|
||||
'analytics': {'gtag': None},
|
||||
'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': {
|
||||
'name': 'readthedocs',
|
||||
'locale': parse_locale('en'),
|
||||
'include_search_page': True,
|
||||
'search_index_only': False,
|
||||
'analytics': {'anonymize_ip': False, 'gtag': None},
|
||||
'highlightjs': True,
|
||||
'hljs_languages': [],
|
||||
'include_homepage_in_sidebar': True,
|
||||
'prev_next_buttons_location': 'bottom',
|
||||
'navigation_depth': 4,
|
||||
'sticky_navigation': True,
|
||||
'logo': None,
|
||||
'titles_only': False,
|
||||
'collapse_navigation': True,
|
||||
},
|
||||
},
|
||||
{
|
||||
'dirs': [os.path.join(theme_dir, 'readthedocs'), mkdocs_templates_dir],
|
||||
'static_templates': ['404.html', 'sitemap.xml'],
|
||||
'vars': {
|
||||
'name': 'readthedocs',
|
||||
'locale': parse_locale('en'),
|
||||
'include_search_page': True,
|
||||
'search_index_only': False,
|
||||
'analytics': {'anonymize_ip': False, 'gtag': None},
|
||||
'highlightjs': True,
|
||||
'hljs_languages': [],
|
||||
'include_homepage_in_sidebar': True,
|
||||
'prev_next_buttons_location': 'bottom',
|
||||
'navigation_depth': 4,
|
||||
'sticky_navigation': True,
|
||||
'logo': None,
|
||||
'titles_only': False,
|
||||
'collapse_navigation': True,
|
||||
},
|
||||
},
|
||||
{
|
||||
'dirs': [mytheme, mkdocs_templates_dir],
|
||||
'static_templates': ['sitemap.xml'],
|
||||
'vars': {'name': None, 'locale': parse_locale('en')},
|
||||
},
|
||||
{
|
||||
'dirs': [custom, os.path.join(theme_dir, 'readthedocs'), mkdocs_templates_dir],
|
||||
'static_templates': ['404.html', 'sitemap.xml'],
|
||||
'vars': {
|
||||
'name': 'readthedocs',
|
||||
'locale': parse_locale('en'),
|
||||
'include_search_page': True,
|
||||
'search_index_only': False,
|
||||
'analytics': {'anonymize_ip': False, 'gtag': None},
|
||||
'highlightjs': True,
|
||||
'hljs_languages': [],
|
||||
'include_homepage_in_sidebar': True,
|
||||
'prev_next_buttons_location': 'bottom',
|
||||
'navigation_depth': 4,
|
||||
'sticky_navigation': True,
|
||||
'logo': None,
|
||||
'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': {
|
||||
'name': 'mkdocs',
|
||||
'locale': parse_locale('fr'),
|
||||
'show_sidebar': False,
|
||||
'some_var': 'bar',
|
||||
'include_search_page': False,
|
||||
'search_index_only': False,
|
||||
'analytics': {'gtag': None},
|
||||
'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):
|
||||
with self.subTest(config_contents):
|
||||
conf = config.Config(schema=(('theme', c.Theme(default='mkdocs')),))
|
||||
conf.load_dict(config_contents)
|
||||
errors, warnings = conf.validate()
|
||||
self.assertEqual(errors, [])
|
||||
self.assertEqual(warnings, [])
|
||||
self.assertEqual(conf['theme'].dirs, result['dirs'])
|
||||
self.assertEqual(conf['theme'].static_templates, set(result['static_templates']))
|
||||
self.assertEqual({k: conf['theme'][k] for k in iter(conf['theme'])}, result['vars'])
|
||||
|
||||
def test_empty_nav(self):
|
||||
conf = defaults.MkDocsConfig()
|
||||
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_error_on_pages(self):
|
||||
conf = defaults.MkDocsConfig()
|
||||
conf.load_dict(
|
||||
{
|
||||
'site_name': 'Example',
|
||||
'pages': ['index.md', 'about.md'],
|
||||
}
|
||||
)
|
||||
errors, warnings = conf.validate()
|
||||
exp_error = "The configuration option 'pages' was removed from MkDocs. Use 'nav' instead."
|
||||
self.assertEqual(errors, [('pages', ValidationError(exp_error))])
|
||||
self.assertEqual(warnings, [])
|
||||
|
||||
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'},
|
||||
)
|
||||
|
||||
cfg = {
|
||||
'config_file_path': j(os.path.abspath('..'), 'mkdocs.yml'),
|
||||
}
|
||||
|
||||
for test_config in test_configs:
|
||||
with self.subTest(test_config):
|
||||
patch = {**cfg, **test_config}
|
||||
|
||||
# Same as the default schema, but don't verify the docs_dir exists.
|
||||
conf = config.Config(
|
||||
schema=(
|
||||
('docs_dir', c.Dir(default='docs')),
|
||||
('site_dir', c.SiteDir(default='site')),
|
||||
('config_file_path', c.Type(str)),
|
||||
)
|
||||
)
|
||||
conf.load_dict(patch)
|
||||
|
||||
errors, warnings = conf.validate()
|
||||
|
||||
self.assertEqual(len(errors), 1)
|
||||
self.assertEqual(warnings, [])
|
||||
Reference in New Issue
Block a user