mirror of https://github.com/tiangolo/fastapi.git
✅ Use `inline-snapshot` to support different Pydantic versions in the test suite (#12534)
Co-authored-by: svlandeg <svlandeg@github.com> Co-authored-by: Sofie Van Landeghem <svlandeg@users.noreply.github.com>
This commit is contained in:
parent
79bc96647b
commit
ea42ebda80
|
|
@ -10,7 +10,7 @@ anyio[trio] >=3.2.1,<5.0.0
|
|||
PyJWT==2.8.0
|
||||
pyyaml >=5.3.1,<7.0.0
|
||||
passlib[bcrypt] >=1.7.2,<2.0.0
|
||||
inline-snapshot==0.19.3
|
||||
inline-snapshot>=0.21.1
|
||||
# types
|
||||
types-ujson ==5.10.0.20240515
|
||||
types-orjson ==3.6.2
|
||||
|
|
|
|||
|
|
@ -5,7 +5,13 @@ from dirty_equals import IsDict
|
|||
from fastapi.testclient import TestClient
|
||||
from inline_snapshot import snapshot
|
||||
|
||||
from tests.utils import needs_py39, needs_py310, needs_pydanticv1, needs_pydanticv2
|
||||
from tests.utils import (
|
||||
needs_py39,
|
||||
needs_py310,
|
||||
needs_pydanticv1,
|
||||
needs_pydanticv2,
|
||||
pydantic_snapshot,
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture(
|
||||
|
|
@ -59,8 +65,8 @@ def test_cookie_param_model_defaults(client: TestClient):
|
|||
def test_cookie_param_model_invalid(client: TestClient):
|
||||
response = client.get("/items/")
|
||||
assert response.status_code == 422
|
||||
assert response.json() == snapshot(
|
||||
IsDict(
|
||||
assert response.json() == pydantic_snapshot(
|
||||
v2=snapshot(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
|
|
@ -71,9 +77,8 @@ def test_cookie_param_model_invalid(client: TestClient):
|
|||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
),
|
||||
v1=snapshot(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
|
|
@ -83,7 +88,7 @@ def test_cookie_param_model_invalid(client: TestClient):
|
|||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -144,19 +149,24 @@ def test_openapi_schema(client: TestClient):
|
|||
"name": "fatebook_tracker",
|
||||
"in": "cookie",
|
||||
"required": False,
|
||||
"schema": IsDict(
|
||||
"schema": pydantic_snapshot(
|
||||
v2=snapshot(
|
||||
{
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
"anyOf": [
|
||||
{"type": "string"},
|
||||
{"type": "null"},
|
||||
],
|
||||
"title": "Fatebook Tracker",
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
),
|
||||
v1=snapshot(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"type": "string",
|
||||
"title": "Fatebook Tracker",
|
||||
}
|
||||
),
|
||||
),
|
||||
},
|
||||
{
|
||||
"name": "googall_tracker",
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import warnings
|
|||
import pytest
|
||||
from dirty_equals import IsDict, IsInt
|
||||
from fastapi.testclient import TestClient
|
||||
from inline_snapshot import snapshot
|
||||
from inline_snapshot import Is, snapshot
|
||||
from sqlalchemy import StaticPool
|
||||
from sqlmodel import SQLModel, create_engine
|
||||
from sqlmodel.main import default_registry
|
||||
|
|
@ -117,14 +117,14 @@ def test_crud_app(client: TestClient):
|
|||
)
|
||||
assert response.status_code == 200, response.text
|
||||
assert response.json() == snapshot(
|
||||
{"name": "Dog Pond", "age": None, "id": hero_id}
|
||||
{"name": "Dog Pond", "age": None, "id": Is(hero_id)}
|
||||
)
|
||||
|
||||
# Get updated hero
|
||||
response = client.get(f"/heroes/{hero_id}")
|
||||
assert response.status_code == 200, response.text
|
||||
assert response.json() == snapshot(
|
||||
{"name": "Dog Pond", "age": None, "id": hero_id}
|
||||
{"name": "Dog Pond", "age": None, "id": Is(hero_id)}
|
||||
)
|
||||
|
||||
# Delete a hero
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import sys
|
|||
|
||||
import pytest
|
||||
from fastapi._compat import PYDANTIC_V2
|
||||
from inline_snapshot import Snapshot
|
||||
|
||||
needs_py39 = pytest.mark.skipif(sys.version_info < (3, 9), reason="requires python3.9+")
|
||||
needs_py310 = pytest.mark.skipif(
|
||||
|
|
@ -9,3 +10,25 @@ needs_py310 = pytest.mark.skipif(
|
|||
)
|
||||
needs_pydanticv2 = pytest.mark.skipif(not PYDANTIC_V2, reason="requires Pydantic v2")
|
||||
needs_pydanticv1 = pytest.mark.skipif(PYDANTIC_V2, reason="requires Pydantic v1")
|
||||
|
||||
|
||||
def pydantic_snapshot(
|
||||
*,
|
||||
v2: Snapshot,
|
||||
v1: Snapshot, # TODO: remove v1 argument when deprecating Pydantic v1
|
||||
):
|
||||
"""
|
||||
This function should be used like this:
|
||||
|
||||
>>> assert value == pydantic_snapshot(v2=snapshot(),v1=snapshot())
|
||||
|
||||
inline-snapshot will create the snapshots when pytest is executed for each versions of pydantic.
|
||||
|
||||
It is also possible to use the function inside snapshots for version-specific values.
|
||||
|
||||
>>> assert value == snapshot({
|
||||
"data": "some data",
|
||||
"version_specific": pydantic_snapshot(v2=snapshot(),v1=snapshot()),
|
||||
})
|
||||
"""
|
||||
return v2 if PYDANTIC_V2 else v1
|
||||
|
|
|
|||
Loading…
Reference in New Issue