Skip to content

Commit 264ce7f

Browse files
committed
more tests
1 parent 28ed9bd commit 264ce7f

File tree

1 file changed

+97
-2
lines changed

1 file changed

+97
-2
lines changed

tests/validators/test_recursive.py

+97-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
from typing import Optional
22

33
import pytest
4-
from dirty_equals import IsPartialDict
4+
from dirty_equals import IsList, IsPartialDict
55

66
from pydantic_core import SchemaError, SchemaValidator, ValidationError
77

8+
from ..conftest import Err
9+
810

911
def test_branch_nullable():
1012
v = SchemaValidator(
@@ -234,7 +236,7 @@ def test_outside_parent():
234236
}
235237

236238

237-
def test_recursion():
239+
def test_recursion_branch():
238240
v = SchemaValidator(
239241
{
240242
'type': 'typed-dict',
@@ -266,3 +268,96 @@ def test_recursion():
266268
'input_value': {'name': 'recursive', 'branch': IsPartialDict(name='recursive')},
267269
}
268270
]
271+
272+
273+
def test_recursive_list():
274+
v = SchemaValidator(
275+
{'type': 'list', 'ref': 'the-list', 'items_schema': {'type': 'recursive-ref', 'schema_ref': 'the-list'}}
276+
)
277+
assert v.validate_python([]) == []
278+
assert v.validate_python([[]]) == [[]]
279+
280+
data = list()
281+
data.append(data)
282+
with pytest.raises(ValidationError, match='Recursion error - cyclic reference detected'):
283+
assert v.validate_python(data)
284+
285+
286+
@pytest.fixture(scope='module')
287+
def multiple_tuple_schema():
288+
return SchemaValidator(
289+
{
290+
'type': 'typed-dict',
291+
'fields': {
292+
'f1': {
293+
'schema': {
294+
'type': 'tuple-fix-len',
295+
'ref': 't',
296+
'items_schema': [
297+
{'type': 'int'},
298+
{'type': 'nullable', 'schema': {'type': 'recursive-ref', 'schema_ref': 't'}},
299+
],
300+
}
301+
},
302+
'f2': {
303+
'schema': {'type': 'nullable', 'schema': {'type': 'recursive-ref', 'schema_ref': 't'}},
304+
'default': None,
305+
},
306+
},
307+
}
308+
)
309+
310+
311+
@pytest.mark.parametrize(
312+
'input_value,expected',
313+
[
314+
({'f1': [1, None]}, {'f1': (1, None), 'f2': None}),
315+
({'f1': [1, None], 'f2': [2, None]}, {'f1': (1, None), 'f2': (2, None)}),
316+
(
317+
{'f1': [1, (3, None)], 'f2': [2, (4, (4, (5, None)))]},
318+
{'f1': (1, (3, None)), 'f2': (2, (4, (4, (5, None))))},
319+
),
320+
({'f1': [1, 2]}, Err(r'f1 -> 1\s+Value must be a valid tuple')),
321+
(
322+
{'f1': [1, (3, None)], 'f2': [2, (4, (4, (5, 6)))]},
323+
Err(r'f2 -> 1 -> 1 -> 1 -> 1\s+Value must be a valid tuple'),
324+
),
325+
],
326+
)
327+
def test_multiple_tuple_param(multiple_tuple_schema, input_value, expected):
328+
if isinstance(expected, Err):
329+
with pytest.raises(ValidationError, match=expected.message):
330+
multiple_tuple_schema.validate_python(input_value)
331+
# debug(repr(exc_info.value))
332+
else:
333+
assert multiple_tuple_schema.validate_python(input_value) == expected
334+
335+
336+
def test_multiple_tuple_repeat(multiple_tuple_schema):
337+
t = (42, None)
338+
assert multiple_tuple_schema.validate_python({'f1': (1, t), 'f2': (2, t)}) == {
339+
'f1': (1, (42, None)),
340+
'f2': (2, (42, None)),
341+
}
342+
343+
344+
def test_multiple_tuple_recursion(multiple_tuple_schema):
345+
data = [1]
346+
data.append(data)
347+
with pytest.raises(ValidationError) as exc_info:
348+
multiple_tuple_schema.validate_python({'f1': data, 'f2': data})
349+
350+
assert exc_info.value.errors() == [
351+
{
352+
'kind': 'recursion_loop',
353+
'loc': ['f1', 1],
354+
'message': 'Recursion error - cyclic reference detected',
355+
'input_value': [1, IsList(length=2)],
356+
},
357+
{
358+
'kind': 'recursion_loop',
359+
'loc': ['f2', 1],
360+
'message': 'Recursion error - cyclic reference detected',
361+
'input_value': [1, IsList(length=2)],
362+
},
363+
]

0 commit comments

Comments
 (0)