File: test_validator.py

package info (click to toggle)
python-apischema 0.18.3-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,636 kB
  • sloc: python: 15,281; makefile: 3; sh: 2
file content (73 lines) | stat: -rw-r--r-- 2,020 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
from dataclasses import dataclass
from typing import Callable, Type

import pytest

from apischema import ValidationError, validator
from apischema.validation.mock import NonTrivialDependency, ValidatorMock
from apischema.validation.validators import Validator, get_validators, validate


@dataclass
class Data:
    a: int
    b: int
    c: int = 0

    @validator
    def a_gt_10(self):
        if self.a <= 10:
            yield "error"

    @validator
    def a_lt_100(self):
        if self.a >= 100:
            raise ValidationError("error2")

    @validator
    def non_trivial(self):
        non_trivial(self)


def non_trivial(data: Data):
    return data.c == data.b


def get_validators_by_method(cls: Type, method: Callable) -> Validator:
    return next(val for val in get_validators(cls) if val.func == method)


def test_get_validators():
    assert get_validators(Data) == [
        get_validators_by_method(Data, method)
        for method in (Data.a_gt_10, Data.a_lt_100, Data.non_trivial)
    ]


def test_validator_descriptor():
    # Class field is descriptor
    validator = get_validators_by_method(Data, Data.a_gt_10)
    assert validator.dependencies == {"a"}
    # Can be called from class and instance
    with pytest.raises(ValidationError):
        assert Data(200, 0).a_lt_100()
    with pytest.raises(ValidationError):
        assert Data.a_lt_100(Data(200, 0))


def test_validate():
    validate(Data(42, 0))
    with pytest.raises(ValidationError) as err:
        validate(Data(0, 0))
    assert err.value.errors == [{"loc": [], "err": "error"}]
    with pytest.raises(ValidationError) as err:
        validate(Data(200, 0))
    assert err.value.errors == [{"loc": [], "err": "error2"}]


def test_non_trivial():
    with pytest.raises(NonTrivialDependency) as err:
        validate(ValidatorMock(Data, {"a": 42}), get_validators(Data))
    # err.value.attr != "c" because `c` has a default value
    assert err.value.attr == "b"
    assert err.value.validator.func == Data.non_trivial