|
| 1 | +import pytest |
| 2 | + |
| 3 | +from pydantic_core import ValidationError |
| 4 | + |
| 5 | +from .conftest import PyAndJson |
| 6 | + |
| 7 | + |
| 8 | +def test_after(py_and_json: PyAndJson): |
| 9 | + def f(input_value, *, context, **kwargs): |
| 10 | + return input_value + f'| context: {context}' |
| 11 | + |
| 12 | + v = py_and_json({'type': 'function', 'mode': 'after', 'function': f, 'schema': 'str'}) |
| 13 | + |
| 14 | + assert v.validate_test('foobar') == 'foobar| context: None' |
| 15 | + assert v.validate_test('foobar', None, {1: 10}) == 'foobar| context: {1: 10}' |
| 16 | + assert v.validate_test('foobar', None, 'frogspawn') == 'foobar| context: frogspawn' |
| 17 | + |
| 18 | + |
| 19 | +def test_mutable_context(py_and_json: PyAndJson): |
| 20 | + def f(input_value, *, context, **kwargs): |
| 21 | + context['foo'] = input_value |
| 22 | + return input_value |
| 23 | + |
| 24 | + v = py_and_json({'type': 'function', 'mode': 'before', 'function': f, 'schema': 'str'}) |
| 25 | + mutable_context = {} |
| 26 | + assert v.validate_test('foobar', None, mutable_context) == 'foobar' |
| 27 | + assert mutable_context == {'foo': 'foobar'} |
| 28 | + |
| 29 | + |
| 30 | +def test_typed_dict(py_and_json: PyAndJson): |
| 31 | + def f1(input_value, *, context, **kwargs): |
| 32 | + context['f1'] = input_value |
| 33 | + return input_value + f'| context: {context}' |
| 34 | + |
| 35 | + def f2(input_value, *, context, **kwargs): |
| 36 | + context['f2'] = input_value |
| 37 | + return input_value + f'| context: {context}' |
| 38 | + |
| 39 | + v = py_and_json( |
| 40 | + { |
| 41 | + 'type': 'typed-dict', |
| 42 | + 'fields': { |
| 43 | + 'f1': {'schema': {'type': 'function', 'mode': 'plain', 'function': f1}}, |
| 44 | + 'f2': {'schema': {'type': 'function', 'mode': 'plain', 'function': f2}}, |
| 45 | + }, |
| 46 | + } |
| 47 | + ) |
| 48 | + |
| 49 | + assert v.validate_test({'f1': '1', 'f2': '2'}, None, {'x': 'y'}) == { |
| 50 | + 'f1': "1| context: {'x': 'y', 'f1': '1'}", |
| 51 | + 'f2': "2| context: {'x': 'y', 'f1': '1', 'f2': '2'}", |
| 52 | + } |
| 53 | + |
| 54 | + |
| 55 | +def test_wrap(py_and_json: PyAndJson): |
| 56 | + def f(input_value, *, validator, context, **kwargs): |
| 57 | + return validator(input_value) + f'| context: {context}' |
| 58 | + |
| 59 | + v = py_and_json({'type': 'function', 'mode': 'wrap', 'function': f, 'schema': 'str'}) |
| 60 | + |
| 61 | + assert v.validate_test('foobar') == 'foobar| context: None' |
| 62 | + assert v.validate_test('foobar', None, {1: 10}) == 'foobar| context: {1: 10}' |
| 63 | + assert v.validate_test('foobar', None, 'frogspawn') == 'foobar| context: frogspawn' |
| 64 | + |
| 65 | + |
| 66 | +def test_isinstance(py_and_json: PyAndJson): |
| 67 | + def f(input_value, *, validator, context, **kwargs): |
| 68 | + if 'error' in context: |
| 69 | + raise ValueError('wrong') |
| 70 | + return validator(input_value) |
| 71 | + |
| 72 | + v = py_and_json({'type': 'function', 'mode': 'wrap', 'function': f, 'schema': 'str'}) |
| 73 | + |
| 74 | + assert v.validate_python('foobar', None, {}) == 'foobar' |
| 75 | + |
| 76 | + # internal error!, use generic bit of error message to match both cpython and pypy |
| 77 | + with pytest.raises(TypeError, match='is not iterable'): |
| 78 | + v.validate_test('foobar') |
| 79 | + |
| 80 | + with pytest.raises(TypeError, match='is not iterable'): |
| 81 | + v.isinstance_test('foobar') |
| 82 | + |
| 83 | + with pytest.raises(ValidationError, match=r'Value error, wrong \[kind=value_error,'): |
| 84 | + v.validate_test('foobar', None, {'error'}) |
| 85 | + |
| 86 | + assert v.isinstance_test('foobar', None, {}) is True |
| 87 | + |
| 88 | + with pytest.raises(TypeError, match='is not iterable'): |
| 89 | + v.isinstance_test('foobar') |
| 90 | + |
| 91 | + assert v.isinstance_test('foobar', None, {'error'}) is False |
0 commit comments