You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
139 lines
4.9 KiB
139 lines
4.9 KiB
# pylint: disable=redefined-outer-name
|
|
from copy import deepcopy
|
|
import pytest
|
|
import preserve
|
|
from configspec import *
|
|
|
|
|
|
@pytest.fixture
|
|
def example_spec():
|
|
confspec = ConfigSpecification()
|
|
confspec.add_spec("bool_a", BoolSpec(helptext="Bool A"))
|
|
confspec.add_spec("boollist_a", ListSpec(BoolSpec(), helptext="Bool List A"))
|
|
confspec.add_spec("int_a", IntSpec(-4, 4, helptext="Int A"))
|
|
confspec.add_spec("intlist_a", ListSpec(IntSpec(-4, 4, "Int A")))
|
|
confspec.add_spec("float_a", FloatSpec(-4, 4, helptext="Float A"))
|
|
confspec.add_spec("floatlist_a", ListSpec(FloatSpec(-4, 4, "Float A")))
|
|
confspec.add_spec("string_a", StringSpec(helptext="String A"))
|
|
confspec.add_spec("stringlist_a", ListSpec(StringSpec(), helptext="String List A"))
|
|
|
|
confdictspec = confspec.add_spec("dict_a", DictSpec(helptext="Dict A"))
|
|
confdictspec.add_spec("bool_b", BoolSpec(helptext="Bool B"))
|
|
confdictspec.add_spec("int_b", IntSpec(helptext="Int B"))
|
|
confdictspec.add_spec("float_b", FloatSpec(helptext="Float B"))
|
|
confdictspec.add_spec("string_b", StringSpec(helptext="String B"))
|
|
|
|
confdictlist = confspec.add_spec("dictlist_a", ListSpec(
|
|
DictSpec(), helptext="List of Dicts B"))
|
|
confdictlist.add_specs({"bool_c": BoolSpec(helptext="Bool C"),
|
|
"int_c": IntSpec(helptext="Int C"),
|
|
"float_c": FloatSpec(helptext="Float C"),
|
|
"string_c": StringSpec(helptext="String C")})
|
|
|
|
return confspec
|
|
|
|
|
|
@pytest.fixture
|
|
def example_values():
|
|
vals = {'bool_a': True,
|
|
'boollist_a': [False, True],
|
|
'int_a': 1,
|
|
'intlist_a': [1, 2, 3, 4],
|
|
'float_a': 1.5,
|
|
'floatlist_a': [1.2, 2.1, 3.7, 2.8],
|
|
'string_a': 'sometext',
|
|
'stringlist_a': ['somemoretext', 'yetmoretext'],
|
|
'dict_a': {
|
|
'bool_b': False,
|
|
'int_b': 0,
|
|
'float_b': 0.5,
|
|
'string_b': 'texttesttext'},
|
|
'dictlist_a': [{'bool_c': False,
|
|
'int_c': 3,
|
|
'float_c': 3.4,
|
|
'string_c': 'string1'},
|
|
{'bool_c': True,
|
|
'int_c': 0,
|
|
'float_c': 0.4,
|
|
'string_c': 'string2'}]}
|
|
|
|
return vals
|
|
|
|
|
|
def test_addspec(example_spec):
|
|
# Most of the test is really just forming the fixture without exception
|
|
assert isinstance(example_spec, ConfigSpecification)
|
|
|
|
|
|
def test_preserveable(example_spec):
|
|
assert isinstance(preserve.preserve(example_spec), dict)
|
|
|
|
|
|
def test_config_validate(example_spec, example_values):
|
|
example_spec.validate(example_values)
|
|
|
|
|
|
def test_invalid_bool():
|
|
spec = BoolSpec()
|
|
with pytest.raises(InvalidConfigError, match="value must be a boolean"):
|
|
spec.validate("false")
|
|
with pytest.raises(InvalidConfigError, match="value must be a boolean"):
|
|
spec.validate(None)
|
|
|
|
|
|
def test_invalid_int():
|
|
spec = IntSpec(minval=-4, maxval=4)
|
|
with pytest.raises(InvalidConfigError, match="value must be >="):
|
|
spec.validate(-5)
|
|
with pytest.raises(InvalidConfigError, match="value must be <="):
|
|
spec.validate(5)
|
|
with pytest.raises(InvalidConfigError, match="value must be an integer"):
|
|
spec.validate("5")
|
|
with pytest.raises(InvalidConfigError, match="value must be an integer"):
|
|
spec.validate(None)
|
|
|
|
|
|
def test_invalid_string():
|
|
spec = StringSpec()
|
|
# TODO add regex check
|
|
with pytest.raises(InvalidConfigError, match="value must be a string"):
|
|
spec.validate(1)
|
|
with pytest.raises(InvalidConfigError, match="value must be a string"):
|
|
spec.validate(None)
|
|
|
|
|
|
def test_dict_optional():
|
|
spec = DictSpec()
|
|
spec.add_spec("int1", IntSpec())
|
|
spec.add_spec("int2", IntSpec(), optional=True)
|
|
spec.add_spec("int3", IntSpec(), optional=True, default=1)
|
|
with pytest.raises(InvalidConfigError, match="must contain key 'int1'"):
|
|
spec.validate({})
|
|
|
|
with pytest.raises(InvalidConfigError, match="contains unknown key"):
|
|
spec.validate({"int1": 1, "int5": 0})
|
|
|
|
d = {"int1": 1, "int2": 2, "int3": 3}
|
|
spec.validate(d)
|
|
assert d == {"int1": 1, "int2": 2, "int3": 3}
|
|
|
|
d = {"int1": 1}
|
|
spec.validate(d)
|
|
assert d == {"int1": 1, "int2": None, "int3": 1}
|
|
|
|
|
|
def test_man(example_spec, example_values):
|
|
confman = ConfigManager()
|
|
confman.add_confspec("test_bundle", example_spec)
|
|
confman.load({"test_bundle": example_values})
|
|
assert confman.get_config_bundle("test_bundle") == example_values
|
|
|
|
confman.freeze_value("test_bundle", "int_a")
|
|
newvals = deepcopy(example_values)
|
|
newvals["int_a"] = 4
|
|
|
|
confman.load({"test_bundle": newvals})
|
|
assert confman.get_config_bundle("test_bundle") == example_values
|
|
confman.load_overlay({"test_bundle": {"string_a": "new text"}})
|
|
assert confman.get_config_bundle("test_bundle")["string_a"] == "new text"
|