Example #1
0
def test_validator_context_manager():
    """ Tests the validation context manager """

    # nominal
    surf = 2
    with validator('surface', surf) as v:
        v.alid = surf > 0 and isfinite(surf)

    # wrong value (no inner exception)
    surf = -1
    with pytest.raises(ValidationError) as exc_info:
        with validator('surface', surf) as v:
            v.alid = surf > 0 and isfinite(surf)
    e = exc_info.value
    assert str(e) == "Error validating [surface=-1]. " \
                     "InvalidValue: Function [v.alid = surf > 0 and isfinite(surf)] returned [False] for value -1."

    # wrong type (inner exception)
    with pytest.raises(ValidationError) as exc_info:
        surf = 1j
        with validator('surface', surf) as v:
            v.alid = surf > 0 and isfinite(surf)
    e = exc_info.value
    with pytest.raises(TypeError) as typ_err_info:
        1j > 0
    t = typ_err_info.value
    assert str(e) == "Error validating [surface=1j]. " \
                     "InvalidType: Function [v.alid = surf > 0 and isfinite(surf)] raised %s: %s" \
                     "" % (t.__class__.__name__, t)
Example #2
0
def test_readme_usage_validator():
    """ Tests that the example under index/usage/validation works """

    surf = -1

    with pytest.raises(ValidationError) as exc_info:
        with validator('surface', surf) as v:
            v.alid = surf > 0 and isfinite(surf)
    e = exc_info.value
    assert str(e) == "Error validating [surface=-1]. " \
                     "InvalidValue: Function [v.alid = surf > 0 and isfinite(surf)] returned [False] for value -1."

    surf = 1j

    with pytest.raises(ValidationError) as exc_info:
        with validator('surface', surf) as v:
            v.alid = surf > 0 and isfinite(surf)
    e = exc_info.value
    assert str(e).startswith(
        "Error validating [surface=1j]. "
        "InvalidType: Function [v.alid = surf > 0 and isfinite(surf)] raised "
        "TypeError:"
    )  # the typeerror exact message varies across python versions

    # alternate naming
    surf = -1
    with pytest.raises(ValidationError) as exc_info:
        with validator('surface', surf) as r:
            r.esults = surf > 0 and isfinite(surf)
    e = exc_info.value
    assert str(e) == "Error validating [surface=-1]. " \
                     "InvalidValue: Function [r.esults = surf > 0 and isfinite(surf)] returned [False] for value -1."

    # type validation
    surf = 1j
    with pytest.raises(ValidationError) as exc_info:
        with validator('surface', surf, instance_of=int) as v:
            v.alid = surf > 0
    e = exc_info.value
    assert str(e) == "Error validating [surface=1j]. " \
                     "HasWrongType: Value should be an instance of %r. Wrong value: 1j." % int

    from valid8 import assert_instance_of
    with pytest.raises(ValidationError) as exc_info:
        with validator('surface', surf) as v:
            assert_instance_of(surf, int)
            v.alid = surf > 0
    e = exc_info.value
    assert str(e) == "Error validating [surface=1j]. " \
                     "HasWrongType: Value should be an instance of %r. Wrong value: 1j." % int
def with_validator_boolean_tester(t):
    from valid8 import validator
    from valid8.validation_lib import instance_of

    with validator('t', t, instance_of=tuple) as v:
        v.alid = len(t) == 2 \
                 and instance_of(t[0], Real) and (0 <= t[0] <= 1) \
                 and instance_of(t[1], str) and len(t[1]) == 3 and t[1].islower()
Example #4
0
def test_readme_usage_validator_customization():

    surf = 1j

    # (A) custom error message (exception is still a ValidationError)
    with pytest.raises(ValidationError) as exc_info:
        with validator(
                'surface',
                surf,
                help_msg="Surface should be a finite positive integer") as v:
            v.alid = surf > 0 and isfinite(surf)
    e = exc_info.value
    assert str(e).startswith(
        "Surface should be a finite positive integer. Error validating [surface=1j]. "
        "InvalidType: Function [v.alid = surf > 0 and isfinite(surf)] raised "
        "TypeError:"
    )  # we do not provide the full string as it changes across python versions

    # (B) custom error types (recommended to provide unique applicative errors)
    class InvalidSurface(ValidationError):
        help_msg = 'Surface should be a positive integer'

    with pytest.raises(ValidationError) as exc_info:
        with validator('surface', surf, error_type=InvalidSurface) as v:
            v.alid = surf > 0 and isfinite(surf)
    e = exc_info.value
    assert isinstance(e, InvalidSurface)

    # (C) custom error types with templating
    class InvalidSurface(ValidationError):
        help_msg = 'Surface should be > {minimum}, found {var_value}'

    with pytest.raises(ValidationError) as exc_info:
        with validator('surface', surf, error_type=InvalidSurface,
                       minimum=0) as v:
            v.alid = surf > 0 and isfinite(surf)
    e = exc_info.value
    assert isinstance(e, InvalidSurface)
    assert str(e).startswith(
        "Surface should be > 0, found 1j. Error validating [surface=1j]. "
        "InvalidType: Function [v.alid = surf > 0 and isfinite(surf)] raised "
        "TypeError:")
Example #5
0
def with_validator(s):
    from valid8 import validator
    with validator('s', s, instance_of=str) as v:
        v.alid = (len(s) > 0) and s.islower()
Example #6
0
def test_readme_usage_customization():

    surf = -1

    # (A) custom error message (exception is still a ValidationError)
    # with pytest.raises(ValidationError) as exc_info:
    #     validate('surface', surf, instance_of=int, min_value=0,
    #                 help_msg="Surface should be a positive integer")
    # e = exc_info.value
    # assert str(e) == "Surface should be a positive integer. Error validating [surface=-1]. " \
    #                  "TooSmall: x >= 0 does not hold for x=-1. Wrong value: -1."

    # (A) custom error message (exception is still a ValidationError)
    with pytest.raises(ValidationError) as exc_info:
        with validator(
                'surface',
                surf,
                help_msg="Surface should be a finite positive integer") as v:
            v.alid = surf > 0 and isfinite(surf)
    e = exc_info.value
    assert str(e) == "Surface should be a finite positive integer. Error validating [surface=-1]. " \
                     "InvalidValue: Function [v.alid = surf > 0 and isfinite(surf)] returned [False] for value -1."

    # (B) custom error types (recommended to provide unique applicative errors)
    class InvalidSurface(ValidationError):
        help_msg = 'Surface should be a positive integer'

    with pytest.raises(ValidationError) as exc_info:
        validate('surface',
                 surf,
                 instance_of=int,
                 min_value=0,
                 error_type=InvalidSurface)
    e = exc_info.value
    assert isinstance(e, InvalidSurface)
    assert str(e) == "Surface should be a positive integer. " \
                     "Error validating [surface=-1]. " \
                     "TooSmall: x >= 0 does not hold for x=-1. Wrong value: -1."

    # (C) custom error types with templating
    class InvalidSurface(ValidationError):
        help_msg = 'Surface should be > {minimum}, found {var_value}'

    with pytest.raises(ValidationError) as exc_info:
        validate('surface',
                 surf,
                 instance_of=int,
                 min_value=0,
                 error_type=InvalidSurface,
                 minimum=0)
    e = exc_info.value
    assert isinstance(e, InvalidSurface)
    assert type(e).__name__ == "InvalidSurface[ValueError]"
    assert str(e) == "Surface should be > 0, found -1. Error validating [surface=-1]. " \
                     "TooSmall: x >= 0 does not hold for x=-1. Wrong value: -1."

    # (D) ValueError/TypeError
    with pytest.raises(ValidationError) as exc_info:
        validate('surface', -1, instance_of=int, min_value=0)
    e = exc_info.value
    assert str(
        e
    ) == "Error validating [surface=-1]. TooSmall: x >= 0 does not hold for x=-1. Wrong value: -1."
    assert repr(
        e.__class__
    ) == "<class 'valid8.entry_points.ValidationError[ValueError]'>"

    with pytest.raises(ValidationError) as exc_info:
        validate('surface', 1j, instance_of=int, min_value=0)
    e = exc_info.value
    assert repr(e.__class__
                ) == "<class 'valid8.entry_points.ValidationError[TypeError]'>"
def test_readme_examples_4():
    """ Tests that the example 4 provided in the documentation works (list of custom tuples) """

    l = [(1, 'ras'), (0.2, 'abc')]

    # ---- inline 1
    from valid8 import validate

    # first validate the main type
    validate('l', l, instance_of=list)

    for i, v in enumerate(l):
        # each item is a tuple of size 2
        validate('l[%s]' % i, l[i], instance_of=tuple, length=2)
        # the first element is a float between 0 and 1
        validate('l[%s][0]' % i,
                 l[i][0],
                 instance_of=Real,
                 min_value=0,
                 max_value=1)
        # the second element is a lowercase string of size 3
        validate('l[%s][1]' % i,
                 l[i][1],
                 instance_of=str,
                 length=3,
                 equals=l[i][1].lower())

    # ---- inline 2
    from valid8 import validator
    from valid8.validation_lib import instance_of

    l = [(1, 'ras'), (0.2, 'abc')]

    # all at once
    with validator('l', l, instance_of=list) as v:
        v.alid = all(
            # each item is a tuple of size 2
            instance_of(item, tuple) and len(item) == 2
            # the first element is a float between 0 and 1
            and instance_of(item[0], Real) and (0 <= item[0] <= 1)
            # the second element is a lowercase string of size 3
            and instance_of(item[1], str) and len(item[1]) == 3
            and item[1].islower() for item in l)

    # custom validation function
    def check_valid_tuple(tup):
        """ custom validation function - here in 'failure raiser' style (returning nothing) """

        # each item is a tuple of size 2
        if not isinstance(tup, tuple):
            raise TypeError('item should be a tuple')
        if len(tup) != 2:
            raise ValueError('tuple length should be 2')

        # the first element is a float between 0 and 1
        if not isinstance(tup[0], Real):
            raise TypeError('first element should be a Real')
        if not (0 <= tup[0] <= 1):
            raise ValueError('first element should be between 0 and 1')

        # the second element is a lowercase string of size 3
        if not isinstance(tup[1], str):
            raise TypeError('second element should be a string')
        if not (len(tup[1]) == 3 and tup[1].islower()):
            raise ValueError(
                'second element should be a lowercase string of length 3')

    from valid8 import validate, validation

    # first validate the main type
    validate('l', l, instance_of=list)

    # then validate (and use) the contents
    for i, v in enumerate(l):
        # each item is a valid tuple
        with validation('l[%s]' % i, l[i]):
            check_valid_tuple(l[i])

        # here you can actually USE the current item

    # ---- function input
    from valid8 import validate_arg, and_
    from valid8.validation_lib import instance_of, on_all_, on_each_, has_length, between

    @validate_arg(
        'l',
        instance_of(list),
        on_all_(
            instance_of(tuple),
            has_length(2),  # each item is a tuple of size 2
            on_each_(
                and_(instance_of(Real), between(
                    0, 1)),  # the first element is a float between 0 and 1
                and_(
                    instance_of(str), has_length(3)
                ),  # the 2d element is a string of len 3 BUT we cannot check lowercase
            )))
    def my_function(l):
        pass

    l = [(1, 'ras'), (0.2, 'aBc')]  # we cannot check lowercase
    my_function(l)

    # much better:
    from valid8 import validate_arg, ValidationFailure
    from valid8.validation_lib import instance_of, on_all_, HasWrongType, WrongLength, NotInRange

    def is_valid_tuple(t):
        """ Custom validation function. We could also provide a callable """

        # (a) each item is a tuple of size 2
        # --you can reuse an entire method from the built-in lib when it supports direct calling mode
        instance_of(t, tuple)
        # --otherwise you can reuse a failure class, there are many
        if len(t) != 2: raise WrongLength(t, ref_length=2)

        # (b) the first element is a float between 0 and 1
        if not isinstance(t[0], Real): raise HasWrongType(t[0], Real)
        if not (0 <= t[0] <= 1):
            raise NotInRange(t[0], min_value=0, max_value=1)

        # (c) the second element is a lowercase string of size 3
        instance_of(t[1], str)
        if len(t[1]) != 3: raise WrongLength(t[1], ref_length=3)
        # -- finally you can write custom ValidationFailure types
        if not t[1].islower():
            raise NotLowerCase(t[1])

    class NotLowerCase(ValidationFailure, ValueError):
        """ Example custom exception class used in custom validation function. `ValidationFailure` base class provides some
        mechanisms to easily build the help message (same mechanisms than ValidationError)"""
        help_msg = "Value is not a lowercase string: {wrong_value}"

    @validate_arg('l', instance_of(list), on_all_(is_valid_tuple))
    def my_function(l):
        pass

    l = [(1, 'ras'), (0.2, 'abc')]
    my_function(l)

    # ---- mini_lambda
    from valid8 import validate_arg
    from valid8.validation_lib import instance_of, on_all_

    # just for fun: we create our custom mini_lambda variable named 't'
    from mini_lambda import InputVar, Len, Isinstance
    t = InputVar('t', tuple)

    @validate_arg(
        'l',
        instance_of(list),
        on_all_(
            # each item is a tuple of size 2
            instance_of(tuple),
            Len(t) == 2,
            # the first element is a float between 0 and 1
            Isinstance(t[0], Real),
            (0 <= t[0]) & (t[0] <= 1),
            # the 2d element is a lowercase string of len 3
            Isinstance(t[1], str),
            Len(t[1]) == 3,
            t[1].islower()))
    def my_function(l):
        pass

    l = [(1, 'ras'), (0.2, 'abc')]
    my_function(l)
Example #8
0
def with_validator(x):
    from valid8 import validator
    with validator('x', x, instance_of=Integral) as v:
        v.alid = x >= 0
def inline_validator_custom_boolean(t, custom):
    from valid8 import validator
    with validator('t', t) as v:
        v.alid = custom(t)