Coverage for tests/test_compat.py: 100%

44 statements  

« prev     ^ index     » next       coverage.py v7.6.1, created at 2024-08-08 03:53 +0000

1from typing import List, Union 1abcde

2 

3from fastapi import FastAPI, UploadFile 1abcde

4from fastapi._compat import ( 1abcde

5 ModelField, 

6 Undefined, 

7 _get_model_config, 

8 is_bytes_sequence_annotation, 

9 is_uploadfile_sequence_annotation, 

10) 

11from fastapi.testclient import TestClient 1abcde

12from pydantic import BaseConfig, BaseModel, ConfigDict 1abcde

13from pydantic.fields import FieldInfo 1abcde

14 

15from .utils import needs_pydanticv1, needs_pydanticv2 1abcde

16 

17 

18@needs_pydanticv2 1abcde

19def test_model_field_default_required(): 1abcde

20 # For coverage 

21 field_info = FieldInfo(annotation=str) 1abcde

22 field = ModelField(name="foo", field_info=field_info) 1abcde

23 assert field.default is Undefined 1abcde

24 

25 

26@needs_pydanticv1 1abcde

27def test_upload_file_dummy_with_info_plain_validator_function(): 1abcde

28 # For coverage 

29 assert UploadFile.__get_pydantic_core_schema__(str, lambda x: None) == {} 1abcde

30 

31 

32@needs_pydanticv1 1abcde

33def test_union_scalar_list(): 1abcde

34 # For coverage 

35 # TODO: there might not be a current valid code path that uses this, it would 

36 # potentially enable query parameters defined as both a scalar and a list 

37 # but that would require more refactors, also not sure it's really useful 

38 from fastapi._compat import is_pv1_scalar_field 1abcde

39 

40 field_info = FieldInfo() 1abcde

41 field = ModelField( 1abcde

42 name="foo", 

43 field_info=field_info, 

44 type_=Union[str, List[int]], 

45 class_validators={}, 

46 model_config=BaseConfig, 

47 ) 

48 assert not is_pv1_scalar_field(field) 1abcde

49 

50 

51@needs_pydanticv2 1abcde

52def test_get_model_config(): 1abcde

53 # For coverage in Pydantic v2 

54 class Foo(BaseModel): 1abcde

55 model_config = ConfigDict(from_attributes=True) 1abcde

56 

57 foo = Foo() 1abcde

58 config = _get_model_config(foo) 1abcde

59 assert config == {"from_attributes": True} 1abcde

60 

61 

62def test_complex(): 1abcde

63 app = FastAPI() 1abcde

64 

65 @app.post("/") 1abcde

66 def foo(foo: Union[str, List[int]]): 1abcde

67 return foo 1abcde

68 

69 client = TestClient(app) 1abcde

70 

71 response = client.post("/", json="bar") 1abcde

72 assert response.status_code == 200, response.text 1abcde

73 assert response.json() == "bar" 1abcde

74 

75 response2 = client.post("/", json=[1, 2]) 1abcde

76 assert response2.status_code == 200, response2.text 1abcde

77 assert response2.json() == [1, 2] 1abcde

78 

79 

80def test_is_bytes_sequence_annotation_union(): 1abcde

81 # For coverage 

82 # TODO: in theory this would allow declaring types that could be lists of bytes 

83 # to be read from files and other types, but I'm not even sure it's a good idea 

84 # to support it as a first class "feature" 

85 assert is_bytes_sequence_annotation(Union[List[str], List[bytes]]) 1abcde

86 

87 

88def test_is_uploadfile_sequence_annotation(): 1abcde

89 # For coverage 

90 # TODO: in theory this would allow declaring types that could be lists of UploadFile 

91 # and other types, but I'm not even sure it's a good idea to support it as a first 

92 # class "feature" 

93 assert is_uploadfile_sequence_annotation(Union[List[str], List[UploadFile]]) 1abcde