1
1
"""Tests for `cattrs.v.ensure`."""
2
2
import sys
3
- from typing import List , MutableSequence , Sequence
3
+ from typing import Dict , List , MutableSequence , Sequence
4
4
5
5
from pytest import fixture , mark , raises
6
6
7
7
from cattrs import BaseConverter
8
8
from cattrs ._compat import ExceptionGroup
9
+ from cattrs .errors import IterableValidationError
9
10
from cattrs .v import ensure
10
11
from cattrs .v ._hooks import is_validated , validator_factory
11
12
12
13
13
14
@fixture
14
15
def valconv (converter ) -> BaseConverter :
15
- converter .register_structure_hook_factory (is_validated )( validator_factory )
16
+ converter .register_structure_hook_factory (is_validated , validator_factory )
16
17
return converter
17
18
18
19
@@ -38,7 +39,7 @@ def test_ensured_lists(valconv: BaseConverter):
38
39
valconv .structure ([], ensure (List [int ], lambda lst : len (lst ) > 0 ))
39
40
40
41
if valconv .detailed_validation :
41
- assert isinstance (exc .value , ExceptionGroup )
42
+ assert isinstance (exc .value , IterableValidationError )
42
43
assert isinstance (exc .value .exceptions [0 ], ValueError )
43
44
else :
44
45
assert isinstance (exc .value , ValueError )
@@ -53,7 +54,53 @@ def test_ensured_list_elements(valconv: BaseConverter, type):
53
54
valconv .structure ([1 , - 2 ], ensure (type , elems = ensure (int , lambda i : i > 0 )))
54
55
55
56
if valconv .detailed_validation :
56
- assert isinstance (exc .value , ExceptionGroup )
57
+ assert isinstance (exc .value , IterableValidationError )
58
+ assert isinstance (exc .value .exceptions [0 ], ExceptionGroup )
59
+ assert isinstance (exc .value .exceptions [0 ].exceptions [0 ], ValueError )
60
+ else :
61
+ assert isinstance (exc .value , ValueError )
62
+
63
+ # Now both elements and the list itself.
64
+ assert valconv .structure (
65
+ [1 , 2 ],
66
+ ensure (type , lambda lst : len (lst ) < 3 , elems = ensure (int , lambda i : i > 0 )),
67
+ )
68
+
69
+ with raises (Exception ) as exc :
70
+ valconv .structure (
71
+ [1 , 2 , 3 ],
72
+ ensure (type , lambda lst : len (lst ) < 3 , elems = ensure (int , lambda i : i > 0 )),
73
+ )
74
+
75
+ if valconv .detailed_validation :
76
+ assert isinstance (exc .value , IterableValidationError )
77
+ assert isinstance (exc .value .exceptions [0 ], ValueError )
78
+ else :
79
+ assert isinstance (exc .value , ValueError )
80
+
81
+ with raises (Exception ) as exc :
82
+ valconv .structure (
83
+ [1 , - 2 ],
84
+ ensure (type , lambda lst : len (lst ) < 3 , elems = ensure (int , lambda i : i > 0 )),
85
+ )
86
+
87
+ if valconv .detailed_validation :
88
+ assert isinstance (exc .value , IterableValidationError )
89
+ assert isinstance (exc .value .exceptions [0 ], ExceptionGroup )
90
+ assert isinstance (exc .value .exceptions [0 ].exceptions [0 ], ValueError )
91
+ else :
92
+ assert isinstance (exc .value , ValueError )
93
+
94
+
95
+ def test_ensured_typing_list (valconv : BaseConverter ):
96
+ """Ensure works for typing lists."""
97
+ assert valconv .structure ([1 , 2 ], ensure (List , elems = ensure (int , lambda i : i > 0 )))
98
+
99
+ with raises (Exception ) as exc :
100
+ valconv .structure ([1 , - 2 ], ensure (List , elems = ensure (int , lambda i : i > 0 )))
101
+
102
+ if valconv .detailed_validation :
103
+ assert isinstance (exc .value , IterableValidationError )
57
104
assert isinstance (exc .value .exceptions [0 ], ExceptionGroup )
58
105
assert isinstance (exc .value .exceptions [0 ].exceptions [0 ], ValueError )
59
106
else :
@@ -63,13 +110,42 @@ def test_ensured_list_elements(valconv: BaseConverter, type):
63
110
@mark .skipif (sys .version_info [:2 ] < (3 , 10 ), reason = "Not supported on older Pythons" )
64
111
def test_ensured_list (valconv : BaseConverter ):
65
112
"""Ensure works for builtin lists."""
66
- assert valconv .structure ([1 , 2 ], ensure (List , elems = ensure (int , lambda i : i > 0 )))
113
+ assert valconv .structure ([1 , 2 ], ensure (list , elems = ensure (int , lambda i : i > 0 )))
67
114
68
115
with raises (Exception ) as exc :
69
- valconv .structure ([1 , - 2 ], ensure (List , elems = ensure (int , lambda i : i > 0 )))
116
+ valconv .structure ([1 , - 2 ], ensure (list , elems = ensure (int , lambda i : i > 0 )))
70
117
71
118
if valconv .detailed_validation :
72
- assert isinstance (exc .value , ExceptionGroup )
119
+ assert isinstance (exc .value , IterableValidationError )
120
+ assert isinstance (exc .value .exceptions [0 ], ExceptionGroup )
121
+ assert isinstance (exc .value .exceptions [0 ].exceptions [0 ], ValueError )
122
+ else :
123
+ assert isinstance (exc .value , ValueError )
124
+
125
+
126
+ def test_ensured_typing_dict (valconv : BaseConverter ):
127
+ """Ensure works for typing.Dicts."""
128
+ assert valconv .structure (
129
+ {"a" : 1 }, ensure (Dict , lambda d : len (d ) > 0 , keys = str , values = int )
130
+ )
131
+
132
+ with raises (Exception ) as exc :
133
+ valconv .structure ({}, ensure (Dict , lambda d : len (d ) > 0 , keys = str , values = int ))
134
+
135
+ if valconv .detailed_validation :
136
+ assert isinstance (exc .value , IterableValidationError )
137
+ assert isinstance (exc .value .exceptions [0 ], ValueError )
138
+ else :
139
+ assert isinstance (exc .value , ValueError )
140
+
141
+ with raises (Exception ) as exc :
142
+ valconv .structure (
143
+ {"b" : 1 , "c" : "a" },
144
+ ensure (Dict , keys = ensure (str , lambda s : s .startswith ("a" )), values = int ),
145
+ )
146
+
147
+ if valconv .detailed_validation :
148
+ assert isinstance (exc .value , IterableValidationError )
73
149
assert isinstance (exc .value .exceptions [0 ], ExceptionGroup )
74
150
assert isinstance (exc .value .exceptions [0 ].exceptions [0 ], ValueError )
75
151
else :
0 commit comments