Coverage for tests/test_compat.py: 100%
49 statements
« prev ^ index » next coverage.py v7.6.1, created at 2024-09-06 16:22 +0000
« prev ^ index » next coverage.py v7.6.1, created at 2024-09-06 16:22 +0000
1from typing import Any, Dict, List, Union 1abcde
3from fastapi import FastAPI, UploadFile 1abcde
4from fastapi._compat import ( 1abcde
5 ModelField,
6 Undefined,
7 _get_model_config,
8 get_model_fields,
9 is_bytes_sequence_annotation,
10 is_scalar_field,
11 is_uploadfile_sequence_annotation,
12)
13from fastapi.testclient import TestClient 1abcde
14from pydantic import BaseConfig, BaseModel, ConfigDict 1abcde
15from pydantic.fields import FieldInfo 1abcde
17from .utils import needs_pydanticv1, needs_pydanticv2 1abcde
20@needs_pydanticv2 1abcde
21def test_model_field_default_required(): 1abcde
22 # For coverage
23 field_info = FieldInfo(annotation=str) 1zABCD
24 field = ModelField(name="foo", field_info=field_info) 1zABCD
25 assert field.default is Undefined 1zABCD
28@needs_pydanticv1 1abcde
29def test_upload_file_dummy_with_info_plain_validator_function(): 1abcde
30 # For coverage
31 assert UploadFile.__get_pydantic_core_schema__(str, lambda x: None) == {} 1EFGHI
34@needs_pydanticv1 1abcde
35def test_union_scalar_list(): 1abcde
36 # For coverage
37 # TODO: there might not be a current valid code path that uses this, it would
38 # potentially enable query parameters defined as both a scalar and a list
39 # but that would require more refactors, also not sure it's really useful
40 from fastapi._compat import is_pv1_scalar_field 1pqrst
42 field_info = FieldInfo() 1pqrst
43 field = ModelField( 1pqrst
44 name="foo",
45 field_info=field_info,
46 type_=Union[str, List[int]],
47 class_validators={},
48 model_config=BaseConfig,
49 )
50 assert not is_pv1_scalar_field(field) 1pqrst
53@needs_pydanticv2 1abcde
54def test_get_model_config(): 1abcde
55 # For coverage in Pydantic v2
56 class Foo(BaseModel): 1klmno
57 model_config = ConfigDict(from_attributes=True) 1klmno
59 foo = Foo() 1klmno
60 config = _get_model_config(foo) 1klmno
61 assert config == {"from_attributes": True} 1klmno
64def test_complex(): 1abcde
65 app = FastAPI() 1fghij
67 @app.post("/") 1fghij
68 def foo(foo: Union[str, List[int]]): 1fghij
69 return foo 1fghij
71 client = TestClient(app) 1fghij
73 response = client.post("/", json="bar") 1fghij
74 assert response.status_code == 200, response.text 1fghij
75 assert response.json() == "bar" 1fghij
77 response2 = client.post("/", json=[1, 2]) 1fghij
78 assert response2.status_code == 200, response2.text 1fghij
79 assert response2.json() == [1, 2] 1fghij
82def test_is_bytes_sequence_annotation_union(): 1abcde
83 # For coverage
84 # TODO: in theory this would allow declaring types that could be lists of bytes
85 # to be read from files and other types, but I'm not even sure it's a good idea
86 # to support it as a first class "feature"
87 assert is_bytes_sequence_annotation(Union[List[str], List[bytes]]) 1JKLMN
90def test_is_uploadfile_sequence_annotation(): 1abcde
91 # For coverage
92 # TODO: in theory this would allow declaring types that could be lists of UploadFile
93 # and other types, but I'm not even sure it's a good idea to support it as a first
94 # class "feature"
95 assert is_uploadfile_sequence_annotation(Union[List[str], List[UploadFile]]) 1OPQRS
98def test_is_pv1_scalar_field(): 1abcde
99 # For coverage
100 class Model(BaseModel): 1uvwxy
101 foo: Union[str, Dict[str, Any]] 1uvwxy
103 fields = get_model_fields(Model) 1uvwxy
104 assert not is_scalar_field(fields[0]) 1uvwxy