def test_simple_composition():
    test_obj = {"key1": "value1", "key2": "value2"}

    success_result = validate([("key1", always_true), ("key2", always_true)], test_obj)
    failure_result = validate([("key1", always_true), ("key2", always_false)], test_obj)
    assert bool(success_result) is True
    assert bool(failure_result) is False
def test_multilevel_composition():
    test_obj = {"key1": "value1", "key2": "value2"}

    success1_result = validate([("key1", always_true), always_true, ("key2", always_true), always_true], test_obj)

    success2_result = validate(
        [("key1", always_true, ("nested_key", always_true, always_true)), ("key2", always_true), always_true], test_obj
    )

    assert bool(success1_result) is True
    assert bool(success2_result) is True
def test_shopping_cart_first_item():
    validation_rules1 = (
        ('items', gl.type_(list),
         ('@first',
          ('price', gl.eq(1.34)))))
    result = gl.validate(validation_rules1, valid_test_data)
    assert result.success is True
def test_lazy_validation():
    test_obj = {"key1": "value1", "key2": "value2", "key3": None}
    result = validate(
        (("key1", always_true), ("key2", always_false), ("key3", super_lazy_validator1, super_lazy_validator2)),
        test_obj,
    )
    assert bool(result) is False
    assert result.ctx.get("super_lazy_called") == 1
def test_positive_result_from_bool_validation_ret_val():

    def test_validator(obj, selector, ctx):
        return True

    result = validate(test_validator, 'obj')
    assert isinstance(result, Success)
    assert result.error is None
def test_negative_result_from_bool_error_format_validation_ret_val():

    def test_validator(obj, selector, ctx):
        return False, 'error {msg}', {'msg': 'message'}

    result = validate(test_validator, 'obj')
    assert isinstance(result, Failure)
    assert result.error == 'error message'
def test_negative_result_from_bool_validation_ret_val():

    def test_validator(obj, selector, ctx):
        return False

    result = validate(test_validator, 'obj')
    assert isinstance(result, Failure)
    assert result.error == 'None'
def test_same_result_from_validationresult_ret_val():

    for ret_cls in (Success, Failure, Skip):

        ret_val = ret_cls(
            type_=ValidatorType.primitive,
            validator=lambda obj, selector, ctx: True,
            obj='obj',
            selector='test_selector',
            result=ret_cls is Success,
            msg='message' if ret_cls is Failure else None,
            ctx={})

        def test_validator(obj, selector, ctx):
            return ret_val

        result = validate(test_validator, 'obj')
        assert isinstance(result, ret_cls)
        assert result is ret_val
def test_shopping_cart_with_empty_data():
    result = gl.validate(validation_rules, {})
    assert result.success is False
def test_shopping_cart_with_valid_data():
    result = gl.validate(validation_rules, valid_test_data)
    assert result.success is True
def test_values_exists():
    test_obj = {"key1": "value1", "key2": "value2", "key3": None}
    result = validate((("key1", not_none), ("key2", not_none), ("key3", is_none)), test_obj)
    assert bool(result) is True
def test_comparison_operators_with_invalid_values():
    for validation_rules, test_object, error in _yield_test_data('invalid'):
        result = gl.validate(validation_rules, test_object)
        assert result.success is False
        assert error in result.errors[0][1]
def test_comparison_operators_with_valid_values():
    for validation_rules, test_object, _ in _yield_test_data('valid'):
        result = gl.validate(validation_rules, test_object)
        assert result.success is True