Coverage for pyfields/tests/test_so.py: 99%
126 statements
« prev ^ index » next coverage.py v7.2.7, created at 2023-11-06 16:35 +0000
« prev ^ index » next coverage.py v7.2.7, created at 2023-11-06 16:35 +0000
1# Authors: Sylvain Marie <sylvain.marie@se.com>
2#
3# Copyright (c) Schneider Electric Industries, 2019. All right reserved.
5import pytest
7from pyfields import ReadOnlyFieldError
8from valid8 import ValidationError
11def test_so0(capsys):
12 """ Checks answer at https://stackoverflow.com/a/58344434/7262247 """
14 from pyfields import field, init_fields
16 with capsys.disabled():
17 class C(object):
18 x = field(default=None, doc="the optional 'x' property")
19 y = field(doc="the mandatory 'y' property")
20 z = field(doc="the mandatory 'z' property")
22 @init_fields
23 def __init__(self):
24 pass
26 c = C(y=1, z=2)
27 print(vars(c))
29 with capsys.disabled():
30 out, err = capsys.readouterr()
31 print(out)
32 # assert out == """{'y': 1, 'x': None, 'z': 2}\n"""
33 assert vars(c) == {'y': 1, 'x': None, 'z': 2}
36def test_so1(capsys):
37 """ Checks answer at https://stackoverflow.com/a/58344853/7262247 """
39 from pyfields import field, init_fields
41 class Account(object):
42 first = field(doc="first name")
43 last = field(doc="last name")
44 age = field(doc="the age in years")
45 id = field(doc="an identifier")
46 balance = field(doc="current balance in euros")
48 @init_fields
49 def __init__(self, msg):
50 print(msg)
52 a = Account("hello, world!", first="s", last="marie", age=135, id=0, balance=-200000)
53 print(vars(a))
54 with capsys.disabled():
55 out, err = capsys.readouterr()
56 print(out)
57 assert out.splitlines()[0] == "hello, world!"
58 assert vars(a) == {'age': 135, 'balance': -200000, 'last': 'marie', 'id': 0, 'first': 's'}
61def test_so2():
62 """ Checks that answer at https://stackoverflow.com/a/58383062/7262247 is ok """
64 from pyfields import field
66 class Position(object):
67 x = field(validators=lambda x: x > 0)
68 y = field(validators={'y should be between 0 and 100': lambda y: y > 0 and y < 100})
70 p = Position()
71 p.x = 1
72 with pytest.raises(ValidationError) as exc_info:
73 p.y = 101
74 qualname = Position.y.qualname
75 assert str(exc_info.value) == "Error validating [%s=101]. " \
76 "InvalidValue: y should be between 0 and 100. " \
77 "Function [<lambda>] returned [False] for value 101." % qualname
80def test_so3():
81 """https://stackoverflow.com/a/58391645/7262247"""
83 from pyfields import field
85 class Spam(object):
86 description = field(validators={"description can not be empty": lambda s: len(s) > 0})
87 value = field(validators={"value must be greater than zero": lambda x: x > 0}) 87 ↛ exitline 87 didn't run the lambda on line 87
89 s = Spam()
90 with pytest.raises(ValidationError) as exc_info:
91 s.description = ""
92 qualname = Spam.description.qualname
93 assert str(exc_info.value) == "Error validating [%s='']. " \
94 "InvalidValue: description can not be empty. " \
95 "Function [<lambda>] returned [False] for value ''." % qualname
98def test_so4():
99 """check https://stackoverflow.com/a/58394381/7262247"""
101 from pyfields import field, init_fields
102 from valid8.validation_lib import is_in
104 ALLOWED_COLORS = ('blue', 'yellow', 'brown')
106 class Car(object):
107 """ My class with many fields """
108 color = field(type_hint=str, check_type=True, validators=is_in(ALLOWED_COLORS))
109 name = field(type_hint=str, check_type=True, validators={'should be non-empty': lambda s: len(s) > 0})
110 wheels = field(type_hint=int, check_type=True, validators={'should be positive': lambda x: x > 0})
112 @init_fields
113 def __init__(self, msg="hello world!"):
114 print(msg)
116 c = Car(color='blue', name='roadie', wheels=3)
117 assert vars(c) == {'_wheels': 3, '_name': 'roadie', '_color': 'blue'}
119 qualname = Car.wheels.qualname
121 with pytest.raises(TypeError) as exc_info:
122 c.wheels = 'hello'
123 assert str(exc_info.value) == "Invalid value type provided for '%s'. " \
124 "Value should be of type %r. " \
125 "Instead, received a 'str': 'hello'" % (qualname, int)
127 with pytest.raises(ValidationError) as exc_info:
128 c.wheels = 0
129 assert str(exc_info.value) == "Error validating [%s=0]. " \
130 "InvalidValue: should be positive. " \
131 "Function [<lambda>] returned [False] for value 0." % qualname
134def test_so5():
135 """https://stackoverflow.com/a/58395677/7262247"""
137 from pyfields import field, copy_value, init_fields
138 from valid8.validation_lib import is_in
140 class Well(object):
141 name = field() # Required
142 group = field() # Required
143 operate_list = field(default_factory=copy_value([])) # Optional
144 monitor_list = field(default_factory=copy_value([])) # Optional
145 geometry = field(default=None) # Optional
146 perf = field(default=None) # Optional
148 valid_types = ('type_A', 'type_B')
150 class Operate(object):
151 att = field() # Required
152 type_ = field(type_hint=str, check_type=True, validators=is_in(valid_types)) # Required
153 value = field(default_factory=copy_value([])) # Optional
154 mode = field(default=None) # Optional
155 action = field(default=None) # Optional
157 @init_fields
158 def __init__(self):
159 pass
161 o = Operate(att="foo", type_='type_A')
163 with pytest.raises(TypeError):
164 o.type_ = 1 # <-- raises TypeError: Invalid value type provided
166 with pytest.raises(ValidationError):
167 bad_o = Operate(att="foo", type_='type_WRONG') # <-- raises ValidationError: NotInAllowedValues: x in ('type_A', 'type_B') does not hold for x=type_WRONG
170def test_so6():
171 """checks that answer at https://stackoverflow.com/a/58396678/7262247 works"""
172 from pyfields import field, init_fields
174 class Position(object):
175 x = field(type_hint=int, check_type=True, validators=lambda x: x > 0)
176 y = field(type_hint=int, check_type=True, validators={'y should be between 0 and 100': lambda y: y > 0 and y < 100})
178 @init_fields
179 def __init__(self, msg="hello world!"):
180 print(msg)
182 p = Position(x=1, y=12)
183 with pytest.raises(TypeError) as exc_info:
184 p.x = '1'
185 qualname = Position.x.qualname
186 assert str(exc_info.value) == "Invalid value type provided for '%s'. " \
187 "Value should be of type %r. Instead, received a 'str': '1'" % (qualname, int)
189 with pytest.raises(ValidationError) as exc_info:
190 p.y = 101
193def test_so7():
194 """ checks answer at https://stackoverflow.com/a/58432813/7262247 """
196 from pyfields import field
198 class User(object):
199 username = field(read_only=True, validators={'should contain more than 2 characters': lambda s: len(s) > 2})
201 u = User()
202 u.username = "earthling"
203 assert vars(u) == {'_username': "earthling"}
204 with pytest.raises(ReadOnlyFieldError) as exc_info:
205 u.username = "earthling2"
206 qualname = User.username.qualname
207 assert str(exc_info.value) == "Read-only field '%s' has already been initialized on instance %s and cannot be " \
208 "modified anymore." % (qualname, u)