]> git.ipfire.org Git - thirdparty/fastapi/fastapi.git/commitdiff
✅ Use `inline-snapshot` to support different Pydantic versions in the test suite...
authorFrank Hoffmann <frank-github@polarbit.de>
Mon, 28 Apr 2025 07:13:56 +0000 (09:13 +0200)
committerGitHub <noreply@github.com>
Mon, 28 Apr 2025 07:13:56 +0000 (09:13 +0200)
Co-authored-by: svlandeg <svlandeg@github.com>
Co-authored-by: Sofie Van Landeghem <svlandeg@users.noreply.github.com>
requirements-tests.txt
tests/test_tutorial/test_cookie_param_models/test_tutorial002.py
tests/test_tutorial/test_sql_databases/test_tutorial002.py
tests/utils.py

index 013b9a35a3b2dd86e778ffcc1d179d571249537b..f722825dd81fb9213f6253936bbd9f80061ba0ff 100644 (file)
@@ -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
index 30adadc8a3507d1358b3631be0f092bdb8182ba5..cef6f66309df893de3165123757ea15e13721d27 100644 (file)
@@ -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,18 +149,23 @@ def test_openapi_schema(client: TestClient):
                                 "name": "fatebook_tracker",
                                 "in": "cookie",
                                 "required": False,
-                                "schema": IsDict(
-                                    {
-                                        "anyOf": [{"type": "string"}, {"type": "null"}],
-                                        "title": "Fatebook Tracker",
-                                    }
-                                )
-                                | IsDict(
-                                    # TODO: remove when deprecating Pydantic v1
-                                    {
-                                        "type": "string",
-                                        "title": "Fatebook Tracker",
-                                    }
+                                "schema": pydantic_snapshot(
+                                    v2=snapshot(
+                                        {
+                                            "anyOf": [
+                                                {"type": "string"},
+                                                {"type": "null"},
+                                            ],
+                                            "title": "Fatebook Tracker",
+                                        }
+                                    ),
+                                    v1=snapshot(
+                                        # TODO: remove when deprecating Pydantic v1
+                                        {
+                                            "type": "string",
+                                            "title": "Fatebook Tracker",
+                                        }
+                                    ),
                                 ),
                             },
                             {
index 79e48c1c3306b5205e0798e7d779be63f2e2a5a4..8a98f9a2d02368cf2319573aa99eb487ef0b36ed 100644 (file)
@@ -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
index 460c028f7f2a9a162fac1b99dc9a6bb02266b904..ae9543e3b7b8c223006ecb09b35c04572913e261 100644 (file)
@@ -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