tests, docstrings
This commit is contained in:
parent
84db8d20be
commit
14d8440ee7
5 changed files with 134 additions and 14 deletions
99
tests/unit/validators/test_dict_validator.py
Normal file
99
tests/unit/validators/test_dict_validator.py
Normal file
|
|
@ -0,0 +1,99 @@
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
from ytdl_subscribe.validators.base.validators import BoolValidator
|
||||||
|
from ytdl_subscribe.validators.base.validators import DictValidator
|
||||||
|
from ytdl_subscribe.validators.base.validators import StringValidator
|
||||||
|
from ytdl_subscribe.validators.exceptions import ValidationException
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"value", [{}, {"key": "value"}, {"b": {}, "a": "keys_out_of_order"}]
|
||||||
|
)
|
||||||
|
def test_dict_validator(value):
|
||||||
|
dict_validator = DictValidator(name="good_dict_validator", value=value)
|
||||||
|
assert dict_validator._name == "good_dict_validator"
|
||||||
|
assert dict_validator._value == value
|
||||||
|
assert dict_validator._dict == value
|
||||||
|
assert dict_validator._keys == sorted(list(value.keys()))
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("value", [None, "a", {"set"}, 0])
|
||||||
|
def test_dict_validator_fails_bad_value(value):
|
||||||
|
with pytest.raises(
|
||||||
|
ValidationException, match="Validation error in fail: should be of type object"
|
||||||
|
):
|
||||||
|
_ = DictValidator(name="fail", value=value)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"value, validator_class", [("string", StringValidator), (False, BoolValidator)]
|
||||||
|
)
|
||||||
|
def test_dict_validator_validate_key(value, validator_class):
|
||||||
|
dict_validator = DictValidator(name="validate_key", value={"key_name": value})
|
||||||
|
validated_key = dict_validator._validate_key(
|
||||||
|
key="key_name", validator=validator_class
|
||||||
|
)
|
||||||
|
|
||||||
|
assert isinstance(validated_key, validator_class)
|
||||||
|
assert validated_key.value == value
|
||||||
|
|
||||||
|
|
||||||
|
def test_dict_validator_validate_key_errors_missing():
|
||||||
|
dict_validator = DictValidator(name="validate_key", value={"key": None})
|
||||||
|
with pytest.raises(
|
||||||
|
ValidationException,
|
||||||
|
match="Validation error in validate_key: key_name is missing when it should be present.",
|
||||||
|
):
|
||||||
|
_ = dict_validator._validate_key(key="key_name", validator=StringValidator)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("bad_value", [True, None, {}])
|
||||||
|
def test_dict_validator_validate_key_errors_bad_validation(bad_value):
|
||||||
|
dict_validator = DictValidator(name="parent", value={"child": bad_value})
|
||||||
|
with pytest.raises(
|
||||||
|
ValidationException,
|
||||||
|
match="Validation error in parent.child: should be of type string",
|
||||||
|
):
|
||||||
|
_ = dict_validator._validate_key(key="child", validator=StringValidator)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"value, validator_class", [("string", StringValidator), (False, BoolValidator)]
|
||||||
|
)
|
||||||
|
def test_dict_validator_validate_key_if_present(value, validator_class):
|
||||||
|
dict_validator = DictValidator(name="validate_key", value={"key_name": value})
|
||||||
|
validated_key = dict_validator._validate_key_if_present(
|
||||||
|
key="key_name", validator=validator_class
|
||||||
|
)
|
||||||
|
|
||||||
|
assert isinstance(validated_key, validator_class)
|
||||||
|
assert validated_key.value == value
|
||||||
|
|
||||||
|
|
||||||
|
def test_dict_validator_validate_key_if_present_is_missing():
|
||||||
|
dict_validator = DictValidator(name="validate_key", value={"key_name": None})
|
||||||
|
out = dict_validator._validate_key_if_present(
|
||||||
|
key="non_existent_key", validator=StringValidator
|
||||||
|
)
|
||||||
|
|
||||||
|
assert out is None
|
||||||
|
|
||||||
|
|
||||||
|
def test_dict_validator_validate_key_if_present_is_missing_with_default():
|
||||||
|
dict_validator = DictValidator(name="validate_key", value={"key_name": None})
|
||||||
|
out = dict_validator._validate_key_if_present(
|
||||||
|
key="non_existent_key", validator=StringValidator, default="default"
|
||||||
|
)
|
||||||
|
|
||||||
|
assert isinstance(out, StringValidator)
|
||||||
|
assert out.value == "default"
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("bad_value", [True, None, {}])
|
||||||
|
def test_dict_validator_validate_key_errors_none_bad_validation(bad_value):
|
||||||
|
dict_validator = DictValidator(name="parent", value={"child": bad_value})
|
||||||
|
with pytest.raises(
|
||||||
|
ValidationException,
|
||||||
|
match="Validation error in parent.child: should be of type string",
|
||||||
|
):
|
||||||
|
_ = dict_validator._validate_key(key="child", validator=StringValidator)
|
||||||
|
|
@ -6,10 +6,10 @@ from ytdl_subscribe.validators.exceptions import ValidationException
|
||||||
|
|
||||||
@pytest.mark.parametrize("value", ["a", "unicode 💩", ""])
|
@pytest.mark.parametrize("value", ["a", "unicode 💩", ""])
|
||||||
def test_string_validator(value):
|
def test_string_validator(value):
|
||||||
bool_validator = StringValidator(name="good_str_validator", value=value)
|
string_validator = StringValidator(name="good_str_validator", value=value)
|
||||||
assert bool_validator._name == "good_str_validator"
|
assert string_validator._name == "good_str_validator"
|
||||||
assert bool_validator._value == value
|
assert string_validator._value == value
|
||||||
assert bool_validator.value == value
|
assert string_validator.value == value
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("value", [None, {}, True, 0])
|
@pytest.mark.parametrize("value", [None, {}, True, 0])
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,18 @@
|
||||||
import re
|
import re
|
||||||
from keyword import iskeyword
|
from keyword import iskeyword
|
||||||
from typing import List
|
from typing import List
|
||||||
|
from typing import final
|
||||||
|
|
||||||
from ytdl_subscribe.validators.base.validators import LiteralDictValidator
|
from ytdl_subscribe.validators.base.validators import LiteralDictValidator
|
||||||
from ytdl_subscribe.validators.base.validators import StringValidator
|
from ytdl_subscribe.validators.base.validators import Validator
|
||||||
|
|
||||||
|
|
||||||
class StringFormatterValidator(StringValidator):
|
class StringFormatterValidator(Validator):
|
||||||
"""
|
"""
|
||||||
Ensures user-created formatter strings are valid
|
Ensures user-created formatter strings are valid
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
_expected_value_type = str
|
||||||
_expected_value_type_name = "format string"
|
_expected_value_type_name = "format string"
|
||||||
|
|
||||||
__fields_validator = re.compile(r"{([a-z_]+?)}")
|
__fields_validator = re.compile(r"{([a-z_]+?)}")
|
||||||
|
|
@ -58,6 +60,7 @@ class StringFormatterValidator(StringValidator):
|
||||||
super().__init__(name=name, value=value)
|
super().__init__(name=name, value=value)
|
||||||
self.format_variables = self.__validate_and_get_format_variables()
|
self.format_variables = self.__validate_and_get_format_variables()
|
||||||
|
|
||||||
|
@final
|
||||||
@property
|
@property
|
||||||
def format_string(self) -> str:
|
def format_string(self) -> str:
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,3 @@
|
||||||
import re
|
|
||||||
from keyword import iskeyword
|
|
||||||
from typing import List
|
|
||||||
from typing import Set
|
from typing import Set
|
||||||
|
|
||||||
from ytdl_subscribe.validators.base.validators import StringValidator
|
from ytdl_subscribe.validators.base.validators import StringValidator
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ from typing import List
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
from typing import Type
|
from typing import Type
|
||||||
from typing import TypeVar
|
from typing import TypeVar
|
||||||
|
from typing import final
|
||||||
|
|
||||||
from ytdl_subscribe.validators.exceptions import ValidationException
|
from ytdl_subscribe.validators.exceptions import ValidationException
|
||||||
|
|
||||||
|
|
@ -97,6 +98,7 @@ class DictValidator(Validator):
|
||||||
_expected_value_type = dict
|
_expected_value_type = dict
|
||||||
_expected_value_type_name = "object"
|
_expected_value_type_name = "object"
|
||||||
|
|
||||||
|
@final
|
||||||
@property
|
@property
|
||||||
def _dict(self) -> dict:
|
def _dict(self) -> dict:
|
||||||
"""
|
"""
|
||||||
|
|
@ -106,6 +108,7 @@ class DictValidator(Validator):
|
||||||
"""
|
"""
|
||||||
return self._value
|
return self._value
|
||||||
|
|
||||||
|
@final
|
||||||
@property
|
@property
|
||||||
def _keys(self) -> List[str]:
|
def _keys(self) -> List[str]:
|
||||||
"""
|
"""
|
||||||
|
|
@ -115,6 +118,7 @@ class DictValidator(Validator):
|
||||||
"""
|
"""
|
||||||
return sorted(list(self._dict.keys()))
|
return sorted(list(self._dict.keys()))
|
||||||
|
|
||||||
|
@final
|
||||||
def _validate_key(
|
def _validate_key(
|
||||||
self,
|
self,
|
||||||
key: str,
|
key: str,
|
||||||
|
|
@ -129,30 +133,47 @@ class DictValidator(Validator):
|
||||||
validator
|
validator
|
||||||
The validator to use for the key's value
|
The validator to use for the key's value
|
||||||
default
|
default
|
||||||
If the key's value is None, use this as the default
|
If the key's value does not exist, use this value, unless it is None.
|
||||||
|
|
||||||
Returns
|
Returns
|
||||||
-------
|
-------
|
||||||
An instance of the specified validator
|
An instance of the specified validator
|
||||||
"""
|
"""
|
||||||
value = self._dict.get(key, default)
|
if key not in self._dict and default is None:
|
||||||
if value is None:
|
|
||||||
raise self._validation_exception(
|
raise self._validation_exception(
|
||||||
f"{key} is missing when it should be present."
|
f"{key} is missing when it should be present."
|
||||||
)
|
)
|
||||||
|
|
||||||
return validator(
|
return validator(
|
||||||
name=f"{self._name}.{key}",
|
name=f"{self._name}.{key}",
|
||||||
value=value,
|
value=self._dict.get(key, default),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@final
|
||||||
def _validate_key_if_present(
|
def _validate_key_if_present(
|
||||||
self,
|
self,
|
||||||
key: str,
|
key: str,
|
||||||
validator: Type[T],
|
validator: Type[T],
|
||||||
default: Optional[Any] = None,
|
default: Optional[Any] = None,
|
||||||
) -> Optional[T]:
|
) -> Optional[T]:
|
||||||
if key not in self._dict:
|
"""
|
||||||
|
If the key does not exist in the dict, and no default is provided, return None.
|
||||||
|
Otherwise, validate the key.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
key
|
||||||
|
Name of they key in the dict to validate
|
||||||
|
validator
|
||||||
|
The validator to use for the key's value
|
||||||
|
default
|
||||||
|
If the key's value does not exist, use this value.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
An instance of the specified validator
|
||||||
|
"""
|
||||||
|
if key not in self._dict and default is None:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
return self._validate_key(key=key, validator=validator, default=default)
|
return self._validate_key(key=key, validator=validator, default=default)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue