def test_evaluator_different_vars():
    """ Tests that two different variables cannot be used in the same expression, even with the same symbol """
    a = InputVar('x', int)
    b = InputVar('x', int)

    with pytest.raises(FunctionDefinitionError):
        a + b

    with pytest.raises(FunctionDefinitionError):
        a - b

    with pytest.raises(FunctionDefinitionError):
        a * b

    with pytest.raises(FunctionDefinitionError):
        a**b

    with pytest.raises(FunctionDefinitionError):
        a > b

    with pytest.raises(FunctionDefinitionError):
        a == b

    with pytest.raises(FunctionDefinitionError):
        divmod(a, b)

    with pytest.raises(FunctionDefinitionError):
        a[b]

    with pytest.raises(FunctionDefinitionError):
        # getattr(a, b)  # getattr(): attribute name must be string
        a.__getattr__(b)
Example #2
0
def inline_validate_3(s):
    from valid8 import validate
    # we create a custom mini_lambda variable, since the name 's' is already used
    from mini_lambda import InputVar

    txt = InputVar('txt', str)
    validate('s', s, instance_of=str, min_len=1, custom=txt.islower())
def test_doc_usage_input_variables():
    """ Tests that the examples in doc/usage in the input variables section work """

    from mini_lambda import InputVar
    t = InputVar('t')

    import pandas as pd
    df = InputVar('df', pd.DataFrame)
def test_evaluator_nonexistent_attribute_2():
    """ Object: Tests that a valid evaluator accessing a nonexistent attribute will behave as expected and raise the
    appropriate exception when evaluated """

    li = InputVar('l', list)
    first_elt_test = li.toto()
    first_elt_test = first_elt_test.as_function()

    with pytest.raises(AttributeError):
        first_elt_test([
            1, 0, 0
        ])  # AttributeError: 'list_iterator' object has no attribute 'next'
def test_evaluator_container():
    """ Container Object : tests that `1 in x` raises the correct error message and that the equivalent x.contains()
    works """

    x = InputVar('l', list)

    with pytest.raises(FunctionDefinitionError):
        is_one_in = 1 in x

    is_one_in = x.contains(1)
    is_one_in = is_one_in.as_function()

    assert is_one_in([0, 1, 2])
    assert not is_one_in([0, 0, 0])
def class_field_mini_lambda(value):
    from mini_lambda import InputVar, Len
    from valid8 import validate_field
    from valid8.validation_lib import instance_of
    from valid8.validation_lib.mini_lambda_ import Instance_of

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

    @validate_field(
        't',
        instance_of(tuple),
        Len(t) == 2,
        # the first element is a float between 0 and 1
        Instance_of(t[0], Real),
        (0 <= t[0]) & (t[0] <= 1),
        # the 2d element is a lowercase string of len 3
        Instance_of(t[1], str),
        Len(t[1]) == 3,
        t[1].islower())
    class Foo:
        def __init__(self, t):
            self.s = t

    Foo(value)
def test_evaluator_print_pow():
    """ Asserts that operator precedence is correctly handled in the case of the power operator which is a bit
    special, see https://docs.python.org/3/reference/expressions.html#id16 """

    x = InputVar('x', int)
    po = -x**-x
    assert po.to_string() == '-x ** -x'  # and not -x ** (-x)
def test_evaluator_comprehension():
    """ List Comprehension : tests that `[i for i in li]` is forbidden and raises the appropriate exception """

    li = InputVar('li', list)

    with pytest.raises(FunctionDefinitionError):
        a = [i for i in li]
def test_evaluator_list_slice():
    """ Mapping Container Object : tests that slicing with `x[i]` works"""

    l = InputVar('l', list)

    items_selector = l[0:2]
    items_selector = items_selector.as_function()

    assert items_selector([1, 2, 3]) == [1, 2]
def test_evaluator_iterator_iterable():
    """ Iterable + Iterator: tests that `next(Iter(li))` leads to a valid evaluator"""

    li = InputVar('li', list)
    first_elt_accessor = next(Iter(li))
    first_elt_accessor = first_elt_accessor.as_function()

    assert first_elt_accessor([True, False, False])
    assert not first_elt_accessor([False, True])
def test_evaluator_reversible():
    """ Reversible Container Object : tests that `reversed(x)` works """

    x = InputVar('l', list)

    reversed_x = reversed(x)
    reversed_x = reversed_x.as_function()

    assert list(reversed_x([0, 1, 2])) == [2, 1, 0]
def test_evaluator_complex_1():
    """ A complex case with a combination of Repr, Len, and comparisons """

    s = InputVar('s', str)

    reasonable_string = Repr((2 <= Len(s)) & (Len(s) < 3))
    reasonable_string = reasonable_string.as_function()

    assert reasonable_string('r') == 'False'
def test_evaluator_iterable_iterator_and_comparison():
    """ Iterable + Iterator + Comparable : A complex case where the evaluator is `next(Iter(li)) > 0` """

    li = InputVar('li', list)

    first_elt_test = (next(Iter(li)) > 0)
    first_elt_test = first_elt_test.as_function()

    assert first_elt_test([1, 0, 0])
    assert not first_elt_test([0, 0, 0])
def test_evaluator_comparable_both_evaluators():
    """ Tests that it works when the first function is not a function converted to mini_lambda """

    x = InputVar('x', Real)

    hard_validation = +x > x**2
    hard_validation = hard_validation.as_function()

    assert hard_validation(0.01)
    assert not hard_validation(1)
def test_evaluator_comparable_normal_function_first():
    """ Tests that the comparison operators works between a function and an evaluator """

    x = InputVar('x', Real)

    hard_validation = cos > x
    hard_validation = hard_validation.as_function()

    assert hard_validation(0.1)
    assert not hard_validation(2)
def test_evaluator_format():
    """ Representable Object : tests that format() works """

    s = InputVar('s', str)

    # the str operator cannot be overloaded
    formatted_string = s.format('yes')
    formatted_string = formatted_string.as_function()

    assert formatted_string('{}') == 'yes'

    # the str operator cannot be overloaded
    with pytest.raises(FunctionDefinitionError):
        '{} {}'.format(s, s)

    # so we provide this equivalent
    reasonable_string = Format('{} {}', s, s)
    reasonable_string = reasonable_string.as_function()

    assert reasonable_string('hello') == 'hello hello'
def test_evaluator_sized():
    """ Sized Container Object: tests that len() raises the appropriate error but that the equivalent Len() works """

    s = InputVar('s', str)

    with pytest.raises(FunctionDefinitionError):
        len(s)

    string_length = Len(s)
    string_length = string_length.as_function()

    assert string_length('tho') == 3
def test_evaluator_iterable():
    """ Iterable: tests that `Iter(li)` leads to a valid evaluator and `iter(li)` raises an exception"""

    li = InputVar('li', list)

    with pytest.raises(FunctionDefinitionError):
        basic_evaluator = iter(li)

    basic_evaluator = Iter(li)
    basic_evaluator = basic_evaluator.as_function()

    assert type(basic_evaluator([0, 1])).__name__ == 'list_iterator'
def test_evaluator_mapping_key():
    """ Mapping key Object : tests that dict[s] raises an exception but the workaround works"""

    s = InputVar('s', str)

    with pytest.raises(FunctionDefinitionError):
        {'a': 1}[s]

    item_s_selector = Get({'a': 1}, s)
    item_s_selector = item_s_selector.as_function()

    assert item_s_selector('a') == 1
def test_evaluator_iterable_all():
    """ Iterable + all operator: Checks that the all operator  raises an exception but that the All replacement function
    works """

    li = InputVar('li', list)

    with pytest.raises(FunctionDefinitionError):
        all(li)

    all_is_true = _(All(li))
    assert all_is_true([True, True, True])
    assert not all_is_true([False, True, False])
def test_evaluator_int_convertible():
    """ Int convertible Object : tests that `int` raises the appropriate exception and that equivalent Int() works """

    s = InputVar('x', float)

    with pytest.raises(FunctionDefinitionError):
        int(s)

    to_int = Int(s)
    to_int = to_int.as_function()

    assert to_int(5.5) == 5
def test_evaluator_hashable():
    """ Hashable Object : tests that hash() raises the correct error message and that the equivalent Hash() works """

    x = InputVar('x', float)

    with pytest.raises(FunctionDefinitionError):
        hash(x)

    h = Hash(x)
    h = h.as_function()

    assert h(5.2) == hash(5.2)
    assert h('nkl,m;@\'') == hash('nkl,m;@\'')
def test_evaluator_oct_convertible():
    """ oct convertible Object : tests that `oct` raises the appropriate exception and that equivalent Oct()
    works """

    s = InputVar('x', int)

    with pytest.raises(FunctionDefinitionError):
        oct(s)

    to_octal = Oct(s)
    to_octal = to_octal.as_function()

    assert to_octal(55) == '0o67'
def test_evaluator_float_convertible():
    """ Float convertible Object : tests that `float` raises the appropriate exception and that equivalent Float()
    works """

    s = InputVar('x', int)

    with pytest.raises(FunctionDefinitionError):
        float(s)

    to_float = Float(s)
    to_float = to_float.as_function()

    assert to_float(5) == 5.0
def test_evaluator_long_convertible():
    """ Long convertible Object : tests that `long` raises the appropriate exception and that equivalent Long()
    works """

    s = InputVar('x', float)

    # with pytest.raises(FunctionDefinitionError):
    #     int(s)

    to_long = long(s)
    to_long = to_long.as_function()

    assert to_long(5.5) == 5
def test_evaluator_numeric():
    """ Numeric-like Object : tests that +,-,*,/,%,divmod(),pow(),**,@,//,<<,>>,-,+,abs,~ work """

    x = InputVar('x', int)

    add_one = _(x + 1)
    assert add_one(1) == 2

    remove_one = _(x - 1)
    assert remove_one(1) == 0

    times_two = _(x * 2)
    assert times_two(1) == 2

    div_two = _(x / 2)
    assert div_two(1) == 0.5

    neg = _(x % 2)
    assert neg(3) == 1

    pos = _(divmod(x, 3))
    assert pos(16) == (5, 1)

    pow_two = _(x**2)
    assert pow_two(2) == 4

    pow_two = _(pow(x, 2))
    assert pow_two(2) == 4

    # TODO matmul : @...

    floor_div_two = _(x // 2)
    assert floor_div_two(1) == 0

    lshift_ = _(256 << x)
    assert lshift_(1) == 512

    rshift_ = _(256 >> x)
    assert rshift_(1) == 128

    neg = _(-x)
    assert neg(3) == -3

    pos = _(+x)
    assert pos(-16) == -16

    abs_ = _(abs(x))
    assert abs_(-22) == 22

    inv = _(~x)
    assert inv(2) == -3
def test_evaluator_truth_testable_not():
    """ Truth-Testable Object : tests that not x raises the correct error message and that the equivalent x.not_()
    works. """

    x = InputVar('x', float)

    with pytest.raises(FunctionDefinitionError):
        not x

    h = Not(x)
    h = h.as_function()

    assert h(0)
    assert not h(5.2)
def test_evaluator_complex_convertible():
    """ Complex convertible Object : tests that `complex` raises the appropriate exception and that equivalent
    Complex_() works """

    s = InputVar('x', int)

    with pytest.raises(FunctionDefinitionError):
        complex(s)

    to_cpx = Complex(s)
    to_cpx = to_cpx.as_function()

    assert to_cpx(5) == 5 + 0j
    assert to_cpx('5+1j') == 5 + 1j
def test_evaluator_str():
    """ Representable Object : tests that str() raises the correct error message and that the equivalent Str() works """

    s = InputVar('s', str)

    # the str operator cannot be overloaded
    with pytest.raises(FunctionDefinitionError):
        str(s)

    # so we provide this equivalent
    reasonable_string = Str(s)
    reasonable_string = reasonable_string.as_function()

    assert reasonable_string(1) == '1'
def test_evaluator_logical_or():
    """ Object: Tests that Or function works """

    x = InputVar('x', int)

    with pytest.raises(FunctionDefinitionError):
        x < 5 or x > 10

    r = Or(x < 5, x > 10)
    r = r.as_function()

    assert r(4)
    assert not r(5)
    assert not r(10)
    assert r(11)