refactor testcase for config

This commit is contained in:
Takeshi KOMIYA 2018-03-23 14:05:04 +09:00
parent 1cce27c302
commit e4ecb97d5a
2 changed files with 98 additions and 104 deletions

View File

@ -1,54 +1,3 @@
from sphinx.config import string_classes, ENUM project = 'Sphinx <Tests>'
release = '0.6alpha1'
value1 = 123 # wrong type templates_path = ['_templates']
value2 = 123 # lambda with wrong type
value3 = [] # lambda with correct type
value4 = True # child type
value5 = 3 # parent type
value6 = () # other sequence type, also raises
value7 = ['foo'] # explicitly permitted
class A(object):
pass
class B(A):
pass
class C(A):
pass
value8 = C() # sibling type
# both have no default or permissible types
value9 = 'foo'
value10 = 123
value11 = u'bar'
value12 = u'bar'
value13 = 'bar'
value14 = u'bar'
value15 = 'bar'
value16 = u'bar'
def setup(app):
app.add_config_value('value1', 'string', False)
app.add_config_value('value2', lambda conf: [], False)
app.add_config_value('value3', [], False)
app.add_config_value('value4', 100, False)
app.add_config_value('value5', False, False)
app.add_config_value('value6', [], False)
app.add_config_value('value7', 'string', False, [list])
app.add_config_value('value8', B(), False)
app.add_config_value('value9', None, False)
app.add_config_value('value10', None, False)
app.add_config_value('value11', None, False, [str])
app.add_config_value('value12', 'string', False)
app.add_config_value('value13', None, False, string_classes)
app.add_config_value('value14', None, False, string_classes)
app.add_config_value('value15', u'unicode', False)
app.add_config_value('value16', u'unicode', False)
app.add_config_value('value17', 'default', False, ENUM('default', 'one', 'two'))

View File

@ -11,15 +11,15 @@
""" """
import mock import mock
import pytest import pytest
from six import PY3, iteritems from six import PY3
import sphinx import sphinx
from sphinx.config import Config from sphinx.config import Config, ENUM, string_classes
from sphinx.errors import ExtensionError, ConfigError, VersionRequirementError from sphinx.errors import ExtensionError, ConfigError, VersionRequirementError
from sphinx.testing.path import path from sphinx.testing.path import path
@pytest.mark.sphinx(confoverrides={ @pytest.mark.sphinx(testroot='config', confoverrides={
'master_doc': 'master', 'master_doc': 'master',
'nonexisting_value': 'True', 'nonexisting_value': 'True',
'latex_elements.docclass': 'scrartcl', 'latex_elements.docclass': 'scrartcl',
@ -91,6 +91,30 @@ def test_extension_values(app, status, warning):
assert 'already present' in str(excinfo.value) assert 'already present' in str(excinfo.value)
def test_overrides():
config = Config({'value1': '1', 'value2': 2, 'value6': {'default': 6}},
{'value2': 999, 'value3': '999', 'value5.attr1': 999, 'value6.attr1': 999,
'value7': 'abc,def,ghi', 'value8': 'abc,def,ghi'})
config.add('value1', None, 'env', ())
config.add('value2', None, 'env', ())
config.add('value3', 0, 'env', ())
config.add('value4', 0, 'env', ())
config.add('value5', {'default': 0}, 'env', ())
config.add('value6', {'default': 0}, 'env', ())
config.add('value7', None, 'env', ())
config.add('value8', [], 'env', ())
config.init_values()
assert config.value1 == '1'
assert config.value2 == 999
assert config.value3 == 999
assert config.value4 == 0
assert config.value5 == {'attr1': 999}
assert config.value6 == {'default': 6, 'attr1': 999}
assert config.value7 == 'abc,def,ghi'
assert config.value8 == ['abc', 'def', 'ghi']
@mock.patch("sphinx.config.logger") @mock.patch("sphinx.config.logger")
def test_errors_warnings(logger, tempdir): def test_errors_warnings(logger, tempdir):
# test the error for syntax errors in the config file # test the error for syntax errors in the config file
@ -195,60 +219,81 @@ def test_builtin_conf(app, status, warning):
'warning') 'warning')
# See roots/test-config/conf.py. # example classes for type checking
TYPECHECK_WARNINGS = { class A(object):
'value1': True, pass
'value2': True,
'value3': False,
'value4': True,
'value5': False,
'value6': True,
'value7': False,
'value8': False,
'value9': False,
'value10': False,
'value11': False if PY3 else True,
'value12': False,
'value13': False,
'value14': False,
'value15': False,
'value16': False,
}
@pytest.mark.parametrize("key,should", iteritems(TYPECHECK_WARNINGS)) class B(A):
@pytest.mark.sphinx(testroot='config') pass
def test_check_types(warning, key, should):
warn = warning.getvalue()
if should:
assert key in warn, (
'override on "%s" should raise a type warning' % key
)
else:
assert key not in warn, (
'override on "%s" should NOT raise a type warning' % key
)
@pytest.mark.sphinx(testroot='config') class C(A):
def test_check_enum(app, status, warning): pass
assert "The config value `value17` has to be a one of ('default', 'one', 'two'), " \
not in warning.getvalue()
@pytest.mark.sphinx(testroot='config', confoverrides={'value17': 'invalid'}) # name, default, annotation, actual, warned
def test_check_enum_failed(app, status, warning): TYPECHECK_WARNINGS = [
assert "The config value `value17` has to be a one of ('default', 'one', 'two'), " \ ('value1', 'string', None, 123, True), # wrong type
"but `invalid` is given." in warning.getvalue() ('value2', lambda _: [], None, 123, True), # lambda with wrong type
('value3', lambda _: [], None, [], False), # lambda with correct type
('value4', 100, None, True, True), # child type
('value5', False, None, True, False), # parent type
('value6', [], None, (), True), # other sequence type
('value7', 'string', [list], ['foo'], False), # explicit type annotation
('value8', B(), None, C(), False), # sibling type
('value9', None, None, 'foo', False), # no default or no annotations
('value10', None, None, 123, False), # no default or no annotations
('value11', None, [str], u'bar', False if PY3 else True), # str vs unicode
('value12', 'string', None, u'bar', False), # str vs unicode
('value13', None, string_classes, 'bar', False), # string_classes
('value14', None, string_classes, u'bar', False), # string_classes
('value15', u'unicode', None, 'bar', False), # str vs unicode
('value16', u'unicode', None, u'bar', False), # str vs unicode
]
@pytest.mark.sphinx(testroot='config', confoverrides={'value17': ['one', 'two']}) @mock.patch("sphinx.config.logger")
def test_check_enum_for_list(app, status, warning): @pytest.mark.parametrize("name,default,annotation,actual,warned", TYPECHECK_WARNINGS)
assert "The config value `value17` has to be a one of ('default', 'one', 'two'), " \ def test_check_types(logger, name, default, annotation, actual, warned):
not in warning.getvalue() config = Config({name: actual})
config.add(name, default, 'env', annotation or ())
config.init_values()
config.check_types()
assert logger.warning.called == warned
@pytest.mark.sphinx(testroot='config', confoverrides={'value17': ['one', 'two', 'invalid']}) @mock.patch("sphinx.config.logger")
def test_check_enum_for_list_failed(app, status, warning): def test_check_enum(logger):
assert "The config value `value17` has to be a one of ('default', 'one', 'two'), " \ config = Config()
"but `['one', 'two', 'invalid']` is given." in warning.getvalue() config.add('value', 'default', False, ENUM('default', 'one', 'two'))
config.init_values()
config.check_types()
logger.warning.assert_not_called() # not warned
@mock.patch("sphinx.config.logger")
def test_check_enum_failed(logger):
config = Config({'value': 'invalid'})
config.add('value', 'default', False, ENUM('default', 'one', 'two'))
config.init_values()
config.check_types()
logger.warning.assert_called()
@mock.patch("sphinx.config.logger")
def test_check_enum_for_list(logger):
config = Config({'value': ['one', 'two']})
config.add('value', 'default', False, ENUM('default', 'one', 'two'))
config.init_values()
config.check_types()
logger.warning.assert_not_called() # not warned
@mock.patch("sphinx.config.logger")
def test_check_enum_for_list_failed(logger):
config = Config({'value': ['one', 'two', 'invalid']})
config.add('value', 'default', False, ENUM('default', 'one', 'two'))
config.init_values()
config.check_types()
logger.warning.assert_called()