55from attrs import fields as f
66from pytest import fixture , raises
77
8- from cattrs import ClassValidationError , Converter
9- from cattrs .v import V , customize , transform_error
8+ from cattrs import BaseConverter , ClassValidationError , Converter
9+ from cattrs .v import V , customize , greater_than , transform_error
1010
1111
1212@fixture
13- def c () -> Converter :
14- """We need only converters with detailed_validation=True."""
15- res = Converter ()
16-
17- res .register_structure_hook (
13+ def c (converter : BaseConverter ) -> BaseConverter :
14+ converter .register_structure_hook (
1815 Union [str , int ], lambda v , _ : v if isinstance (v , int ) else str (v )
1916 )
2017
21- return res
18+ return converter
2219
2320
2421@define
@@ -91,12 +88,18 @@ def test_simple_string_validation(c: Converter) -> None:
9188
9289 unstructured = c .unstructure (instance )
9390
94- with raises (ClassValidationError ) as exc_info :
95- c .structure (unstructured , Model )
91+ if c .detailed_validation :
92+ with raises (ClassValidationError ) as exc_info :
93+ c .structure (unstructured , Model )
94+
95+ assert transform_error (exc_info .value ) == [
96+ "invalid value ('A' not lowercase) @ $.b"
97+ ]
98+ else :
99+ with raises (ValueError ) as exc_info :
100+ c .structure (unstructured , Model )
96101
97- assert transform_error (exc_info .value ) == [
98- "invalid value ('A' not lowercase) @ $.b"
99- ]
102+ assert repr (exc_info .value ) == "ValueError(\" 'A' not lowercase\" )"
100103
101104 instance .b = "a"
102105 assert instance == c .structure (c .unstructure (instance ), Model )
@@ -110,13 +113,51 @@ def test_multiple_string_validators(c: Converter) -> None:
110113
111114 unstructured = c .unstructure (instance )
112115
113- with raises (ClassValidationError ) as exc_info :
114- c .structure (unstructured , Model )
116+ if c .detailed_validation :
117+ with raises (ClassValidationError ) as exc_info :
118+ c .structure (unstructured , Model )
115119
116- assert transform_error (exc_info .value ) == [
117- "invalid value ('A' not lowercase) @ $.b" ,
118- "invalid value ('A' is not a valid email) @ $.b" ,
119- ]
120+ assert transform_error (exc_info .value ) == [
121+ "invalid value ('A' not lowercase) @ $.b" ,
122+ "invalid value ('A' is not a valid email) @ $.b" ,
123+ ]
124+ else :
125+ with raises (ValueError ) as exc_info :
126+ c .structure (unstructured , Model )
127+
128+ assert repr (exc_info .value ) == "ValueError(\" 'A' not lowercase\" )"
120129
121130 instance .b = "a@b"
122131 assert instance == c .structure (c .unstructure (instance ), Model )
132+
133+
134+ def test_multiple_field_validators (c : Converter ) -> None :
135+ """Multiple fields are validated."""
136+ customize (
137+ c ,
138+ Model ,
139+ V ((fs := f (Model )).a ).ensure (greater_than (5 )),
140+ V (fs .b ).ensure (is_lowercase ),
141+ )
142+
143+ instance = Model (5 , "A" , ["1" ], [1 ], "" , 0 , 0 , {"a" : 1 })
144+
145+ unstructured = c .unstructure (instance )
146+
147+ if c .detailed_validation :
148+ with raises (ClassValidationError ) as exc_info :
149+ c .structure (unstructured , Model )
150+
151+ assert transform_error (exc_info .value ) == [
152+ "invalid value (5 not greater than 5) @ $.a" ,
153+ "invalid value ('A' not lowercase) @ $.b" ,
154+ ]
155+ else :
156+ with raises (ValueError ) as exc_info :
157+ c .structure (unstructured , Model )
158+
159+ assert repr (exc_info .value ) == "ValueError('5 not greater than 5')"
160+
161+ instance .a = 6
162+ instance .b = "a"
163+ assert instance == c .structure (c .unstructure (instance ), Model )
0 commit comments