# *- coding: utf-8 -*- # pylint: disable=wildcard-import, missing-docstring, no-self-use, bad-continuation # pylint: disable=invalid-name, redefined-outer-name, too-few-public-methods """Validator tests""" import pytest from configobj import ConfigObj from configobj.validate import * class TestBasic(object): def test_values_too_small(self, val): config = ''' test1=40 test2=hello test3=3 test4=5.0 [section] test1=40 test2=hello test3=3 test4=5.0 [[sub section]] test1=40 test2=hello test3=3 test4=5.0 '''.splitlines() configspec = ''' test1= integer(30,50) test2= string test3=integer test4=float(6.0) [section ] test1=integer(30,50) test2=string test3=integer test4=float(6.0) [[sub section]] test1=integer(30,50) test2=string test3=integer test4=float(6.0) '''.splitlines() c1 = ConfigObj(config, configspec=configspec) test = c1.validate(val) assert test == { 'test1': True, 'test2': True, 'test3': True, 'test4': False, 'section': { 'test1': True, 'test2': True, 'test3': True, 'test4': False, 'sub section': { 'test1': True, 'test2': True, 'test3': True, 'test4': False, }, }, } with pytest.raises(VdtValueTooSmallError) as excinfo: val.check(c1.configspec['test4'], c1['test4']) assert str(excinfo.value) == 'the value "5.0" is too small.' def test_values(self, val): val_test_config = ''' key = 0 key2 = 1.1 [section] key = some text key2 = 1.1, 3.0, 17, 6.8 [[sub-section]] key = option1 key2 = True'''.splitlines() val_test_configspec = ''' key = integer key2 = float [section] key = string key2 = float_list(4) [[sub-section]] key = option(option1, option2) key2 = boolean'''.splitlines() val_test = ConfigObj(val_test_config, configspec=val_test_configspec) assert val_test.validate(val) val_test['key'] = 'text not a digit' val_res = val_test.validate(val) assert val_res == {'key2': True, 'section': True, 'key': False} def test_defaults(self, val): configspec = ''' test1=integer(30,50, default=40) test2=string(default="hello") test3=integer(default=3) test4=float(6.0, default=6.0) [section ] test1=integer(30,50, default=40) test2=string(default="hello") test3=integer(default=3) test4=float(6.0, default=6.0) [[sub section]] test1=integer(30,50, default=40) test2=string(default="hello") test3=integer(default=3) test4=float(6.0, default=6.0) '''.splitlines() default_test = ConfigObj(['test1=30'], configspec=configspec) assert repr(default_test) == "ConfigObj({'test1': '30'})" assert default_test.defaults == [] assert default_test.default_values == {} assert default_test.validate(val) assert default_test == { 'test1': 30, 'test2': 'hello', 'test3': 3, 'test4': 6.0, 'section': { 'test1': 40, 'test2': 'hello', 'test3': 3, 'test4': 6.0, 'sub section': { 'test1': 40, 'test3': 3, 'test2': 'hello', 'test4': 6.0, }, }, } assert default_test.defaults == ['test2', 'test3', 'test4'] assert default_test.default_values == { 'test1': 40, 'test2': 'hello', 'test3': 3, 'test4': 6.0 } assert default_test.restore_default('test1') == 40 assert default_test['test1'] == 40 assert 'test1' in default_test.defaults # pylint: disable=unsupported-membership-test def change(section, key): section[key] = 3 default_test.walk(change) assert default_test['section']['sub section']['test4'] == 3 default_test.restore_defaults() assert default_test == { 'test1': 40, 'test2': "hello", 'test3': 3, 'test4': 6.0, 'section': { 'test1': 40, 'test2': "hello", 'test3': 3, 'test4': 6.0, 'sub section': { 'test1': 40, 'test2': "hello", 'test3': 3, 'test4': 6.0 }}} class TestStringChecks(object): def test_required_string_cannot_be_none(self, val): # issue #93 val.check('string(min=1)', None) with pytest.raises(VdtMissingValue): val.check('string(min=1)', None, missing=True) @pytest.mark.parametrize('text', ("text = ", "")) def test_required_string_cannot_be_empty_or_missing(self, val, text): # issue #93 config = [text] configspec = ["text = string(min=1)"] configobj = ConfigObj(config, configspec=configspec) assert configobj.validate(val, preserve_errors=True) is not True, "Validation should've failed" class TestListChecks(object): TYPESPECS = ( "'integer', 'string', 'boolean', 'float'", "'int', 'str', 'bool', 'float'", "int, str, bool, float", ) def test_force_list(self, val): config = ''' scalar = 1 '''.splitlines() configspec = ''' scalar = force_list '''.splitlines() configobj = ConfigObj(config, configspec=configspec) assert configobj.validate(val, preserve_errors=True) is True, "Validation failed unexpectedly" assert configobj['scalar'] == ['1'] @pytest.mark.parametrize('typespec', TYPESPECS) def test_mixed_list(self, val, typespec): config = ''' mixed = 1, 2, yes, 3.1415 '''.splitlines() configspec = ''' mixed = mixed_list({}) '''.format(typespec).splitlines() configobj = ConfigObj(config, configspec=configspec) assert configobj.validate(val, preserve_errors=True) is True, "Validation failed unexpectedly" assert configobj['mixed'] == [1, '2', True, 3.1415] class TestDottedQuadToNum(object): def test_stripped(self): assert dottedQuadToNum('192.0.2.0') == 3221225984 assert dottedQuadToNum('192.0.2.1 ') == 3221225985 assert dottedQuadToNum(' 192.0.2.2') == 3221225986 assert dottedQuadToNum('\t\t192.0.2.3\n') == 3221225987 with pytest.raises(ValueError) as excinfo: dottedQuadToNum('192. 0. 2. 4') assert str(excinfo.value) == 'Not a good dotted-quad IP: 192. 0. 2. 4' def test_boundaries(self): assert dottedQuadToNum('0.0.0.0') == 0 assert dottedQuadToNum('255.255.255.255') == 4294967295 with pytest.raises(ValueError) as excinfo: dottedQuadToNum('255.255.255.256') assert str(excinfo.value) == ( 'Not a good dotted-quad IP: 255.255.255.256') with pytest.raises(ValueError) as excinfo: dottedQuadToNum('-1') assert str(excinfo.value) == 'Not a good dotted-quad IP: -1'