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)
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 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 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_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_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_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_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_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_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_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_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_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_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(): """ 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_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_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_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_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 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_and(): """ Object: Tests that And function works """ x = InputVar('x', int) with pytest.raises(FunctionDefinitionError): x > 5 and x < 10 r = And(x > 5, x < 10) r = r.as_function() assert not r(5) assert r(6) assert r(9) assert not r(10)
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)