99 get_origin ,
1010 Mapping ,
1111 TYPE_CHECKING ,
12+ Literal ,
1213)
1314from unittest import TestCase
1415
@@ -27,6 +28,20 @@ class UselessContainer(ValueConstructible):
2728 pass
2829
2930
31+ @dataclass ()
32+ class RequiredPropsContainer (MappingConstructible ):
33+ x : float
34+ y : float
35+ z : float
36+
37+
38+ class NoTypesContainer (MappingConstructible ):
39+ def __init__ (self , u , v , w ):
40+ self .u = u
41+ self .v = v
42+ self .w = w
43+
44+
3045@dataclass ()
3146class SimpleTypesContainer (MappingConstructible , JsonSerializable ):
3247 a : Any = None
@@ -35,6 +50,7 @@ class SimpleTypesContainer(MappingConstructible, JsonSerializable):
3550 d : float = 0.0
3651 e : str = "abc"
3752 f : type = int
53+ g : Literal [0 , 1 , True , False , "on" , "off" ] = 0
3854
3955
4056@dataclass ()
@@ -52,20 +68,6 @@ class UnionTypesContainer(MappingConstructible, JsonSerializable):
5268 m : SimpleTypesContainer | ComplexTypesContainer | None = None
5369
5470
55- @dataclass ()
56- class RequiredPropsContainer (MappingConstructible , JsonSerializable ):
57- x : float
58- y : float
59- z : float
60-
61-
62- @dataclass ()
63- class NoTypesContainer (MappingConstructible , JsonSerializable ):
64- u = 0
65- v = 0
66- w = 0
67-
68-
6971if TYPE_CHECKING :
7072 # make IDEs and flake8 happy
7173 from xrlint .rule import RuleConfig
@@ -122,13 +124,29 @@ def test_assumptions(self):
122124class JsonSerializableTest (TestCase ):
123125 def test_simple_ok (self ):
124126 self .assertEqual (
125- {"a" : None , "b" : False , "c" : 0 , "d" : 0.0 , "e" : "abc" , "f" : "int" },
127+ {
128+ "a" : None ,
129+ "b" : False ,
130+ "c" : 0 ,
131+ "d" : 0.0 ,
132+ "e" : "abc" ,
133+ "f" : "<class 'int'>" ,
134+ "g" : 0 ,
135+ },
126136 SimpleTypesContainer ().to_json (),
127137 )
128138 self .assertEqual (
129- {"a" : "?" , "b" : True , "c" : 12 , "d" : 34.56 , "e" : "uvw" , "f" : "bool" },
139+ {
140+ "a" : "?" ,
141+ "b" : True ,
142+ "c" : 12 ,
143+ "d" : 34.56 ,
144+ "e" : "uvw" ,
145+ "f" : "<class 'bool'>" ,
146+ "g" : "off" ,
147+ },
130148 SimpleTypesContainer (
131- a = "?" , b = True , c = 12 , d = 34.56 , e = "uvw" , f = bool
149+ a = "?" , b = True , c = 12 , d = 34.56 , e = "uvw" , f = bool , g = "off"
132150 ).to_json (),
133151 )
134152
@@ -144,7 +162,15 @@ def test_complex_ok(self):
144162 )
145163 self .assertEqual (
146164 {
147- "p" : {"a" : None , "b" : False , "c" : 0 , "d" : 0.0 , "e" : "abc" , "f" : "int" },
165+ "p" : {
166+ "a" : None ,
167+ "b" : False ,
168+ "c" : 0 ,
169+ "d" : 0.0 ,
170+ "e" : "abc" ,
171+ "f" : "<class 'int'>" ,
172+ "g" : 0 ,
173+ },
148174 "q" : {"p" : True , "q" : False },
149175 "r" : {
150176 "u" : {
@@ -153,27 +179,38 @@ def test_complex_ok(self):
153179 "c" : 0 ,
154180 "d" : 0.0 ,
155181 "e" : "abc" ,
156- "f" : "int" ,
182+ "f" : "<class 'int'>" ,
183+ "g" : 0 ,
157184 },
158185 "v" : {
159186 "a" : None ,
160187 "b" : False ,
161188 "c" : 0 ,
162189 "d" : 0.0 ,
163190 "e" : "abc" ,
164- "f" : "int" ,
191+ "f" : "<class 'int'>" ,
192+ "g" : 0 ,
165193 },
166194 },
167195 "s" : [1 , 2 , 3 ],
168196 "t" : [
169- {"a" : None , "b" : False , "c" : 5 , "d" : 6.7 , "e" : "abc" , "f" : "int" },
197+ {
198+ "a" : None ,
199+ "b" : False ,
200+ "c" : 5 ,
201+ "d" : 6.7 ,
202+ "e" : "abc" ,
203+ "f" : "<class 'int'>" ,
204+ "g" : 0 ,
205+ },
170206 {
171207 "a" : None ,
172208 "b" : False ,
173209 "c" : 8 ,
174210 "d" : 9.1 ,
175211 "e" : "abc" ,
176- "f" : "SimpleTypesContainer" ,
212+ "f" : "<class 'tests.util.test_codec.SimpleTypesContainer'>" ,
213+ "g" : 0 ,
177214 },
178215 ],
179216 "u" : None ,
@@ -193,7 +230,7 @@ class Problematic(JsonSerializable):
193230 " None|bool|int|float|str|dict|list|tuple, but got object"
194231 ),
195232 ):
196- Problematic (data = object ()).to_json (name = "problematic" )
233+ Problematic (data = object ()).to_json (value_name = "problematic" )
197234
198235
199236class ValueConstructibleTest (TestCase ):
@@ -263,11 +300,32 @@ def test_useless_fail(self):
263300 ):
264301 UselessContainer .from_value (UselessContainer , value_name = "utc" )
265302
303+ def test_required_props_ok (self ):
304+ rpc = RequiredPropsContainer .from_value ({"x" : 12.0 , "y" : 23.0 , "z" : 34.0 })
305+ self .assertEqual (RequiredPropsContainer (x = 12.0 , y = 23.0 , z = 34.0 ), rpc )
306+
307+ # noinspection PyMethodMayBeStatic
308+ def test_required_props_fail (self ):
309+ with pytest .raises (
310+ TypeError ,
311+ match = (
312+ r"missing value for required property rpc.y"
313+ r" of type RequiredPropsContainer \| dict\[str, Any\]"
314+ ),
315+ ):
316+ RequiredPropsContainer .from_value ({"x" : 12.0 , "z" : 34.0 }, "rpc" )
317+
318+ def test_no_types_ok (self ):
319+ ntc = NoTypesContainer .from_value (dict (u = True , v = 654 , w = "abc" ))
320+ self .assertEqual (True , ntc .u )
321+ self .assertEqual (654 , ntc .v )
322+ self .assertEqual ("abc" , ntc .w )
323+
266324
267325class MappingConstructibleTest (TestCase ):
268326
269327 def test_simple_ok (self ):
270- kwargs = dict (a = "?" , b = True , c = 12 , d = 34.56 , e = "uvw" , f = bytes )
328+ kwargs = dict (a = "?" , b = True , c = 12 , d = 34.56 , e = "uvw" , f = bytes , g = "on" )
271329 container = SimpleTypesContainer (** kwargs )
272330 self .assertEqual (container , SimpleTypesContainer .from_value (kwargs ))
273331 self .assertIs (container , SimpleTypesContainer .from_value (container ))
@@ -339,6 +397,12 @@ def test_simple_fail(self):
339397 ):
340398 SimpleTypesContainer .from_value ({"b" : None }, value_name = "stc" )
341399
400+ with pytest .raises (
401+ TypeError ,
402+ match = r"stc.g must be one of 0, 1, True, False, 'on', 'off', but got 74" ,
403+ ):
404+ SimpleTypesContainer .from_value ({"g" : 74 }, value_name = "stc" )
405+
342406 with pytest .raises (
343407 TypeError , match = "x is not a member of stc of type SimpleTypesContainer"
344408 ):
@@ -439,6 +503,7 @@ def test_resolves_types(self):
439503 "d" ,
440504 "e" ,
441505 "f" ,
506+ "g" ,
442507 "p" ,
443508 "q" ,
444509 "r" ,
0 commit comments