-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
/
test_hypothesis_plugin.py
122 lines (99 loc) · 4.12 KB
/
test_hypothesis_plugin.py
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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
import typing
import pytest
import pydantic
from pydantic.networks import import_email_validator
try:
from hypothesis import HealthCheck, given, settings, strategies as st
except ImportError:
from unittest import mock
given = settings = lambda *a, **kw: (lambda f: f) # pass-through decorator
HealthCheck = st = mock.Mock()
pytestmark = pytest.mark.skipif(True, reason='"hypothesis" not installed')
def gen_models():
class MiscModel(pydantic.BaseModel):
# Each of these models contains a few related fields; the idea is that
# if there's a bug we have neither too many fields to dig through nor
# too many models to read.
obj: pydantic.PyObject
color: pydantic.color.Color
json_any: pydantic.Json
class StringsModel(pydantic.BaseModel):
card: pydantic.PaymentCardNumber
secbytes: pydantic.SecretBytes
secstr: pydantic.SecretStr
class UUIDsModel(pydantic.BaseModel):
uuid1: pydantic.UUID1
uuid3: pydantic.UUID3
uuid4: pydantic.UUID4
uuid5: pydantic.UUID5
class IPvAnyAddress(pydantic.BaseModel):
address: pydantic.IPvAnyAddress
class IPvAnyInterface(pydantic.BaseModel):
interface: pydantic.IPvAnyInterface
class IPvAnyNetwork(pydantic.BaseModel):
network: pydantic.IPvAnyNetwork
class StrictNumbersModel(pydantic.BaseModel):
strictbool: pydantic.StrictBool
strictint: pydantic.StrictInt
strictfloat: pydantic.StrictFloat
strictstr: pydantic.StrictStr
class NumbersModel(pydantic.BaseModel):
posint: pydantic.PositiveInt
negint: pydantic.NegativeInt
posfloat: pydantic.PositiveFloat
negfloat: pydantic.NegativeFloat
nonposint: pydantic.NonPositiveInt
nonnegint: pydantic.NonNegativeInt
nonposfloat: pydantic.NonPositiveFloat
nonnegfloat: pydantic.NonNegativeFloat
class JsonModel(pydantic.BaseModel):
json_int: pydantic.Json[int]
json_float: pydantic.Json[float]
json_str: pydantic.Json[str]
json_int_or_str: pydantic.Json[typing.Union[int, str]]
json_list_of_float: pydantic.Json[typing.List[float]]
json_pydantic_model: pydantic.Json[pydantic.BaseModel]
class ConstrainedNumbersModel(pydantic.BaseModel):
conintt: pydantic.conint(gt=10, lt=100)
coninte: pydantic.conint(ge=10, le=100)
conintmul: pydantic.conint(ge=10, le=100, multiple_of=7)
confloatt: pydantic.confloat(gt=10, lt=100)
confloate: pydantic.confloat(ge=10, le=100)
confloatemul: pydantic.confloat(ge=10, le=100, multiple_of=4.2)
confloattmul: pydantic.confloat(gt=10, lt=100, multiple_of=10)
condecimalt: pydantic.condecimal(gt=10, lt=100)
condecimale: pydantic.condecimal(ge=10, le=100)
condecimaltplc: pydantic.condecimal(gt=10, lt=100, decimal_places=5)
condecimaleplc: pydantic.condecimal(ge=10, le=100, decimal_places=2)
yield from (
MiscModel,
StringsModel,
UUIDsModel,
IPvAnyAddress,
IPvAnyInterface,
IPvAnyNetwork,
StrictNumbersModel,
NumbersModel,
JsonModel,
ConstrainedNumbersModel,
)
try:
import_email_validator()
except ImportError:
pass
else:
class EmailsModel(pydantic.BaseModel):
email: pydantic.EmailStr
name_email: pydantic.NameEmail
yield EmailsModel
@pytest.mark.parametrize('model', gen_models())
@settings(suppress_health_check={HealthCheck.too_slow}, deadline=None)
@given(data=st.data())
def test_can_construct_models_with_all_fields(data, model):
# The value of this test is to confirm that Hypothesis knows how to provide
# valid values for each field - otherwise, this would raise ValidationError.
instance = data.draw(st.from_type(model))
# We additionally check that the instance really is of type `model`, because
# an evil implementation could avoid ValidationError by means of e.g.
# `st.register_type_strategy(model, st.none())`, skipping the constructor.
assert isinstance(instance, model)