diff --git a/pyvalid/__accepts.py b/pyvalid/__accepts.py index 6dcbd25..3fe1c25 100644 --- a/pyvalid/__accepts.py +++ b/pyvalid/__accepts.py @@ -9,6 +9,7 @@ from collections.abc import Callable except ImportError: from collections import Callable +from warnings import warn from pyvalid.__exceptions import InvalidArgumentNumberError, ArgumentValidationError from pyvalid.switch import is_enabled @@ -167,7 +168,7 @@ def __validate_args(self, func, args, kwargs): continue else: raise InvalidArgumentNumberError(func) - is_valid = False + status, warning, msg = False, False, "" for allowed_val in allowed_values: is_validator = ( isinstance(allowed_val, Validator) or @@ -179,15 +180,21 @@ def __validate_args(self, func, args, kwargs): ) if is_validator: is_valid = allowed_val(value) + status = is_valid.status + warning = is_valid.is_warning + msg = is_valid.msg elif isinstance(allowed_val, type): - is_valid = isinstance(value, allowed_val) + status = isinstance(value, allowed_val) else: - is_valid = value == allowed_val - if is_valid: + status = value == allowed_val + if status: break - if not is_valid: + if not status: ord_num = self.__ordinal(i + 1) - raise ArgumentValidationError(func, ord_num, value, allowed_values) + if not warning: + raise ArgumentValidationError(func, ord_num, value, allowed_values, msg) + else: + warn(msg) def __ordinal(self, num): """Returns the ordinal number of a given integer, as a string. diff --git a/pyvalid/__exceptions.py b/pyvalid/__exceptions.py index 520d65a..fa6faf2 100644 --- a/pyvalid/__exceptions.py +++ b/pyvalid/__exceptions.py @@ -64,17 +64,17 @@ class ArgumentValidationError(PyvalidError): """Raised when the function's parameter contains the value is different from the expected one. """ - def __init__(self, func, arg_num, actual_value, allowed_arg_values): + def __init__(self, func, arg_num, actual_value, allowed_arg_values, msg): error_message_template = ( - 'The {} argument of the "{}" function is "{}" of the "{}" type, while ' - 'expected values are: "{}".' + 'The {} argument of the "{}" function is "{}" of the "{}" type.\n{} falied. \n{}' ) self.error = error_message_template.format( arg_num, self.__get_func_name__(func), actual_value, type(actual_value), - allowed_arg_values + allowed_arg_values, + msg ) def __str__(self): diff --git a/pyvalid/validators/__base.py b/pyvalid/validators/__base.py index c384511..8a94122 100644 --- a/pyvalid/validators/__base.py +++ b/pyvalid/validators/__base.py @@ -4,6 +4,7 @@ except ImportError: from collections import Callable +import inspect from six import with_metaclass from pyvalid import accepts @@ -27,10 +28,10 @@ def checkers(self): raise NotImplementedError def __call__(self, val): - is_valid = False if self.allowed_types is None or isinstance(val, self.allowed_types): - is_valid = self._check(val) - return is_valid + return self._check(val) + IsValid.status = False + return IsValid def __init__(self, **kwargs): self.allowed_types = kwargs.get('allowed_types', None) @@ -44,9 +45,30 @@ def __init__(self, **kwargs): del self.checkers[checker_func] def _check(self, val): - valid = True + valid = None for checker_func, checker_args in self.checkers.items(): valid = checker_func(val, *checker_args) - if not valid: + if not valid.status: break return valid + + +class IsValid: + """ + Class that holds all the properties required to set when the validation succeeds or fails. + + Args: + status (bool): True if the validation is successful otherwise false. + is_warning (bool): True if warning needs to be raised instead of exception. + msg (str): Customized message on failure. + """ + status = False + is_warning = False + msg = "" + + @classmethod + def get_caller(cls): + """ + Get parent method name. + """ + return inspect.stack()[1][3] + "()" diff --git a/pyvalid/validators/__init__.py b/pyvalid/validators/__init__.py index bcbf189..3d393f9 100644 --- a/pyvalid/validators/__init__.py +++ b/pyvalid/validators/__init__.py @@ -1,4 +1,4 @@ -from pyvalid.validators.__base import AbstractValidator, Validator +from pyvalid.validators.__base import AbstractValidator, IsValid, Validator from pyvalid.validators.__iterable import IterableValidator from pyvalid.validators.__number import NumberValidator from pyvalid.validators.__string import StringValidator @@ -10,6 +10,7 @@ 'is_validator', 'Validator', 'AbstractValidator', + 'IsValid', 'IterableValidator', 'NumberValidator', 'StringValidator', diff --git a/pyvalid/validators/__iterable.py b/pyvalid/validators/__iterable.py index 9cbb51e..7736e15 100644 --- a/pyvalid/validators/__iterable.py +++ b/pyvalid/validators/__iterable.py @@ -1,12 +1,10 @@ -import warnings - try: from collections.abc import Iterable except ImportError: from collections import Iterable from pyvalid import accepts -from pyvalid.validators import AbstractValidator +from pyvalid.validators import AbstractValidator, IsValid class IterableValidator(AbstractValidator): @@ -45,7 +43,12 @@ def iterable_type_checker(cls, val, iterable_type): If the type of given iterable does not match the required type. """ - return type(val) == iterable_type + IsValid.status = type(val) == iterable_type + if not IsValid.status: + IsValid.msg = f"In {IsValid.get_caller()}, " \ + f"expected type '{iterable_type}' but got '{type(val)}' instead." + + return IsValid @classmethod def empty_checker(cls, val, empty_allowed): @@ -67,10 +70,16 @@ def empty_checker(cls, val, empty_allowed): If the iterable is empty. """ if not empty_allowed: - return len(val) != 0 + IsValid.status = len(val) != 0 + if not IsValid.status: + IsValid.msg = f"In {IsValid.get_caller()}, " \ + f"expected non-empty iterable but got '{val}" else: - warnings.warn("Iterable is empty, but does not impact the execution.") - return True + IsValid.status = True + IsValid.is_warning = True + IsValid.msg = "In {IsValid.get_caller()}, iterable is empty." + + return IsValid @classmethod def element_type_checker(cls, val, elements_type): @@ -88,13 +97,15 @@ def element_type_checker(cls, val, elements_type): False: If at least one element of the iterable is not of required type. """ - valid = True + IsValid.status = True for element in val: - valid = isinstance(element, elements_type) - if not valid: + IsValid.status = isinstance(element, elements_type) + if not IsValid.status: + IsValid.msg = f"In {IsValid.get_caller()}, " \ + f"expected type '{elements_type}' but got '{type(element)}' instead." break - return valid + return IsValid @classmethod def elements_min_val_checker(cls, val, min_val): @@ -115,14 +126,15 @@ def elements_min_val_checker(cls, val, min_val): If at least one element of the iterable is less than the . """ - valid = True - + IsValid.status = True for element in val: if element < min_val: - valid = False + IsValid.status = False + IsValid.msg = f"In {IsValid.get_caller()}, " \ + f"expected '>={min_val}' but got '{val}' instead." break - return valid + return IsValid @classmethod def elements_max_val_checker(cls, val, max_val): @@ -143,14 +155,15 @@ def elements_max_val_checker(cls, val, max_val): If at least one element of the iterable is greater than the . """ - valid = True - + IsValid.status = True for element in val: if element > max_val: - valid = False + IsValid.status = False + IsValid.msg = f"In {IsValid.get_caller()}, " \ + f"expected '<={max_val}' but got '{val}' instead." break - return valid + return IsValid @property def checkers(self): diff --git a/pyvalid/validators/__number.py b/pyvalid/validators/__number.py index 30654c9..97b5304 100644 --- a/pyvalid/validators/__number.py +++ b/pyvalid/validators/__number.py @@ -5,7 +5,7 @@ from collections import Iterable, Container from pyvalid import accepts -from pyvalid.validators import AbstractValidator +from pyvalid.validators import AbstractValidator, IsValid class NumberValidator(AbstractValidator): @@ -32,31 +32,55 @@ def number_type_checker(cls, val, number_type): If the type of given number does not match the required type. """ - return type(val) == number_type + IsValid.status = type(val) == number_type + if not IsValid.status: + IsValid.msg = f"In {IsValid.get_caller()}, " \ + f"expected type '{number_type}' but got '{type(val)}' instead." + + return IsValid @classmethod def min_val_checker(cls, val, min_val): - return val >= min_val + IsValid.status = val >= min_val + if not IsValid.status: + IsValid.msg = f"In {IsValid.get_caller()}, " \ + f"expected '>={min_val}' but got '{val}' instead." + + return IsValid @classmethod def max_val_checker(cls, val, max_val): - return val <= max_val + IsValid.status = val <= max_val + if not IsValid.status: + IsValid.msg = f"In {IsValid.get_caller()}, " \ + f"expected '<={max_val}' but got '{val}' instead." + + return IsValid @classmethod def in_range_checker(cls, val, in_range): - is_valid = False if isinstance(in_range, Container): - is_valid = val in in_range + IsValid.status = val in in_range elif isinstance(in_range, Iterable): for item in in_range: if item == val: - is_valid = True + IsValid.status = True break - return is_valid + if not IsValid.status: + IsValid.msg = f"In {IsValid.get_caller()}, " \ + f"'{val}' must be in range '{in_range}'." + + return IsValid @classmethod def not_in_range_checker(cls, val, not_in_range): - return not cls.in_range_checker(val, not_in_range) + in_range = cls.in_range_checker(val, not_in_range) + IsValid.status = not in_range.status + if not IsValid.status: + IsValid.msg = f"In {IsValid.get_caller()}, " \ + f"'{val}' must not be in range '{not_in_range}'." + + return IsValid @property def checkers(self): diff --git a/pyvalid/validators/__string.py b/pyvalid/validators/__string.py index 609d4b4..c7eafe4 100644 --- a/pyvalid/validators/__string.py +++ b/pyvalid/validators/__string.py @@ -5,43 +5,66 @@ from collections import Iterable, Container from pyvalid import accepts -from pyvalid.validators import AbstractValidator +from pyvalid.validators import AbstractValidator, IsValid class StringValidator(AbstractValidator): @classmethod def min_len_checker(cls, val, min_len): - return len(val) >= min_len + IsValid.status = len(val) >= min_len + if not IsValid.status: + IsValid.msg = f"In {IsValid.get_caller()}, " \ + f"expected string length to be '<={min_len}' but got length '{val}' instead." + + return IsValid @classmethod def max_len_checker(cls, val, max_len): - return len(val) <= max_len + IsValid.status = len(val) <= max_len + if not IsValid.status: + IsValid.msg = f"In {IsValid.get_caller()}, " \ + f"expected string length to be '>={max_len}' but got length '{val}' instead." + + return IsValid @classmethod def in_range_checker(cls, val, in_range): - is_valid = False if isinstance(in_range, Container): - is_valid = val in in_range + IsValid.status = val in in_range elif isinstance(in_range, Iterable): for item in in_range: if item == val: - is_valid = True + IsValid.status = True break - return is_valid + if not IsValid.status: + IsValid.msg = f"In {IsValid.get_caller()}, " \ + f"'{val}' must be in range '{in_range}'." + + return IsValid @classmethod def not_in_range_checker(cls, val, not_in_range): - return not cls.in_range_checker(val, not_in_range) + in_range = cls.in_range_checker(val, not_in_range) + IsValid.status = not in_range.status + if not IsValid.status: + IsValid.msg = f"In {IsValid.get_caller()}, " \ + f"'{val}' must not be in range '{not_in_range}'." + + return IsValid @classmethod def re_checker(cls, val, pattern, flags=0): try: match_obj = re.match(pattern, val, flags) - is_valid = match_obj is not None + IsValid.status = match_obj is not None except re.error: - is_valid = False - return is_valid + IsValid.status = False + if not IsValid.status: + IsValid.msg = f"In {IsValid.get_caller()}, " \ + f"'{val}' must not match the pattern '{pattern}'." + + return IsValid @property def checkers(self): diff --git a/pyvalid/validators/__tensor.py b/pyvalid/validators/__tensor.py index 85ef991..9bbe4b4 100644 --- a/pyvalid/validators/__tensor.py +++ b/pyvalid/validators/__tensor.py @@ -1,9 +1,7 @@ -import warnings - import torch from pyvalid import accepts -from pyvalid.validators import AbstractValidator, StringValidator +from pyvalid.validators import AbstractValidator, IsValid, StringValidator class TensorValidator(AbstractValidator): @@ -45,7 +43,12 @@ def tensor_type_checker(cls, val, tensor_type): If the type of given tensor does not match the required type. """ - return val.type() == tensor_type + IsValid.status = val.type() == tensor_type + if not IsValid.status: + IsValid.msg = f"In {IsValid.get_caller()}, " \ + f"expected type '{tensor_type}' but got '{type(val)}' instead." + + return IsValid @classmethod def dimension_checker(cls, val, dim): @@ -64,7 +67,12 @@ def dimension_checker(cls, val, dim): If the given tensor is not of required dimension. """ - return val.dim() == dim + IsValid.status = val.dim() == dim + if not IsValid.status: + IsValid.msg = f"In {IsValid.get_caller()}, " \ + f"expected tensor of dimension '{dim}' but got '{val.dim()}' instead." + + return IsValid @classmethod def empty_checker(cls, val, empty_allowed): @@ -87,10 +95,16 @@ def empty_checker(cls, val, empty_allowed): """ if not empty_allowed: - return val.nelement() != 0 + IsValid.status = val.nelement() != 0 + if not IsValid.status: + IsValid.msg = f"In {IsValid.get_caller()}, " \ + f"expected non-empty tensor but got '{val}" else: - warnings.warn("Tensor is empty, but does not impact the execution.") - return True + IsValid.status = True + IsValid.is_warning = True + IsValid.msg = "In {IsValid.get_caller()}, tensor is empty." + + return IsValid @classmethod def nan_checker(cls, val, nans_allowed): @@ -113,12 +127,16 @@ def nan_checker(cls, val, nans_allowed): """ if not nans_allowed: - return torch.isnan(val).sum().item() == 0 + IsValid.status = torch.isnan(val).sum().item() == 0 + if not IsValid.status: + IsValid.msg = f"In {IsValid.get_caller()}, " \ + f"expected NaN free tensor but got '{val}" else: - warnings.warn( - "Tensor contains NaN values, but does not impact the execution." - ) - return True + IsValid.status = True + IsValid.is_warning = True + IsValid.msg = "In {IsValid.get_caller()}, Tensor contains NaN values." + + return IsValid @property def checkers(self): diff --git a/tests/test_accepts.py b/tests/test_accepts.py index 5abb6b4..6efe8fc 100644 --- a/tests/test_accepts.py +++ b/tests/test_accepts.py @@ -3,6 +3,7 @@ from pyvalid import ArgumentValidationError, InvalidArgumentNumberError, \ accepts from pyvalid.validators import is_validator +from pyvalid.validators import IsValid class AcceptsDecoratorTestCase(unittest.TestCase): @@ -35,11 +36,13 @@ def func4(arg1=str(), **kwargs): @is_validator def func5_checker1(val): - return val == 'val1' + IsValid.status = val == 'val1' + return IsValid @is_validator def func5_checker2(val): - return val == 'val2' + IsValid.status = val == 'val2' + return IsValid @accepts(func5_checker1, [func5_checker2, 'val3', bool]) def func5(arg1, arg2): diff --git a/tests/test_iterable_validator.py b/tests/test_iterable_validator.py index 3cfa885..9a44fc8 100644 --- a/tests/test_iterable_validator.py +++ b/tests/test_iterable_validator.py @@ -10,77 +10,78 @@ def test_iterable_type(self): Verify iterable_type_checker() method. """ validator = IterableValidator(iterable_type=list) - self.assertTrue(validator([1, 3, 25, 14])) - self.assertFalse(validator({1: 'a', 2: 'b'})) + self.assertTrue(validator([1, 3, 25, 14]).status) + self.assertFalse(validator({1: 'a', 2: 'b'}).status) validator = IterableValidator(iterable_type=tuple) - self.assertTrue(validator((1, 3, 25, 14))) - self.assertFalse(validator([1, 3, 25, 14])) + self.assertTrue(validator((1, 3, 25, 14)).status) + self.assertFalse(validator([1, 3, 25, 14]).status) def test_empty_allowed(self): """ Verify empty_checker() method. """ validator = IterableValidator(empty_allowed=False) - self.assertTrue(validator([1, 3, 25, 14])) - self.assertFalse(validator([])) - self.assertFalse(None) + self.assertTrue(validator([1, 3, 25, 14]).status) + self.assertFalse(validator([]).status) + self.assertFalse(validator(None).status) validator = IterableValidator(empty_allowed=True) - self.assertTrue(validator([1, 3, 25, 14])) - self.assertTrue(validator([])) - self.assertFalse(None) + self.assertTrue(validator([1, 3, 25, 14]).status) + self.assertTrue(validator([]).status) + self.assertTrue(validator([]).is_warning) + self.assertFalse(validator(None).status) def test_elements_type(self): """ Verify element_type_checker() method. """ validator = IterableValidator(elements_type=int) - self.assertTrue(validator([1, 3, 25, 14])) - self.assertFalse(validator([3.56, 6.4532, 65.57, 5.546])) - self.assertFalse(validator(['CPython', 'PyPy', 'Jython', 'Cython'])) - self.assertTrue(validator([])) # Ignore empty - self.assertFalse(None) + self.assertTrue(validator([1, 3, 25, 14]).status) + self.assertFalse(validator([3.56, 6.4532, 65.57, 5.546]).status) + self.assertFalse(validator(['CPython', 'PyPy', 'Jython', 'Cython']).status) + self.assertTrue(validator([]).status) # Ignore empty + self.assertFalse(validator(None).status) validator = IterableValidator(elements_type=float) - self.assertFalse(validator([1, 3, 25, 14])) - self.assertTrue(validator([3.56, 6.4532, 65.57, 5.546])) - self.assertFalse(validator(['CPython', 'PyPy', 'Jython', 'Cython'])) - self.assertFalse(None) + self.assertFalse(validator([1, 3, 25, 14]).status) + self.assertTrue(validator([3.56, 6.4532, 65.57, 5.546]).status) + self.assertFalse(validator(['CPython', 'PyPy', 'Jython', 'Cython']).status) + self.assertFalse(validator(None).status) validator = IterableValidator(elements_type=str) - self.assertFalse(validator([1, 3, 25, 14])) - self.assertFalse(validator([3.56, 6.4532, 65.57, 5.546])) - self.assertTrue(validator(['CPython', 'PyPy', 'Jython', 'Cython'])) - self.assertFalse(None) + self.assertFalse(validator([1, 3, 25, 14]).status) + self.assertFalse(validator([3.56, 6.4532, 65.57, 5.546]).status) + self.assertTrue(validator(['CPython', 'PyPy', 'Jython', 'Cython']).status) + self.assertFalse(validator(None).status) def test_min_val(self): """ Verify elements_min_val_checker() method. """ validator = IterableValidator(min_val=0) - self.assertTrue(validator([1, 3, 25, 14])) - self.assertFalse(validator([-1, -3, -25, -14])) - self.assertFalse(None) + self.assertTrue(validator([1, 3, 25, 14]).status) + self.assertFalse(validator([-1, -3, -25, -14]).status) + self.assertFalse(validator(None).status) validator = IterableValidator(min_val=-50.3) - self.assertTrue(validator([-1.6, 3.56, 25.53, -14.4])) - self.assertFalse(validator([-72.67, 3.56, 25.53, -14.4])) - self.assertFalse(None) + self.assertTrue(validator([-1.6, 3.56, 25.53, -14.4]).status) + self.assertFalse(validator([-72.67, 3.56, 25.53, -14.4]).status) + self.assertFalse(validator(None).status) def test_max_val(self): """ Verify elements_max_val_checker() method. """ validator = IterableValidator(max_val=100) - self.assertTrue(validator([12, 96, 24, 100])) - self.assertFalse(validator([104, 205, 835, 143])) - self.assertFalse(None) + self.assertTrue(validator([12, 96, 24, 100]).status) + self.assertFalse(validator([104, 205, 835, 143]).status) + self.assertFalse(validator(None).status) validator = IterableValidator(max_val=150.25) - self.assertTrue(validator([-154.6, 45.56, 125.53, -12.4])) - self.assertFalse(validator([164.67, 33.56, 110.53, -140.4])) - self.assertFalse(None) + self.assertTrue(validator([-154.6, 45.56, 125.53, -12.4]).status) + self.assertFalse(validator([164.67, 33.56, 110.53, -140.4]).status) + self.assertFalse(validator(None).status) def test_range(self): """ @@ -91,12 +92,12 @@ def test_range(self): IterableValidator(min_val=100, max_val=50) validator = IterableValidator(min_val=50, max_val=100) - self.assertTrue(validator([60, 80, 100])) - self.assertTrue(validator([70, 60, 50])) - self.assertTrue(validator([])) - self.assertFalse(validator([101, 10, 10, 10])) - self.assertFalse(validator([-50, -25, 0])) - self.assertFalse(None) + self.assertTrue(validator([60, 80, 100]).status) + self.assertTrue(validator([70, 60, 50]).status) + self.assertTrue(validator([]).status) + self.assertFalse(validator([101, 10, 10, 10]).status) + self.assertFalse(validator([-50, -25, 0]).status) + self.assertFalse(validator(None).status) def test_mixed(self): """ @@ -105,12 +106,12 @@ def test_mixed(self): validator = IterableValidator( empty_allowed=False, elements_type=int, min_val=-128, max_val=128 ) - self.assertTrue(validator([1, 3, 25, 120])) # List - self.assertTrue(validator((1, 3, 25, 3))) # Tuple - self.assertTrue(validator({1: 'pyvalid', 2: 'cython'})) # Dictionary - self.assertTrue(validator({1, 3, 25, 120})) # Set - self.assertFalse(validator(8)) # Integer - self.assertFalse(None) + self.assertTrue(validator([1, 3, 25, 120]).status) # List + self.assertTrue(validator((1, 3, 25, 3)).status) # Tuple + self.assertTrue(validator({1: 'pyvalid', 2: 'cython'}).status) # Dictionary + self.assertTrue(validator({1, 3, 25, 120}).status) # Set + self.assertFalse(validator(8).status) # Integer + self.assertFalse(validator(None).status) if __name__ == '__main__': diff --git a/tests/test_number_validator.py b/tests/test_number_validator.py index 85aa9ad..080dbfb 100644 --- a/tests/test_number_validator.py +++ b/tests/test_number_validator.py @@ -1,50 +1,51 @@ import unittest from pyvalid.validators import NumberValidator +from pyvalid.validators import IsValid class NumberValidatorTestCase(unittest.TestCase): def test_number_type(self): validator = NumberValidator(number_type=int) - self.assertTrue(validator(12)) - self.assertFalse(validator(10.56)) + self.assertTrue(validator(12).status) + self.assertFalse(validator(10.56).status) validator = NumberValidator(number_type=float) - self.assertTrue(validator(10.56)) - self.assertFalse(validator(12)) + self.assertTrue(validator(10.56).status) + self.assertFalse(validator(12).status) def test_min_val(self): validator = NumberValidator(min_val=-3.14) - self.assertTrue(validator(3.14)) - self.assertTrue(validator(-3.14)) - self.assertFalse(validator(-273.15)) - self.assertFalse(None) + self.assertTrue(validator(3.14).status) + self.assertTrue(validator(-3.14).status) + self.assertFalse(validator(-273.15).status) + self.assertFalse(validator(None).status) def test_max_val(self): validator = NumberValidator(max_val=42) - self.assertTrue(validator(8)) - self.assertTrue(validator(0)) - self.assertFalse(validator(512)) - self.assertFalse(None) + self.assertTrue(validator(8).status) + self.assertTrue(validator(0).status) + self.assertFalse(validator(512).status) + self.assertFalse(validator(None).status) def test_in_range(self): validator = NumberValidator( in_range=[2**x for x in range(16)] ) - self.assertTrue(validator(1)) - self.assertTrue(validator(256.0)) - self.assertFalse(validator(0)) - self.assertFalse(None) + self.assertTrue(validator(1).status) + self.assertTrue(validator(256.0).status) + self.assertFalse(validator(0).status) + self.assertFalse(validator(None).status) def test_not_in_range(self): validator = NumberValidator( not_in_range=[2**x for x in range(16)] ) - self.assertTrue(validator(0)) - self.assertTrue(validator(-1)) - self.assertFalse(validator(2)) - self.assertFalse(None) + self.assertTrue(validator(0).status) + self.assertTrue(validator(-1).status) + self.assertFalse(validator(2).status) + self.assertFalse(validator(None).status) def test_mixed(self): with self.assertRaises(ValueError): @@ -54,12 +55,12 @@ def test_mixed(self): min_val=0, max_val=2**16, not_in_range=[2**x for x in range(16)] ) - self.assertTrue(validator(0)) - self.assertTrue(validator(2**16 - 0.1)) - self.assertFalse(validator(2**16 + 0.1)) - self.assertFalse(validator(8)) - self.assertFalse(validator(-8)) - self.assertFalse(None) + self.assertTrue(validator(0).status) + self.assertTrue(validator(2**16 - 0.1).status) + self.assertFalse(validator(2**16 + 0.1).status) + self.assertFalse(validator(8).status) + self.assertFalse(validator(-8).status) + self.assertFalse(validator(None).status) if __name__ == '__main__': diff --git a/tests/test_string_validator.py b/tests/test_string_validator.py index 3407ac0..6188b19 100644 --- a/tests/test_string_validator.py +++ b/tests/test_string_validator.py @@ -8,66 +8,66 @@ class StringValidatorTestCase(unittest.TestCase): def test_min_len(self): validator = StringValidator(min_len=2) - self.assertTrue(validator('Python')) - self.assertTrue(validator('Py')) - self.assertFalse(validator('P')) - self.assertFalse(validator(None)) + self.assertTrue(validator('Python').status) + self.assertTrue(validator('Py').status) + self.assertFalse(validator('P').status) + self.assertFalse(validator(None).status) def test_max_len(self): validator = StringValidator(max_len=6) - self.assertTrue(validator(str())) - self.assertTrue(validator('Python')) - self.assertFalse(validator('Python3')) - self.assertFalse(validator(None)) + self.assertTrue(validator(str()).status) + self.assertTrue(validator('Python').status) + self.assertFalse(validator('Python3').status) + self.assertFalse(validator(None).status) def test_in_range(self): validator = StringValidator( in_range=['CPython', 'PyPy', 'IronPython', 'Jython', 'Cython'] ) - self.assertTrue(validator('PyPy')) - self.assertTrue(validator('Cython')) - self.assertFalse(validator('Ruby')) - self.assertFalse(validator(None)) + self.assertTrue(validator('PyPy').status) + self.assertTrue(validator('Cython').status) + self.assertFalse(validator('Ruby').status) + self.assertFalse(validator(None).status) def test_not_in_range(self): validator = StringValidator( not_in_range=['CPython', 'PyPy', 'IronPython', 'Jython', 'Cython'] ) - self.assertTrue(validator('Ruby')) - self.assertTrue(validator('Java')) - self.assertFalse(validator('CPython')) - self.assertFalse(validator(None)) + self.assertTrue(validator('Ruby').status) + self.assertTrue(validator('Java').status) + self.assertFalse(validator('CPython').status) + self.assertFalse(validator(None).status) def test_re(self): # Allowed characters are: latin alphabet letters and digits validator = StringValidator(re_pattern='^[a-zA-Z0-9]+$') - self.assertTrue(validator('pyvalid')) - self.assertTrue(validator('42')) - self.assertFalse(validator('__pyvalid__')) + self.assertTrue(validator('pyvalid').status) + self.assertTrue(validator('42').status) + self.assertFalse(validator('__pyvalid__').status) # Regular expression is broken validator = StringValidator(re_pattern=':)') - self.assertFalse(validator('pyvalid')) - self.assertFalse(validator(':)')) + self.assertFalse(validator('pyvalid').status) + self.assertFalse(validator(':)').status) # Try to use regular expression with flag validator = StringValidator( re_pattern='^pyvalid$', re_flags=re.IGNORECASE ) - self.assertTrue(validator('pyvalid')) - self.assertTrue(validator('PyValid')) - self.assertFalse(validator('42')) - self.assertFalse(validator(None)) + self.assertTrue(validator('pyvalid').status) + self.assertTrue(validator('PyValid').status) + self.assertFalse(validator('42').status) + self.assertFalse(validator(None).status) def test_mixed(self): validator = StringValidator( min_len=6, max_len=64, not_in_range=['password', 'qwerty', '123456789', 'sunshine'], ) - self.assertTrue(validator('Super_Mega_Strong_Password_2000')) - self.assertTrue(validator('_' * 6)) - self.assertFalse(validator('_' * 3)) - self.assertFalse(validator('_' * 128)) - self.assertFalse(validator('sunshine')) - self.assertFalse(validator(None)) + self.assertTrue(validator('Super_Mega_Strong_Password_2000').status) + self.assertTrue(validator('_' * 6).status) + self.assertFalse(validator('_' * 3).status) + self.assertFalse(validator('_' * 128).status) + self.assertFalse(validator('sunshine').status) + self.assertFalse(validator(None).status) if __name__ == '__main__': diff --git a/tests/test_tensor_validator.py b/tests/test_tensor_validator.py index 0848efd..867fdfa 100644 --- a/tests/test_tensor_validator.py +++ b/tests/test_tensor_validator.py @@ -18,22 +18,22 @@ def test_tensor_type(self): Verify tensor_type_checker() method. """ validator = TensorValidator(tensor_type="torch.FloatTensor") - self.assertTrue(validator(self.t)) + self.assertTrue(validator(self.t).status) validator = TensorValidator(tensor_type="torch.IntTensor") - self.assertFalse(validator(self.t)) + self.assertFalse(validator(self.t).status) def test_dim(self): """ Verify dimension_checker() method. """ validator = TensorValidator(dim=2) - self.assertTrue(validator(self.t)) - self.assertTrue(validator(torch.Tensor([[]]))) + self.assertTrue(validator(self.t).status) + self.assertTrue(validator(torch.Tensor([[]])).status) validator = TensorValidator(dim=1) - self.assertFalse(validator(self.t)) - self.assertFalse(validator(torch.Tensor([[]]))) + self.assertFalse(validator(self.t).status) + self.assertFalse(validator(torch.Tensor([[]])).status) def test_empty_allowed(self): """ @@ -41,11 +41,12 @@ def test_empty_allowed(self): """ validator = TensorValidator(empty_allowed=False) self.assertTrue(validator(self.t)) - self.assertFalse(validator(torch.Tensor([[]]))) + self.assertFalse(validator(torch.Tensor([[]])).status) validator = TensorValidator(empty_allowed=True) self.assertTrue(validator(self.t)) - self.assertTrue(validator(torch.Tensor([[]]))) + self.assertTrue(validator(torch.Tensor([[]])).status) + self.assertTrue(validator(torch.Tensor([[]])).is_warning) def test_nans_allowed(self): """ @@ -53,11 +54,12 @@ def test_nans_allowed(self): """ validator = TensorValidator(nans_allowed=False) self.assertTrue(validator(self.t)) - self.assertFalse(validator(torch.Tensor([np.NaN, 7.3459, 0.3454, np.NaN]))) + self.assertFalse(validator(torch.Tensor([np.NaN, 7.3459, 0.3454, np.NaN])).status) validator = TensorValidator(nans_allowed=True) self.assertTrue(validator(self.t)) - self.assertTrue(validator(torch.Tensor([np.NaN, 7.3459, 0.3454, np.NaN]))) + self.assertTrue(validator(torch.Tensor([np.NaN, 7.3459, 0.3454, np.NaN])).status) + self.assertTrue(validator(torch.Tensor([np.NaN, 7.3459, 0.3454, np.NaN])).is_warning) def test_mixed(self): """ @@ -69,8 +71,9 @@ def test_mixed(self): empty_allowed=False, nans_allowed=False ) - self.assertTrue(validator(self.t)) - self.assertFalse(validator([1, 2])) # Non-tensor + self.assertTrue(validator(self.t).status) + self.assertFalse(validator([1, 2]).status) # Non-tensor + self.assertFalse(validator(None).status) if __name__ == '__main__':