]> git.ipfire.org Git - thirdparty/fastapi/sqlmodel.git/commitdiff
✅ Simplify tests for code examples, one test file for multiple variants (#1664)
authorMotov Yurii <109919500+YuriiMotov@users.noreply.github.com>
Wed, 24 Dec 2025 15:47:05 +0000 (16:47 +0100)
committerGitHub <noreply@github.com>
Wed, 24 Dec 2025 15:47:05 +0000 (16:47 +0100)
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
186 files changed:
tests/test_advanced/test_decimal/test_tutorial001.py
tests/test_advanced/test_decimal/test_tutorial001_py310.py [deleted file]
tests/test_advanced/test_uuid/test_tutorial001.py
tests/test_advanced/test_uuid/test_tutorial001_py310.py [deleted file]
tests/test_advanced/test_uuid/test_tutorial002.py
tests/test_advanced/test_uuid/test_tutorial002_py310.py [deleted file]
tests/test_tutorial/test_code_structure/test_tutorial002.py
tests/test_tutorial/test_code_structure/test_tutorial002_py310.py [deleted file]
tests/test_tutorial/test_code_structure/test_tutorial002_py39.py [deleted file]
tests/test_tutorial/test_connect/test_create_connected_tables/test_tutorial001.py
tests/test_tutorial/test_connect/test_create_connected_tables/test_tutorial001_py310.py [deleted file]
tests/test_tutorial/test_connect/test_delete/test_tutorial001.py
tests/test_tutorial/test_connect/test_delete/test_tutorial001_py310.py [deleted file]
tests/test_tutorial/test_connect/test_insert/test_tutorial001.py
tests/test_tutorial/test_connect/test_insert/test_tutorial001_py310.py [deleted file]
tests/test_tutorial/test_connect/test_select/test_tutorial001_py310_tutorial002_py310.py [deleted file]
tests/test_tutorial/test_connect/test_select/test_tutorial001_tutorial002.py
tests/test_tutorial/test_connect/test_select/test_tutorial003.py
tests/test_tutorial/test_connect/test_select/test_tutorial003_py310.py [deleted file]
tests/test_tutorial/test_connect/test_select/test_tutorial004.py
tests/test_tutorial/test_connect/test_select/test_tutorial004_py310.py [deleted file]
tests/test_tutorial/test_connect/test_select/test_tutorial005.py
tests/test_tutorial/test_connect/test_select/test_tutorial005_py310.py [deleted file]
tests/test_tutorial/test_connect/test_update/test_tutorial001.py
tests/test_tutorial/test_connect/test_update/test_tutorial001_py310.py [deleted file]
tests/test_tutorial/test_create_db_and_table/test_tutorial001.py
tests/test_tutorial/test_create_db_and_table/test_tutorial001_py310.py [deleted file]
tests/test_tutorial/test_create_db_and_table/test_tutorial002.py
tests/test_tutorial/test_create_db_and_table/test_tutorial002_py310.py [deleted file]
tests/test_tutorial/test_create_db_and_table/test_tutorial003.py
tests/test_tutorial/test_create_db_and_table/test_tutorial003_py310.py [deleted file]
tests/test_tutorial/test_delete/test_tutorial001_py310_tutorial002_py310.py [deleted file]
tests/test_tutorial/test_delete/test_tutorial001_tutorial002.py
tests/test_tutorial/test_fastapi/test_app_testing/test_tutorial001_py310_tests_main.py [deleted file]
tests/test_tutorial/test_fastapi/test_app_testing/test_tutorial001_py39_tests_main.py [deleted file]
tests/test_tutorial/test_fastapi/test_app_testing/test_tutorial001_tests001.py
tests/test_tutorial/test_fastapi/test_app_testing/test_tutorial001_tests002.py
tests/test_tutorial/test_fastapi/test_app_testing/test_tutorial001_tests003.py
tests/test_tutorial/test_fastapi/test_app_testing/test_tutorial001_tests004.py
tests/test_tutorial/test_fastapi/test_app_testing/test_tutorial001_tests_main.py
tests/test_tutorial/test_fastapi/test_delete/test_tutorial001.py
tests/test_tutorial/test_fastapi/test_delete/test_tutorial001_py310.py [deleted file]
tests/test_tutorial/test_fastapi/test_delete/test_tutorial001_py39.py [deleted file]
tests/test_tutorial/test_fastapi/test_limit_and_offset/test_tutorial001.py
tests/test_tutorial/test_fastapi/test_limit_and_offset/test_tutorial001_py310.py [deleted file]
tests/test_tutorial/test_fastapi/test_limit_and_offset/test_tutorial001_py39.py [deleted file]
tests/test_tutorial/test_fastapi/test_multiple_models/test_tutorial001.py
tests/test_tutorial/test_fastapi/test_multiple_models/test_tutorial001_py310.py [deleted file]
tests/test_tutorial/test_fastapi/test_multiple_models/test_tutorial001_py39.py [deleted file]
tests/test_tutorial/test_fastapi/test_multiple_models/test_tutorial002.py
tests/test_tutorial/test_fastapi/test_multiple_models/test_tutorial002_py310.py [deleted file]
tests/test_tutorial/test_fastapi/test_multiple_models/test_tutorial002_py39.py [deleted file]
tests/test_tutorial/test_fastapi/test_read_one/test_tutorial001.py
tests/test_tutorial/test_fastapi/test_read_one/test_tutorial001_py310.py [deleted file]
tests/test_tutorial/test_fastapi/test_read_one/test_tutorial001_py39.py [deleted file]
tests/test_tutorial/test_fastapi/test_relationships/test_tutorial001.py
tests/test_tutorial/test_fastapi/test_relationships/test_tutorial001_py310.py [deleted file]
tests/test_tutorial/test_fastapi/test_relationships/test_tutorial001_py39.py [deleted file]
tests/test_tutorial/test_fastapi/test_response_model/test_tutorial001.py
tests/test_tutorial/test_fastapi/test_response_model/test_tutorial001_py310.py [deleted file]
tests/test_tutorial/test_fastapi/test_response_model/test_tutorial001_py39.py [deleted file]
tests/test_tutorial/test_fastapi/test_session_with_dependency/test_tutorial001.py
tests/test_tutorial/test_fastapi/test_session_with_dependency/test_tutorial001_py310.py [deleted file]
tests/test_tutorial/test_fastapi/test_session_with_dependency/test_tutorial001_py39.py [deleted file]
tests/test_tutorial/test_fastapi/test_simple_hero_api/test_tutorial001.py
tests/test_tutorial/test_fastapi/test_simple_hero_api/test_tutorial001_py310.py [deleted file]
tests/test_tutorial/test_fastapi/test_teams/test_tutorial001.py
tests/test_tutorial/test_fastapi/test_teams/test_tutorial001_py310.py [deleted file]
tests/test_tutorial/test_fastapi/test_teams/test_tutorial001_py39.py [deleted file]
tests/test_tutorial/test_fastapi/test_update/test_tutorial001.py
tests/test_tutorial/test_fastapi/test_update/test_tutorial001_py310.py [deleted file]
tests/test_tutorial/test_fastapi/test_update/test_tutorial001_py39.py [deleted file]
tests/test_tutorial/test_fastapi/test_update/test_tutorial002.py
tests/test_tutorial/test_fastapi/test_update/test_tutorial002_py310.py [deleted file]
tests/test_tutorial/test_fastapi/test_update/test_tutorial002_py39.py [deleted file]
tests/test_tutorial/test_indexes/test_tutorial001.py
tests/test_tutorial/test_indexes/test_tutorial001_py310.py [deleted file]
tests/test_tutorial/test_indexes/test_tutorial002.py
tests/test_tutorial/test_indexes/test_tutorial002_py310.py [deleted file]
tests/test_tutorial/test_insert/test_tutorial001.py
tests/test_tutorial/test_insert/test_tutorial001_py310.py [deleted file]
tests/test_tutorial/test_insert/test_tutorial002.py
tests/test_tutorial/test_insert/test_tutorial002_py310.py [deleted file]
tests/test_tutorial/test_insert/test_tutorial003.py
tests/test_tutorial/test_insert/test_tutorial003_py310.py [deleted file]
tests/test_tutorial/test_limit_and_offset/test_tutorial001.py
tests/test_tutorial/test_limit_and_offset/test_tutorial001_py310.py [deleted file]
tests/test_tutorial/test_limit_and_offset/test_tutorial002.py
tests/test_tutorial/test_limit_and_offset/test_tutorial002_py310.py [deleted file]
tests/test_tutorial/test_limit_and_offset/test_tutorial003.py
tests/test_tutorial/test_limit_and_offset/test_tutorial003_py310.py [deleted file]
tests/test_tutorial/test_limit_and_offset/test_tutorial004.py
tests/test_tutorial/test_limit_and_offset/test_tutorial004_py310.py [deleted file]
tests/test_tutorial/test_many_to_many/test_tutorial001.py
tests/test_tutorial/test_many_to_many/test_tutorial001_py310.py [deleted file]
tests/test_tutorial/test_many_to_many/test_tutorial001_py39.py [deleted file]
tests/test_tutorial/test_many_to_many/test_tutorial002.py
tests/test_tutorial/test_many_to_many/test_tutorial002_py310.py [deleted file]
tests/test_tutorial/test_many_to_many/test_tutorial002_py39.py [deleted file]
tests/test_tutorial/test_many_to_many/test_tutorial003.py
tests/test_tutorial/test_many_to_many/test_tutorial003_py310.py [deleted file]
tests/test_tutorial/test_many_to_many/test_tutorial003_py39.py [deleted file]
tests/test_tutorial/test_one/test_tutorial001.py
tests/test_tutorial/test_one/test_tutorial001_py310.py [deleted file]
tests/test_tutorial/test_one/test_tutorial002.py
tests/test_tutorial/test_one/test_tutorial002_py310.py [deleted file]
tests/test_tutorial/test_one/test_tutorial003.py
tests/test_tutorial/test_one/test_tutorial003_py310.py [deleted file]
tests/test_tutorial/test_one/test_tutorial004.py
tests/test_tutorial/test_one/test_tutorial004_py310.py [deleted file]
tests/test_tutorial/test_one/test_tutorial005.py
tests/test_tutorial/test_one/test_tutorial005_py310.py [deleted file]
tests/test_tutorial/test_one/test_tutorial006.py
tests/test_tutorial/test_one/test_tutorial006_py310.py [deleted file]
tests/test_tutorial/test_one/test_tutorial007.py
tests/test_tutorial/test_one/test_tutorial007_py310.py [deleted file]
tests/test_tutorial/test_one/test_tutorial008.py
tests/test_tutorial/test_one/test_tutorial008_py310.py [deleted file]
tests/test_tutorial/test_one/test_tutorial009.py
tests/test_tutorial/test_one/test_tutorial009_py310.py [deleted file]
tests/test_tutorial/test_relationship_attributes/test_back_populates/test_tutorial001.py
tests/test_tutorial/test_relationship_attributes/test_back_populates/test_tutorial001_py310.py [deleted file]
tests/test_tutorial/test_relationship_attributes/test_back_populates/test_tutorial001_py39.py [deleted file]
tests/test_tutorial/test_relationship_attributes/test_back_populates/test_tutorial002.py
tests/test_tutorial/test_relationship_attributes/test_back_populates/test_tutorial002_py310.py [deleted file]
tests/test_tutorial/test_relationship_attributes/test_back_populates/test_tutorial002_py39.py [deleted file]
tests/test_tutorial/test_relationship_attributes/test_back_populates/test_tutorial003.py
tests/test_tutorial/test_relationship_attributes/test_back_populates/test_tutorial003_py310.py [deleted file]
tests/test_tutorial/test_relationship_attributes/test_back_populates/test_tutorial003_py39.py [deleted file]
tests/test_tutorial/test_relationship_attributes/test_create_and_update_relationships/test_tutorial001.py
tests/test_tutorial/test_relationship_attributes/test_create_and_update_relationships/test_tutorial001_py310.py [deleted file]
tests/test_tutorial/test_relationship_attributes/test_create_and_update_relationships/test_tutorial001_py39.py [deleted file]
tests/test_tutorial/test_relationship_attributes/test_define_relationship_attributes/test_tutorial001.py
tests/test_tutorial/test_relationship_attributes/test_define_relationship_attributes/test_tutorial001_py310.py [deleted file]
tests/test_tutorial/test_relationship_attributes/test_define_relationship_attributes/test_tutorial001_py39.py [deleted file]
tests/test_tutorial/test_relationship_attributes/test_delete_records_relationship/test_tutorial001.py
tests/test_tutorial/test_relationship_attributes/test_delete_records_relationship/test_tutorial001_py310.py [deleted file]
tests/test_tutorial/test_relationship_attributes/test_delete_records_relationship/test_tutorial001_py39.py [deleted file]
tests/test_tutorial/test_relationship_attributes/test_delete_records_relationship/test_tutorial002.py
tests/test_tutorial/test_relationship_attributes/test_delete_records_relationship/test_tutorial002_py310.py [deleted file]
tests/test_tutorial/test_relationship_attributes/test_delete_records_relationship/test_tutorial002_py39.py [deleted file]
tests/test_tutorial/test_relationship_attributes/test_delete_records_relationship/test_tutorial003.py
tests/test_tutorial/test_relationship_attributes/test_delete_records_relationship/test_tutorial003_py310.py [deleted file]
tests/test_tutorial/test_relationship_attributes/test_delete_records_relationship/test_tutorial003_py39.py [deleted file]
tests/test_tutorial/test_relationship_attributes/test_delete_records_relationship/test_tutorial004.py
tests/test_tutorial/test_relationship_attributes/test_delete_records_relationship/test_tutorial004_py310.py [deleted file]
tests/test_tutorial/test_relationship_attributes/test_delete_records_relationship/test_tutorial004_py39.py [deleted file]
tests/test_tutorial/test_relationship_attributes/test_delete_records_relationship/test_tutorial005.py
tests/test_tutorial/test_relationship_attributes/test_delete_records_relationship/test_tutorial005_py310.py [deleted file]
tests/test_tutorial/test_relationship_attributes/test_delete_records_relationship/test_tutorial005_py39.py [deleted file]
tests/test_tutorial/test_relationship_attributes/test_read_relationships/test_tutorial001.py
tests/test_tutorial/test_relationship_attributes/test_read_relationships/test_tutorial001_py310.py [deleted file]
tests/test_tutorial/test_relationship_attributes/test_read_relationships/test_tutorial001_py39.py [deleted file]
tests/test_tutorial/test_relationship_attributes/test_read_relationships/test_tutorial002.py
tests/test_tutorial/test_relationship_attributes/test_read_relationships/test_tutorial002_py310.py [deleted file]
tests/test_tutorial/test_relationship_attributes/test_read_relationships/test_tutorial002_py39.py [deleted file]
tests/test_tutorial/test_select/test_tutorial001_py310_tutorial002_py310.py [deleted file]
tests/test_tutorial/test_select/test_tutorial001_tutorial002.py
tests/test_tutorial/test_select/test_tutorial003_py310_tutorial004_py310.py [deleted file]
tests/test_tutorial/test_select/test_tutorial003_tutorial004.py
tests/test_tutorial/test_update/test_tutorial001_py310_tutorial002_py310.py [deleted file]
tests/test_tutorial/test_update/test_tutorial001_tutorial002.py
tests/test_tutorial/test_update/test_tutorial003_py310_tutorial004_py310.py [deleted file]
tests/test_tutorial/test_update/test_tutorial003_tutorial004.py
tests/test_tutorial/test_where/test_tutorial001.py
tests/test_tutorial/test_where/test_tutorial001_py310.py [deleted file]
tests/test_tutorial/test_where/test_tutorial002.py
tests/test_tutorial/test_where/test_tutorial002_py310.py [deleted file]
tests/test_tutorial/test_where/test_tutorial003.py
tests/test_tutorial/test_where/test_tutorial003_py310.py [deleted file]
tests/test_tutorial/test_where/test_tutorial004.py
tests/test_tutorial/test_where/test_tutorial004_py310.py [deleted file]
tests/test_tutorial/test_where/test_tutorial005.py
tests/test_tutorial/test_where/test_tutorial005_py310.py [deleted file]
tests/test_tutorial/test_where/test_tutorial006.py
tests/test_tutorial/test_where/test_tutorial006_py310.py [deleted file]
tests/test_tutorial/test_where/test_tutorial007.py
tests/test_tutorial/test_where/test_tutorial007_py310.py [deleted file]
tests/test_tutorial/test_where/test_tutorial008.py
tests/test_tutorial/test_where/test_tutorial008_py310.py [deleted file]
tests/test_tutorial/test_where/test_tutorial009.py
tests/test_tutorial/test_where/test_tutorial009_py310.py [deleted file]
tests/test_tutorial/test_where/test_tutorial010.py
tests/test_tutorial/test_where/test_tutorial010_py310.py [deleted file]
tests/test_tutorial/test_where/test_tutorial011.py
tests/test_tutorial/test_where/test_tutorial011_py310.py [deleted file]

index 2dc562209f63e680540abee009edc1507efb2d50..dad8f24c4c4376bdeae58587d467fb0aa02e6ade 100644 (file)
@@ -1,9 +1,26 @@
+import importlib
 from decimal import Decimal
-from unittest.mock import patch
+from types import ModuleType
 
+import pytest
 from sqlmodel import create_engine
 
-from ...conftest import get_testing_print_function
+from ...conftest import PrintMock, needs_py310
+
+
+@pytest.fixture(
+    name="mod",
+    params=[
+        "tutorial001",
+        pytest.param("tutorial001_py310", marks=needs_py310),
+    ],
+)
+def get_module(request: pytest.FixtureRequest) -> ModuleType:
+    mod = importlib.import_module(f"docs_src.advanced.decimal.{request.param}")
+    mod.sqlite_url = "sqlite://"
+    mod.engine = create_engine(mod.sqlite_url)
+    return mod
+
 
 expected_calls = [
     [
@@ -30,15 +47,6 @@ expected_calls = [
 ]
 
 
-def test_tutorial():
-    from docs_src.advanced.decimal import tutorial001 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == expected_calls
+def test_tutorial(print_mock: PrintMock, mod: ModuleType):
+    mod.main()
+    assert print_mock.calls == expected_calls
diff --git a/tests/test_advanced/test_decimal/test_tutorial001_py310.py b/tests/test_advanced/test_decimal/test_tutorial001_py310.py
deleted file mode 100644 (file)
index 4cda8b4..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-from decimal import Decimal
-from unittest.mock import patch
-
-from sqlmodel import create_engine
-
-from ...conftest import get_testing_print_function, needs_py310
-
-expected_calls = [
-    [
-        "Hero 1:",
-        {
-            "name": "Deadpond",
-            "age": None,
-            "id": 1,
-            "secret_name": "Dive Wilson",
-            "money": Decimal("1.100"),
-        },
-    ],
-    [
-        "Hero 2:",
-        {
-            "name": "Rusty-Man",
-            "age": 48,
-            "id": 3,
-            "secret_name": "Tommy Sharp",
-            "money": Decimal("2.200"),
-        },
-    ],
-    ["Total money: 3.300"],
-]
-
-
-@needs_py310
-def test_tutorial():
-    from docs_src.advanced.decimal import tutorial001_py310 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == expected_calls
index b9d5a368003d7573b5ccaaeed8314d5260e63665..ab4f3387dc1b01d9439dcc43a37852d72d2a792c 100644 (file)
@@ -1,31 +1,38 @@
-from unittest.mock import patch
+import importlib
+from types import ModuleType
 
+import pytest
 from dirty_equals import IsUUID
 from sqlmodel import create_engine
 
-from ...conftest import get_testing_print_function
+from ...conftest import PrintMock, needs_py310
 
 
-def test_tutorial() -> None:
-    from docs_src.advanced.uuid import tutorial001 as mod
-
+@pytest.fixture(
+    name="mod",
+    params=[
+        "tutorial001",
+        pytest.param("tutorial001_py310", marks=needs_py310),
+    ],
+)
+def get_module(request: pytest.FixtureRequest) -> ModuleType:
+    mod = importlib.import_module(f"docs_src.advanced.uuid.{request.param}")
     mod.sqlite_url = "sqlite://"
     mod.engine = create_engine(mod.sqlite_url)
-    calls = []
+    return mod
 
-    new_print = get_testing_print_function(calls)
 
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    first_uuid = calls[1][0]["id"]
+def test_tutorial(print_mock: PrintMock, mod: ModuleType) -> None:
+    mod.main()
+    first_uuid = print_mock.calls[1][0]["id"]
     assert first_uuid == IsUUID(4)
 
-    second_uuid = calls[7][0]["id"]
+    second_uuid = print_mock.calls[7][0]["id"]
     assert second_uuid == IsUUID(4)
 
     assert first_uuid != second_uuid
 
-    assert calls == [
+    assert print_mock.calls == [
         ["The hero before saving in the DB"],
         [
             {
diff --git a/tests/test_advanced/test_uuid/test_tutorial001_py310.py b/tests/test_advanced/test_uuid/test_tutorial001_py310.py
deleted file mode 100644 (file)
index 1250c32..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-from unittest.mock import patch
-
-from dirty_equals import IsUUID
-from sqlmodel import create_engine
-
-from ...conftest import get_testing_print_function, needs_py310
-
-
-@needs_py310
-def test_tutorial() -> None:
-    from docs_src.advanced.uuid import tutorial001_py310 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    first_uuid = calls[1][0]["id"]
-    assert first_uuid == IsUUID(4)
-
-    second_uuid = calls[7][0]["id"]
-    assert second_uuid == IsUUID(4)
-
-    assert first_uuid != second_uuid
-
-    assert calls == [
-        ["The hero before saving in the DB"],
-        [
-            {
-                "name": "Deadpond",
-                "secret_name": "Dive Wilson",
-                "id": first_uuid,
-                "age": None,
-            }
-        ],
-        ["The hero ID was already set"],
-        [first_uuid],
-        ["After saving in the DB"],
-        [
-            {
-                "name": "Deadpond",
-                "secret_name": "Dive Wilson",
-                "age": None,
-                "id": first_uuid,
-            }
-        ],
-        ["Created hero:"],
-        [
-            {
-                "name": "Spider-Boy",
-                "secret_name": "Pedro Parqueador",
-                "age": None,
-                "id": second_uuid,
-            }
-        ],
-        ["Created hero ID:"],
-        [second_uuid],
-        ["Selected hero:"],
-        [
-            {
-                "name": "Spider-Boy",
-                "secret_name": "Pedro Parqueador",
-                "age": None,
-                "id": second_uuid,
-            }
-        ],
-        ["Selected hero ID:"],
-        [second_uuid],
-    ]
index c9f4e5a35d8e4c50361173293d67a3ba20547810..b1ff5ba3fdfea7b69280876f819597304430d0a1 100644 (file)
@@ -1,31 +1,38 @@
-from unittest.mock import patch
+import importlib
+from types import ModuleType
 
+import pytest
 from dirty_equals import IsUUID
 from sqlmodel import create_engine
 
-from ...conftest import get_testing_print_function
+from ...conftest import PrintMock, needs_py310
 
 
-def test_tutorial() -> None:
-    from docs_src.advanced.uuid import tutorial002 as mod
-
+@pytest.fixture(
+    name="mod",
+    params=[
+        "tutorial002",
+        pytest.param("tutorial002_py310", marks=needs_py310),
+    ],
+)
+def get_module(request: pytest.FixtureRequest) -> ModuleType:
+    mod = importlib.import_module(f"docs_src.advanced.uuid.{request.param}")
     mod.sqlite_url = "sqlite://"
     mod.engine = create_engine(mod.sqlite_url)
-    calls = []
+    return mod
 
-    new_print = get_testing_print_function(calls)
 
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    first_uuid = calls[1][0]["id"]
+def test_tutorial(print_mock: PrintMock, mod: ModuleType) -> None:
+    mod.main()
+    first_uuid = print_mock.calls[1][0]["id"]
     assert first_uuid == IsUUID(4)
 
-    second_uuid = calls[7][0]["id"]
+    second_uuid = print_mock.calls[7][0]["id"]
     assert second_uuid == IsUUID(4)
 
     assert first_uuid != second_uuid
 
-    assert calls == [
+    assert print_mock.calls == [
         ["The hero before saving in the DB"],
         [
             {
diff --git a/tests/test_advanced/test_uuid/test_tutorial002_py310.py b/tests/test_advanced/test_uuid/test_tutorial002_py310.py
deleted file mode 100644 (file)
index ba472e3..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-from unittest.mock import patch
-
-from dirty_equals import IsUUID
-from sqlmodel import create_engine
-
-from ...conftest import get_testing_print_function, needs_py310
-
-
-@needs_py310
-def test_tutorial() -> None:
-    from docs_src.advanced.uuid import tutorial002_py310 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    first_uuid = calls[1][0]["id"]
-    assert first_uuid == IsUUID(4)
-
-    second_uuid = calls[7][0]["id"]
-    assert second_uuid == IsUUID(4)
-
-    assert first_uuid != second_uuid
-
-    assert calls == [
-        ["The hero before saving in the DB"],
-        [
-            {
-                "name": "Deadpond",
-                "secret_name": "Dive Wilson",
-                "id": first_uuid,
-                "age": None,
-            }
-        ],
-        ["The hero ID was already set"],
-        [first_uuid],
-        ["After saving in the DB"],
-        [
-            {
-                "name": "Deadpond",
-                "secret_name": "Dive Wilson",
-                "age": None,
-                "id": first_uuid,
-            }
-        ],
-        ["Created hero:"],
-        [
-            {
-                "name": "Spider-Boy",
-                "secret_name": "Pedro Parqueador",
-                "age": None,
-                "id": second_uuid,
-            }
-        ],
-        ["Created hero ID:"],
-        [second_uuid],
-        ["Selected hero:"],
-        [
-            {
-                "name": "Spider-Boy",
-                "secret_name": "Pedro Parqueador",
-                "age": None,
-                "id": second_uuid,
-            }
-        ],
-        ["Selected hero ID:"],
-        [second_uuid],
-    ]
index ccbb84909713249f6efee37a82d9a4b846df2dd9..f1d4043e8517655b962b3a4dbb9fde1f8b6dd2be 100644 (file)
@@ -1,8 +1,11 @@
-from unittest.mock import patch
+import importlib
+from dataclasses import dataclass
+from types import ModuleType
 
+import pytest
 from sqlmodel import create_engine
 
-from ...conftest import get_testing_print_function
+from ...conftest import PrintMock, needs_py39, needs_py310
 
 expected_calls = [
     [
@@ -22,16 +25,34 @@ expected_calls = [
 ]
 
 
-def test_tutorial():
-    from docs_src.tutorial.code_structure.tutorial002 import app, database
+@dataclass
+class Modules:
+    app: ModuleType
+    database: ModuleType
 
-    database.sqlite_url = "sqlite://"
-    database.engine = create_engine(database.sqlite_url)
-    app.engine = database.engine
-    calls = []
 
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        app.main()
-    assert calls == expected_calls
+@pytest.fixture(
+    name="modules",
+    params=[
+        "tutorial002",
+        pytest.param("tutorial002_py39", marks=needs_py39),
+        pytest.param("tutorial002_py310", marks=needs_py310),
+    ],
+)
+def get_modules(request: pytest.FixtureRequest) -> Modules:
+    app_module = importlib.import_module(
+        f"docs_src.tutorial.code_structure.{request.param}.app"
+    )
+    database_module = importlib.import_module(
+        f"docs_src.tutorial.code_structure.{request.param}.database"
+    )
+    database_module.sqlite_url = "sqlite://"
+    database_module.engine = create_engine(database_module.sqlite_url)
+    app_module.engine = database_module.engine
+
+    return Modules(app=app_module, database=database_module)
+
+
+def test_tutorial(print_mock: PrintMock, modules: Modules):
+    modules.app.main()
+    assert print_mock.calls == expected_calls
diff --git a/tests/test_tutorial/test_code_structure/test_tutorial002_py310.py b/tests/test_tutorial/test_code_structure/test_tutorial002_py310.py
deleted file mode 100644 (file)
index be28486..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-from unittest.mock import patch
-
-from sqlmodel import create_engine
-
-from ...conftest import get_testing_print_function, needs_py310
-
-expected_calls = [
-    [
-        "Created hero:",
-        {
-            "id": 1,
-            "name": "Deadpond",
-            "age": None,
-            "secret_name": "Dive Wilson",
-            "team_id": 1,
-        },
-    ],
-    [
-        "Hero's team:",
-        {"name": "Z-Force", "headquarters": "Sister Margaret's Bar", "id": 1},
-    ],
-]
-
-
-@needs_py310
-def test_tutorial():
-    from docs_src.tutorial.code_structure.tutorial002_py310 import app, database
-
-    database.sqlite_url = "sqlite://"
-    database.engine = create_engine(database.sqlite_url)
-    app.engine = database.engine
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        app.main()
-    assert calls == expected_calls
diff --git a/tests/test_tutorial/test_code_structure/test_tutorial002_py39.py b/tests/test_tutorial/test_code_structure/test_tutorial002_py39.py
deleted file mode 100644 (file)
index 55f6a43..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-from unittest.mock import patch
-
-from sqlmodel import create_engine
-
-from ...conftest import get_testing_print_function, needs_py39
-
-expected_calls = [
-    [
-        "Created hero:",
-        {
-            "id": 1,
-            "name": "Deadpond",
-            "age": None,
-            "secret_name": "Dive Wilson",
-            "team_id": 1,
-        },
-    ],
-    [
-        "Hero's team:",
-        {"name": "Z-Force", "headquarters": "Sister Margaret's Bar", "id": 1},
-    ],
-]
-
-
-@needs_py39
-def test_tutorial():
-    from docs_src.tutorial.code_structure.tutorial002_py39 import app, database
-
-    database.sqlite_url = "sqlite://"
-    database.engine = create_engine(database.sqlite_url)
-    app.engine = database.engine
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        app.main()
-    assert calls == expected_calls
index 265a05931c4522c6ef510157c4fac2ca5f8a9a5e..49d4acfa0072b9447044c9d478d010f48662efe2 100644 (file)
@@ -1,14 +1,32 @@
+import importlib
+from types import ModuleType
+
+import pytest
 from sqlalchemy import inspect
 from sqlalchemy.engine.reflection import Inspector
 from sqlmodel import create_engine
 
+from tests.conftest import needs_py310
+
+
+@pytest.fixture(
+    name="module",
+    params=[
+        "tutorial001",
+        pytest.param("tutorial001_py310", marks=needs_py310),
+    ],
+)
+def get_module(request: pytest.FixtureRequest) -> ModuleType:
+    module = importlib.import_module(
+        f"docs_src.tutorial.connect.create_tables.{request.param}"
+    )
+    return module
 
-def test_tutorial001():
-    from docs_src.tutorial.connect.create_tables import tutorial001 as mod
 
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    mod.main()
-    insp: Inspector = inspect(mod.engine)
-    assert insp.has_table(str(mod.Hero.__tablename__))
-    assert insp.has_table(str(mod.Team.__tablename__))
+def test_tutorial001(module: ModuleType):
+    module.sqlite_url = "sqlite://"
+    module.engine = create_engine(module.sqlite_url)
+    module.main()
+    insp: Inspector = inspect(module.engine)
+    assert insp.has_table(str(module.Hero.__tablename__))
+    assert insp.has_table(str(module.Team.__tablename__))
diff --git a/tests/test_tutorial/test_connect/test_create_connected_tables/test_tutorial001_py310.py b/tests/test_tutorial/test_connect/test_create_connected_tables/test_tutorial001_py310.py
deleted file mode 100644 (file)
index 95f15a4..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-from sqlalchemy import inspect
-from sqlalchemy.engine.reflection import Inspector
-from sqlmodel import create_engine
-
-from ....conftest import needs_py310
-
-
-@needs_py310
-def test_tutorial001():
-    from docs_src.tutorial.connect.create_tables import tutorial001_py310 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    mod.main()
-    insp: Inspector = inspect(mod.engine)
-    assert insp.has_table(str(mod.Hero.__tablename__))
-    assert insp.has_table(str(mod.Team.__tablename__))
index 1a9fe293ba4527d405c4ab363998828880b783f1..cc25dd42e36d52fa735f5ea74d1045747fc23e0b 100644 (file)
@@ -1,8 +1,10 @@
-from unittest.mock import patch
+import importlib
+from types import ModuleType
 
+import pytest
 from sqlmodel import create_engine
 
-from ....conftest import get_testing_print_function
+from ....conftest import PrintMock, needs_py310
 
 expected_calls = [
     [
@@ -58,15 +60,22 @@ expected_calls = [
 ]
 
 
-def test_tutorial():
-    from docs_src.tutorial.connect.delete import tutorial001 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
+@pytest.fixture(
+    name="module",
+    params=[
+        "tutorial001",
+        pytest.param("tutorial001_py310", marks=needs_py310),
+    ],
+)
+def get_module(request: pytest.FixtureRequest) -> ModuleType:
+    module = importlib.import_module(
+        f"docs_src.tutorial.connect.delete.{request.param}"
+    )
+    module.sqlite_url = "sqlite://"
+    module.engine = create_engine(module.sqlite_url)
+    return module
 
-    new_print = get_testing_print_function(calls)
 
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == expected_calls
+def test_tutorial(print_mock: PrintMock, module: ModuleType):
+    module.main()
+    assert print_mock.calls == expected_calls
diff --git a/tests/test_tutorial/test_connect/test_delete/test_tutorial001_py310.py b/tests/test_tutorial/test_connect/test_delete/test_tutorial001_py310.py
deleted file mode 100644 (file)
index f1bef3e..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-from unittest.mock import patch
-
-from sqlmodel import create_engine
-
-from ....conftest import get_testing_print_function, needs_py310
-
-expected_calls = [
-    [
-        "Created hero:",
-        {
-            "age": None,
-            "id": 1,
-            "secret_name": "Dive Wilson",
-            "team_id": 2,
-            "name": "Deadpond",
-        },
-    ],
-    [
-        "Created hero:",
-        {
-            "age": 48,
-            "id": 2,
-            "secret_name": "Tommy Sharp",
-            "team_id": 1,
-            "name": "Rusty-Man",
-        },
-    ],
-    [
-        "Created hero:",
-        {
-            "age": None,
-            "id": 3,
-            "secret_name": "Pedro Parqueador",
-            "team_id": None,
-            "name": "Spider-Boy",
-        },
-    ],
-    [
-        "Updated hero:",
-        {
-            "age": None,
-            "id": 3,
-            "secret_name": "Pedro Parqueador",
-            "team_id": 1,
-            "name": "Spider-Boy",
-        },
-    ],
-    [
-        "No longer Preventer:",
-        {
-            "age": None,
-            "id": 3,
-            "secret_name": "Pedro Parqueador",
-            "team_id": None,
-            "name": "Spider-Boy",
-        },
-    ],
-]
-
-
-@needs_py310
-def test_tutorial():
-    from docs_src.tutorial.connect.delete import tutorial001_py310 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == expected_calls
index cfc08ee8541de711e09b97825ae6d69dedb8203d..6c4ec3ab1cdfbb2f3080e246a95251c0afcc4633 100644 (file)
@@ -1,8 +1,10 @@
-from unittest.mock import patch
+import importlib
+from types import ModuleType
 
+import pytest
 from sqlmodel import create_engine
 
-from ....conftest import get_testing_print_function
+from ....conftest import PrintMock, needs_py310
 
 expected_calls = [
     [
@@ -38,15 +40,22 @@ expected_calls = [
 ]
 
 
-def test_tutorial001():
-    from docs_src.tutorial.connect.insert import tutorial001 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == expected_calls
+@pytest.fixture(
+    name="module",
+    params=[
+        "tutorial001",
+        pytest.param("tutorial001_py310", marks=needs_py310),
+    ],
+)
+def get_module(request: pytest.FixtureRequest) -> ModuleType:
+    module = importlib.import_module(
+        f"docs_src.tutorial.connect.insert.{request.param}"
+    )
+    module.sqlite_url = "sqlite://"
+    module.engine = create_engine(module.sqlite_url)
+    return module
+
+
+def test_tutorial001(print_mock: PrintMock, module: ModuleType):
+    module.main()
+    assert print_mock.calls == expected_calls
diff --git a/tests/test_tutorial/test_connect/test_insert/test_tutorial001_py310.py b/tests/test_tutorial/test_connect/test_insert/test_tutorial001_py310.py
deleted file mode 100644 (file)
index 6dabc10..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-from unittest.mock import patch
-
-from sqlmodel import create_engine
-
-from ....conftest import get_testing_print_function, needs_py310
-
-expected_calls = [
-    [
-        "Created hero:",
-        {
-            "age": None,
-            "id": 1,
-            "secret_name": "Dive Wilson",
-            "team_id": 2,
-            "name": "Deadpond",
-        },
-    ],
-    [
-        "Created hero:",
-        {
-            "age": 48,
-            "id": 2,
-            "secret_name": "Tommy Sharp",
-            "team_id": 1,
-            "name": "Rusty-Man",
-        },
-    ],
-    [
-        "Created hero:",
-        {
-            "age": None,
-            "id": 3,
-            "secret_name": "Pedro Parqueador",
-            "team_id": None,
-            "name": "Spider-Boy",
-        },
-    ],
-]
-
-
-@needs_py310
-def test_tutorial001():
-    from docs_src.tutorial.connect.insert import tutorial001_py310 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == expected_calls
diff --git a/tests/test_tutorial/test_connect/test_select/test_tutorial001_py310_tutorial002_py310.py b/tests/test_tutorial/test_connect/test_select/test_tutorial001_py310_tutorial002_py310.py
deleted file mode 100644 (file)
index 4809d79..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-from unittest.mock import patch
-
-from sqlmodel import create_engine
-
-from ....conftest import get_testing_print_function, needs_py310
-
-expected_calls = [
-    [
-        "Created hero:",
-        {
-            "age": None,
-            "id": 1,
-            "secret_name": "Dive Wilson",
-            "team_id": 2,
-            "name": "Deadpond",
-        },
-    ],
-    [
-        "Created hero:",
-        {
-            "age": 48,
-            "id": 2,
-            "secret_name": "Tommy Sharp",
-            "team_id": 1,
-            "name": "Rusty-Man",
-        },
-    ],
-    [
-        "Created hero:",
-        {
-            "age": None,
-            "id": 3,
-            "secret_name": "Pedro Parqueador",
-            "team_id": None,
-            "name": "Spider-Boy",
-        },
-    ],
-    [
-        "Hero:",
-        {
-            "age": None,
-            "id": 1,
-            "secret_name": "Dive Wilson",
-            "team_id": 2,
-            "name": "Deadpond",
-        },
-        "Team:",
-        {"id": 2, "name": "Z-Force", "headquarters": "Sister Margaret's Bar"},
-    ],
-    [
-        "Hero:",
-        {
-            "age": 48,
-            "id": 2,
-            "secret_name": "Tommy Sharp",
-            "team_id": 1,
-            "name": "Rusty-Man",
-        },
-        "Team:",
-        {"id": 1, "name": "Preventers", "headquarters": "Sharp Tower"},
-    ],
-]
-
-
-@needs_py310
-def test_tutorial001():
-    from docs_src.tutorial.connect.select import tutorial001_py310 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == expected_calls
-
-
-@needs_py310
-def test_tutorial002():
-    from docs_src.tutorial.connect.select import tutorial002_py310 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == expected_calls
index c0d6b59dd98abea9c37f6a6260b29f8b90c85fef..6553bc1ae633cda8a496d2b112fed05f5c4e13a6 100644 (file)
@@ -1,8 +1,10 @@
-from unittest.mock import patch
+import importlib
+from types import ModuleType
 
+import pytest
 from sqlmodel import create_engine
 
-from ....conftest import get_testing_print_function
+from ....conftest import PrintMock, needs_py310
 
 expected_calls = [
     [
@@ -62,29 +64,37 @@ expected_calls = [
 ]
 
 
-def test_tutorial001():
-    from docs_src.tutorial.connect.select import tutorial001 as mod
+@pytest.fixture(name="module")
+def get_module(request: pytest.FixtureRequest) -> ModuleType:
+    module = importlib.import_module(
+        f"docs_src.tutorial.connect.select.{request.param}"
+    )
+    module.sqlite_url = "sqlite://"
+    module.engine = create_engine(module.sqlite_url)
+    return module
 
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
 
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == expected_calls
-
-
-def test_tutorial002():
-    from docs_src.tutorial.connect.select import tutorial002 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
+@pytest.mark.parametrize(
+    "module",
+    [
+        "tutorial001",
+        pytest.param("tutorial001_py310", marks=needs_py310),
+    ],
+    indirect=True,
+)
+def test_tutorial001(print_mock: PrintMock, module: ModuleType):
+    module.main()
+    assert print_mock.calls == expected_calls
 
-    new_print = get_testing_print_function(calls)
 
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == expected_calls
+@pytest.mark.parametrize(
+    "module",
+    [
+        "tutorial002",
+        pytest.param("tutorial002_py310", marks=needs_py310),
+    ],
+    indirect=True,
+)
+def test_tutorial002(print_mock: PrintMock, module: ModuleType):
+    module.main()
+    assert print_mock.calls == expected_calls
index f309e1c44e9e3aa606853f6e2179c769b17fa34a..6036b672a33f538d6817777a6d067575a2900c14 100644 (file)
@@ -1,8 +1,10 @@
-from unittest.mock import patch
+import importlib
+from types import ModuleType
 
+import pytest
 from sqlmodel import create_engine
 
-from ....conftest import get_testing_print_function
+from ....conftest import PrintMock, needs_py310
 
 expected_calls = [
     [
@@ -74,15 +76,22 @@ expected_calls = [
 ]
 
 
-def test_tutorial():
-    from docs_src.tutorial.connect.select import tutorial003 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
+@pytest.fixture(
+    name="module",
+    params=[
+        "tutorial003",
+        pytest.param("tutorial003_py310", marks=needs_py310),
+    ],
+)
+def get_module(request: pytest.FixtureRequest) -> ModuleType:
+    module = importlib.import_module(
+        f"docs_src.tutorial.connect.select.{request.param}"
+    )
+    module.sqlite_url = "sqlite://"
+    module.engine = create_engine(module.sqlite_url)
+    return module
 
-    new_print = get_testing_print_function(calls)
 
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == expected_calls
+def test_tutorial(print_mock: PrintMock, module: ModuleType):
+    module.main()
+    assert print_mock.calls == expected_calls
diff --git a/tests/test_tutorial/test_connect/test_select/test_tutorial003_py310.py b/tests/test_tutorial/test_connect/test_select/test_tutorial003_py310.py
deleted file mode 100644 (file)
index e826ce4..0000000
+++ /dev/null
@@ -1,89 +0,0 @@
-from unittest.mock import patch
-
-from sqlmodel import create_engine
-
-from ....conftest import get_testing_print_function, needs_py310
-
-expected_calls = [
-    [
-        "Created hero:",
-        {
-            "age": None,
-            "id": 1,
-            "secret_name": "Dive Wilson",
-            "team_id": 2,
-            "name": "Deadpond",
-        },
-    ],
-    [
-        "Created hero:",
-        {
-            "age": 48,
-            "id": 2,
-            "secret_name": "Tommy Sharp",
-            "team_id": 1,
-            "name": "Rusty-Man",
-        },
-    ],
-    [
-        "Created hero:",
-        {
-            "age": None,
-            "id": 3,
-            "secret_name": "Pedro Parqueador",
-            "team_id": None,
-            "name": "Spider-Boy",
-        },
-    ],
-    [
-        "Hero:",
-        {
-            "age": None,
-            "id": 1,
-            "secret_name": "Dive Wilson",
-            "team_id": 2,
-            "name": "Deadpond",
-        },
-        "Team:",
-        {"id": 2, "name": "Z-Force", "headquarters": "Sister Margaret's Bar"},
-    ],
-    [
-        "Hero:",
-        {
-            "age": 48,
-            "id": 2,
-            "secret_name": "Tommy Sharp",
-            "team_id": 1,
-            "name": "Rusty-Man",
-        },
-        "Team:",
-        {"id": 1, "name": "Preventers", "headquarters": "Sharp Tower"},
-    ],
-    [
-        "Hero:",
-        {
-            "age": None,
-            "id": 3,
-            "secret_name": "Pedro Parqueador",
-            "team_id": None,
-            "name": "Spider-Boy",
-        },
-        "Team:",
-        None,
-    ],
-]
-
-
-@needs_py310
-def test_tutorial():
-    from docs_src.tutorial.connect.select import tutorial003_py310 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == expected_calls
index a33c81485601ea30036215322d18596595ddf12b..c9fa695eda399d1a7119c8ea9414e5af8db5e1ad 100644 (file)
@@ -1,8 +1,10 @@
-from unittest.mock import patch
+import importlib
+from types import ModuleType
 
+import pytest
 from sqlmodel import create_engine
 
-from ....conftest import get_testing_print_function
+from ....conftest import PrintMock, needs_py310
 
 expected_calls = [
     [
@@ -48,15 +50,22 @@ expected_calls = [
 ]
 
 
-def test_tutorial():
-    from docs_src.tutorial.connect.select import tutorial004 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
+@pytest.fixture(
+    name="module",
+    params=[
+        "tutorial004",
+        pytest.param("tutorial004_py310", marks=needs_py310),
+    ],
+)
+def get_module(request: pytest.FixtureRequest) -> ModuleType:
+    module = importlib.import_module(
+        f"docs_src.tutorial.connect.select.{request.param}"
+    )
+    module.sqlite_url = "sqlite://"
+    module.engine = create_engine(module.sqlite_url)
+    return module
 
-    new_print = get_testing_print_function(calls)
 
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == expected_calls
+def test_tutorial(print_mock: PrintMock, module: ModuleType):
+    module.main()
+    assert print_mock.calls == expected_calls
diff --git a/tests/test_tutorial/test_connect/test_select/test_tutorial004_py310.py b/tests/test_tutorial/test_connect/test_select/test_tutorial004_py310.py
deleted file mode 100644 (file)
index 33dd8a4..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-from unittest.mock import patch
-
-from sqlmodel import create_engine
-
-from ....conftest import get_testing_print_function, needs_py310
-
-expected_calls = [
-    [
-        "Created hero:",
-        {
-            "age": None,
-            "id": 1,
-            "secret_name": "Dive Wilson",
-            "team_id": 2,
-            "name": "Deadpond",
-        },
-    ],
-    [
-        "Created hero:",
-        {
-            "age": 48,
-            "id": 2,
-            "secret_name": "Tommy Sharp",
-            "team_id": 1,
-            "name": "Rusty-Man",
-        },
-    ],
-    [
-        "Created hero:",
-        {
-            "age": None,
-            "id": 3,
-            "secret_name": "Pedro Parqueador",
-            "team_id": None,
-            "name": "Spider-Boy",
-        },
-    ],
-    [
-        "Preventer Hero:",
-        {
-            "age": 48,
-            "id": 2,
-            "secret_name": "Tommy Sharp",
-            "team_id": 1,
-            "name": "Rusty-Man",
-        },
-    ],
-]
-
-
-@needs_py310
-def test_tutorial():
-    from docs_src.tutorial.connect.select import tutorial004_py310 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == expected_calls
index f7ad78dc65d18bb23e7b8f37d7af05d85a8c703e..12d98b7e6634103271ce5d82613f4453799c3773 100644 (file)
@@ -1,8 +1,10 @@
-from unittest.mock import patch
+import importlib
+from types import ModuleType
 
+import pytest
 from sqlmodel import create_engine
 
-from ....conftest import get_testing_print_function
+from ....conftest import PrintMock, needs_py310
 
 expected_calls = [
     [
@@ -50,15 +52,22 @@ expected_calls = [
 ]
 
 
-def test_tutorial():
-    from docs_src.tutorial.connect.select import tutorial005 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
+@pytest.fixture(
+    name="module",
+    params=[
+        "tutorial005",
+        pytest.param("tutorial005_py310", marks=needs_py310),
+    ],
+)
+def get_module(request: pytest.FixtureRequest) -> ModuleType:
+    module = importlib.import_module(
+        f"docs_src.tutorial.connect.select.{request.param}"
+    )
+    module.sqlite_url = "sqlite://"
+    module.engine = create_engine(module.sqlite_url)
+    return module
 
-    new_print = get_testing_print_function(calls)
 
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == expected_calls
+def test_tutorial(print_mock: PrintMock, module: ModuleType):
+    module.main()
+    assert print_mock.calls == expected_calls
diff --git a/tests/test_tutorial/test_connect/test_select/test_tutorial005_py310.py b/tests/test_tutorial/test_connect/test_select/test_tutorial005_py310.py
deleted file mode 100644 (file)
index 8cddb64..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-from unittest.mock import patch
-
-from sqlmodel import create_engine
-
-from ....conftest import get_testing_print_function, needs_py310
-
-expected_calls = [
-    [
-        "Created hero:",
-        {
-            "age": None,
-            "id": 1,
-            "secret_name": "Dive Wilson",
-            "team_id": 2,
-            "name": "Deadpond",
-        },
-    ],
-    [
-        "Created hero:",
-        {
-            "age": 48,
-            "id": 2,
-            "secret_name": "Tommy Sharp",
-            "team_id": 1,
-            "name": "Rusty-Man",
-        },
-    ],
-    [
-        "Created hero:",
-        {
-            "age": None,
-            "id": 3,
-            "secret_name": "Pedro Parqueador",
-            "team_id": None,
-            "name": "Spider-Boy",
-        },
-    ],
-    [
-        "Preventer Hero:",
-        {
-            "age": 48,
-            "id": 2,
-            "secret_name": "Tommy Sharp",
-            "team_id": 1,
-            "name": "Rusty-Man",
-        },
-        "Team:",
-        {"id": 1, "name": "Preventers", "headquarters": "Sharp Tower"},
-    ],
-]
-
-
-@needs_py310
-def test_tutorial():
-    from docs_src.tutorial.connect.select import tutorial005_py310 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == expected_calls
index d6875946c16041afc1d25bbc9a65fd797e6b9a6c..aa94c912160c35fac18703ad03fa4be0ff994c44 100644 (file)
@@ -1,8 +1,10 @@
-from unittest.mock import patch
+import importlib
+from types import ModuleType
 
+import pytest
 from sqlmodel import create_engine
 
-from ....conftest import get_testing_print_function
+from ....conftest import PrintMock, needs_py310
 
 expected_calls = [
     [
@@ -48,15 +50,22 @@ expected_calls = [
 ]
 
 
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.connect.update import tutorial001 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
+@pytest.fixture(
+    name="module",
+    params=[
+        "tutorial001",
+        pytest.param("tutorial001_py310", marks=needs_py310),
+    ],
+)
+def get_module(request: pytest.FixtureRequest) -> ModuleType:
+    module = importlib.import_module(
+        f"docs_src.tutorial.connect.update.{request.param}"
+    )
+    module.sqlite_url = "sqlite://"
+    module.engine = create_engine(module.sqlite_url)
+    return module
 
-    new_print = get_testing_print_function(calls)
 
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == expected_calls
+def test_tutorial(print_mock: PrintMock, module: ModuleType):
+    module.main()
+    assert print_mock.calls == expected_calls
diff --git a/tests/test_tutorial/test_connect/test_update/test_tutorial001_py310.py b/tests/test_tutorial/test_connect/test_update/test_tutorial001_py310.py
deleted file mode 100644 (file)
index f370265..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-from unittest.mock import patch
-
-from sqlmodel import create_engine
-
-from ....conftest import get_testing_print_function, needs_py310
-
-expected_calls = [
-    [
-        "Created hero:",
-        {
-            "age": None,
-            "id": 1,
-            "secret_name": "Dive Wilson",
-            "team_id": 2,
-            "name": "Deadpond",
-        },
-    ],
-    [
-        "Created hero:",
-        {
-            "age": 48,
-            "id": 2,
-            "secret_name": "Tommy Sharp",
-            "team_id": 1,
-            "name": "Rusty-Man",
-        },
-    ],
-    [
-        "Created hero:",
-        {
-            "age": None,
-            "id": 3,
-            "secret_name": "Pedro Parqueador",
-            "team_id": None,
-            "name": "Spider-Boy",
-        },
-    ],
-    [
-        "Updated hero:",
-        {
-            "age": None,
-            "id": 3,
-            "secret_name": "Pedro Parqueador",
-            "team_id": 1,
-            "name": "Spider-Boy",
-        },
-    ],
-]
-
-
-@needs_py310
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.connect.update import tutorial001_py310 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == expected_calls
index b6a2e72628703c042d050724a1be29843a02199d..4aeeb64b6c9ed7c7a9651a682be3c197b8c24eb6 100644 (file)
@@ -1,10 +1,19 @@
 from pathlib import Path
 
-from ...conftest import coverage_run
+import pytest
 
+from ...conftest import coverage_run, needs_py310
 
-def test_create_db_and_table(cov_tmp_path: Path):
-    module = "docs_src.tutorial.create_db_and_table.tutorial001"
+
+@pytest.mark.parametrize(
+    "module_name",
+    [
+        "tutorial001",
+        pytest.param("tutorial001_py310", marks=needs_py310),
+    ],
+)
+def test_create_db_and_table(cov_tmp_path: Path, module_name: str):
+    module = f"docs_src.tutorial.create_db_and_table.{module_name}"
     result = coverage_run(module=module, cwd=cov_tmp_path)
     assert "BEGIN" in result.stdout
     assert 'PRAGMA main.table_info("hero")' in result.stdout
diff --git a/tests/test_tutorial/test_create_db_and_table/test_tutorial001_py310.py b/tests/test_tutorial/test_create_db_and_table/test_tutorial001_py310.py
deleted file mode 100644 (file)
index 465b9f9..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-from pathlib import Path
-
-from ...conftest import coverage_run, needs_py310
-
-
-@needs_py310
-def test_create_db_and_table(cov_tmp_path: Path):
-    module = "docs_src.tutorial.create_db_and_table.tutorial001_py310"
-    result = coverage_run(module=module, cwd=cov_tmp_path)
-    assert "BEGIN" in result.stdout
-    assert 'PRAGMA main.table_info("hero")' in result.stdout
-    assert "CREATE TABLE hero (" in result.stdout
-    assert "id INTEGER NOT NULL," in result.stdout
-    assert "name VARCHAR NOT NULL," in result.stdout
-    assert "secret_name VARCHAR NOT NULL," in result.stdout
-    assert "age INTEGER," in result.stdout
-    assert "PRIMARY KEY (id)" in result.stdout
-    assert ")" in result.stdout
-    assert "COMMIT" in result.stdout
index 3a24ae1609ed7f22e04ebb90190b32ba855a3ca3..0f1ad85fe9f33a9b2bc6c17dca37502d009967e5 100644 (file)
@@ -1,13 +1,31 @@
+import importlib
+from types import ModuleType
+
+import pytest
 from sqlalchemy import inspect
 from sqlalchemy.engine.reflection import Inspector
 from sqlmodel import create_engine
 
+from ...conftest import needs_py310
+
+
+@pytest.fixture(
+    name="module",
+    params=[
+        "tutorial002",
+        pytest.param("tutorial002_py310", marks=needs_py310),
+    ],
+)
+def get_module(request: pytest.FixtureRequest) -> ModuleType:
+    module = importlib.import_module(
+        f"docs_src.tutorial.create_db_and_table.{request.param}"
+    )
+    module.sqlite_url = "sqlite://"
+    module.engine = create_engine(module.sqlite_url)
+    return module
 
-def test_create_db_and_table(clear_sqlmodel):
-    from docs_src.tutorial.create_db_and_table import tutorial002 as mod
 
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    mod.create_db_and_tables()
-    insp: Inspector = inspect(mod.engine)
-    assert insp.has_table(str(mod.Hero.__tablename__))
+def test_create_db_and_table(module: ModuleType):
+    module.create_db_and_tables()
+    insp: Inspector = inspect(module.engine)
+    assert insp.has_table(str(module.Hero.__tablename__))
diff --git a/tests/test_tutorial/test_create_db_and_table/test_tutorial002_py310.py b/tests/test_tutorial/test_create_db_and_table/test_tutorial002_py310.py
deleted file mode 100644 (file)
index 3ca3186..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-from sqlalchemy import inspect
-from sqlalchemy.engine.reflection import Inspector
-from sqlmodel import create_engine
-
-from ...conftest import needs_py310
-
-
-@needs_py310
-def test_create_db_and_table(clear_sqlmodel):
-    from docs_src.tutorial.create_db_and_table import tutorial002_py310 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    mod.create_db_and_tables()
-    insp: Inspector = inspect(mod.engine)
-    assert insp.has_table(str(mod.Hero.__tablename__))
index e5c55c70f31abd9548f3708114d85642541036ee..446feae71a7201da7956b20cd9c5afd29d3c7455 100644 (file)
@@ -1,13 +1,31 @@
+import importlib
+from types import ModuleType
+
+import pytest
 from sqlalchemy import inspect
 from sqlalchemy.engine.reflection import Inspector
 from sqlmodel import create_engine
 
+from ...conftest import needs_py310
+
+
+@pytest.fixture(
+    name="module",
+    params=[
+        "tutorial003",
+        pytest.param("tutorial003_py310", marks=needs_py310),
+    ],
+)
+def get_module(request: pytest.FixtureRequest) -> ModuleType:
+    module = importlib.import_module(
+        f"docs_src.tutorial.create_db_and_table.{request.param}"
+    )
+    module.sqlite_url = "sqlite://"
+    module.engine = create_engine(module.sqlite_url)
+    return module
 
-def test_create_db_and_table(clear_sqlmodel):
-    from docs_src.tutorial.create_db_and_table import tutorial003 as mod
 
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    mod.create_db_and_tables()
-    insp: Inspector = inspect(mod.engine)
-    assert insp.has_table(str(mod.Hero.__tablename__))
+def test_create_db_and_table(module: ModuleType):
+    module.create_db_and_tables()
+    insp: Inspector = inspect(module.engine)
+    assert insp.has_table(str(module.Hero.__tablename__))
diff --git a/tests/test_tutorial/test_create_db_and_table/test_tutorial003_py310.py b/tests/test_tutorial/test_create_db_and_table/test_tutorial003_py310.py
deleted file mode 100644 (file)
index a1806ce..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-from sqlalchemy import inspect
-from sqlalchemy.engine.reflection import Inspector
-from sqlmodel import create_engine
-
-from ...conftest import needs_py310
-
-
-@needs_py310
-def test_create_db_and_table(clear_sqlmodel):
-    from docs_src.tutorial.create_db_and_table import tutorial003_py310 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    mod.create_db_and_tables()
-    insp: Inspector = inspect(mod.engine)
-    assert insp.has_table(str(mod.Hero.__tablename__))
diff --git a/tests/test_tutorial/test_delete/test_tutorial001_py310_tutorial002_py310.py b/tests/test_tutorial/test_delete/test_tutorial001_py310_tutorial002_py310.py
deleted file mode 100644 (file)
index 0f97e74..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-from unittest.mock import patch
-
-from sqlmodel import create_engine
-
-from ...conftest import get_testing_print_function, needs_py310
-
-expected_calls = [
-    [
-        "Hero 1:",
-        {"id": 2, "name": "Spider-Boy", "secret_name": "Pedro Parqueador", "age": None},
-    ],
-    [
-        "Hero 2:",
-        {
-            "id": 7,
-            "name": "Captain North America",
-            "secret_name": "Esteban Rogelios",
-            "age": 93,
-        },
-    ],
-    [
-        "Updated hero 1:",
-        {
-            "id": 2,
-            "name": "Spider-Youngster",
-            "secret_name": "Pedro Parqueador",
-            "age": 16,
-        },
-    ],
-    [
-        "Updated hero 2:",
-        {
-            "id": 7,
-            "name": "Captain North America Except Canada",
-            "secret_name": "Esteban Rogelios",
-            "age": 110,
-        },
-    ],
-    [
-        "Hero: ",
-        {
-            "id": 2,
-            "name": "Spider-Youngster",
-            "secret_name": "Pedro Parqueador",
-            "age": 16,
-        },
-    ],
-    [
-        "Deleted hero:",
-        {
-            "id": 2,
-            "name": "Spider-Youngster",
-            "secret_name": "Pedro Parqueador",
-            "age": 16,
-        },
-    ],
-    ["There's no hero named Spider-Youngster"],
-]
-
-
-@needs_py310
-def test_tutorial001(clear_sqlmodel):
-    from docs_src.tutorial.delete import tutorial001_py310 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == expected_calls
-
-
-@needs_py310
-def test_tutorial002(clear_sqlmodel):
-    from docs_src.tutorial.delete import tutorial002_py310 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == expected_calls
index 1d6497b327896cb3d143a5a1b33102a8e4156867..3d755ae02777616160a9c55eaf0ac684210b32f9 100644 (file)
@@ -1,8 +1,10 @@
-from unittest.mock import patch
+import importlib
+from types import ModuleType
 
+import pytest
 from sqlmodel import create_engine
 
-from ...conftest import get_testing_print_function
+from ...conftest import PrintMock, needs_py310
 
 expected_calls = [
     [
@@ -58,29 +60,35 @@ expected_calls = [
 ]
 
 
-def test_tutorial001(clear_sqlmodel):
-    from docs_src.tutorial.delete import tutorial001 as mod
+@pytest.fixture(name="module")
+def get_module(request: pytest.FixtureRequest) -> ModuleType:
+    module = importlib.import_module(f"docs_src.tutorial.delete.{request.param}")
+    module.sqlite_url = "sqlite://"
+    module.engine = create_engine(module.sqlite_url)
+    return module
 
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
 
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == expected_calls
-
-
-def test_tutorial002(clear_sqlmodel):
-    from docs_src.tutorial.delete import tutorial002 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
+@pytest.mark.parametrize(
+    "module",
+    [
+        "tutorial001",
+        pytest.param("tutorial001_py310", marks=needs_py310),
+    ],
+    indirect=True,
+)
+def test_tutorial001(print_mock: PrintMock, module: ModuleType):
+    module.main()
+    assert print_mock.calls == expected_calls
 
-    new_print = get_testing_print_function(calls)
 
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == expected_calls
+@pytest.mark.parametrize(
+    "module",
+    [
+        "tutorial002",
+        pytest.param("tutorial002_py310", marks=needs_py310),
+    ],
+    indirect=True,
+)
+def test_tutorial002(print_mock: PrintMock, module: ModuleType):
+    module.main()
+    assert print_mock.calls == expected_calls
diff --git a/tests/test_tutorial/test_fastapi/test_app_testing/test_tutorial001_py310_tests_main.py b/tests/test_tutorial/test_fastapi/test_app_testing/test_tutorial001_py310_tests_main.py
deleted file mode 100644 (file)
index 781de7c..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-import subprocess
-from pathlib import Path
-
-from ....conftest import needs_py310
-
-
-@needs_py310
-def test_run_tests(clear_sqlmodel):
-    from docs_src.tutorial.fastapi.app_testing.tutorial001_py310 import test_main as mod
-
-    test_path = Path(mod.__file__).resolve().parent
-    top_level_path = Path(__file__).resolve().parent.parent.parent.parent.parent
-    result = subprocess.run(
-        [
-            "coverage",
-            "run",
-            "--parallel-mode",
-            "-m",
-            "pytest",
-            test_path,
-        ],
-        cwd=top_level_path,
-        capture_output=True,
-    )
-    assert result.returncode == 0, result.stdout.decode("utf-8")
diff --git a/tests/test_tutorial/test_fastapi/test_app_testing/test_tutorial001_py39_tests_main.py b/tests/test_tutorial/test_fastapi/test_app_testing/test_tutorial001_py39_tests_main.py
deleted file mode 100644 (file)
index 6dbcc80..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-import subprocess
-from pathlib import Path
-
-from ....conftest import needs_py39
-
-
-@needs_py39
-def test_run_tests(clear_sqlmodel):
-    from docs_src.tutorial.fastapi.app_testing.tutorial001_py39 import test_main as mod
-
-    test_path = Path(mod.__file__).resolve().parent
-    top_level_path = Path(__file__).resolve().parent.parent.parent.parent.parent
-    result = subprocess.run(
-        [
-            "coverage",
-            "run",
-            "--parallel-mode",
-            "-m",
-            "pytest",
-            test_path,
-        ],
-        cwd=top_level_path,
-        capture_output=True,
-    )
-    assert result.returncode == 0, result.stdout.decode("utf-8")
index 4da11c212183440304cfcd6c6fbf89a59b4c7a8d..95be986fc9f9d1677e215752a9832d072fe03620 100644 (file)
@@ -1,18 +1,44 @@
 import importlib
+import sys
+from dataclasses import dataclass
+from types import ModuleType
 
 import pytest
 
-from docs_src.tutorial.fastapi.app_testing.tutorial001 import main as app_mod
-from docs_src.tutorial.fastapi.app_testing.tutorial001 import test_main_001 as test_mod
+from tests.conftest import needs_py39, needs_py310
 
 
-@pytest.fixture(name="prepare", autouse=True)
-def prepare_fixture(clear_sqlmodel):
+@dataclass
+class Modules:
+    app: ModuleType
+    test: ModuleType
+
+
+@pytest.fixture(
+    name="modules_path",
+    params=[
+        "tutorial001",
+        pytest.param("tutorial001_py39", marks=needs_py39),
+        pytest.param("tutorial001_py310", marks=needs_py310),
+    ],
+)
+def get_modules_path(request: pytest.FixtureRequest) -> str:
+    return f"docs_src.tutorial.fastapi.app_testing.{request.param}"
+
+
+@pytest.fixture(name="modules")
+def load_modules(clear_sqlmodel, modules_path: str) -> Modules:
     # Trigger side effects of registering table models in SQLModel
     # This has to be called after clear_sqlmodel
-    importlib.reload(app_mod)
-    importlib.reload(test_mod)
+    app_mod_path = f"{modules_path}.main"
+    if app_mod_path in sys.modules:
+        app_mod = sys.modules[app_mod_path]
+        importlib.reload(app_mod)
+    else:
+        app_mod = importlib.import_module(app_mod_path)
+    test_mod = importlib.import_module(f"{modules_path}.test_main_001")
+    return Modules(app=app_mod, test=test_mod)
 
 
-def test_tutorial():
-    test_mod.test_create_hero()
+def test_tutorial(modules: Modules):
+    modules.test.test_create_hero()
index 241e92323b88db009d03dec7a50f4b8ecf28ff36..1f360c6f12ad150af6d13df0807b3fe0d91f41b5 100644 (file)
@@ -1,18 +1,44 @@
 import importlib
+import sys
+from dataclasses import dataclass
+from types import ModuleType
 
 import pytest
 
-from docs_src.tutorial.fastapi.app_testing.tutorial001 import main as app_mod
-from docs_src.tutorial.fastapi.app_testing.tutorial001 import test_main_002 as test_mod
+from tests.conftest import needs_py39, needs_py310
 
 
-@pytest.fixture(name="prepare", autouse=True)
-def prepare_fixture(clear_sqlmodel):
+@dataclass
+class Modules:
+    app: ModuleType
+    test: ModuleType
+
+
+@pytest.fixture(
+    name="modules_path",
+    params=[
+        "tutorial001",
+        pytest.param("tutorial001_py39", marks=needs_py39),
+        pytest.param("tutorial001_py310", marks=needs_py310),
+    ],
+)
+def get_modules_path(request: pytest.FixtureRequest) -> str:
+    return f"docs_src.tutorial.fastapi.app_testing.{request.param}"
+
+
+@pytest.fixture(name="modules")
+def load_modules(clear_sqlmodel, modules_path: str) -> Modules:
     # Trigger side effects of registering table models in SQLModel
     # This has to be called after clear_sqlmodel
-    importlib.reload(app_mod)
-    importlib.reload(test_mod)
+    app_mod_path = f"{modules_path}.main"
+    if app_mod_path in sys.modules:
+        app_mod = sys.modules[app_mod_path]
+        importlib.reload(app_mod)
+    else:
+        app_mod = importlib.import_module(app_mod_path)
+    test_mod = importlib.import_module(f"{modules_path}.test_main_002")
+    return Modules(app=app_mod, test=test_mod)
 
 
-def test_tutorial():
-    test_mod.test_create_hero()
+def test_tutorial(modules: Modules):
+    modules.test.test_create_hero()
index 32e0161bad805981301331802cbda4d551966460..4911173b62ca54dd2701f377265d25df49205478 100644 (file)
@@ -1,18 +1,44 @@
 import importlib
+import sys
+from dataclasses import dataclass
+from types import ModuleType
 
 import pytest
 
-from docs_src.tutorial.fastapi.app_testing.tutorial001 import main as app_mod
-from docs_src.tutorial.fastapi.app_testing.tutorial001 import test_main_003 as test_mod
+from tests.conftest import needs_py39, needs_py310
 
 
-@pytest.fixture(name="prepare", autouse=True)
-def prepare_fixture(clear_sqlmodel):
+@dataclass
+class Modules:
+    app: ModuleType
+    test: ModuleType
+
+
+@pytest.fixture(
+    name="modules_path",
+    params=[
+        "tutorial001",
+        pytest.param("tutorial001_py39", marks=needs_py39),
+        pytest.param("tutorial001_py310", marks=needs_py310),
+    ],
+)
+def get_modules_path(request: pytest.FixtureRequest) -> str:
+    return f"docs_src.tutorial.fastapi.app_testing.{request.param}"
+
+
+@pytest.fixture(name="modules")
+def load_modules(clear_sqlmodel, modules_path: str) -> Modules:
     # Trigger side effects of registering table models in SQLModel
     # This has to be called after clear_sqlmodel
-    importlib.reload(app_mod)
-    importlib.reload(test_mod)
+    app_mod_path = f"{modules_path}.main"
+    if app_mod_path in sys.modules:
+        app_mod = sys.modules[app_mod_path]
+        importlib.reload(app_mod)
+    else:
+        app_mod = importlib.import_module(app_mod_path)
+    test_mod = importlib.import_module(f"{modules_path}.test_main_003")
+    return Modules(app=app_mod, test=test_mod)
 
 
-def test_tutorial():
-    test_mod.test_create_hero()
+def test_tutorial(modules: Modules):
+    modules.test.test_create_hero()
index c6402b24291d426c191ab9577b8eb910cabf2d07..b3ca441d24a234947ff4c8f4e199489b2e24fdaf 100644 (file)
@@ -1,18 +1,44 @@
 import importlib
+import sys
+from dataclasses import dataclass
+from types import ModuleType
 
 import pytest
 
-from docs_src.tutorial.fastapi.app_testing.tutorial001 import main as app_mod
-from docs_src.tutorial.fastapi.app_testing.tutorial001 import test_main_004 as test_mod
+from tests.conftest import needs_py39, needs_py310
 
 
-@pytest.fixture(name="prepare", autouse=True)
-def prepare_fixture(clear_sqlmodel):
+@dataclass
+class Modules:
+    app: ModuleType
+    test: ModuleType
+
+
+@pytest.fixture(
+    name="modules_path",
+    params=[
+        "tutorial001",
+        pytest.param("tutorial001_py39", marks=needs_py39),
+        pytest.param("tutorial001_py310", marks=needs_py310),
+    ],
+)
+def get_modules_path(request: pytest.FixtureRequest) -> str:
+    return f"docs_src.tutorial.fastapi.app_testing.{request.param}"
+
+
+@pytest.fixture(name="modules")
+def load_modules(clear_sqlmodel, modules_path: str) -> Modules:
     # Trigger side effects of registering table models in SQLModel
     # This has to be called after clear_sqlmodel
-    importlib.reload(app_mod)
-    importlib.reload(test_mod)
+    app_mod_path = f"{modules_path}.main"
+    if app_mod_path in sys.modules:
+        app_mod = sys.modules[app_mod_path]
+        importlib.reload(app_mod)
+    else:
+        app_mod = importlib.import_module(app_mod_path)
+    test_mod = importlib.import_module(f"{modules_path}.test_main_004")
+    return Modules(app=app_mod, test=test_mod)
 
 
-def test_tutorial():
-    test_mod.test_create_hero()
+def test_tutorial(modules: Modules):
+    modules.test.test_create_hero()
index d7c1329b386daaa5bc5097ff7902038aeca619b0..28959f79d8acfdf0f4df406d970173c759a2aee1 100644 (file)
@@ -1,11 +1,30 @@
+import importlib
 import subprocess
 from pathlib import Path
+from types import ModuleType
 
+import pytest
 
-def test_run_tests(clear_sqlmodel):
-    from docs_src.tutorial.fastapi.app_testing.tutorial001 import test_main as mod
+from ....conftest import needs_py39, needs_py310
 
-    test_path = Path(mod.__file__).resolve().parent
+
+@pytest.fixture(
+    name="module",
+    params=[
+        "tutorial001",
+        pytest.param("tutorial001_py39", marks=needs_py39),
+        pytest.param("tutorial001_py310", marks=needs_py310),
+    ],
+)
+def get_module(request: pytest.FixtureRequest) -> ModuleType:
+    module = importlib.import_module(
+        f"docs_src.tutorial.fastapi.app_testing.{request.param}.test_main"
+    )
+    return module
+
+
+def test_run_tests(module: ModuleType):
+    test_path = Path(module.__file__).resolve().parent
     top_level_path = Path(__file__).resolve().parent.parent.parent.parent.parent
     result = subprocess.run(
         [
index f293199b4063c431a4ad85b98ecbef63579066de..1480a06f54a5294678a2e2c9ec6d563011f864c1 100644 (file)
@@ -1,18 +1,34 @@
+import importlib
+from types import ModuleType
+
+import pytest
 from dirty_equals import IsDict
 from fastapi.testclient import TestClient
 from sqlmodel import create_engine
 from sqlmodel.pool import StaticPool
 
+from tests.conftest import needs_py39, needs_py310
 
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.fastapi.delete import tutorial001 as mod
 
+@pytest.fixture(
+    name="module",
+    params=[
+        "tutorial001",
+        pytest.param("tutorial001_py39", marks=needs_py39),
+        pytest.param("tutorial001_py310", marks=needs_py310),
+    ],
+)
+def get_module(request: pytest.FixtureRequest) -> ModuleType:
+    mod = importlib.import_module(f"docs_src.tutorial.fastapi.delete.{request.param}")
     mod.sqlite_url = "sqlite://"
     mod.engine = create_engine(
         mod.sqlite_url, connect_args=mod.connect_args, poolclass=StaticPool
     )
+    return mod
+
 
-    with TestClient(mod.app) as client:
+def test_tutorial(module: ModuleType):
+    with TestClient(module.app) as client:
         hero1_data = {"name": "Deadpond", "secret_name": "Dive Wilson"}
         hero2_data = {
             "name": "Spider-Boy",
diff --git a/tests/test_tutorial/test_fastapi/test_delete/test_tutorial001_py310.py b/tests/test_tutorial/test_fastapi/test_delete/test_tutorial001_py310.py
deleted file mode 100644 (file)
index 2757c87..0000000
+++ /dev/null
@@ -1,377 +0,0 @@
-from dirty_equals import IsDict
-from fastapi.testclient import TestClient
-from sqlmodel import create_engine
-from sqlmodel.pool import StaticPool
-
-from ....conftest import needs_py310
-
-
-@needs_py310
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.fastapi.delete import tutorial001_py310 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(
-        mod.sqlite_url, connect_args=mod.connect_args, poolclass=StaticPool
-    )
-
-    with TestClient(mod.app) as client:
-        hero1_data = {"name": "Deadpond", "secret_name": "Dive Wilson"}
-        hero2_data = {
-            "name": "Spider-Boy",
-            "secret_name": "Pedro Parqueador",
-            "id": 9000,
-        }
-        hero3_data = {
-            "name": "Rusty-Man",
-            "secret_name": "Tommy Sharp",
-            "age": 48,
-        }
-        response = client.post("/heroes/", json=hero1_data)
-        assert response.status_code == 200, response.text
-        response = client.post("/heroes/", json=hero2_data)
-        assert response.status_code == 200, response.text
-        hero2 = response.json()
-        hero2_id = hero2["id"]
-        response = client.post("/heroes/", json=hero3_data)
-        assert response.status_code == 200, response.text
-        response = client.get(f"/heroes/{hero2_id}")
-        assert response.status_code == 200, response.text
-        response = client.get("/heroes/9000")
-        assert response.status_code == 404, response.text
-        response = client.get("/heroes/")
-        assert response.status_code == 200, response.text
-        data = response.json()
-        assert len(data) == 3
-        response = client.patch(
-            f"/heroes/{hero2_id}", json={"secret_name": "Spider-Youngster"}
-        )
-        assert response.status_code == 200, response.text
-        response = client.patch("/heroes/9001", json={"name": "Dragon Cube X"})
-        assert response.status_code == 404, response.text
-
-        response = client.delete(f"/heroes/{hero2_id}")
-        assert response.status_code == 200, response.text
-        response = client.get("/heroes/")
-        assert response.status_code == 200, response.text
-        data = response.json()
-        assert len(data) == 2
-
-        response = client.delete("/heroes/9000")
-        assert response.status_code == 404, response.text
-
-        response = client.get("/openapi.json")
-        assert response.status_code == 200, response.text
-        assert response.json() == {
-            "openapi": "3.1.0",
-            "info": {"title": "FastAPI", "version": "0.1.0"},
-            "paths": {
-                "/heroes/": {
-                    "get": {
-                        "summary": "Read Heroes",
-                        "operationId": "read_heroes_heroes__get",
-                        "parameters": [
-                            {
-                                "required": False,
-                                "schema": {
-                                    "title": "Offset",
-                                    "type": "integer",
-                                    "default": 0,
-                                },
-                                "name": "offset",
-                                "in": "query",
-                            },
-                            {
-                                "required": False,
-                                "schema": {
-                                    "title": "Limit",
-                                    "maximum": 100.0,
-                                    "type": "integer",
-                                    "default": 100,
-                                },
-                                "name": "limit",
-                                "in": "query",
-                            },
-                        ],
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "title": "Response Read Heroes Heroes  Get",
-                                            "type": "array",
-                                            "items": {
-                                                "$ref": "#/components/schemas/HeroPublic"
-                                            },
-                                        }
-                                    }
-                                },
-                            },
-                            "422": {
-                                "description": "Validation Error",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HTTPValidationError"
-                                        }
-                                    }
-                                },
-                            },
-                        },
-                    },
-                    "post": {
-                        "summary": "Create Hero",
-                        "operationId": "create_hero_heroes__post",
-                        "requestBody": {
-                            "content": {
-                                "application/json": {
-                                    "schema": {
-                                        "$ref": "#/components/schemas/HeroCreate"
-                                    }
-                                }
-                            },
-                            "required": True,
-                        },
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HeroPublic"
-                                        }
-                                    }
-                                },
-                            },
-                            "422": {
-                                "description": "Validation Error",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HTTPValidationError"
-                                        }
-                                    }
-                                },
-                            },
-                        },
-                    },
-                },
-                "/heroes/{hero_id}": {
-                    "get": {
-                        "summary": "Read Hero",
-                        "operationId": "read_hero_heroes__hero_id__get",
-                        "parameters": [
-                            {
-                                "required": True,
-                                "schema": {"title": "Hero Id", "type": "integer"},
-                                "name": "hero_id",
-                                "in": "path",
-                            }
-                        ],
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HeroPublic"
-                                        }
-                                    }
-                                },
-                            },
-                            "422": {
-                                "description": "Validation Error",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HTTPValidationError"
-                                        }
-                                    }
-                                },
-                            },
-                        },
-                    },
-                    "delete": {
-                        "summary": "Delete Hero",
-                        "operationId": "delete_hero_heroes__hero_id__delete",
-                        "parameters": [
-                            {
-                                "required": True,
-                                "schema": {"title": "Hero Id", "type": "integer"},
-                                "name": "hero_id",
-                                "in": "path",
-                            }
-                        ],
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {"application/json": {"schema": {}}},
-                            },
-                            "422": {
-                                "description": "Validation Error",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HTTPValidationError"
-                                        }
-                                    }
-                                },
-                            },
-                        },
-                    },
-                    "patch": {
-                        "summary": "Update Hero",
-                        "operationId": "update_hero_heroes__hero_id__patch",
-                        "parameters": [
-                            {
-                                "required": True,
-                                "schema": {"title": "Hero Id", "type": "integer"},
-                                "name": "hero_id",
-                                "in": "path",
-                            }
-                        ],
-                        "requestBody": {
-                            "content": {
-                                "application/json": {
-                                    "schema": {
-                                        "$ref": "#/components/schemas/HeroUpdate"
-                                    }
-                                }
-                            },
-                            "required": True,
-                        },
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HeroPublic"
-                                        }
-                                    }
-                                },
-                            },
-                            "422": {
-                                "description": "Validation Error",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HTTPValidationError"
-                                        }
-                                    }
-                                },
-                            },
-                        },
-                    },
-                },
-            },
-            "components": {
-                "schemas": {
-                    "HTTPValidationError": {
-                        "title": "HTTPValidationError",
-                        "type": "object",
-                        "properties": {
-                            "detail": {
-                                "title": "Detail",
-                                "type": "array",
-                                "items": {
-                                    "$ref": "#/components/schemas/ValidationError"
-                                },
-                            }
-                        },
-                    },
-                    "HeroCreate": {
-                        "title": "HeroCreate",
-                        "required": ["name", "secret_name"],
-                        "type": "object",
-                        "properties": {
-                            "name": {"title": "Name", "type": "string"},
-                            "secret_name": {"title": "Secret Name", "type": "string"},
-                            "age": IsDict(
-                                {
-                                    "title": "Age",
-                                    "anyOf": [{"type": "integer"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Age", "type": "integer"}
-                            ),
-                        },
-                    },
-                    "HeroPublic": {
-                        "title": "HeroPublic",
-                        "required": ["name", "secret_name", "id"],
-                        "type": "object",
-                        "properties": {
-                            "name": {"title": "Name", "type": "string"},
-                            "secret_name": {"title": "Secret Name", "type": "string"},
-                            "age": IsDict(
-                                {
-                                    "title": "Age",
-                                    "anyOf": [{"type": "integer"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Age", "type": "integer"}
-                            ),
-                            "id": {"title": "Id", "type": "integer"},
-                        },
-                    },
-                    "HeroUpdate": {
-                        "title": "HeroUpdate",
-                        "type": "object",
-                        "properties": {
-                            "name": IsDict(
-                                {
-                                    "title": "Name",
-                                    "anyOf": [{"type": "string"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Name", "type": "string"}
-                            ),
-                            "secret_name": IsDict(
-                                {
-                                    "title": "Secret Name",
-                                    "anyOf": [{"type": "string"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Secret Name", "type": "string"}
-                            ),
-                            "age": IsDict(
-                                {
-                                    "title": "Age",
-                                    "anyOf": [{"type": "integer"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Age", "type": "integer"}
-                            ),
-                        },
-                    },
-                    "ValidationError": {
-                        "title": "ValidationError",
-                        "required": ["loc", "msg", "type"],
-                        "type": "object",
-                        "properties": {
-                            "loc": {
-                                "title": "Location",
-                                "type": "array",
-                                "items": {
-                                    "anyOf": [{"type": "string"}, {"type": "integer"}]
-                                },
-                            },
-                            "msg": {"title": "Message", "type": "string"},
-                            "type": {"title": "Error Type", "type": "string"},
-                        },
-                    },
-                }
-            },
-        }
diff --git a/tests/test_tutorial/test_fastapi/test_delete/test_tutorial001_py39.py b/tests/test_tutorial/test_fastapi/test_delete/test_tutorial001_py39.py
deleted file mode 100644 (file)
index 3299086..0000000
+++ /dev/null
@@ -1,377 +0,0 @@
-from dirty_equals import IsDict
-from fastapi.testclient import TestClient
-from sqlmodel import create_engine
-from sqlmodel.pool import StaticPool
-
-from ....conftest import needs_py39
-
-
-@needs_py39
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.fastapi.delete import tutorial001_py39 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(
-        mod.sqlite_url, connect_args=mod.connect_args, poolclass=StaticPool
-    )
-
-    with TestClient(mod.app) as client:
-        hero1_data = {"name": "Deadpond", "secret_name": "Dive Wilson"}
-        hero2_data = {
-            "name": "Spider-Boy",
-            "secret_name": "Pedro Parqueador",
-            "id": 9000,
-        }
-        hero3_data = {
-            "name": "Rusty-Man",
-            "secret_name": "Tommy Sharp",
-            "age": 48,
-        }
-        response = client.post("/heroes/", json=hero1_data)
-        assert response.status_code == 200, response.text
-        response = client.post("/heroes/", json=hero2_data)
-        assert response.status_code == 200, response.text
-        hero2 = response.json()
-        hero2_id = hero2["id"]
-        response = client.post("/heroes/", json=hero3_data)
-        assert response.status_code == 200, response.text
-        response = client.get(f"/heroes/{hero2_id}")
-        assert response.status_code == 200, response.text
-        response = client.get("/heroes/9000")
-        assert response.status_code == 404, response.text
-        response = client.get("/heroes/")
-        assert response.status_code == 200, response.text
-        data = response.json()
-        assert len(data) == 3
-        response = client.patch(
-            f"/heroes/{hero2_id}", json={"secret_name": "Spider-Youngster"}
-        )
-        assert response.status_code == 200, response.text
-        response = client.patch("/heroes/9001", json={"name": "Dragon Cube X"})
-        assert response.status_code == 404, response.text
-
-        response = client.delete(f"/heroes/{hero2_id}")
-        assert response.status_code == 200, response.text
-        response = client.get("/heroes/")
-        assert response.status_code == 200, response.text
-        data = response.json()
-        assert len(data) == 2
-
-        response = client.delete("/heroes/9000")
-        assert response.status_code == 404, response.text
-
-        response = client.get("/openapi.json")
-        assert response.status_code == 200, response.text
-        assert response.json() == {
-            "openapi": "3.1.0",
-            "info": {"title": "FastAPI", "version": "0.1.0"},
-            "paths": {
-                "/heroes/": {
-                    "get": {
-                        "summary": "Read Heroes",
-                        "operationId": "read_heroes_heroes__get",
-                        "parameters": [
-                            {
-                                "required": False,
-                                "schema": {
-                                    "title": "Offset",
-                                    "type": "integer",
-                                    "default": 0,
-                                },
-                                "name": "offset",
-                                "in": "query",
-                            },
-                            {
-                                "required": False,
-                                "schema": {
-                                    "title": "Limit",
-                                    "maximum": 100.0,
-                                    "type": "integer",
-                                    "default": 100,
-                                },
-                                "name": "limit",
-                                "in": "query",
-                            },
-                        ],
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "title": "Response Read Heroes Heroes  Get",
-                                            "type": "array",
-                                            "items": {
-                                                "$ref": "#/components/schemas/HeroPublic"
-                                            },
-                                        }
-                                    }
-                                },
-                            },
-                            "422": {
-                                "description": "Validation Error",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HTTPValidationError"
-                                        }
-                                    }
-                                },
-                            },
-                        },
-                    },
-                    "post": {
-                        "summary": "Create Hero",
-                        "operationId": "create_hero_heroes__post",
-                        "requestBody": {
-                            "content": {
-                                "application/json": {
-                                    "schema": {
-                                        "$ref": "#/components/schemas/HeroCreate"
-                                    }
-                                }
-                            },
-                            "required": True,
-                        },
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HeroPublic"
-                                        }
-                                    }
-                                },
-                            },
-                            "422": {
-                                "description": "Validation Error",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HTTPValidationError"
-                                        }
-                                    }
-                                },
-                            },
-                        },
-                    },
-                },
-                "/heroes/{hero_id}": {
-                    "get": {
-                        "summary": "Read Hero",
-                        "operationId": "read_hero_heroes__hero_id__get",
-                        "parameters": [
-                            {
-                                "required": True,
-                                "schema": {"title": "Hero Id", "type": "integer"},
-                                "name": "hero_id",
-                                "in": "path",
-                            }
-                        ],
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HeroPublic"
-                                        }
-                                    }
-                                },
-                            },
-                            "422": {
-                                "description": "Validation Error",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HTTPValidationError"
-                                        }
-                                    }
-                                },
-                            },
-                        },
-                    },
-                    "delete": {
-                        "summary": "Delete Hero",
-                        "operationId": "delete_hero_heroes__hero_id__delete",
-                        "parameters": [
-                            {
-                                "required": True,
-                                "schema": {"title": "Hero Id", "type": "integer"},
-                                "name": "hero_id",
-                                "in": "path",
-                            }
-                        ],
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {"application/json": {"schema": {}}},
-                            },
-                            "422": {
-                                "description": "Validation Error",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HTTPValidationError"
-                                        }
-                                    }
-                                },
-                            },
-                        },
-                    },
-                    "patch": {
-                        "summary": "Update Hero",
-                        "operationId": "update_hero_heroes__hero_id__patch",
-                        "parameters": [
-                            {
-                                "required": True,
-                                "schema": {"title": "Hero Id", "type": "integer"},
-                                "name": "hero_id",
-                                "in": "path",
-                            }
-                        ],
-                        "requestBody": {
-                            "content": {
-                                "application/json": {
-                                    "schema": {
-                                        "$ref": "#/components/schemas/HeroUpdate"
-                                    }
-                                }
-                            },
-                            "required": True,
-                        },
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HeroPublic"
-                                        }
-                                    }
-                                },
-                            },
-                            "422": {
-                                "description": "Validation Error",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HTTPValidationError"
-                                        }
-                                    }
-                                },
-                            },
-                        },
-                    },
-                },
-            },
-            "components": {
-                "schemas": {
-                    "HTTPValidationError": {
-                        "title": "HTTPValidationError",
-                        "type": "object",
-                        "properties": {
-                            "detail": {
-                                "title": "Detail",
-                                "type": "array",
-                                "items": {
-                                    "$ref": "#/components/schemas/ValidationError"
-                                },
-                            }
-                        },
-                    },
-                    "HeroCreate": {
-                        "title": "HeroCreate",
-                        "required": ["name", "secret_name"],
-                        "type": "object",
-                        "properties": {
-                            "name": {"title": "Name", "type": "string"},
-                            "secret_name": {"title": "Secret Name", "type": "string"},
-                            "age": IsDict(
-                                {
-                                    "title": "Age",
-                                    "anyOf": [{"type": "integer"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Age", "type": "integer"}
-                            ),
-                        },
-                    },
-                    "HeroPublic": {
-                        "title": "HeroPublic",
-                        "required": ["name", "secret_name", "id"],
-                        "type": "object",
-                        "properties": {
-                            "name": {"title": "Name", "type": "string"},
-                            "secret_name": {"title": "Secret Name", "type": "string"},
-                            "age": IsDict(
-                                {
-                                    "title": "Age",
-                                    "anyOf": [{"type": "integer"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Age", "type": "integer"}
-                            ),
-                            "id": {"title": "Id", "type": "integer"},
-                        },
-                    },
-                    "HeroUpdate": {
-                        "title": "HeroUpdate",
-                        "type": "object",
-                        "properties": {
-                            "name": IsDict(
-                                {
-                                    "title": "Name",
-                                    "anyOf": [{"type": "string"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Name", "type": "string"}
-                            ),
-                            "secret_name": IsDict(
-                                {
-                                    "title": "Secret Name",
-                                    "anyOf": [{"type": "string"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Secret Name", "type": "string"}
-                            ),
-                            "age": IsDict(
-                                {
-                                    "title": "Age",
-                                    "anyOf": [{"type": "integer"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Age", "type": "integer"}
-                            ),
-                        },
-                    },
-                    "ValidationError": {
-                        "title": "ValidationError",
-                        "required": ["loc", "msg", "type"],
-                        "type": "object",
-                        "properties": {
-                            "loc": {
-                                "title": "Location",
-                                "type": "array",
-                                "items": {
-                                    "anyOf": [{"type": "string"}, {"type": "integer"}]
-                                },
-                            },
-                            "msg": {"title": "Message", "type": "string"},
-                            "type": {"title": "Error Type", "type": "string"},
-                        },
-                    },
-                }
-            },
-        }
index 4047539f0a29d1cbe108367840cf65848066a39a..dc3db8b5b0a0fda686da6272674873d9969aa106 100644 (file)
@@ -1,18 +1,36 @@
+import importlib
+from types import ModuleType
+
+import pytest
 from dirty_equals import IsDict
 from fastapi.testclient import TestClient
 from sqlmodel import create_engine
 from sqlmodel.pool import StaticPool
 
+from tests.conftest import needs_py39, needs_py310
 
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.fastapi.limit_and_offset import tutorial001 as mod
 
+@pytest.fixture(
+    name="module",
+    params=[
+        "tutorial001",
+        pytest.param("tutorial001_py39", marks=needs_py39),
+        pytest.param("tutorial001_py310", marks=needs_py310),
+    ],
+)
+def get_module(request: pytest.FixtureRequest) -> ModuleType:
+    mod = importlib.import_module(
+        f"docs_src.tutorial.fastapi.limit_and_offset.{request.param}"
+    )
     mod.sqlite_url = "sqlite://"
     mod.engine = create_engine(
         mod.sqlite_url, connect_args=mod.connect_args, poolclass=StaticPool
     )
+    return mod
+
 
-    with TestClient(mod.app) as client:
+def test_tutorial(module: ModuleType):
+    with TestClient(module.app) as client:
         hero1_data = {"name": "Deadpond", "secret_name": "Dive Wilson"}
         hero2_data = {
             "name": "Spider-Boy",
diff --git a/tests/test_tutorial/test_fastapi/test_limit_and_offset/test_tutorial001_py310.py b/tests/test_tutorial/test_fastapi/test_limit_and_offset/test_tutorial001_py310.py
deleted file mode 100644 (file)
index 480b92a..0000000
+++ /dev/null
@@ -1,274 +0,0 @@
-from dirty_equals import IsDict
-from fastapi.testclient import TestClient
-from sqlmodel import create_engine
-from sqlmodel.pool import StaticPool
-
-from ....conftest import needs_py310
-
-
-@needs_py310
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.fastapi.limit_and_offset import tutorial001_py310 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(
-        mod.sqlite_url, connect_args=mod.connect_args, poolclass=StaticPool
-    )
-
-    with TestClient(mod.app) as client:
-        hero1_data = {"name": "Deadpond", "secret_name": "Dive Wilson"}
-        hero2_data = {
-            "name": "Spider-Boy",
-            "secret_name": "Pedro Parqueador",
-            "id": 9000,
-        }
-        hero3_data = {
-            "name": "Rusty-Man",
-            "secret_name": "Tommy Sharp",
-            "age": 48,
-        }
-        response = client.post("/heroes/", json=hero1_data)
-        assert response.status_code == 200, response.text
-        response = client.post("/heroes/", json=hero2_data)
-        assert response.status_code == 200, response.text
-        hero2 = response.json()
-        hero_id = hero2["id"]
-        response = client.post("/heroes/", json=hero3_data)
-        assert response.status_code == 200, response.text
-        response = client.get(f"/heroes/{hero_id}")
-        assert response.status_code == 200, response.text
-        response = client.get("/heroes/9000")
-        assert response.status_code == 404, response.text
-
-        response = client.get("/heroes/")
-        assert response.status_code == 200, response.text
-        data = response.json()
-        assert len(data) == 3
-
-        response = client.get("/heroes/", params={"limit": 2})
-        assert response.status_code == 200, response.text
-        data = response.json()
-        assert len(data) == 2
-        assert data[0]["name"] == hero1_data["name"]
-        assert data[1]["name"] == hero2_data["name"]
-
-        response = client.get("/heroes/", params={"offset": 1})
-        assert response.status_code == 200, response.text
-        data = response.json()
-        assert len(data) == 2
-        assert data[0]["name"] == hero2_data["name"]
-        assert data[1]["name"] == hero3_data["name"]
-
-        response = client.get("/heroes/", params={"offset": 1, "limit": 1})
-        assert response.status_code == 200, response.text
-        data = response.json()
-        assert len(data) == 1
-        assert data[0]["name"] == hero2_data["name"]
-
-        response = client.get("/openapi.json")
-        assert response.status_code == 200, response.text
-        assert response.json() == {
-            "openapi": "3.1.0",
-            "info": {"title": "FastAPI", "version": "0.1.0"},
-            "paths": {
-                "/heroes/": {
-                    "get": {
-                        "summary": "Read Heroes",
-                        "operationId": "read_heroes_heroes__get",
-                        "parameters": [
-                            {
-                                "required": False,
-                                "schema": {
-                                    "title": "Offset",
-                                    "type": "integer",
-                                    "default": 0,
-                                },
-                                "name": "offset",
-                                "in": "query",
-                            },
-                            {
-                                "required": False,
-                                "schema": {
-                                    "title": "Limit",
-                                    "maximum": 100.0,
-                                    "type": "integer",
-                                    "default": 100,
-                                },
-                                "name": "limit",
-                                "in": "query",
-                            },
-                        ],
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "title": "Response Read Heroes Heroes  Get",
-                                            "type": "array",
-                                            "items": {
-                                                "$ref": "#/components/schemas/HeroPublic"
-                                            },
-                                        }
-                                    }
-                                },
-                            },
-                            "422": {
-                                "description": "Validation Error",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HTTPValidationError"
-                                        }
-                                    }
-                                },
-                            },
-                        },
-                    },
-                    "post": {
-                        "summary": "Create Hero",
-                        "operationId": "create_hero_heroes__post",
-                        "requestBody": {
-                            "content": {
-                                "application/json": {
-                                    "schema": {
-                                        "$ref": "#/components/schemas/HeroCreate"
-                                    }
-                                }
-                            },
-                            "required": True,
-                        },
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HeroPublic"
-                                        }
-                                    }
-                                },
-                            },
-                            "422": {
-                                "description": "Validation Error",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HTTPValidationError"
-                                        }
-                                    }
-                                },
-                            },
-                        },
-                    },
-                },
-                "/heroes/{hero_id}": {
-                    "get": {
-                        "summary": "Read Hero",
-                        "operationId": "read_hero_heroes__hero_id__get",
-                        "parameters": [
-                            {
-                                "required": True,
-                                "schema": {"title": "Hero Id", "type": "integer"},
-                                "name": "hero_id",
-                                "in": "path",
-                            }
-                        ],
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HeroPublic"
-                                        }
-                                    }
-                                },
-                            },
-                            "422": {
-                                "description": "Validation Error",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HTTPValidationError"
-                                        }
-                                    }
-                                },
-                            },
-                        },
-                    }
-                },
-            },
-            "components": {
-                "schemas": {
-                    "HTTPValidationError": {
-                        "title": "HTTPValidationError",
-                        "type": "object",
-                        "properties": {
-                            "detail": {
-                                "title": "Detail",
-                                "type": "array",
-                                "items": {
-                                    "$ref": "#/components/schemas/ValidationError"
-                                },
-                            }
-                        },
-                    },
-                    "HeroCreate": {
-                        "title": "HeroCreate",
-                        "required": ["name", "secret_name"],
-                        "type": "object",
-                        "properties": {
-                            "name": {"title": "Name", "type": "string"},
-                            "secret_name": {"title": "Secret Name", "type": "string"},
-                            "age": IsDict(
-                                {
-                                    "title": "Age",
-                                    "anyOf": [{"type": "integer"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Age", "type": "integer"}
-                            ),
-                        },
-                    },
-                    "HeroPublic": {
-                        "title": "HeroPublic",
-                        "required": ["name", "secret_name", "id"],
-                        "type": "object",
-                        "properties": {
-                            "name": {"title": "Name", "type": "string"},
-                            "secret_name": {"title": "Secret Name", "type": "string"},
-                            "age": IsDict(
-                                {
-                                    "title": "Age",
-                                    "anyOf": [{"type": "integer"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Age", "type": "integer"}
-                            ),
-                            "id": {"title": "Id", "type": "integer"},
-                        },
-                    },
-                    "ValidationError": {
-                        "title": "ValidationError",
-                        "required": ["loc", "msg", "type"],
-                        "type": "object",
-                        "properties": {
-                            "loc": {
-                                "title": "Location",
-                                "type": "array",
-                                "items": {
-                                    "anyOf": [{"type": "string"}, {"type": "integer"}]
-                                },
-                            },
-                            "msg": {"title": "Message", "type": "string"},
-                            "type": {"title": "Error Type", "type": "string"},
-                        },
-                    },
-                }
-            },
-        }
diff --git a/tests/test_tutorial/test_fastapi/test_limit_and_offset/test_tutorial001_py39.py b/tests/test_tutorial/test_fastapi/test_limit_and_offset/test_tutorial001_py39.py
deleted file mode 100644 (file)
index 0a9d5c9..0000000
+++ /dev/null
@@ -1,274 +0,0 @@
-from dirty_equals import IsDict
-from fastapi.testclient import TestClient
-from sqlmodel import create_engine
-from sqlmodel.pool import StaticPool
-
-from ....conftest import needs_py39
-
-
-@needs_py39
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.fastapi.limit_and_offset import tutorial001_py39 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(
-        mod.sqlite_url, connect_args=mod.connect_args, poolclass=StaticPool
-    )
-
-    with TestClient(mod.app) as client:
-        hero1_data = {"name": "Deadpond", "secret_name": "Dive Wilson"}
-        hero2_data = {
-            "name": "Spider-Boy",
-            "secret_name": "Pedro Parqueador",
-            "id": 9000,
-        }
-        hero3_data = {
-            "name": "Rusty-Man",
-            "secret_name": "Tommy Sharp",
-            "age": 48,
-        }
-        response = client.post("/heroes/", json=hero1_data)
-        assert response.status_code == 200, response.text
-        response = client.post("/heroes/", json=hero2_data)
-        assert response.status_code == 200, response.text
-        hero2 = response.json()
-        hero_id = hero2["id"]
-        response = client.post("/heroes/", json=hero3_data)
-        assert response.status_code == 200, response.text
-        response = client.get(f"/heroes/{hero_id}")
-        assert response.status_code == 200, response.text
-        response = client.get("/heroes/9000")
-        assert response.status_code == 404, response.text
-
-        response = client.get("/heroes/")
-        assert response.status_code == 200, response.text
-        data = response.json()
-        assert len(data) == 3
-
-        response = client.get("/heroes/", params={"limit": 2})
-        assert response.status_code == 200, response.text
-        data = response.json()
-        assert len(data) == 2
-        assert data[0]["name"] == hero1_data["name"]
-        assert data[1]["name"] == hero2_data["name"]
-
-        response = client.get("/heroes/", params={"offset": 1})
-        assert response.status_code == 200, response.text
-        data = response.json()
-        assert len(data) == 2
-        assert data[0]["name"] == hero2_data["name"]
-        assert data[1]["name"] == hero3_data["name"]
-
-        response = client.get("/heroes/", params={"offset": 1, "limit": 1})
-        assert response.status_code == 200, response.text
-        data = response.json()
-        assert len(data) == 1
-        assert data[0]["name"] == hero2_data["name"]
-
-        response = client.get("/openapi.json")
-        assert response.status_code == 200, response.text
-        assert response.json() == {
-            "openapi": "3.1.0",
-            "info": {"title": "FastAPI", "version": "0.1.0"},
-            "paths": {
-                "/heroes/": {
-                    "get": {
-                        "summary": "Read Heroes",
-                        "operationId": "read_heroes_heroes__get",
-                        "parameters": [
-                            {
-                                "required": False,
-                                "schema": {
-                                    "title": "Offset",
-                                    "type": "integer",
-                                    "default": 0,
-                                },
-                                "name": "offset",
-                                "in": "query",
-                            },
-                            {
-                                "required": False,
-                                "schema": {
-                                    "title": "Limit",
-                                    "maximum": 100.0,
-                                    "type": "integer",
-                                    "default": 100,
-                                },
-                                "name": "limit",
-                                "in": "query",
-                            },
-                        ],
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "title": "Response Read Heroes Heroes  Get",
-                                            "type": "array",
-                                            "items": {
-                                                "$ref": "#/components/schemas/HeroPublic"
-                                            },
-                                        }
-                                    }
-                                },
-                            },
-                            "422": {
-                                "description": "Validation Error",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HTTPValidationError"
-                                        }
-                                    }
-                                },
-                            },
-                        },
-                    },
-                    "post": {
-                        "summary": "Create Hero",
-                        "operationId": "create_hero_heroes__post",
-                        "requestBody": {
-                            "content": {
-                                "application/json": {
-                                    "schema": {
-                                        "$ref": "#/components/schemas/HeroCreate"
-                                    }
-                                }
-                            },
-                            "required": True,
-                        },
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HeroPublic"
-                                        }
-                                    }
-                                },
-                            },
-                            "422": {
-                                "description": "Validation Error",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HTTPValidationError"
-                                        }
-                                    }
-                                },
-                            },
-                        },
-                    },
-                },
-                "/heroes/{hero_id}": {
-                    "get": {
-                        "summary": "Read Hero",
-                        "operationId": "read_hero_heroes__hero_id__get",
-                        "parameters": [
-                            {
-                                "required": True,
-                                "schema": {"title": "Hero Id", "type": "integer"},
-                                "name": "hero_id",
-                                "in": "path",
-                            }
-                        ],
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HeroPublic"
-                                        }
-                                    }
-                                },
-                            },
-                            "422": {
-                                "description": "Validation Error",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HTTPValidationError"
-                                        }
-                                    }
-                                },
-                            },
-                        },
-                    }
-                },
-            },
-            "components": {
-                "schemas": {
-                    "HTTPValidationError": {
-                        "title": "HTTPValidationError",
-                        "type": "object",
-                        "properties": {
-                            "detail": {
-                                "title": "Detail",
-                                "type": "array",
-                                "items": {
-                                    "$ref": "#/components/schemas/ValidationError"
-                                },
-                            }
-                        },
-                    },
-                    "HeroCreate": {
-                        "title": "HeroCreate",
-                        "required": ["name", "secret_name"],
-                        "type": "object",
-                        "properties": {
-                            "name": {"title": "Name", "type": "string"},
-                            "secret_name": {"title": "Secret Name", "type": "string"},
-                            "age": IsDict(
-                                {
-                                    "title": "Age",
-                                    "anyOf": [{"type": "integer"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Age", "type": "integer"}
-                            ),
-                        },
-                    },
-                    "HeroPublic": {
-                        "title": "HeroPublic",
-                        "required": ["name", "secret_name", "id"],
-                        "type": "object",
-                        "properties": {
-                            "name": {"title": "Name", "type": "string"},
-                            "secret_name": {"title": "Secret Name", "type": "string"},
-                            "age": IsDict(
-                                {
-                                    "title": "Age",
-                                    "anyOf": [{"type": "integer"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Age", "type": "integer"}
-                            ),
-                            "id": {"title": "Id", "type": "integer"},
-                        },
-                    },
-                    "ValidationError": {
-                        "title": "ValidationError",
-                        "required": ["loc", "msg", "type"],
-                        "type": "object",
-                        "properties": {
-                            "loc": {
-                                "title": "Location",
-                                "type": "array",
-                                "items": {
-                                    "anyOf": [{"type": "string"}, {"type": "integer"}]
-                                },
-                            },
-                            "msg": {"title": "Message", "type": "string"},
-                            "type": {"title": "Error Type", "type": "string"},
-                        },
-                    },
-                }
-            },
-        }
index 276a021c54b91615c391dd2210cb6b288924f265..27629c891d6894bedd703d24cea8bd5d75b0e82b 100644 (file)
@@ -1,3 +1,7 @@
+import importlib
+from types import ModuleType
+
+import pytest
 from dirty_equals import IsDict
 from fastapi.testclient import TestClient
 from sqlalchemy import inspect
@@ -5,16 +9,30 @@ from sqlalchemy.engine.reflection import Inspector
 from sqlmodel import create_engine
 from sqlmodel.pool import StaticPool
 
+from tests.conftest import needs_py39, needs_py310
 
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.fastapi.multiple_models import tutorial001 as mod
 
+@pytest.fixture(
+    name="module",
+    params=[
+        "tutorial001",
+        pytest.param("tutorial001_py39", marks=needs_py39),
+        pytest.param("tutorial001_py310", marks=needs_py310),
+    ],
+)
+def get_module(request: pytest.FixtureRequest) -> ModuleType:
+    mod = importlib.import_module(
+        f"docs_src.tutorial.fastapi.multiple_models.{request.param}"
+    )
     mod.sqlite_url = "sqlite://"
     mod.engine = create_engine(
         mod.sqlite_url, connect_args=mod.connect_args, poolclass=StaticPool
     )
+    return mod
+
 
-    with TestClient(mod.app) as client:
+def test_tutorial(module: ModuleType):
+    with TestClient(module.app) as client:
         hero1_data = {"name": "Deadpond", "secret_name": "Dive Wilson"}
         hero2_data = {
             "name": "Spider-Boy",
@@ -195,8 +213,8 @@ def test_tutorial(clear_sqlmodel):
         }
 
     # Test inherited indexes
-    insp: Inspector = inspect(mod.engine)
-    indexes = insp.get_indexes(str(mod.Hero.__tablename__))
+    insp: Inspector = inspect(module.engine)
+    indexes = insp.get_indexes(str(module.Hero.__tablename__))
     expected_indexes = [
         {
             "name": "ix_hero_name",
diff --git a/tests/test_tutorial/test_fastapi/test_multiple_models/test_tutorial001_py310.py b/tests/test_tutorial/test_fastapi/test_multiple_models/test_tutorial001_py310.py
deleted file mode 100644 (file)
index b6f082a..0000000
+++ /dev/null
@@ -1,220 +0,0 @@
-from dirty_equals import IsDict
-from fastapi.testclient import TestClient
-from sqlalchemy import inspect
-from sqlalchemy.engine.reflection import Inspector
-from sqlmodel import create_engine
-from sqlmodel.pool import StaticPool
-
-from ....conftest import needs_py310
-
-
-@needs_py310
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.fastapi.multiple_models import tutorial001_py310 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(
-        mod.sqlite_url, connect_args=mod.connect_args, poolclass=StaticPool
-    )
-
-    with TestClient(mod.app) as client:
-        hero1_data = {"name": "Deadpond", "secret_name": "Dive Wilson"}
-        hero2_data = {
-            "name": "Spider-Boy",
-            "secret_name": "Pedro Parqueador",
-            "id": 9000,
-        }
-        response = client.post("/heroes/", json=hero1_data)
-        data = response.json()
-
-        assert response.status_code == 200, response.text
-        assert data["name"] == hero1_data["name"]
-        assert data["secret_name"] == hero1_data["secret_name"]
-        assert data["id"] is not None
-        assert data["age"] is None
-
-        response = client.post("/heroes/", json=hero2_data)
-        data = response.json()
-
-        assert response.status_code == 200, response.text
-        assert data["name"] == hero2_data["name"]
-        assert data["secret_name"] == hero2_data["secret_name"]
-        assert data["id"] != hero2_data["id"], (
-            "Now it's not possible to predefine the ID from the request, "
-            "it's now set by the database"
-        )
-        assert data["age"] is None
-
-        response = client.get("/heroes/")
-        data = response.json()
-
-        assert response.status_code == 200, response.text
-        assert len(data) == 2
-        assert data[0]["name"] == hero1_data["name"]
-        assert data[0]["secret_name"] == hero1_data["secret_name"]
-        assert data[1]["name"] == hero2_data["name"]
-        assert data[1]["secret_name"] == hero2_data["secret_name"]
-        assert data[1]["id"] != hero2_data["id"]
-
-        response = client.get("/openapi.json")
-        assert response.status_code == 200, response.text
-
-        assert response.json() == {
-            "openapi": "3.1.0",
-            "info": {"title": "FastAPI", "version": "0.1.0"},
-            "paths": {
-                "/heroes/": {
-                    "get": {
-                        "summary": "Read Heroes",
-                        "operationId": "read_heroes_heroes__get",
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "title": "Response Read Heroes Heroes  Get",
-                                            "type": "array",
-                                            "items": {
-                                                "$ref": "#/components/schemas/HeroPublic"
-                                            },
-                                        }
-                                    }
-                                },
-                            }
-                        },
-                    },
-                    "post": {
-                        "summary": "Create Hero",
-                        "operationId": "create_hero_heroes__post",
-                        "requestBody": {
-                            "content": {
-                                "application/json": {
-                                    "schema": {
-                                        "$ref": "#/components/schemas/HeroCreate"
-                                    }
-                                }
-                            },
-                            "required": True,
-                        },
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HeroPublic"
-                                        }
-                                    }
-                                },
-                            },
-                            "422": {
-                                "description": "Validation Error",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HTTPValidationError"
-                                        }
-                                    }
-                                },
-                            },
-                        },
-                    },
-                }
-            },
-            "components": {
-                "schemas": {
-                    "HTTPValidationError": {
-                        "title": "HTTPValidationError",
-                        "type": "object",
-                        "properties": {
-                            "detail": {
-                                "title": "Detail",
-                                "type": "array",
-                                "items": {
-                                    "$ref": "#/components/schemas/ValidationError"
-                                },
-                            }
-                        },
-                    },
-                    "HeroCreate": {
-                        "title": "HeroCreate",
-                        "required": ["name", "secret_name"],
-                        "type": "object",
-                        "properties": {
-                            "name": {"title": "Name", "type": "string"},
-                            "secret_name": {"title": "Secret Name", "type": "string"},
-                            "age": IsDict(
-                                {
-                                    "title": "Age",
-                                    "anyOf": [{"type": "integer"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Age", "type": "integer"}
-                            ),
-                        },
-                    },
-                    "HeroPublic": {
-                        "title": "HeroPublic",
-                        "required": ["id", "name", "secret_name"],
-                        "type": "object",
-                        "properties": {
-                            "id": {"title": "Id", "type": "integer"},
-                            "name": {"title": "Name", "type": "string"},
-                            "secret_name": {"title": "Secret Name", "type": "string"},
-                            "age": IsDict(
-                                {
-                                    "title": "Age",
-                                    "anyOf": [{"type": "integer"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Age", "type": "integer"}
-                            ),
-                        },
-                    },
-                    "ValidationError": {
-                        "title": "ValidationError",
-                        "required": ["loc", "msg", "type"],
-                        "type": "object",
-                        "properties": {
-                            "loc": {
-                                "title": "Location",
-                                "type": "array",
-                                "items": {
-                                    "anyOf": [{"type": "string"}, {"type": "integer"}]
-                                },
-                            },
-                            "msg": {"title": "Message", "type": "string"},
-                            "type": {"title": "Error Type", "type": "string"},
-                        },
-                    },
-                }
-            },
-        }
-
-    # Test inherited indexes
-    insp: Inspector = inspect(mod.engine)
-    indexes = insp.get_indexes(str(mod.Hero.__tablename__))
-    expected_indexes = [
-        {
-            "name": "ix_hero_name",
-            "dialect_options": {},
-            "column_names": ["name"],
-            "unique": 0,
-        },
-        {
-            "name": "ix_hero_age",
-            "dialect_options": {},
-            "column_names": ["age"],
-            "unique": 0,
-        },
-    ]
-    for index in expected_indexes:
-        assert index in indexes, "This expected index should be in the indexes in DB"
-        # Now that this index was checked, remove it from the list of indexes
-        indexes.pop(indexes.index(index))
-    assert len(indexes) == 0, "The database should only have the expected indexes"
diff --git a/tests/test_tutorial/test_fastapi/test_multiple_models/test_tutorial001_py39.py b/tests/test_tutorial/test_fastapi/test_multiple_models/test_tutorial001_py39.py
deleted file mode 100644 (file)
index 82365ce..0000000
+++ /dev/null
@@ -1,221 +0,0 @@
-from dirty_equals import IsDict
-from fastapi.testclient import TestClient
-from sqlalchemy import inspect
-from sqlalchemy.engine.reflection import Inspector
-from sqlmodel import create_engine
-from sqlmodel.pool import StaticPool
-
-from ....conftest import needs_py39
-
-
-@needs_py39
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.fastapi.multiple_models import tutorial001_py39 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(
-        mod.sqlite_url, connect_args=mod.connect_args, poolclass=StaticPool
-    )
-
-    with TestClient(mod.app) as client:
-        hero1_data = {"name": "Deadpond", "secret_name": "Dive Wilson"}
-        hero2_data = {
-            "name": "Spider-Boy",
-            "secret_name": "Pedro Parqueador",
-            "id": 9000,
-        }
-        response = client.post("/heroes/", json=hero1_data)
-        data = response.json()
-
-        assert response.status_code == 200, response.text
-        assert data["name"] == hero1_data["name"]
-        assert data["secret_name"] == hero1_data["secret_name"]
-        assert data["id"] is not None
-        assert data["age"] is None
-
-        response = client.post("/heroes/", json=hero2_data)
-        data = response.json()
-
-        assert response.status_code == 200, response.text
-        assert data["name"] == hero2_data["name"]
-        assert data["secret_name"] == hero2_data["secret_name"]
-        assert data["id"] != hero2_data["id"], (
-            "Now it's not possible to predefine the ID from the request, "
-            "it's now set by the database"
-        )
-        assert data["age"] is None
-
-        response = client.get("/heroes/")
-        data = response.json()
-
-        assert response.status_code == 200, response.text
-        assert len(data) == 2
-        assert data[0]["name"] == hero1_data["name"]
-        assert data[0]["secret_name"] == hero1_data["secret_name"]
-        assert data[1]["name"] == hero2_data["name"]
-        assert data[1]["secret_name"] == hero2_data["secret_name"]
-        assert data[1]["id"] != hero2_data["id"]
-
-        response = client.get("/openapi.json")
-
-        assert response.status_code == 200, response.text
-
-        assert response.json() == {
-            "openapi": "3.1.0",
-            "info": {"title": "FastAPI", "version": "0.1.0"},
-            "paths": {
-                "/heroes/": {
-                    "get": {
-                        "summary": "Read Heroes",
-                        "operationId": "read_heroes_heroes__get",
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "title": "Response Read Heroes Heroes  Get",
-                                            "type": "array",
-                                            "items": {
-                                                "$ref": "#/components/schemas/HeroPublic"
-                                            },
-                                        }
-                                    }
-                                },
-                            }
-                        },
-                    },
-                    "post": {
-                        "summary": "Create Hero",
-                        "operationId": "create_hero_heroes__post",
-                        "requestBody": {
-                            "content": {
-                                "application/json": {
-                                    "schema": {
-                                        "$ref": "#/components/schemas/HeroCreate"
-                                    }
-                                }
-                            },
-                            "required": True,
-                        },
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HeroPublic"
-                                        }
-                                    }
-                                },
-                            },
-                            "422": {
-                                "description": "Validation Error",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HTTPValidationError"
-                                        }
-                                    }
-                                },
-                            },
-                        },
-                    },
-                }
-            },
-            "components": {
-                "schemas": {
-                    "HTTPValidationError": {
-                        "title": "HTTPValidationError",
-                        "type": "object",
-                        "properties": {
-                            "detail": {
-                                "title": "Detail",
-                                "type": "array",
-                                "items": {
-                                    "$ref": "#/components/schemas/ValidationError"
-                                },
-                            }
-                        },
-                    },
-                    "HeroCreate": {
-                        "title": "HeroCreate",
-                        "required": ["name", "secret_name"],
-                        "type": "object",
-                        "properties": {
-                            "name": {"title": "Name", "type": "string"},
-                            "secret_name": {"title": "Secret Name", "type": "string"},
-                            "age": IsDict(
-                                {
-                                    "title": "Age",
-                                    "anyOf": [{"type": "integer"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Age", "type": "integer"}
-                            ),
-                        },
-                    },
-                    "HeroPublic": {
-                        "title": "HeroPublic",
-                        "required": ["id", "name", "secret_name"],
-                        "type": "object",
-                        "properties": {
-                            "id": {"title": "Id", "type": "integer"},
-                            "name": {"title": "Name", "type": "string"},
-                            "secret_name": {"title": "Secret Name", "type": "string"},
-                            "age": IsDict(
-                                {
-                                    "title": "Age",
-                                    "anyOf": [{"type": "integer"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Age", "type": "integer"}
-                            ),
-                        },
-                    },
-                    "ValidationError": {
-                        "title": "ValidationError",
-                        "required": ["loc", "msg", "type"],
-                        "type": "object",
-                        "properties": {
-                            "loc": {
-                                "title": "Location",
-                                "type": "array",
-                                "items": {
-                                    "anyOf": [{"type": "string"}, {"type": "integer"}]
-                                },
-                            },
-                            "msg": {"title": "Message", "type": "string"},
-                            "type": {"title": "Error Type", "type": "string"},
-                        },
-                    },
-                }
-            },
-        }
-
-    # Test inherited indexes
-    insp: Inspector = inspect(mod.engine)
-    indexes = insp.get_indexes(str(mod.Hero.__tablename__))
-    expected_indexes = [
-        {
-            "name": "ix_hero_name",
-            "dialect_options": {},
-            "column_names": ["name"],
-            "unique": 0,
-        },
-        {
-            "name": "ix_hero_age",
-            "dialect_options": {},
-            "column_names": ["age"],
-            "unique": 0,
-        },
-    ]
-    for index in expected_indexes:
-        assert index in indexes, "This expected index should be in the indexes in DB"
-        # Now that this index was checked, remove it from the list of indexes
-        indexes.pop(indexes.index(index))
-    assert len(indexes) == 0, "The database should only have the expected indexes"
index 8327c6d5661fb85cd64782b4b8ceeee5ce7c296b..c840bde253ffeb9215d54f4768459a2aea68acba 100644 (file)
@@ -1,3 +1,7 @@
+import importlib
+from types import ModuleType
+
+import pytest
 from dirty_equals import IsDict
 from fastapi.testclient import TestClient
 from sqlalchemy import inspect
@@ -5,16 +9,30 @@ from sqlalchemy.engine.reflection import Inspector
 from sqlmodel import create_engine
 from sqlmodel.pool import StaticPool
 
+from tests.conftest import needs_py39, needs_py310
 
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.fastapi.multiple_models import tutorial002 as mod
 
+@pytest.fixture(
+    name="module",
+    params=[
+        "tutorial002",
+        pytest.param("tutorial002_py39", marks=needs_py39),
+        pytest.param("tutorial002_py310", marks=needs_py310),
+    ],
+)
+def get_module(request: pytest.FixtureRequest) -> ModuleType:
+    mod = importlib.import_module(
+        f"docs_src.tutorial.fastapi.multiple_models.{request.param}"
+    )
     mod.sqlite_url = "sqlite://"
     mod.engine = create_engine(
         mod.sqlite_url, connect_args=mod.connect_args, poolclass=StaticPool
     )
+    return mod
+
 
-    with TestClient(mod.app) as client:
+def test_tutorial(module: ModuleType):
+    with TestClient(module.app) as client:
         hero1_data = {"name": "Deadpond", "secret_name": "Dive Wilson"}
         hero2_data = {
             "name": "Spider-Boy",
@@ -195,8 +213,8 @@ def test_tutorial(clear_sqlmodel):
         }
 
     # Test inherited indexes
-    insp: Inspector = inspect(mod.engine)
-    indexes = insp.get_indexes(str(mod.Hero.__tablename__))
+    insp: Inspector = inspect(module.engine)
+    indexes = insp.get_indexes(str(module.Hero.__tablename__))
     expected_indexes = [
         {
             "name": "ix_hero_age",
diff --git a/tests/test_tutorial/test_fastapi/test_multiple_models/test_tutorial002_py310.py b/tests/test_tutorial/test_fastapi/test_multiple_models/test_tutorial002_py310.py
deleted file mode 100644 (file)
index 30edc4d..0000000
+++ /dev/null
@@ -1,221 +0,0 @@
-from dirty_equals import IsDict
-from fastapi.testclient import TestClient
-from sqlalchemy import inspect
-from sqlalchemy.engine.reflection import Inspector
-from sqlmodel import create_engine
-from sqlmodel.pool import StaticPool
-
-from ....conftest import needs_py310
-
-
-@needs_py310
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.fastapi.multiple_models import tutorial002_py310 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(
-        mod.sqlite_url, connect_args=mod.connect_args, poolclass=StaticPool
-    )
-
-    with TestClient(mod.app) as client:
-        hero1_data = {"name": "Deadpond", "secret_name": "Dive Wilson"}
-        hero2_data = {
-            "name": "Spider-Boy",
-            "secret_name": "Pedro Parqueador",
-            "id": 9000,
-        }
-        response = client.post("/heroes/", json=hero1_data)
-        data = response.json()
-
-        assert response.status_code == 200, response.text
-        assert data["name"] == hero1_data["name"]
-        assert data["secret_name"] == hero1_data["secret_name"]
-        assert data["id"] is not None
-        assert data["age"] is None
-
-        response = client.post("/heroes/", json=hero2_data)
-        data = response.json()
-
-        assert response.status_code == 200, response.text
-        assert data["name"] == hero2_data["name"]
-        assert data["secret_name"] == hero2_data["secret_name"]
-        assert data["id"] != hero2_data["id"], (
-            "Now it's not possible to predefine the ID from the request, "
-            "it's now set by the database"
-        )
-        assert data["age"] is None
-
-        response = client.get("/heroes/")
-        data = response.json()
-
-        assert response.status_code == 200, response.text
-        assert len(data) == 2
-        assert data[0]["name"] == hero1_data["name"]
-        assert data[0]["secret_name"] == hero1_data["secret_name"]
-        assert data[1]["name"] == hero2_data["name"]
-        assert data[1]["secret_name"] == hero2_data["secret_name"]
-        assert data[1]["id"] != hero2_data["id"]
-
-        response = client.get("/openapi.json")
-
-        assert response.status_code == 200, response.text
-
-        assert response.json() == {
-            "openapi": "3.1.0",
-            "info": {"title": "FastAPI", "version": "0.1.0"},
-            "paths": {
-                "/heroes/": {
-                    "get": {
-                        "summary": "Read Heroes",
-                        "operationId": "read_heroes_heroes__get",
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "title": "Response Read Heroes Heroes  Get",
-                                            "type": "array",
-                                            "items": {
-                                                "$ref": "#/components/schemas/HeroPublic"
-                                            },
-                                        }
-                                    }
-                                },
-                            }
-                        },
-                    },
-                    "post": {
-                        "summary": "Create Hero",
-                        "operationId": "create_hero_heroes__post",
-                        "requestBody": {
-                            "content": {
-                                "application/json": {
-                                    "schema": {
-                                        "$ref": "#/components/schemas/HeroCreate"
-                                    }
-                                }
-                            },
-                            "required": True,
-                        },
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HeroPublic"
-                                        }
-                                    }
-                                },
-                            },
-                            "422": {
-                                "description": "Validation Error",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HTTPValidationError"
-                                        }
-                                    }
-                                },
-                            },
-                        },
-                    },
-                }
-            },
-            "components": {
-                "schemas": {
-                    "HTTPValidationError": {
-                        "title": "HTTPValidationError",
-                        "type": "object",
-                        "properties": {
-                            "detail": {
-                                "title": "Detail",
-                                "type": "array",
-                                "items": {
-                                    "$ref": "#/components/schemas/ValidationError"
-                                },
-                            }
-                        },
-                    },
-                    "HeroCreate": {
-                        "title": "HeroCreate",
-                        "required": ["name", "secret_name"],
-                        "type": "object",
-                        "properties": {
-                            "name": {"title": "Name", "type": "string"},
-                            "secret_name": {"title": "Secret Name", "type": "string"},
-                            "age": IsDict(
-                                {
-                                    "title": "Age",
-                                    "anyOf": [{"type": "integer"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Age", "type": "integer"}
-                            ),
-                        },
-                    },
-                    "HeroPublic": {
-                        "title": "HeroPublic",
-                        "required": ["name", "secret_name", "id"],
-                        "type": "object",
-                        "properties": {
-                            "name": {"title": "Name", "type": "string"},
-                            "secret_name": {"title": "Secret Name", "type": "string"},
-                            "age": IsDict(
-                                {
-                                    "title": "Age",
-                                    "anyOf": [{"type": "integer"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Age", "type": "integer"}
-                            ),
-                            "id": {"title": "Id", "type": "integer"},
-                        },
-                    },
-                    "ValidationError": {
-                        "title": "ValidationError",
-                        "required": ["loc", "msg", "type"],
-                        "type": "object",
-                        "properties": {
-                            "loc": {
-                                "title": "Location",
-                                "type": "array",
-                                "items": {
-                                    "anyOf": [{"type": "string"}, {"type": "integer"}]
-                                },
-                            },
-                            "msg": {"title": "Message", "type": "string"},
-                            "type": {"title": "Error Type", "type": "string"},
-                        },
-                    },
-                }
-            },
-        }
-
-    # Test inherited indexes
-    insp: Inspector = inspect(mod.engine)
-    indexes = insp.get_indexes(str(mod.Hero.__tablename__))
-    expected_indexes = [
-        {
-            "name": "ix_hero_age",
-            "dialect_options": {},
-            "column_names": ["age"],
-            "unique": 0,
-        },
-        {
-            "name": "ix_hero_name",
-            "dialect_options": {},
-            "column_names": ["name"],
-            "unique": 0,
-        },
-    ]
-    for index in expected_indexes:
-        assert index in indexes, "This expected index should be in the indexes in DB"
-        # Now that this index was checked, remove it from the list of indexes
-        indexes.pop(indexes.index(index))
-    assert len(indexes) == 0, "The database should only have the expected indexes"
diff --git a/tests/test_tutorial/test_fastapi/test_multiple_models/test_tutorial002_py39.py b/tests/test_tutorial/test_fastapi/test_multiple_models/test_tutorial002_py39.py
deleted file mode 100644 (file)
index 2b86d3f..0000000
+++ /dev/null
@@ -1,221 +0,0 @@
-from dirty_equals import IsDict
-from fastapi.testclient import TestClient
-from sqlalchemy import inspect
-from sqlalchemy.engine.reflection import Inspector
-from sqlmodel import create_engine
-from sqlmodel.pool import StaticPool
-
-from ....conftest import needs_py39
-
-
-@needs_py39
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.fastapi.multiple_models import tutorial002_py39 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(
-        mod.sqlite_url, connect_args=mod.connect_args, poolclass=StaticPool
-    )
-
-    with TestClient(mod.app) as client:
-        hero1_data = {"name": "Deadpond", "secret_name": "Dive Wilson"}
-        hero2_data = {
-            "name": "Spider-Boy",
-            "secret_name": "Pedro Parqueador",
-            "id": 9000,
-        }
-        response = client.post("/heroes/", json=hero1_data)
-        data = response.json()
-
-        assert response.status_code == 200, response.text
-        assert data["name"] == hero1_data["name"]
-        assert data["secret_name"] == hero1_data["secret_name"]
-        assert data["id"] is not None
-        assert data["age"] is None
-
-        response = client.post("/heroes/", json=hero2_data)
-        data = response.json()
-
-        assert response.status_code == 200, response.text
-        assert data["name"] == hero2_data["name"]
-        assert data["secret_name"] == hero2_data["secret_name"]
-        assert data["id"] != hero2_data["id"], (
-            "Now it's not possible to predefine the ID from the request, "
-            "it's now set by the database"
-        )
-        assert data["age"] is None
-
-        response = client.get("/heroes/")
-        data = response.json()
-
-        assert response.status_code == 200, response.text
-        assert len(data) == 2
-        assert data[0]["name"] == hero1_data["name"]
-        assert data[0]["secret_name"] == hero1_data["secret_name"]
-        assert data[1]["name"] == hero2_data["name"]
-        assert data[1]["secret_name"] == hero2_data["secret_name"]
-        assert data[1]["id"] != hero2_data["id"]
-
-        response = client.get("/openapi.json")
-
-        assert response.status_code == 200, response.text
-
-        assert response.json() == {
-            "openapi": "3.1.0",
-            "info": {"title": "FastAPI", "version": "0.1.0"},
-            "paths": {
-                "/heroes/": {
-                    "get": {
-                        "summary": "Read Heroes",
-                        "operationId": "read_heroes_heroes__get",
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "title": "Response Read Heroes Heroes  Get",
-                                            "type": "array",
-                                            "items": {
-                                                "$ref": "#/components/schemas/HeroPublic"
-                                            },
-                                        }
-                                    }
-                                },
-                            }
-                        },
-                    },
-                    "post": {
-                        "summary": "Create Hero",
-                        "operationId": "create_hero_heroes__post",
-                        "requestBody": {
-                            "content": {
-                                "application/json": {
-                                    "schema": {
-                                        "$ref": "#/components/schemas/HeroCreate"
-                                    }
-                                }
-                            },
-                            "required": True,
-                        },
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HeroPublic"
-                                        }
-                                    }
-                                },
-                            },
-                            "422": {
-                                "description": "Validation Error",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HTTPValidationError"
-                                        }
-                                    }
-                                },
-                            },
-                        },
-                    },
-                }
-            },
-            "components": {
-                "schemas": {
-                    "HTTPValidationError": {
-                        "title": "HTTPValidationError",
-                        "type": "object",
-                        "properties": {
-                            "detail": {
-                                "title": "Detail",
-                                "type": "array",
-                                "items": {
-                                    "$ref": "#/components/schemas/ValidationError"
-                                },
-                            }
-                        },
-                    },
-                    "HeroCreate": {
-                        "title": "HeroCreate",
-                        "required": ["name", "secret_name"],
-                        "type": "object",
-                        "properties": {
-                            "name": {"title": "Name", "type": "string"},
-                            "secret_name": {"title": "Secret Name", "type": "string"},
-                            "age": IsDict(
-                                {
-                                    "title": "Age",
-                                    "anyOf": [{"type": "integer"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Age", "type": "integer"}
-                            ),
-                        },
-                    },
-                    "HeroPublic": {
-                        "title": "HeroPublic",
-                        "required": ["name", "secret_name", "id"],
-                        "type": "object",
-                        "properties": {
-                            "name": {"title": "Name", "type": "string"},
-                            "secret_name": {"title": "Secret Name", "type": "string"},
-                            "age": IsDict(
-                                {
-                                    "title": "Age",
-                                    "anyOf": [{"type": "integer"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Age", "type": "integer"}
-                            ),
-                            "id": {"title": "Id", "type": "integer"},
-                        },
-                    },
-                    "ValidationError": {
-                        "title": "ValidationError",
-                        "required": ["loc", "msg", "type"],
-                        "type": "object",
-                        "properties": {
-                            "loc": {
-                                "title": "Location",
-                                "type": "array",
-                                "items": {
-                                    "anyOf": [{"type": "string"}, {"type": "integer"}]
-                                },
-                            },
-                            "msg": {"title": "Message", "type": "string"},
-                            "type": {"title": "Error Type", "type": "string"},
-                        },
-                    },
-                }
-            },
-        }
-
-    # Test inherited indexes
-    insp: Inspector = inspect(mod.engine)
-    indexes = insp.get_indexes(str(mod.Hero.__tablename__))
-    expected_indexes = [
-        {
-            "name": "ix_hero_age",
-            "dialect_options": {},
-            "column_names": ["age"],
-            "unique": 0,
-        },
-        {
-            "name": "ix_hero_name",
-            "dialect_options": {},
-            "column_names": ["name"],
-            "unique": 0,
-        },
-    ]
-    for index in expected_indexes:
-        assert index in indexes, "This expected index should be in the indexes in DB"
-        # Now that this index was checked, remove it from the list of indexes
-        indexes.pop(indexes.index(index))
-    assert len(indexes) == 0, "The database should only have the expected indexes"
index 9b1d527565a0efd2a06af1017dd16dd4d3fbffe9..affea513ddcaef6e1f6acf5d652dde9d80c3a67b 100644 (file)
@@ -1,18 +1,34 @@
+import importlib
+from types import ModuleType
+
+import pytest
 from dirty_equals import IsDict
 from fastapi.testclient import TestClient
 from sqlmodel import create_engine
 from sqlmodel.pool import StaticPool
 
+from tests.conftest import needs_py39, needs_py310
 
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.fastapi.read_one import tutorial001 as mod
 
+@pytest.fixture(
+    name="module",
+    params=[
+        "tutorial001",
+        pytest.param("tutorial001_py39", marks=needs_py39),
+        pytest.param("tutorial001_py310", marks=needs_py310),
+    ],
+)
+def get_module(request: pytest.FixtureRequest) -> ModuleType:
+    mod = importlib.import_module(f"docs_src.tutorial.fastapi.read_one.{request.param}")
     mod.sqlite_url = "sqlite://"
     mod.engine = create_engine(
         mod.sqlite_url, connect_args=mod.connect_args, poolclass=StaticPool
     )
+    return mod
+
 
-    with TestClient(mod.app) as client:
+def test_tutorial(module: ModuleType):
+    with TestClient(module.app) as client:
         hero1_data = {"name": "Deadpond", "secret_name": "Dive Wilson"}
         hero2_data = {
             "name": "Spider-Boy",
diff --git a/tests/test_tutorial/test_fastapi/test_read_one/test_tutorial001_py310.py b/tests/test_tutorial/test_fastapi/test_read_one/test_tutorial001_py310.py
deleted file mode 100644 (file)
index f18b0d6..0000000
+++ /dev/null
@@ -1,219 +0,0 @@
-from dirty_equals import IsDict
-from fastapi.testclient import TestClient
-from sqlmodel import create_engine
-from sqlmodel.pool import StaticPool
-
-from ....conftest import needs_py310
-
-
-@needs_py310
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.fastapi.read_one import tutorial001_py310 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(
-        mod.sqlite_url, connect_args=mod.connect_args, poolclass=StaticPool
-    )
-
-    with TestClient(mod.app) as client:
-        hero1_data = {"name": "Deadpond", "secret_name": "Dive Wilson"}
-        hero2_data = {
-            "name": "Spider-Boy",
-            "secret_name": "Pedro Parqueador",
-            "id": 9000,
-        }
-        response = client.post("/heroes/", json=hero1_data)
-        assert response.status_code == 200, response.text
-        response = client.post("/heroes/", json=hero2_data)
-        assert response.status_code == 200, response.text
-        hero2 = response.json()
-        response = client.get("/heroes/")
-        assert response.status_code == 200, response.text
-        data = response.json()
-        assert len(data) == 2
-
-        hero_id = hero2["id"]
-        response = client.get(f"/heroes/{hero_id}")
-        assert response.status_code == 200, response.text
-        data = response.json()
-        assert data == hero2
-
-        response = client.get("/heroes/9000")
-        assert response.status_code == 404, response.text
-
-        response = client.get("/openapi.json")
-
-        assert response.status_code == 200, response.text
-
-        assert response.json() == {
-            "openapi": "3.1.0",
-            "info": {"title": "FastAPI", "version": "0.1.0"},
-            "paths": {
-                "/heroes/": {
-                    "get": {
-                        "summary": "Read Heroes",
-                        "operationId": "read_heroes_heroes__get",
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "title": "Response Read Heroes Heroes  Get",
-                                            "type": "array",
-                                            "items": {
-                                                "$ref": "#/components/schemas/HeroPublic"
-                                            },
-                                        }
-                                    }
-                                },
-                            }
-                        },
-                    },
-                    "post": {
-                        "summary": "Create Hero",
-                        "operationId": "create_hero_heroes__post",
-                        "requestBody": {
-                            "content": {
-                                "application/json": {
-                                    "schema": {
-                                        "$ref": "#/components/schemas/HeroCreate"
-                                    }
-                                }
-                            },
-                            "required": True,
-                        },
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HeroPublic"
-                                        }
-                                    }
-                                },
-                            },
-                            "422": {
-                                "description": "Validation Error",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HTTPValidationError"
-                                        }
-                                    }
-                                },
-                            },
-                        },
-                    },
-                },
-                "/heroes/{hero_id}": {
-                    "get": {
-                        "summary": "Read Hero",
-                        "operationId": "read_hero_heroes__hero_id__get",
-                        "parameters": [
-                            {
-                                "required": True,
-                                "schema": {"title": "Hero Id", "type": "integer"},
-                                "name": "hero_id",
-                                "in": "path",
-                            }
-                        ],
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HeroPublic"
-                                        }
-                                    }
-                                },
-                            },
-                            "422": {
-                                "description": "Validation Error",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HTTPValidationError"
-                                        }
-                                    }
-                                },
-                            },
-                        },
-                    }
-                },
-            },
-            "components": {
-                "schemas": {
-                    "HTTPValidationError": {
-                        "title": "HTTPValidationError",
-                        "type": "object",
-                        "properties": {
-                            "detail": {
-                                "title": "Detail",
-                                "type": "array",
-                                "items": {
-                                    "$ref": "#/components/schemas/ValidationError"
-                                },
-                            }
-                        },
-                    },
-                    "HeroCreate": {
-                        "title": "HeroCreate",
-                        "required": ["name", "secret_name"],
-                        "type": "object",
-                        "properties": {
-                            "name": {"title": "Name", "type": "string"},
-                            "secret_name": {"title": "Secret Name", "type": "string"},
-                            "age": IsDict(
-                                {
-                                    "title": "Age",
-                                    "anyOf": [{"type": "integer"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Age", "type": "integer"}
-                            ),
-                        },
-                    },
-                    "HeroPublic": {
-                        "title": "HeroPublic",
-                        "required": ["name", "secret_name", "id"],
-                        "type": "object",
-                        "properties": {
-                            "name": {"title": "Name", "type": "string"},
-                            "secret_name": {"title": "Secret Name", "type": "string"},
-                            "age": IsDict(
-                                {
-                                    "title": "Age",
-                                    "anyOf": [{"type": "integer"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Age", "type": "integer"}
-                            ),
-                            "id": {"title": "Id", "type": "integer"},
-                        },
-                    },
-                    "ValidationError": {
-                        "title": "ValidationError",
-                        "required": ["loc", "msg", "type"],
-                        "type": "object",
-                        "properties": {
-                            "loc": {
-                                "title": "Location",
-                                "type": "array",
-                                "items": {
-                                    "anyOf": [{"type": "string"}, {"type": "integer"}]
-                                },
-                            },
-                            "msg": {"title": "Message", "type": "string"},
-                            "type": {"title": "Error Type", "type": "string"},
-                        },
-                    },
-                }
-            },
-        }
diff --git a/tests/test_tutorial/test_fastapi/test_read_one/test_tutorial001_py39.py b/tests/test_tutorial/test_fastapi/test_read_one/test_tutorial001_py39.py
deleted file mode 100644 (file)
index 4423d1a..0000000
+++ /dev/null
@@ -1,219 +0,0 @@
-from dirty_equals import IsDict
-from fastapi.testclient import TestClient
-from sqlmodel import create_engine
-from sqlmodel.pool import StaticPool
-
-from ....conftest import needs_py39
-
-
-@needs_py39
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.fastapi.read_one import tutorial001_py39 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(
-        mod.sqlite_url, connect_args=mod.connect_args, poolclass=StaticPool
-    )
-
-    with TestClient(mod.app) as client:
-        hero1_data = {"name": "Deadpond", "secret_name": "Dive Wilson"}
-        hero2_data = {
-            "name": "Spider-Boy",
-            "secret_name": "Pedro Parqueador",
-            "id": 9000,
-        }
-        response = client.post("/heroes/", json=hero1_data)
-        assert response.status_code == 200, response.text
-        response = client.post("/heroes/", json=hero2_data)
-        assert response.status_code == 200, response.text
-        hero2 = response.json()
-        response = client.get("/heroes/")
-        assert response.status_code == 200, response.text
-        data = response.json()
-        assert len(data) == 2
-
-        hero_id = hero2["id"]
-        response = client.get(f"/heroes/{hero_id}")
-        assert response.status_code == 200, response.text
-        data = response.json()
-        assert data == hero2
-
-        response = client.get("/heroes/9000")
-        assert response.status_code == 404, response.text
-
-        response = client.get("/openapi.json")
-
-        assert response.status_code == 200, response.text
-
-        assert response.json() == {
-            "openapi": "3.1.0",
-            "info": {"title": "FastAPI", "version": "0.1.0"},
-            "paths": {
-                "/heroes/": {
-                    "get": {
-                        "summary": "Read Heroes",
-                        "operationId": "read_heroes_heroes__get",
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "title": "Response Read Heroes Heroes  Get",
-                                            "type": "array",
-                                            "items": {
-                                                "$ref": "#/components/schemas/HeroPublic"
-                                            },
-                                        }
-                                    }
-                                },
-                            }
-                        },
-                    },
-                    "post": {
-                        "summary": "Create Hero",
-                        "operationId": "create_hero_heroes__post",
-                        "requestBody": {
-                            "content": {
-                                "application/json": {
-                                    "schema": {
-                                        "$ref": "#/components/schemas/HeroCreate"
-                                    }
-                                }
-                            },
-                            "required": True,
-                        },
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HeroPublic"
-                                        }
-                                    }
-                                },
-                            },
-                            "422": {
-                                "description": "Validation Error",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HTTPValidationError"
-                                        }
-                                    }
-                                },
-                            },
-                        },
-                    },
-                },
-                "/heroes/{hero_id}": {
-                    "get": {
-                        "summary": "Read Hero",
-                        "operationId": "read_hero_heroes__hero_id__get",
-                        "parameters": [
-                            {
-                                "required": True,
-                                "schema": {"title": "Hero Id", "type": "integer"},
-                                "name": "hero_id",
-                                "in": "path",
-                            }
-                        ],
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HeroPublic"
-                                        }
-                                    }
-                                },
-                            },
-                            "422": {
-                                "description": "Validation Error",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HTTPValidationError"
-                                        }
-                                    }
-                                },
-                            },
-                        },
-                    }
-                },
-            },
-            "components": {
-                "schemas": {
-                    "HTTPValidationError": {
-                        "title": "HTTPValidationError",
-                        "type": "object",
-                        "properties": {
-                            "detail": {
-                                "title": "Detail",
-                                "type": "array",
-                                "items": {
-                                    "$ref": "#/components/schemas/ValidationError"
-                                },
-                            }
-                        },
-                    },
-                    "HeroCreate": {
-                        "title": "HeroCreate",
-                        "required": ["name", "secret_name"],
-                        "type": "object",
-                        "properties": {
-                            "name": {"title": "Name", "type": "string"},
-                            "secret_name": {"title": "Secret Name", "type": "string"},
-                            "age": IsDict(
-                                {
-                                    "title": "Age",
-                                    "anyOf": [{"type": "integer"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Age", "type": "integer"}
-                            ),
-                        },
-                    },
-                    "HeroPublic": {
-                        "title": "HeroPublic",
-                        "required": ["name", "secret_name", "id"],
-                        "type": "object",
-                        "properties": {
-                            "name": {"title": "Name", "type": "string"},
-                            "secret_name": {"title": "Secret Name", "type": "string"},
-                            "age": IsDict(
-                                {
-                                    "title": "Age",
-                                    "anyOf": [{"type": "integer"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Age", "type": "integer"}
-                            ),
-                            "id": {"title": "Id", "type": "integer"},
-                        },
-                    },
-                    "ValidationError": {
-                        "title": "ValidationError",
-                        "required": ["loc", "msg", "type"],
-                        "type": "object",
-                        "properties": {
-                            "loc": {
-                                "title": "Location",
-                                "type": "array",
-                                "items": {
-                                    "anyOf": [{"type": "string"}, {"type": "integer"}]
-                                },
-                            },
-                            "msg": {"title": "Message", "type": "string"},
-                            "type": {"title": "Error Type", "type": "string"},
-                        },
-                    },
-                }
-            },
-        }
index 4b4f47b762a8495e748af733f75169ae6256f1c3..1d0446ed41687ddc97a42711b41e3b802c2fe98c 100644 (file)
@@ -1,18 +1,36 @@
+import importlib
+from types import ModuleType
+
+import pytest
 from dirty_equals import IsDict
 from fastapi.testclient import TestClient
 from sqlmodel import create_engine
 from sqlmodel.pool import StaticPool
 
+from tests.conftest import needs_py39, needs_py310
 
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.fastapi.relationships import tutorial001 as mod
 
+@pytest.fixture(
+    name="module",
+    params=[
+        "tutorial001",
+        pytest.param("tutorial001_py39", marks=needs_py39),
+        pytest.param("tutorial001_py310", marks=needs_py310),
+    ],
+)
+def get_module(request: pytest.FixtureRequest) -> ModuleType:
+    mod = importlib.import_module(
+        f"docs_src.tutorial.fastapi.relationships.{request.param}"
+    )
     mod.sqlite_url = "sqlite://"
     mod.engine = create_engine(
         mod.sqlite_url, connect_args=mod.connect_args, poolclass=StaticPool
     )
+    return mod
+
 
-    with TestClient(mod.app) as client:
+def test_tutorial(module: ModuleType):
+    with TestClient(module.app) as client:
         team_preventers = {"name": "Preventers", "headquarters": "Sharp Tower"}
         team_z_force = {"name": "Z-Force", "headquarters": "Sister Margaret's Bar"}
         response = client.post("/teams/", json=team_preventers)
diff --git a/tests/test_tutorial/test_fastapi/test_relationships/test_tutorial001_py310.py b/tests/test_tutorial/test_fastapi/test_relationships/test_tutorial001_py310.py
deleted file mode 100644 (file)
index dcb78f5..0000000
+++ /dev/null
@@ -1,767 +0,0 @@
-from dirty_equals import IsDict
-from fastapi.testclient import TestClient
-from sqlmodel import create_engine
-from sqlmodel.pool import StaticPool
-
-from ....conftest import needs_py310
-
-
-@needs_py310
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.fastapi.relationships import tutorial001_py310 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(
-        mod.sqlite_url, connect_args=mod.connect_args, poolclass=StaticPool
-    )
-
-    with TestClient(mod.app) as client:
-        team_preventers = {"name": "Preventers", "headquarters": "Sharp Tower"}
-        team_z_force = {"name": "Z-Force", "headquarters": "Sister Margaret's Bar"}
-        response = client.post("/teams/", json=team_preventers)
-        assert response.status_code == 200, response.text
-        team_preventers_data = response.json()
-        team_preventers_id = team_preventers_data["id"]
-        response = client.post("/teams/", json=team_z_force)
-        assert response.status_code == 200, response.text
-        team_z_force_data = response.json()
-        team_z_force_id = team_z_force_data["id"]
-        response = client.get("/teams/")
-        data = response.json()
-        assert len(data) == 2
-        response = client.get("/teams/9000")
-        assert response.status_code == 404, response.text
-        response = client.patch(
-            f"/teams/{team_preventers_id}", json={"headquarters": "Preventers Tower"}
-        )
-        data = response.json()
-        assert response.status_code == 200, response.text
-        assert data["name"] == team_preventers["name"]
-        assert data["headquarters"] == "Preventers Tower"
-        response = client.patch("/teams/9000", json={"name": "Freedom League"})
-        assert response.status_code == 404, response.text
-
-        hero1_data = {
-            "name": "Deadpond",
-            "secret_name": "Dive Wilson",
-            "team_id": team_z_force_id,
-        }
-        hero2_data = {
-            "name": "Spider-Boy",
-            "secret_name": "Pedro Parqueador",
-            "id": 9000,
-        }
-        hero3_data = {
-            "name": "Rusty-Man",
-            "secret_name": "Tommy Sharp",
-            "age": 48,
-            "team_id": team_preventers_id,
-        }
-        response = client.post("/heroes/", json=hero1_data)
-        assert response.status_code == 200, response.text
-        hero1 = response.json()
-        hero1_id = hero1["id"]
-        response = client.post("/heroes/", json=hero2_data)
-        assert response.status_code == 200, response.text
-        hero2 = response.json()
-        hero2_id = hero2["id"]
-        response = client.post("/heroes/", json=hero3_data)
-        assert response.status_code == 200, response.text
-        response = client.get("/heroes/9000")
-        assert response.status_code == 404, response.text
-        response = client.get("/heroes/")
-        assert response.status_code == 200, response.text
-        data = response.json()
-        assert len(data) == 3
-        response = client.get(f"/heroes/{hero1_id}")
-        assert response.status_code == 200, response.text
-        data = response.json()
-        assert data["name"] == hero1_data["name"]
-        assert data["team"]["name"] == team_z_force["name"]
-        response = client.patch(
-            f"/heroes/{hero2_id}", json={"secret_name": "Spider-Youngster"}
-        )
-        assert response.status_code == 200, response.text
-        response = client.patch("/heroes/9001", json={"name": "Dragon Cube X"})
-        assert response.status_code == 404, response.text
-        response = client.delete(f"/heroes/{hero2_id}")
-        assert response.status_code == 200, response.text
-        response = client.get("/heroes/")
-        assert response.status_code == 200, response.text
-        data = response.json()
-        assert len(data) == 2
-        response = client.delete("/heroes/9000")
-        assert response.status_code == 404, response.text
-
-        response = client.get(f"/teams/{team_preventers_id}")
-        data = response.json()
-        assert response.status_code == 200, response.text
-        assert data["name"] == team_preventers_data["name"]
-        assert data["heroes"][0]["name"] == hero3_data["name"]
-
-        response = client.delete(f"/teams/{team_preventers_id}")
-        assert response.status_code == 200, response.text
-        response = client.delete("/teams/9000")
-        assert response.status_code == 404, response.text
-        response = client.get("/teams/")
-        assert response.status_code == 200, response.text
-        data = response.json()
-        assert len(data) == 1
-
-        response = client.get("/openapi.json")
-        assert response.status_code == 200, response.text
-        assert response.json() == {
-            "openapi": "3.1.0",
-            "info": {"title": "FastAPI", "version": "0.1.0"},
-            "paths": {
-                "/heroes/": {
-                    "get": {
-                        "summary": "Read Heroes",
-                        "operationId": "read_heroes_heroes__get",
-                        "parameters": [
-                            {
-                                "required": False,
-                                "schema": {
-                                    "title": "Offset",
-                                    "type": "integer",
-                                    "default": 0,
-                                },
-                                "name": "offset",
-                                "in": "query",
-                            },
-                            {
-                                "required": False,
-                                "schema": {
-                                    "title": "Limit",
-                                    "maximum": 100.0,
-                                    "type": "integer",
-                                    "default": 100,
-                                },
-                                "name": "limit",
-                                "in": "query",
-                            },
-                        ],
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "title": "Response Read Heroes Heroes  Get",
-                                            "type": "array",
-                                            "items": {
-                                                "$ref": "#/components/schemas/HeroPublic"
-                                            },
-                                        }
-                                    }
-                                },
-                            },
-                            "422": {
-                                "description": "Validation Error",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HTTPValidationError"
-                                        }
-                                    }
-                                },
-                            },
-                        },
-                    },
-                    "post": {
-                        "summary": "Create Hero",
-                        "operationId": "create_hero_heroes__post",
-                        "requestBody": {
-                            "content": {
-                                "application/json": {
-                                    "schema": {
-                                        "$ref": "#/components/schemas/HeroCreate"
-                                    }
-                                }
-                            },
-                            "required": True,
-                        },
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HeroPublic"
-                                        }
-                                    }
-                                },
-                            },
-                            "422": {
-                                "description": "Validation Error",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HTTPValidationError"
-                                        }
-                                    }
-                                },
-                            },
-                        },
-                    },
-                },
-                "/heroes/{hero_id}": {
-                    "get": {
-                        "summary": "Read Hero",
-                        "operationId": "read_hero_heroes__hero_id__get",
-                        "parameters": [
-                            {
-                                "required": True,
-                                "schema": {"title": "Hero Id", "type": "integer"},
-                                "name": "hero_id",
-                                "in": "path",
-                            }
-                        ],
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HeroPublicWithTeam"
-                                        }
-                                    }
-                                },
-                            },
-                            "422": {
-                                "description": "Validation Error",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HTTPValidationError"
-                                        }
-                                    }
-                                },
-                            },
-                        },
-                    },
-                    "delete": {
-                        "summary": "Delete Hero",
-                        "operationId": "delete_hero_heroes__hero_id__delete",
-                        "parameters": [
-                            {
-                                "required": True,
-                                "schema": {"title": "Hero Id", "type": "integer"},
-                                "name": "hero_id",
-                                "in": "path",
-                            }
-                        ],
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {"application/json": {"schema": {}}},
-                            },
-                            "422": {
-                                "description": "Validation Error",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HTTPValidationError"
-                                        }
-                                    }
-                                },
-                            },
-                        },
-                    },
-                    "patch": {
-                        "summary": "Update Hero",
-                        "operationId": "update_hero_heroes__hero_id__patch",
-                        "parameters": [
-                            {
-                                "required": True,
-                                "schema": {"title": "Hero Id", "type": "integer"},
-                                "name": "hero_id",
-                                "in": "path",
-                            }
-                        ],
-                        "requestBody": {
-                            "content": {
-                                "application/json": {
-                                    "schema": {
-                                        "$ref": "#/components/schemas/HeroUpdate"
-                                    }
-                                }
-                            },
-                            "required": True,
-                        },
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HeroPublic"
-                                        }
-                                    }
-                                },
-                            },
-                            "422": {
-                                "description": "Validation Error",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HTTPValidationError"
-                                        }
-                                    }
-                                },
-                            },
-                        },
-                    },
-                },
-                "/teams/": {
-                    "get": {
-                        "summary": "Read Teams",
-                        "operationId": "read_teams_teams__get",
-                        "parameters": [
-                            {
-                                "required": False,
-                                "schema": {
-                                    "title": "Offset",
-                                    "type": "integer",
-                                    "default": 0,
-                                },
-                                "name": "offset",
-                                "in": "query",
-                            },
-                            {
-                                "required": False,
-                                "schema": {
-                                    "title": "Limit",
-                                    "maximum": 100.0,
-                                    "type": "integer",
-                                    "default": 100,
-                                },
-                                "name": "limit",
-                                "in": "query",
-                            },
-                        ],
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "title": "Response Read Teams Teams  Get",
-                                            "type": "array",
-                                            "items": {
-                                                "$ref": "#/components/schemas/TeamPublic"
-                                            },
-                                        }
-                                    }
-                                },
-                            },
-                            "422": {
-                                "description": "Validation Error",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HTTPValidationError"
-                                        }
-                                    }
-                                },
-                            },
-                        },
-                    },
-                    "post": {
-                        "summary": "Create Team",
-                        "operationId": "create_team_teams__post",
-                        "requestBody": {
-                            "content": {
-                                "application/json": {
-                                    "schema": {
-                                        "$ref": "#/components/schemas/TeamCreate"
-                                    }
-                                }
-                            },
-                            "required": True,
-                        },
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/TeamPublic"
-                                        }
-                                    }
-                                },
-                            },
-                            "422": {
-                                "description": "Validation Error",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HTTPValidationError"
-                                        }
-                                    }
-                                },
-                            },
-                        },
-                    },
-                },
-                "/teams/{team_id}": {
-                    "get": {
-                        "summary": "Read Team",
-                        "operationId": "read_team_teams__team_id__get",
-                        "parameters": [
-                            {
-                                "required": True,
-                                "schema": {"title": "Team Id", "type": "integer"},
-                                "name": "team_id",
-                                "in": "path",
-                            }
-                        ],
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/TeamPublicWithHeroes"
-                                        }
-                                    }
-                                },
-                            },
-                            "422": {
-                                "description": "Validation Error",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HTTPValidationError"
-                                        }
-                                    }
-                                },
-                            },
-                        },
-                    },
-                    "delete": {
-                        "summary": "Delete Team",
-                        "operationId": "delete_team_teams__team_id__delete",
-                        "parameters": [
-                            {
-                                "required": True,
-                                "schema": {"title": "Team Id", "type": "integer"},
-                                "name": "team_id",
-                                "in": "path",
-                            }
-                        ],
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {"application/json": {"schema": {}}},
-                            },
-                            "422": {
-                                "description": "Validation Error",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HTTPValidationError"
-                                        }
-                                    }
-                                },
-                            },
-                        },
-                    },
-                    "patch": {
-                        "summary": "Update Team",
-                        "operationId": "update_team_teams__team_id__patch",
-                        "parameters": [
-                            {
-                                "required": True,
-                                "schema": {"title": "Team Id", "type": "integer"},
-                                "name": "team_id",
-                                "in": "path",
-                            }
-                        ],
-                        "requestBody": {
-                            "content": {
-                                "application/json": {
-                                    "schema": {
-                                        "$ref": "#/components/schemas/TeamUpdate"
-                                    }
-                                }
-                            },
-                            "required": True,
-                        },
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/TeamPublic"
-                                        }
-                                    }
-                                },
-                            },
-                            "422": {
-                                "description": "Validation Error",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HTTPValidationError"
-                                        }
-                                    }
-                                },
-                            },
-                        },
-                    },
-                },
-            },
-            "components": {
-                "schemas": {
-                    "HTTPValidationError": {
-                        "title": "HTTPValidationError",
-                        "type": "object",
-                        "properties": {
-                            "detail": {
-                                "title": "Detail",
-                                "type": "array",
-                                "items": {
-                                    "$ref": "#/components/schemas/ValidationError"
-                                },
-                            }
-                        },
-                    },
-                    "HeroCreate": {
-                        "title": "HeroCreate",
-                        "required": ["name", "secret_name"],
-                        "type": "object",
-                        "properties": {
-                            "name": {"title": "Name", "type": "string"},
-                            "secret_name": {"title": "Secret Name", "type": "string"},
-                            "age": IsDict(
-                                {
-                                    "title": "Age",
-                                    "anyOf": [{"type": "integer"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Age", "type": "integer"}
-                            ),
-                            "team_id": IsDict(
-                                {
-                                    "title": "Team Id",
-                                    "anyOf": [{"type": "integer"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Team Id", "type": "integer"}
-                            ),
-                        },
-                    },
-                    "HeroPublic": {
-                        "title": "HeroPublic",
-                        "required": ["name", "secret_name", "id"],
-                        "type": "object",
-                        "properties": {
-                            "name": {"title": "Name", "type": "string"},
-                            "secret_name": {"title": "Secret Name", "type": "string"},
-                            "age": IsDict(
-                                {
-                                    "title": "Age",
-                                    "anyOf": [{"type": "integer"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Age", "type": "integer"}
-                            ),
-                            "team_id": IsDict(
-                                {
-                                    "title": "Team Id",
-                                    "anyOf": [{"type": "integer"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Team Id", "type": "integer"}
-                            ),
-                            "id": {"title": "Id", "type": "integer"},
-                        },
-                    },
-                    "HeroPublicWithTeam": {
-                        "title": "HeroPublicWithTeam",
-                        "required": ["name", "secret_name", "id"],
-                        "type": "object",
-                        "properties": {
-                            "name": {"title": "Name", "type": "string"},
-                            "secret_name": {"title": "Secret Name", "type": "string"},
-                            "age": IsDict(
-                                {
-                                    "title": "Age",
-                                    "anyOf": [{"type": "integer"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Age", "type": "integer"}
-                            ),
-                            "team_id": IsDict(
-                                {
-                                    "title": "Team Id",
-                                    "anyOf": [{"type": "integer"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Team Id", "type": "integer"}
-                            ),
-                            "id": {"title": "Id", "type": "integer"},
-                            "team": IsDict(
-                                {
-                                    "anyOf": [
-                                        {"$ref": "#/components/schemas/TeamPublic"},
-                                        {"type": "null"},
-                                    ]
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"$ref": "#/components/schemas/TeamPublic"}
-                            ),
-                        },
-                    },
-                    "HeroUpdate": {
-                        "title": "HeroUpdate",
-                        "type": "object",
-                        "properties": {
-                            "name": IsDict(
-                                {
-                                    "title": "Name",
-                                    "anyOf": [{"type": "string"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Name", "type": "string"}
-                            ),
-                            "secret_name": IsDict(
-                                {
-                                    "title": "Secret Name",
-                                    "anyOf": [{"type": "string"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Secret Name", "type": "string"}
-                            ),
-                            "age": IsDict(
-                                {
-                                    "title": "Age",
-                                    "anyOf": [{"type": "integer"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Age", "type": "integer"}
-                            ),
-                            "team_id": IsDict(
-                                {
-                                    "title": "Team Id",
-                                    "anyOf": [{"type": "integer"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Team Id", "type": "integer"}
-                            ),
-                        },
-                    },
-                    "TeamCreate": {
-                        "title": "TeamCreate",
-                        "required": ["name", "headquarters"],
-                        "type": "object",
-                        "properties": {
-                            "name": {"title": "Name", "type": "string"},
-                            "headquarters": {"title": "Headquarters", "type": "string"},
-                        },
-                    },
-                    "TeamPublic": {
-                        "title": "TeamPublic",
-                        "required": ["name", "headquarters", "id"],
-                        "type": "object",
-                        "properties": {
-                            "name": {"title": "Name", "type": "string"},
-                            "headquarters": {"title": "Headquarters", "type": "string"},
-                            "id": {"title": "Id", "type": "integer"},
-                        },
-                    },
-                    "TeamPublicWithHeroes": {
-                        "title": "TeamPublicWithHeroes",
-                        "required": ["name", "headquarters", "id"],
-                        "type": "object",
-                        "properties": {
-                            "name": {"title": "Name", "type": "string"},
-                            "headquarters": {"title": "Headquarters", "type": "string"},
-                            "id": {"title": "Id", "type": "integer"},
-                            "heroes": {
-                                "title": "Heroes",
-                                "type": "array",
-                                "items": {"$ref": "#/components/schemas/HeroPublic"},
-                                "default": [],
-                            },
-                        },
-                    },
-                    "TeamUpdate": {
-                        "title": "TeamUpdate",
-                        "type": "object",
-                        "properties": {
-                            "id": IsDict(
-                                {
-                                    "title": "Id",
-                                    "anyOf": [{"type": "integer"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Id", "type": "integer"}
-                            ),
-                            "name": IsDict(
-                                {
-                                    "title": "Name",
-                                    "anyOf": [{"type": "string"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Name", "type": "string"}
-                            ),
-                            "headquarters": IsDict(
-                                {
-                                    "title": "Headquarters",
-                                    "anyOf": [{"type": "string"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Headquarters", "type": "string"}
-                            ),
-                        },
-                    },
-                    "ValidationError": {
-                        "title": "ValidationError",
-                        "required": ["loc", "msg", "type"],
-                        "type": "object",
-                        "properties": {
-                            "loc": {
-                                "title": "Location",
-                                "type": "array",
-                                "items": {
-                                    "anyOf": [{"type": "string"}, {"type": "integer"}]
-                                },
-                            },
-                            "msg": {"title": "Message", "type": "string"},
-                            "type": {"title": "Error Type", "type": "string"},
-                        },
-                    },
-                }
-            },
-        }
diff --git a/tests/test_tutorial/test_fastapi/test_relationships/test_tutorial001_py39.py b/tests/test_tutorial/test_fastapi/test_relationships/test_tutorial001_py39.py
deleted file mode 100644 (file)
index 5ef7338..0000000
+++ /dev/null
@@ -1,767 +0,0 @@
-from dirty_equals import IsDict
-from fastapi.testclient import TestClient
-from sqlmodel import create_engine
-from sqlmodel.pool import StaticPool
-
-from ....conftest import needs_py39
-
-
-@needs_py39
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.fastapi.relationships import tutorial001_py39 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(
-        mod.sqlite_url, connect_args=mod.connect_args, poolclass=StaticPool
-    )
-
-    with TestClient(mod.app) as client:
-        team_preventers = {"name": "Preventers", "headquarters": "Sharp Tower"}
-        team_z_force = {"name": "Z-Force", "headquarters": "Sister Margaret's Bar"}
-        response = client.post("/teams/", json=team_preventers)
-        assert response.status_code == 200, response.text
-        team_preventers_data = response.json()
-        team_preventers_id = team_preventers_data["id"]
-        response = client.post("/teams/", json=team_z_force)
-        assert response.status_code == 200, response.text
-        team_z_force_data = response.json()
-        team_z_force_id = team_z_force_data["id"]
-        response = client.get("/teams/")
-        data = response.json()
-        assert len(data) == 2
-        response = client.get("/teams/9000")
-        assert response.status_code == 404, response.text
-        response = client.patch(
-            f"/teams/{team_preventers_id}", json={"headquarters": "Preventers Tower"}
-        )
-        data = response.json()
-        assert response.status_code == 200, response.text
-        assert data["name"] == team_preventers["name"]
-        assert data["headquarters"] == "Preventers Tower"
-        response = client.patch("/teams/9000", json={"name": "Freedom League"})
-        assert response.status_code == 404, response.text
-
-        hero1_data = {
-            "name": "Deadpond",
-            "secret_name": "Dive Wilson",
-            "team_id": team_z_force_id,
-        }
-        hero2_data = {
-            "name": "Spider-Boy",
-            "secret_name": "Pedro Parqueador",
-            "id": 9000,
-        }
-        hero3_data = {
-            "name": "Rusty-Man",
-            "secret_name": "Tommy Sharp",
-            "age": 48,
-            "team_id": team_preventers_id,
-        }
-        response = client.post("/heroes/", json=hero1_data)
-        assert response.status_code == 200, response.text
-        hero1 = response.json()
-        hero1_id = hero1["id"]
-        response = client.post("/heroes/", json=hero2_data)
-        assert response.status_code == 200, response.text
-        hero2 = response.json()
-        hero2_id = hero2["id"]
-        response = client.post("/heroes/", json=hero3_data)
-        assert response.status_code == 200, response.text
-        response = client.get("/heroes/9000")
-        assert response.status_code == 404, response.text
-        response = client.get("/heroes/")
-        assert response.status_code == 200, response.text
-        data = response.json()
-        assert len(data) == 3
-        response = client.get(f"/heroes/{hero1_id}")
-        assert response.status_code == 200, response.text
-        data = response.json()
-        assert data["name"] == hero1_data["name"]
-        assert data["team"]["name"] == team_z_force["name"]
-        response = client.patch(
-            f"/heroes/{hero2_id}", json={"secret_name": "Spider-Youngster"}
-        )
-        assert response.status_code == 200, response.text
-        response = client.patch("/heroes/9001", json={"name": "Dragon Cube X"})
-        assert response.status_code == 404, response.text
-        response = client.delete(f"/heroes/{hero2_id}")
-        assert response.status_code == 200, response.text
-        response = client.get("/heroes/")
-        assert response.status_code == 200, response.text
-        data = response.json()
-        assert len(data) == 2
-        response = client.delete("/heroes/9000")
-        assert response.status_code == 404, response.text
-
-        response = client.get(f"/teams/{team_preventers_id}")
-        data = response.json()
-        assert response.status_code == 200, response.text
-        assert data["name"] == team_preventers_data["name"]
-        assert data["heroes"][0]["name"] == hero3_data["name"]
-
-        response = client.delete(f"/teams/{team_preventers_id}")
-        assert response.status_code == 200, response.text
-        response = client.delete("/teams/9000")
-        assert response.status_code == 404, response.text
-        response = client.get("/teams/")
-        assert response.status_code == 200, response.text
-        data = response.json()
-        assert len(data) == 1
-
-        response = client.get("/openapi.json")
-        assert response.status_code == 200, response.text
-        assert response.json() == {
-            "openapi": "3.1.0",
-            "info": {"title": "FastAPI", "version": "0.1.0"},
-            "paths": {
-                "/heroes/": {
-                    "get": {
-                        "summary": "Read Heroes",
-                        "operationId": "read_heroes_heroes__get",
-                        "parameters": [
-                            {
-                                "required": False,
-                                "schema": {
-                                    "title": "Offset",
-                                    "type": "integer",
-                                    "default": 0,
-                                },
-                                "name": "offset",
-                                "in": "query",
-                            },
-                            {
-                                "required": False,
-                                "schema": {
-                                    "title": "Limit",
-                                    "maximum": 100.0,
-                                    "type": "integer",
-                                    "default": 100,
-                                },
-                                "name": "limit",
-                                "in": "query",
-                            },
-                        ],
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "title": "Response Read Heroes Heroes  Get",
-                                            "type": "array",
-                                            "items": {
-                                                "$ref": "#/components/schemas/HeroPublic"
-                                            },
-                                        }
-                                    }
-                                },
-                            },
-                            "422": {
-                                "description": "Validation Error",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HTTPValidationError"
-                                        }
-                                    }
-                                },
-                            },
-                        },
-                    },
-                    "post": {
-                        "summary": "Create Hero",
-                        "operationId": "create_hero_heroes__post",
-                        "requestBody": {
-                            "content": {
-                                "application/json": {
-                                    "schema": {
-                                        "$ref": "#/components/schemas/HeroCreate"
-                                    }
-                                }
-                            },
-                            "required": True,
-                        },
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HeroPublic"
-                                        }
-                                    }
-                                },
-                            },
-                            "422": {
-                                "description": "Validation Error",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HTTPValidationError"
-                                        }
-                                    }
-                                },
-                            },
-                        },
-                    },
-                },
-                "/heroes/{hero_id}": {
-                    "get": {
-                        "summary": "Read Hero",
-                        "operationId": "read_hero_heroes__hero_id__get",
-                        "parameters": [
-                            {
-                                "required": True,
-                                "schema": {"title": "Hero Id", "type": "integer"},
-                                "name": "hero_id",
-                                "in": "path",
-                            }
-                        ],
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HeroPublicWithTeam"
-                                        }
-                                    }
-                                },
-                            },
-                            "422": {
-                                "description": "Validation Error",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HTTPValidationError"
-                                        }
-                                    }
-                                },
-                            },
-                        },
-                    },
-                    "delete": {
-                        "summary": "Delete Hero",
-                        "operationId": "delete_hero_heroes__hero_id__delete",
-                        "parameters": [
-                            {
-                                "required": True,
-                                "schema": {"title": "Hero Id", "type": "integer"},
-                                "name": "hero_id",
-                                "in": "path",
-                            }
-                        ],
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {"application/json": {"schema": {}}},
-                            },
-                            "422": {
-                                "description": "Validation Error",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HTTPValidationError"
-                                        }
-                                    }
-                                },
-                            },
-                        },
-                    },
-                    "patch": {
-                        "summary": "Update Hero",
-                        "operationId": "update_hero_heroes__hero_id__patch",
-                        "parameters": [
-                            {
-                                "required": True,
-                                "schema": {"title": "Hero Id", "type": "integer"},
-                                "name": "hero_id",
-                                "in": "path",
-                            }
-                        ],
-                        "requestBody": {
-                            "content": {
-                                "application/json": {
-                                    "schema": {
-                                        "$ref": "#/components/schemas/HeroUpdate"
-                                    }
-                                }
-                            },
-                            "required": True,
-                        },
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HeroPublic"
-                                        }
-                                    }
-                                },
-                            },
-                            "422": {
-                                "description": "Validation Error",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HTTPValidationError"
-                                        }
-                                    }
-                                },
-                            },
-                        },
-                    },
-                },
-                "/teams/": {
-                    "get": {
-                        "summary": "Read Teams",
-                        "operationId": "read_teams_teams__get",
-                        "parameters": [
-                            {
-                                "required": False,
-                                "schema": {
-                                    "title": "Offset",
-                                    "type": "integer",
-                                    "default": 0,
-                                },
-                                "name": "offset",
-                                "in": "query",
-                            },
-                            {
-                                "required": False,
-                                "schema": {
-                                    "title": "Limit",
-                                    "maximum": 100.0,
-                                    "type": "integer",
-                                    "default": 100,
-                                },
-                                "name": "limit",
-                                "in": "query",
-                            },
-                        ],
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "title": "Response Read Teams Teams  Get",
-                                            "type": "array",
-                                            "items": {
-                                                "$ref": "#/components/schemas/TeamPublic"
-                                            },
-                                        }
-                                    }
-                                },
-                            },
-                            "422": {
-                                "description": "Validation Error",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HTTPValidationError"
-                                        }
-                                    }
-                                },
-                            },
-                        },
-                    },
-                    "post": {
-                        "summary": "Create Team",
-                        "operationId": "create_team_teams__post",
-                        "requestBody": {
-                            "content": {
-                                "application/json": {
-                                    "schema": {
-                                        "$ref": "#/components/schemas/TeamCreate"
-                                    }
-                                }
-                            },
-                            "required": True,
-                        },
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/TeamPublic"
-                                        }
-                                    }
-                                },
-                            },
-                            "422": {
-                                "description": "Validation Error",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HTTPValidationError"
-                                        }
-                                    }
-                                },
-                            },
-                        },
-                    },
-                },
-                "/teams/{team_id}": {
-                    "get": {
-                        "summary": "Read Team",
-                        "operationId": "read_team_teams__team_id__get",
-                        "parameters": [
-                            {
-                                "required": True,
-                                "schema": {"title": "Team Id", "type": "integer"},
-                                "name": "team_id",
-                                "in": "path",
-                            }
-                        ],
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/TeamPublicWithHeroes"
-                                        }
-                                    }
-                                },
-                            },
-                            "422": {
-                                "description": "Validation Error",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HTTPValidationError"
-                                        }
-                                    }
-                                },
-                            },
-                        },
-                    },
-                    "delete": {
-                        "summary": "Delete Team",
-                        "operationId": "delete_team_teams__team_id__delete",
-                        "parameters": [
-                            {
-                                "required": True,
-                                "schema": {"title": "Team Id", "type": "integer"},
-                                "name": "team_id",
-                                "in": "path",
-                            }
-                        ],
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {"application/json": {"schema": {}}},
-                            },
-                            "422": {
-                                "description": "Validation Error",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HTTPValidationError"
-                                        }
-                                    }
-                                },
-                            },
-                        },
-                    },
-                    "patch": {
-                        "summary": "Update Team",
-                        "operationId": "update_team_teams__team_id__patch",
-                        "parameters": [
-                            {
-                                "required": True,
-                                "schema": {"title": "Team Id", "type": "integer"},
-                                "name": "team_id",
-                                "in": "path",
-                            }
-                        ],
-                        "requestBody": {
-                            "content": {
-                                "application/json": {
-                                    "schema": {
-                                        "$ref": "#/components/schemas/TeamUpdate"
-                                    }
-                                }
-                            },
-                            "required": True,
-                        },
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/TeamPublic"
-                                        }
-                                    }
-                                },
-                            },
-                            "422": {
-                                "description": "Validation Error",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HTTPValidationError"
-                                        }
-                                    }
-                                },
-                            },
-                        },
-                    },
-                },
-            },
-            "components": {
-                "schemas": {
-                    "HTTPValidationError": {
-                        "title": "HTTPValidationError",
-                        "type": "object",
-                        "properties": {
-                            "detail": {
-                                "title": "Detail",
-                                "type": "array",
-                                "items": {
-                                    "$ref": "#/components/schemas/ValidationError"
-                                },
-                            }
-                        },
-                    },
-                    "HeroCreate": {
-                        "title": "HeroCreate",
-                        "required": ["name", "secret_name"],
-                        "type": "object",
-                        "properties": {
-                            "name": {"title": "Name", "type": "string"},
-                            "secret_name": {"title": "Secret Name", "type": "string"},
-                            "age": IsDict(
-                                {
-                                    "title": "Age",
-                                    "anyOf": [{"type": "integer"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Age", "type": "integer"}
-                            ),
-                            "team_id": IsDict(
-                                {
-                                    "title": "Team Id",
-                                    "anyOf": [{"type": "integer"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Team Id", "type": "integer"}
-                            ),
-                        },
-                    },
-                    "HeroPublic": {
-                        "title": "HeroPublic",
-                        "required": ["name", "secret_name", "id"],
-                        "type": "object",
-                        "properties": {
-                            "name": {"title": "Name", "type": "string"},
-                            "secret_name": {"title": "Secret Name", "type": "string"},
-                            "age": IsDict(
-                                {
-                                    "title": "Age",
-                                    "anyOf": [{"type": "integer"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Age", "type": "integer"}
-                            ),
-                            "team_id": IsDict(
-                                {
-                                    "title": "Team Id",
-                                    "anyOf": [{"type": "integer"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Team Id", "type": "integer"}
-                            ),
-                            "id": {"title": "Id", "type": "integer"},
-                        },
-                    },
-                    "HeroPublicWithTeam": {
-                        "title": "HeroPublicWithTeam",
-                        "required": ["name", "secret_name", "id"],
-                        "type": "object",
-                        "properties": {
-                            "name": {"title": "Name", "type": "string"},
-                            "secret_name": {"title": "Secret Name", "type": "string"},
-                            "age": IsDict(
-                                {
-                                    "title": "Age",
-                                    "anyOf": [{"type": "integer"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Age", "type": "integer"}
-                            ),
-                            "team_id": IsDict(
-                                {
-                                    "title": "Team Id",
-                                    "anyOf": [{"type": "integer"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Team Id", "type": "integer"}
-                            ),
-                            "id": {"title": "Id", "type": "integer"},
-                            "team": IsDict(
-                                {
-                                    "anyOf": [
-                                        {"$ref": "#/components/schemas/TeamPublic"},
-                                        {"type": "null"},
-                                    ]
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"$ref": "#/components/schemas/TeamPublic"}
-                            ),
-                        },
-                    },
-                    "HeroUpdate": {
-                        "title": "HeroUpdate",
-                        "type": "object",
-                        "properties": {
-                            "name": IsDict(
-                                {
-                                    "title": "Name",
-                                    "anyOf": [{"type": "string"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Name", "type": "string"}
-                            ),
-                            "secret_name": IsDict(
-                                {
-                                    "title": "Secret Name",
-                                    "anyOf": [{"type": "string"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Secret Name", "type": "string"}
-                            ),
-                            "age": IsDict(
-                                {
-                                    "title": "Age",
-                                    "anyOf": [{"type": "integer"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Age", "type": "integer"}
-                            ),
-                            "team_id": IsDict(
-                                {
-                                    "title": "Team Id",
-                                    "anyOf": [{"type": "integer"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Team Id", "type": "integer"}
-                            ),
-                        },
-                    },
-                    "TeamCreate": {
-                        "title": "TeamCreate",
-                        "required": ["name", "headquarters"],
-                        "type": "object",
-                        "properties": {
-                            "name": {"title": "Name", "type": "string"},
-                            "headquarters": {"title": "Headquarters", "type": "string"},
-                        },
-                    },
-                    "TeamPublic": {
-                        "title": "TeamPublic",
-                        "required": ["name", "headquarters", "id"],
-                        "type": "object",
-                        "properties": {
-                            "name": {"title": "Name", "type": "string"},
-                            "headquarters": {"title": "Headquarters", "type": "string"},
-                            "id": {"title": "Id", "type": "integer"},
-                        },
-                    },
-                    "TeamPublicWithHeroes": {
-                        "title": "TeamPublicWithHeroes",
-                        "required": ["name", "headquarters", "id"],
-                        "type": "object",
-                        "properties": {
-                            "name": {"title": "Name", "type": "string"},
-                            "headquarters": {"title": "Headquarters", "type": "string"},
-                            "id": {"title": "Id", "type": "integer"},
-                            "heroes": {
-                                "title": "Heroes",
-                                "type": "array",
-                                "items": {"$ref": "#/components/schemas/HeroPublic"},
-                                "default": [],
-                            },
-                        },
-                    },
-                    "TeamUpdate": {
-                        "title": "TeamUpdate",
-                        "type": "object",
-                        "properties": {
-                            "id": IsDict(
-                                {
-                                    "title": "Id",
-                                    "anyOf": [{"type": "integer"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Id", "type": "integer"}
-                            ),
-                            "name": IsDict(
-                                {
-                                    "title": "Name",
-                                    "anyOf": [{"type": "string"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Name", "type": "string"}
-                            ),
-                            "headquarters": IsDict(
-                                {
-                                    "title": "Headquarters",
-                                    "anyOf": [{"type": "string"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Headquarters", "type": "string"}
-                            ),
-                        },
-                    },
-                    "ValidationError": {
-                        "title": "ValidationError",
-                        "required": ["loc", "msg", "type"],
-                        "type": "object",
-                        "properties": {
-                            "loc": {
-                                "title": "Location",
-                                "type": "array",
-                                "items": {
-                                    "anyOf": [{"type": "string"}, {"type": "integer"}]
-                                },
-                            },
-                            "msg": {"title": "Message", "type": "string"},
-                            "type": {"title": "Error Type", "type": "string"},
-                        },
-                    },
-                }
-            },
-        }
index 8f273bbd93ecc430020f6ed5159fc7e4caaf019d..186a12031188acf528cfccb433458492f275b88c 100644 (file)
@@ -1,18 +1,36 @@
+import importlib
+from types import ModuleType
+
+import pytest
 from dirty_equals import IsDict
 from fastapi.testclient import TestClient
 from sqlmodel import create_engine
 from sqlmodel.pool import StaticPool
 
+from tests.conftest import needs_py39, needs_py310
 
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.fastapi.response_model import tutorial001 as mod
 
+@pytest.fixture(
+    name="module",
+    params=[
+        "tutorial001",
+        pytest.param("tutorial001_py39", marks=needs_py39),
+        pytest.param("tutorial001_py310", marks=needs_py310),
+    ],
+)
+def get_module(request: pytest.FixtureRequest) -> ModuleType:
+    mod = importlib.import_module(
+        f"docs_src.tutorial.fastapi.response_model.{request.param}"
+    )
     mod.sqlite_url = "sqlite://"
     mod.engine = create_engine(
         mod.sqlite_url, connect_args=mod.connect_args, poolclass=StaticPool
     )
+    return mod
+
 
-    with TestClient(mod.app) as client:
+def test_tutorial(module: ModuleType):
+    with TestClient(module.app) as client:
         hero_data = {"name": "Deadpond", "secret_name": "Dive Wilson"}
         response = client.post("/heroes/", json=hero_data)
         data = response.json()
diff --git a/tests/test_tutorial/test_fastapi/test_response_model/test_tutorial001_py310.py b/tests/test_tutorial/test_fastapi/test_response_model/test_tutorial001_py310.py
deleted file mode 100644 (file)
index d249cc4..0000000
+++ /dev/null
@@ -1,162 +0,0 @@
-from dirty_equals import IsDict
-from fastapi.testclient import TestClient
-from sqlmodel import create_engine
-from sqlmodel.pool import StaticPool
-
-from ....conftest import needs_py310
-
-
-@needs_py310
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.fastapi.response_model import tutorial001_py310 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(
-        mod.sqlite_url, connect_args=mod.connect_args, poolclass=StaticPool
-    )
-
-    with TestClient(mod.app) as client:
-        hero_data = {"name": "Deadpond", "secret_name": "Dive Wilson"}
-        response = client.post("/heroes/", json=hero_data)
-        data = response.json()
-
-        assert response.status_code == 200, response.text
-        assert data["name"] == hero_data["name"]
-        assert data["secret_name"] == hero_data["secret_name"]
-        assert data["id"] is not None
-        assert data["age"] is None
-
-        response = client.get("/heroes/")
-        data = response.json()
-
-        assert response.status_code == 200, response.text
-        assert len(data) == 1
-        assert data[0]["name"] == hero_data["name"]
-        assert data[0]["secret_name"] == hero_data["secret_name"]
-
-        response = client.get("/openapi.json")
-
-        assert response.status_code == 200, response.text
-
-        assert response.json() == {
-            "openapi": "3.1.0",
-            "info": {"title": "FastAPI", "version": "0.1.0"},
-            "paths": {
-                "/heroes/": {
-                    "get": {
-                        "summary": "Read Heroes",
-                        "operationId": "read_heroes_heroes__get",
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "title": "Response Read Heroes Heroes  Get",
-                                            "type": "array",
-                                            "items": {
-                                                "$ref": "#/components/schemas/Hero"
-                                            },
-                                        }
-                                    }
-                                },
-                            }
-                        },
-                    },
-                    "post": {
-                        "summary": "Create Hero",
-                        "operationId": "create_hero_heroes__post",
-                        "requestBody": {
-                            "content": {
-                                "application/json": {
-                                    "schema": {"$ref": "#/components/schemas/Hero"}
-                                }
-                            },
-                            "required": True,
-                        },
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {"$ref": "#/components/schemas/Hero"}
-                                    }
-                                },
-                            },
-                            "422": {
-                                "description": "Validation Error",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HTTPValidationError"
-                                        }
-                                    }
-                                },
-                            },
-                        },
-                    },
-                }
-            },
-            "components": {
-                "schemas": {
-                    "HTTPValidationError": {
-                        "title": "HTTPValidationError",
-                        "type": "object",
-                        "properties": {
-                            "detail": {
-                                "title": "Detail",
-                                "type": "array",
-                                "items": {
-                                    "$ref": "#/components/schemas/ValidationError"
-                                },
-                            }
-                        },
-                    },
-                    "Hero": {
-                        "title": "Hero",
-                        "required": ["name", "secret_name"],
-                        "type": "object",
-                        "properties": {
-                            "id": IsDict(
-                                {
-                                    "title": "Id",
-                                    "anyOf": [{"type": "integer"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Id", "type": "integer"}
-                            ),
-                            "name": {"title": "Name", "type": "string"},
-                            "secret_name": {"title": "Secret Name", "type": "string"},
-                            "age": IsDict(
-                                {
-                                    "title": "Age",
-                                    "anyOf": [{"type": "integer"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Age", "type": "integer"}
-                            ),
-                        },
-                    },
-                    "ValidationError": {
-                        "title": "ValidationError",
-                        "required": ["loc", "msg", "type"],
-                        "type": "object",
-                        "properties": {
-                            "loc": {
-                                "title": "Location",
-                                "type": "array",
-                                "items": {
-                                    "anyOf": [{"type": "string"}, {"type": "integer"}]
-                                },
-                            },
-                            "msg": {"title": "Message", "type": "string"},
-                            "type": {"title": "Error Type", "type": "string"},
-                        },
-                    },
-                }
-            },
-        }
diff --git a/tests/test_tutorial/test_fastapi/test_response_model/test_tutorial001_py39.py b/tests/test_tutorial/test_fastapi/test_response_model/test_tutorial001_py39.py
deleted file mode 100644 (file)
index b9fb2be..0000000
+++ /dev/null
@@ -1,162 +0,0 @@
-from dirty_equals import IsDict
-from fastapi.testclient import TestClient
-from sqlmodel import create_engine
-from sqlmodel.pool import StaticPool
-
-from ....conftest import needs_py39
-
-
-@needs_py39
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.fastapi.response_model import tutorial001_py39 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(
-        mod.sqlite_url, connect_args=mod.connect_args, poolclass=StaticPool
-    )
-
-    with TestClient(mod.app) as client:
-        hero_data = {"name": "Deadpond", "secret_name": "Dive Wilson"}
-        response = client.post("/heroes/", json=hero_data)
-        data = response.json()
-
-        assert response.status_code == 200, response.text
-        assert data["name"] == hero_data["name"]
-        assert data["secret_name"] == hero_data["secret_name"]
-        assert data["id"] is not None
-        assert data["age"] is None
-
-        response = client.get("/heroes/")
-        data = response.json()
-
-        assert response.status_code == 200, response.text
-        assert len(data) == 1
-        assert data[0]["name"] == hero_data["name"]
-        assert data[0]["secret_name"] == hero_data["secret_name"]
-
-        response = client.get("/openapi.json")
-
-        assert response.status_code == 200, response.text
-
-        assert response.json() == {
-            "openapi": "3.1.0",
-            "info": {"title": "FastAPI", "version": "0.1.0"},
-            "paths": {
-                "/heroes/": {
-                    "get": {
-                        "summary": "Read Heroes",
-                        "operationId": "read_heroes_heroes__get",
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "title": "Response Read Heroes Heroes  Get",
-                                            "type": "array",
-                                            "items": {
-                                                "$ref": "#/components/schemas/Hero"
-                                            },
-                                        }
-                                    }
-                                },
-                            }
-                        },
-                    },
-                    "post": {
-                        "summary": "Create Hero",
-                        "operationId": "create_hero_heroes__post",
-                        "requestBody": {
-                            "content": {
-                                "application/json": {
-                                    "schema": {"$ref": "#/components/schemas/Hero"}
-                                }
-                            },
-                            "required": True,
-                        },
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {"$ref": "#/components/schemas/Hero"}
-                                    }
-                                },
-                            },
-                            "422": {
-                                "description": "Validation Error",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HTTPValidationError"
-                                        }
-                                    }
-                                },
-                            },
-                        },
-                    },
-                }
-            },
-            "components": {
-                "schemas": {
-                    "HTTPValidationError": {
-                        "title": "HTTPValidationError",
-                        "type": "object",
-                        "properties": {
-                            "detail": {
-                                "title": "Detail",
-                                "type": "array",
-                                "items": {
-                                    "$ref": "#/components/schemas/ValidationError"
-                                },
-                            }
-                        },
-                    },
-                    "Hero": {
-                        "title": "Hero",
-                        "required": ["name", "secret_name"],
-                        "type": "object",
-                        "properties": {
-                            "id": IsDict(
-                                {
-                                    "title": "Id",
-                                    "anyOf": [{"type": "integer"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Id", "type": "integer"}
-                            ),
-                            "name": {"title": "Name", "type": "string"},
-                            "secret_name": {"title": "Secret Name", "type": "string"},
-                            "age": IsDict(
-                                {
-                                    "title": "Age",
-                                    "anyOf": [{"type": "integer"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Age", "type": "integer"}
-                            ),
-                        },
-                    },
-                    "ValidationError": {
-                        "title": "ValidationError",
-                        "required": ["loc", "msg", "type"],
-                        "type": "object",
-                        "properties": {
-                            "loc": {
-                                "title": "Location",
-                                "type": "array",
-                                "items": {
-                                    "anyOf": [{"type": "string"}, {"type": "integer"}]
-                                },
-                            },
-                            "msg": {"title": "Message", "type": "string"},
-                            "type": {"title": "Error Type", "type": "string"},
-                        },
-                    },
-                }
-            },
-        }
index 388cfa9b2bfcc6ad307188a5380941bdf2d69c2b..184fb219a9427bcda403236c5b0558268e8a7761 100644 (file)
@@ -1,18 +1,36 @@
+import importlib
+from types import ModuleType
+
+import pytest
 from dirty_equals import IsDict
 from fastapi.testclient import TestClient
 from sqlmodel import create_engine
 from sqlmodel.pool import StaticPool
 
+from tests.conftest import needs_py39, needs_py310
 
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.fastapi.session_with_dependency import tutorial001 as mod
 
+@pytest.fixture(
+    name="module",
+    params=[
+        "tutorial001",
+        pytest.param("tutorial001_py39", marks=needs_py39),
+        pytest.param("tutorial001_py310", marks=needs_py310),
+    ],
+)
+def get_module(request: pytest.FixtureRequest) -> ModuleType:
+    mod = importlib.import_module(
+        f"docs_src.tutorial.fastapi.session_with_dependency.{request.param}"
+    )
     mod.sqlite_url = "sqlite://"
     mod.engine = create_engine(
         mod.sqlite_url, connect_args=mod.connect_args, poolclass=StaticPool
     )
+    return mod
+
 
-    with TestClient(mod.app) as client:
+def test_tutorial(module: ModuleType):
+    with TestClient(module.app) as client:
         hero1_data = {"name": "Deadpond", "secret_name": "Dive Wilson"}
         hero2_data = {
             "name": "Spider-Boy",
diff --git a/tests/test_tutorial/test_fastapi/test_session_with_dependency/test_tutorial001_py310.py b/tests/test_tutorial/test_fastapi/test_session_with_dependency/test_tutorial001_py310.py
deleted file mode 100644 (file)
index 65bab47..0000000
+++ /dev/null
@@ -1,379 +0,0 @@
-from dirty_equals import IsDict
-from fastapi.testclient import TestClient
-from sqlmodel import create_engine
-from sqlmodel.pool import StaticPool
-
-from ....conftest import needs_py310
-
-
-@needs_py310
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.fastapi.session_with_dependency import (
-        tutorial001_py310 as mod,
-    )
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(
-        mod.sqlite_url, connect_args=mod.connect_args, poolclass=StaticPool
-    )
-
-    with TestClient(mod.app) as client:
-        hero1_data = {"name": "Deadpond", "secret_name": "Dive Wilson"}
-        hero2_data = {
-            "name": "Spider-Boy",
-            "secret_name": "Pedro Parqueador",
-            "id": 9000,
-        }
-        hero3_data = {
-            "name": "Rusty-Man",
-            "secret_name": "Tommy Sharp",
-            "age": 48,
-        }
-        response = client.post("/heroes/", json=hero1_data)
-        assert response.status_code == 200, response.text
-        response = client.post("/heroes/", json=hero2_data)
-        assert response.status_code == 200, response.text
-        hero2 = response.json()
-        hero2_id = hero2["id"]
-        response = client.post("/heroes/", json=hero3_data)
-        assert response.status_code == 200, response.text
-        response = client.get(f"/heroes/{hero2_id}")
-        assert response.status_code == 200, response.text
-        response = client.get("/heroes/9000")
-        assert response.status_code == 404, response.text
-        response = client.get("/heroes/")
-        assert response.status_code == 200, response.text
-        data = response.json()
-        assert len(data) == 3
-        response = client.patch(
-            f"/heroes/{hero2_id}", json={"secret_name": "Spider-Youngster"}
-        )
-        assert response.status_code == 200, response.text
-        response = client.patch("/heroes/9001", json={"name": "Dragon Cube X"})
-        assert response.status_code == 404, response.text
-
-        response = client.delete(f"/heroes/{hero2_id}")
-        assert response.status_code == 200, response.text
-        response = client.get("/heroes/")
-        assert response.status_code == 200, response.text
-        data = response.json()
-        assert len(data) == 2
-
-        response = client.delete("/heroes/9000")
-        assert response.status_code == 404, response.text
-
-        response = client.get("/openapi.json")
-        assert response.status_code == 200, response.text
-        assert response.json() == {
-            "openapi": "3.1.0",
-            "info": {"title": "FastAPI", "version": "0.1.0"},
-            "paths": {
-                "/heroes/": {
-                    "get": {
-                        "summary": "Read Heroes",
-                        "operationId": "read_heroes_heroes__get",
-                        "parameters": [
-                            {
-                                "required": False,
-                                "schema": {
-                                    "title": "Offset",
-                                    "type": "integer",
-                                    "default": 0,
-                                },
-                                "name": "offset",
-                                "in": "query",
-                            },
-                            {
-                                "required": False,
-                                "schema": {
-                                    "title": "Limit",
-                                    "maximum": 100.0,
-                                    "type": "integer",
-                                    "default": 100,
-                                },
-                                "name": "limit",
-                                "in": "query",
-                            },
-                        ],
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "title": "Response Read Heroes Heroes  Get",
-                                            "type": "array",
-                                            "items": {
-                                                "$ref": "#/components/schemas/HeroPublic"
-                                            },
-                                        }
-                                    }
-                                },
-                            },
-                            "422": {
-                                "description": "Validation Error",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HTTPValidationError"
-                                        }
-                                    }
-                                },
-                            },
-                        },
-                    },
-                    "post": {
-                        "summary": "Create Hero",
-                        "operationId": "create_hero_heroes__post",
-                        "requestBody": {
-                            "content": {
-                                "application/json": {
-                                    "schema": {
-                                        "$ref": "#/components/schemas/HeroCreate"
-                                    }
-                                }
-                            },
-                            "required": True,
-                        },
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HeroPublic"
-                                        }
-                                    }
-                                },
-                            },
-                            "422": {
-                                "description": "Validation Error",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HTTPValidationError"
-                                        }
-                                    }
-                                },
-                            },
-                        },
-                    },
-                },
-                "/heroes/{hero_id}": {
-                    "get": {
-                        "summary": "Read Hero",
-                        "operationId": "read_hero_heroes__hero_id__get",
-                        "parameters": [
-                            {
-                                "required": True,
-                                "schema": {"title": "Hero Id", "type": "integer"},
-                                "name": "hero_id",
-                                "in": "path",
-                            }
-                        ],
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HeroPublic"
-                                        }
-                                    }
-                                },
-                            },
-                            "422": {
-                                "description": "Validation Error",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HTTPValidationError"
-                                        }
-                                    }
-                                },
-                            },
-                        },
-                    },
-                    "delete": {
-                        "summary": "Delete Hero",
-                        "operationId": "delete_hero_heroes__hero_id__delete",
-                        "parameters": [
-                            {
-                                "required": True,
-                                "schema": {"title": "Hero Id", "type": "integer"},
-                                "name": "hero_id",
-                                "in": "path",
-                            }
-                        ],
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {"application/json": {"schema": {}}},
-                            },
-                            "422": {
-                                "description": "Validation Error",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HTTPValidationError"
-                                        }
-                                    }
-                                },
-                            },
-                        },
-                    },
-                    "patch": {
-                        "summary": "Update Hero",
-                        "operationId": "update_hero_heroes__hero_id__patch",
-                        "parameters": [
-                            {
-                                "required": True,
-                                "schema": {"title": "Hero Id", "type": "integer"},
-                                "name": "hero_id",
-                                "in": "path",
-                            }
-                        ],
-                        "requestBody": {
-                            "content": {
-                                "application/json": {
-                                    "schema": {
-                                        "$ref": "#/components/schemas/HeroUpdate"
-                                    }
-                                }
-                            },
-                            "required": True,
-                        },
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HeroPublic"
-                                        }
-                                    }
-                                },
-                            },
-                            "422": {
-                                "description": "Validation Error",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HTTPValidationError"
-                                        }
-                                    }
-                                },
-                            },
-                        },
-                    },
-                },
-            },
-            "components": {
-                "schemas": {
-                    "HTTPValidationError": {
-                        "title": "HTTPValidationError",
-                        "type": "object",
-                        "properties": {
-                            "detail": {
-                                "title": "Detail",
-                                "type": "array",
-                                "items": {
-                                    "$ref": "#/components/schemas/ValidationError"
-                                },
-                            }
-                        },
-                    },
-                    "HeroCreate": {
-                        "title": "HeroCreate",
-                        "required": ["name", "secret_name"],
-                        "type": "object",
-                        "properties": {
-                            "name": {"title": "Name", "type": "string"},
-                            "secret_name": {"title": "Secret Name", "type": "string"},
-                            "age": IsDict(
-                                {
-                                    "title": "Age",
-                                    "anyOf": [{"type": "integer"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Age", "type": "integer"}
-                            ),
-                        },
-                    },
-                    "HeroPublic": {
-                        "title": "HeroPublic",
-                        "required": ["name", "secret_name", "id"],
-                        "type": "object",
-                        "properties": {
-                            "name": {"title": "Name", "type": "string"},
-                            "secret_name": {"title": "Secret Name", "type": "string"},
-                            "age": IsDict(
-                                {
-                                    "title": "Age",
-                                    "anyOf": [{"type": "integer"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Age", "type": "integer"}
-                            ),
-                            "id": {"title": "Id", "type": "integer"},
-                        },
-                    },
-                    "HeroUpdate": {
-                        "title": "HeroUpdate",
-                        "type": "object",
-                        "properties": {
-                            "name": IsDict(
-                                {
-                                    "title": "Name",
-                                    "anyOf": [{"type": "string"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Name", "type": "string"}
-                            ),
-                            "secret_name": IsDict(
-                                {
-                                    "title": "Secret Name",
-                                    "anyOf": [{"type": "string"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Secret Name", "type": "string"}
-                            ),
-                            "age": IsDict(
-                                {
-                                    "title": "Age",
-                                    "anyOf": [{"type": "integer"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Age", "type": "integer"}
-                            ),
-                        },
-                    },
-                    "ValidationError": {
-                        "title": "ValidationError",
-                        "required": ["loc", "msg", "type"],
-                        "type": "object",
-                        "properties": {
-                            "loc": {
-                                "title": "Location",
-                                "type": "array",
-                                "items": {
-                                    "anyOf": [{"type": "string"}, {"type": "integer"}]
-                                },
-                            },
-                            "msg": {"title": "Message", "type": "string"},
-                            "type": {"title": "Error Type", "type": "string"},
-                        },
-                    },
-                }
-            },
-        }
diff --git a/tests/test_tutorial/test_fastapi/test_session_with_dependency/test_tutorial001_py39.py b/tests/test_tutorial/test_fastapi/test_session_with_dependency/test_tutorial001_py39.py
deleted file mode 100644 (file)
index cdab85d..0000000
+++ /dev/null
@@ -1,379 +0,0 @@
-from dirty_equals import IsDict
-from fastapi.testclient import TestClient
-from sqlmodel import create_engine
-from sqlmodel.pool import StaticPool
-
-from ....conftest import needs_py39
-
-
-@needs_py39
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.fastapi.session_with_dependency import (
-        tutorial001_py39 as mod,
-    )
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(
-        mod.sqlite_url, connect_args=mod.connect_args, poolclass=StaticPool
-    )
-
-    with TestClient(mod.app) as client:
-        hero1_data = {"name": "Deadpond", "secret_name": "Dive Wilson"}
-        hero2_data = {
-            "name": "Spider-Boy",
-            "secret_name": "Pedro Parqueador",
-            "id": 9000,
-        }
-        hero3_data = {
-            "name": "Rusty-Man",
-            "secret_name": "Tommy Sharp",
-            "age": 48,
-        }
-        response = client.post("/heroes/", json=hero1_data)
-        assert response.status_code == 200, response.text
-        response = client.post("/heroes/", json=hero2_data)
-        assert response.status_code == 200, response.text
-        hero2 = response.json()
-        hero2_id = hero2["id"]
-        response = client.post("/heroes/", json=hero3_data)
-        assert response.status_code == 200, response.text
-        response = client.get(f"/heroes/{hero2_id}")
-        assert response.status_code == 200, response.text
-        response = client.get("/heroes/9000")
-        assert response.status_code == 404, response.text
-        response = client.get("/heroes/")
-        assert response.status_code == 200, response.text
-        data = response.json()
-        assert len(data) == 3
-        response = client.patch(
-            f"/heroes/{hero2_id}", json={"secret_name": "Spider-Youngster"}
-        )
-        assert response.status_code == 200, response.text
-        response = client.patch("/heroes/9001", json={"name": "Dragon Cube X"})
-        assert response.status_code == 404, response.text
-
-        response = client.delete(f"/heroes/{hero2_id}")
-        assert response.status_code == 200, response.text
-        response = client.get("/heroes/")
-        assert response.status_code == 200, response.text
-        data = response.json()
-        assert len(data) == 2
-
-        response = client.delete("/heroes/9000")
-        assert response.status_code == 404, response.text
-
-        response = client.get("/openapi.json")
-        assert response.status_code == 200, response.text
-        assert response.json() == {
-            "openapi": "3.1.0",
-            "info": {"title": "FastAPI", "version": "0.1.0"},
-            "paths": {
-                "/heroes/": {
-                    "get": {
-                        "summary": "Read Heroes",
-                        "operationId": "read_heroes_heroes__get",
-                        "parameters": [
-                            {
-                                "required": False,
-                                "schema": {
-                                    "title": "Offset",
-                                    "type": "integer",
-                                    "default": 0,
-                                },
-                                "name": "offset",
-                                "in": "query",
-                            },
-                            {
-                                "required": False,
-                                "schema": {
-                                    "title": "Limit",
-                                    "maximum": 100.0,
-                                    "type": "integer",
-                                    "default": 100,
-                                },
-                                "name": "limit",
-                                "in": "query",
-                            },
-                        ],
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "title": "Response Read Heroes Heroes  Get",
-                                            "type": "array",
-                                            "items": {
-                                                "$ref": "#/components/schemas/HeroPublic"
-                                            },
-                                        }
-                                    }
-                                },
-                            },
-                            "422": {
-                                "description": "Validation Error",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HTTPValidationError"
-                                        }
-                                    }
-                                },
-                            },
-                        },
-                    },
-                    "post": {
-                        "summary": "Create Hero",
-                        "operationId": "create_hero_heroes__post",
-                        "requestBody": {
-                            "content": {
-                                "application/json": {
-                                    "schema": {
-                                        "$ref": "#/components/schemas/HeroCreate"
-                                    }
-                                }
-                            },
-                            "required": True,
-                        },
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HeroPublic"
-                                        }
-                                    }
-                                },
-                            },
-                            "422": {
-                                "description": "Validation Error",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HTTPValidationError"
-                                        }
-                                    }
-                                },
-                            },
-                        },
-                    },
-                },
-                "/heroes/{hero_id}": {
-                    "get": {
-                        "summary": "Read Hero",
-                        "operationId": "read_hero_heroes__hero_id__get",
-                        "parameters": [
-                            {
-                                "required": True,
-                                "schema": {"title": "Hero Id", "type": "integer"},
-                                "name": "hero_id",
-                                "in": "path",
-                            }
-                        ],
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HeroPublic"
-                                        }
-                                    }
-                                },
-                            },
-                            "422": {
-                                "description": "Validation Error",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HTTPValidationError"
-                                        }
-                                    }
-                                },
-                            },
-                        },
-                    },
-                    "delete": {
-                        "summary": "Delete Hero",
-                        "operationId": "delete_hero_heroes__hero_id__delete",
-                        "parameters": [
-                            {
-                                "required": True,
-                                "schema": {"title": "Hero Id", "type": "integer"},
-                                "name": "hero_id",
-                                "in": "path",
-                            }
-                        ],
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {"application/json": {"schema": {}}},
-                            },
-                            "422": {
-                                "description": "Validation Error",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HTTPValidationError"
-                                        }
-                                    }
-                                },
-                            },
-                        },
-                    },
-                    "patch": {
-                        "summary": "Update Hero",
-                        "operationId": "update_hero_heroes__hero_id__patch",
-                        "parameters": [
-                            {
-                                "required": True,
-                                "schema": {"title": "Hero Id", "type": "integer"},
-                                "name": "hero_id",
-                                "in": "path",
-                            }
-                        ],
-                        "requestBody": {
-                            "content": {
-                                "application/json": {
-                                    "schema": {
-                                        "$ref": "#/components/schemas/HeroUpdate"
-                                    }
-                                }
-                            },
-                            "required": True,
-                        },
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HeroPublic"
-                                        }
-                                    }
-                                },
-                            },
-                            "422": {
-                                "description": "Validation Error",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HTTPValidationError"
-                                        }
-                                    }
-                                },
-                            },
-                        },
-                    },
-                },
-            },
-            "components": {
-                "schemas": {
-                    "HTTPValidationError": {
-                        "title": "HTTPValidationError",
-                        "type": "object",
-                        "properties": {
-                            "detail": {
-                                "title": "Detail",
-                                "type": "array",
-                                "items": {
-                                    "$ref": "#/components/schemas/ValidationError"
-                                },
-                            }
-                        },
-                    },
-                    "HeroCreate": {
-                        "title": "HeroCreate",
-                        "required": ["name", "secret_name"],
-                        "type": "object",
-                        "properties": {
-                            "name": {"title": "Name", "type": "string"},
-                            "secret_name": {"title": "Secret Name", "type": "string"},
-                            "age": IsDict(
-                                {
-                                    "title": "Age",
-                                    "anyOf": [{"type": "integer"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Age", "type": "integer"}
-                            ),
-                        },
-                    },
-                    "HeroPublic": {
-                        "title": "HeroPublic",
-                        "required": ["name", "secret_name", "id"],
-                        "type": "object",
-                        "properties": {
-                            "name": {"title": "Name", "type": "string"},
-                            "secret_name": {"title": "Secret Name", "type": "string"},
-                            "age": IsDict(
-                                {
-                                    "title": "Age",
-                                    "anyOf": [{"type": "integer"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Age", "type": "integer"}
-                            ),
-                            "id": {"title": "Id", "type": "integer"},
-                        },
-                    },
-                    "HeroUpdate": {
-                        "title": "HeroUpdate",
-                        "type": "object",
-                        "properties": {
-                            "name": IsDict(
-                                {
-                                    "title": "Name",
-                                    "anyOf": [{"type": "string"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Name", "type": "string"}
-                            ),
-                            "secret_name": IsDict(
-                                {
-                                    "title": "Secret Name",
-                                    "anyOf": [{"type": "string"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Secret Name", "type": "string"}
-                            ),
-                            "age": IsDict(
-                                {
-                                    "title": "Age",
-                                    "anyOf": [{"type": "integer"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Age", "type": "integer"}
-                            ),
-                        },
-                    },
-                    "ValidationError": {
-                        "title": "ValidationError",
-                        "required": ["loc", "msg", "type"],
-                        "type": "object",
-                        "properties": {
-                            "loc": {
-                                "title": "Location",
-                                "type": "array",
-                                "items": {
-                                    "anyOf": [{"type": "string"}, {"type": "integer"}]
-                                },
-                            },
-                            "msg": {"title": "Message", "type": "string"},
-                            "type": {"title": "Error Type", "type": "string"},
-                        },
-                    },
-                }
-            },
-        }
index 9df7e50b814e95a6945296b9a8704974d022c9e3..dba7bc3879dc1035031f0977d327020673a01c22 100644 (file)
@@ -1,18 +1,35 @@
+import importlib
+from types import ModuleType
+
+import pytest
 from dirty_equals import IsDict
 from fastapi.testclient import TestClient
 from sqlmodel import create_engine
 from sqlmodel.pool import StaticPool
 
+from tests.conftest import needs_py310
 
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.fastapi.simple_hero_api import tutorial001 as mod
 
+@pytest.fixture(
+    name="module",
+    params=[
+        "tutorial001",
+        pytest.param("tutorial001_py310", marks=needs_py310),
+    ],
+)
+def get_module(request: pytest.FixtureRequest) -> ModuleType:
+    mod = importlib.import_module(
+        f"docs_src.tutorial.fastapi.simple_hero_api.{request.param}"
+    )
     mod.sqlite_url = "sqlite://"
     mod.engine = create_engine(
         mod.sqlite_url, connect_args=mod.connect_args, poolclass=StaticPool
     )
+    return mod
+
 
-    with TestClient(mod.app) as client:
+def test_tutorial(module: ModuleType):
+    with TestClient(module.app) as client:
         hero1_data = {"name": "Deadpond", "secret_name": "Dive Wilson"}
         hero2_data = {
             "name": "Spider-Boy",
diff --git a/tests/test_tutorial/test_fastapi/test_simple_hero_api/test_tutorial001_py310.py b/tests/test_tutorial/test_fastapi/test_simple_hero_api/test_tutorial001_py310.py
deleted file mode 100644 (file)
index a47513d..0000000
+++ /dev/null
@@ -1,168 +0,0 @@
-from dirty_equals import IsDict
-from fastapi.testclient import TestClient
-from sqlmodel import create_engine
-from sqlmodel.pool import StaticPool
-
-from ....conftest import needs_py310
-
-
-@needs_py310
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.fastapi.simple_hero_api import tutorial001_py310 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(
-        mod.sqlite_url, connect_args=mod.connect_args, poolclass=StaticPool
-    )
-
-    with TestClient(mod.app) as client:
-        hero1_data = {"name": "Deadpond", "secret_name": "Dive Wilson"}
-        hero2_data = {
-            "name": "Spider-Boy",
-            "secret_name": "Pedro Parqueador",
-            "id": 9000,
-        }
-        response = client.post("/heroes/", json=hero1_data)
-        data = response.json()
-
-        assert response.status_code == 200, response.text
-        assert data["name"] == hero1_data["name"]
-        assert data["secret_name"] == hero1_data["secret_name"]
-        assert data["id"] is not None
-        assert data["age"] is None
-
-        response = client.post("/heroes/", json=hero2_data)
-        data = response.json()
-
-        assert response.status_code == 200, response.text
-        assert data["name"] == hero2_data["name"]
-        assert data["secret_name"] == hero2_data["secret_name"]
-        assert data["id"] == hero2_data["id"], (
-            "Up to this point it's still possible to "
-            "set the ID of the hero in the request"
-        )
-        assert data["age"] is None
-
-        response = client.get("/heroes/")
-        data = response.json()
-
-        assert response.status_code == 200, response.text
-        assert len(data) == 2
-        assert data[0]["name"] == hero1_data["name"]
-        assert data[0]["secret_name"] == hero1_data["secret_name"]
-        assert data[1]["name"] == hero2_data["name"]
-        assert data[1]["secret_name"] == hero2_data["secret_name"]
-        assert data[1]["id"] == hero2_data["id"]
-
-        response = client.get("/openapi.json")
-
-        assert response.status_code == 200, response.text
-
-        assert response.json() == {
-            "openapi": "3.1.0",
-            "info": {"title": "FastAPI", "version": "0.1.0"},
-            "paths": {
-                "/heroes/": {
-                    "get": {
-                        "summary": "Read Heroes",
-                        "operationId": "read_heroes_heroes__get",
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {"application/json": {"schema": {}}},
-                            }
-                        },
-                    },
-                    "post": {
-                        "summary": "Create Hero",
-                        "operationId": "create_hero_heroes__post",
-                        "requestBody": {
-                            "content": {
-                                "application/json": {
-                                    "schema": {"$ref": "#/components/schemas/Hero"}
-                                }
-                            },
-                            "required": True,
-                        },
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {"application/json": {"schema": {}}},
-                            },
-                            "422": {
-                                "description": "Validation Error",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HTTPValidationError"
-                                        }
-                                    }
-                                },
-                            },
-                        },
-                    },
-                }
-            },
-            "components": {
-                "schemas": {
-                    "HTTPValidationError": {
-                        "title": "HTTPValidationError",
-                        "type": "object",
-                        "properties": {
-                            "detail": {
-                                "title": "Detail",
-                                "type": "array",
-                                "items": {
-                                    "$ref": "#/components/schemas/ValidationError"
-                                },
-                            }
-                        },
-                    },
-                    "Hero": {
-                        "title": "Hero",
-                        "required": ["name", "secret_name"],
-                        "type": "object",
-                        "properties": {
-                            "id": IsDict(
-                                {
-                                    "title": "Id",
-                                    "anyOf": [{"type": "integer"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Id", "type": "integer"}
-                            ),
-                            "name": {"title": "Name", "type": "string"},
-                            "secret_name": {"title": "Secret Name", "type": "string"},
-                            "age": IsDict(
-                                {
-                                    "title": "Age",
-                                    "anyOf": [{"type": "integer"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Age", "type": "integer"}
-                            ),
-                        },
-                    },
-                    "ValidationError": {
-                        "title": "ValidationError",
-                        "required": ["loc", "msg", "type"],
-                        "type": "object",
-                        "properties": {
-                            "loc": {
-                                "title": "Location",
-                                "type": "array",
-                                "items": {
-                                    "anyOf": [{"type": "string"}, {"type": "integer"}]
-                                },
-                            },
-                            "msg": {"title": "Message", "type": "string"},
-                            "type": {"title": "Error Type", "type": "string"},
-                        },
-                    },
-                }
-            },
-        }
index 25daadf74bc7888d5620ffaa3656968e3f63487a..2e7d66a036448ed6287e274afe8977766ee71a63 100644 (file)
@@ -1,18 +1,34 @@
+import importlib
+from types import ModuleType
+
+import pytest
 from dirty_equals import IsDict
 from fastapi.testclient import TestClient
 from sqlmodel import create_engine
 from sqlmodel.pool import StaticPool
 
+from tests.conftest import needs_py39, needs_py310
 
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.fastapi.teams import tutorial001 as mod
 
+@pytest.fixture(
+    name="module",
+    params=[
+        "tutorial001",
+        pytest.param("tutorial001_py39", marks=needs_py39),
+        pytest.param("tutorial001_py310", marks=needs_py310),
+    ],
+)
+def get_module(request: pytest.FixtureRequest) -> ModuleType:
+    mod = importlib.import_module(f"docs_src.tutorial.fastapi.teams.{request.param}")
     mod.sqlite_url = "sqlite://"
     mod.engine = create_engine(
         mod.sqlite_url, connect_args=mod.connect_args, poolclass=StaticPool
     )
+    return mod
+
 
-    with TestClient(mod.app) as client:
+def test_tutorial(module: ModuleType):
+    with TestClient(module.app) as client:
         hero1_data = {"name": "Deadpond", "secret_name": "Dive Wilson"}
         hero2_data = {
             "name": "Spider-Boy",
diff --git a/tests/test_tutorial/test_fastapi/test_teams/test_tutorial001_py310.py b/tests/test_tutorial/test_fastapi/test_teams/test_tutorial001_py310.py
deleted file mode 100644 (file)
index 63f8a1d..0000000
+++ /dev/null
@@ -1,686 +0,0 @@
-from dirty_equals import IsDict
-from fastapi.testclient import TestClient
-from sqlmodel import create_engine
-from sqlmodel.pool import StaticPool
-
-from ....conftest import needs_py310
-
-
-@needs_py310
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.fastapi.teams import tutorial001_py310 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(
-        mod.sqlite_url, connect_args=mod.connect_args, poolclass=StaticPool
-    )
-
-    with TestClient(mod.app) as client:
-        hero1_data = {"name": "Deadpond", "secret_name": "Dive Wilson"}
-        hero2_data = {
-            "name": "Spider-Boy",
-            "secret_name": "Pedro Parqueador",
-            "id": 9000,
-        }
-        hero3_data = {
-            "name": "Rusty-Man",
-            "secret_name": "Tommy Sharp",
-            "age": 48,
-        }
-        response = client.post("/heroes/", json=hero1_data)
-        assert response.status_code == 200, response.text
-        response = client.post("/heroes/", json=hero2_data)
-        assert response.status_code == 200, response.text
-        hero2 = response.json()
-        hero2_id = hero2["id"]
-        response = client.post("/heroes/", json=hero3_data)
-        assert response.status_code == 200, response.text
-        response = client.get(f"/heroes/{hero2_id}")
-        assert response.status_code == 200, response.text
-        response = client.get("/heroes/9000")
-        assert response.status_code == 404, response.text
-        response = client.get("/heroes/")
-        assert response.status_code == 200, response.text
-        data = response.json()
-        assert len(data) == 3
-        response = client.patch(
-            f"/heroes/{hero2_id}", json={"secret_name": "Spider-Youngster"}
-        )
-        assert response.status_code == 200, response.text
-        response = client.patch("/heroes/9001", json={"name": "Dragon Cube X"})
-        assert response.status_code == 404, response.text
-        response = client.delete(f"/heroes/{hero2_id}")
-        assert response.status_code == 200, response.text
-        response = client.get("/heroes/")
-        assert response.status_code == 200, response.text
-        data = response.json()
-        assert len(data) == 2
-        response = client.delete("/heroes/9000")
-        assert response.status_code == 404, response.text
-
-        team_preventers = {"name": "Preventers", "headquarters": "Sharp Tower"}
-        team_z_force = {"name": "Z-Force", "headquarters": "Sister Margaret's Bar"}
-        response = client.post("/teams/", json=team_preventers)
-        assert response.status_code == 200, response.text
-        team_preventers_data = response.json()
-        team_preventers_id = team_preventers_data["id"]
-        response = client.post("/teams/", json=team_z_force)
-        assert response.status_code == 200, response.text
-        team_z_force_data = response.json()
-        team_z_force_data["id"]
-        response = client.get("/teams/")
-        data = response.json()
-        assert len(data) == 2
-        response = client.get(f"/teams/{team_preventers_id}")
-        data = response.json()
-        assert response.status_code == 200, response.text
-        assert data == team_preventers_data
-        response = client.get("/teams/9000")
-        assert response.status_code == 404, response.text
-        response = client.patch(
-            f"/teams/{team_preventers_id}", json={"headquarters": "Preventers Tower"}
-        )
-        data = response.json()
-        assert response.status_code == 200, response.text
-        assert data["name"] == team_preventers["name"]
-        assert data["headquarters"] == "Preventers Tower"
-        response = client.patch("/teams/9000", json={"name": "Freedom League"})
-        assert response.status_code == 404, response.text
-        response = client.delete(f"/teams/{team_preventers_id}")
-        assert response.status_code == 200, response.text
-        response = client.delete("/teams/9000")
-        assert response.status_code == 404, response.text
-        response = client.get("/teams/")
-        assert response.status_code == 200, response.text
-        data = response.json()
-        assert len(data) == 1
-
-        response = client.get("/openapi.json")
-        assert response.status_code == 200, response.text
-        assert response.json() == {
-            "openapi": "3.1.0",
-            "info": {"title": "FastAPI", "version": "0.1.0"},
-            "paths": {
-                "/heroes/": {
-                    "get": {
-                        "summary": "Read Heroes",
-                        "operationId": "read_heroes_heroes__get",
-                        "parameters": [
-                            {
-                                "required": False,
-                                "schema": {
-                                    "title": "Offset",
-                                    "type": "integer",
-                                    "default": 0,
-                                },
-                                "name": "offset",
-                                "in": "query",
-                            },
-                            {
-                                "required": False,
-                                "schema": {
-                                    "title": "Limit",
-                                    "maximum": 100.0,
-                                    "type": "integer",
-                                    "default": 100,
-                                },
-                                "name": "limit",
-                                "in": "query",
-                            },
-                        ],
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "title": "Response Read Heroes Heroes  Get",
-                                            "type": "array",
-                                            "items": {
-                                                "$ref": "#/components/schemas/HeroPublic"
-                                            },
-                                        }
-                                    }
-                                },
-                            },
-                            "422": {
-                                "description": "Validation Error",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HTTPValidationError"
-                                        }
-                                    }
-                                },
-                            },
-                        },
-                    },
-                    "post": {
-                        "summary": "Create Hero",
-                        "operationId": "create_hero_heroes__post",
-                        "requestBody": {
-                            "content": {
-                                "application/json": {
-                                    "schema": {
-                                        "$ref": "#/components/schemas/HeroCreate"
-                                    }
-                                }
-                            },
-                            "required": True,
-                        },
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HeroPublic"
-                                        }
-                                    }
-                                },
-                            },
-                            "422": {
-                                "description": "Validation Error",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HTTPValidationError"
-                                        }
-                                    }
-                                },
-                            },
-                        },
-                    },
-                },
-                "/heroes/{hero_id}": {
-                    "get": {
-                        "summary": "Read Hero",
-                        "operationId": "read_hero_heroes__hero_id__get",
-                        "parameters": [
-                            {
-                                "required": True,
-                                "schema": {"title": "Hero Id", "type": "integer"},
-                                "name": "hero_id",
-                                "in": "path",
-                            }
-                        ],
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HeroPublic"
-                                        }
-                                    }
-                                },
-                            },
-                            "422": {
-                                "description": "Validation Error",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HTTPValidationError"
-                                        }
-                                    }
-                                },
-                            },
-                        },
-                    },
-                    "delete": {
-                        "summary": "Delete Hero",
-                        "operationId": "delete_hero_heroes__hero_id__delete",
-                        "parameters": [
-                            {
-                                "required": True,
-                                "schema": {"title": "Hero Id", "type": "integer"},
-                                "name": "hero_id",
-                                "in": "path",
-                            }
-                        ],
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {"application/json": {"schema": {}}},
-                            },
-                            "422": {
-                                "description": "Validation Error",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HTTPValidationError"
-                                        }
-                                    }
-                                },
-                            },
-                        },
-                    },
-                    "patch": {
-                        "summary": "Update Hero",
-                        "operationId": "update_hero_heroes__hero_id__patch",
-                        "parameters": [
-                            {
-                                "required": True,
-                                "schema": {"title": "Hero Id", "type": "integer"},
-                                "name": "hero_id",
-                                "in": "path",
-                            }
-                        ],
-                        "requestBody": {
-                            "content": {
-                                "application/json": {
-                                    "schema": {
-                                        "$ref": "#/components/schemas/HeroUpdate"
-                                    }
-                                }
-                            },
-                            "required": True,
-                        },
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HeroPublic"
-                                        }
-                                    }
-                                },
-                            },
-                            "422": {
-                                "description": "Validation Error",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HTTPValidationError"
-                                        }
-                                    }
-                                },
-                            },
-                        },
-                    },
-                },
-                "/teams/": {
-                    "get": {
-                        "summary": "Read Teams",
-                        "operationId": "read_teams_teams__get",
-                        "parameters": [
-                            {
-                                "required": False,
-                                "schema": {
-                                    "title": "Offset",
-                                    "type": "integer",
-                                    "default": 0,
-                                },
-                                "name": "offset",
-                                "in": "query",
-                            },
-                            {
-                                "required": False,
-                                "schema": {
-                                    "title": "Limit",
-                                    "maximum": 100.0,
-                                    "type": "integer",
-                                    "default": 100,
-                                },
-                                "name": "limit",
-                                "in": "query",
-                            },
-                        ],
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "title": "Response Read Teams Teams  Get",
-                                            "type": "array",
-                                            "items": {
-                                                "$ref": "#/components/schemas/TeamPublic"
-                                            },
-                                        }
-                                    }
-                                },
-                            },
-                            "422": {
-                                "description": "Validation Error",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HTTPValidationError"
-                                        }
-                                    }
-                                },
-                            },
-                        },
-                    },
-                    "post": {
-                        "summary": "Create Team",
-                        "operationId": "create_team_teams__post",
-                        "requestBody": {
-                            "content": {
-                                "application/json": {
-                                    "schema": {
-                                        "$ref": "#/components/schemas/TeamCreate"
-                                    }
-                                }
-                            },
-                            "required": True,
-                        },
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/TeamPublic"
-                                        }
-                                    }
-                                },
-                            },
-                            "422": {
-                                "description": "Validation Error",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HTTPValidationError"
-                                        }
-                                    }
-                                },
-                            },
-                        },
-                    },
-                },
-                "/teams/{team_id}": {
-                    "get": {
-                        "summary": "Read Team",
-                        "operationId": "read_team_teams__team_id__get",
-                        "parameters": [
-                            {
-                                "required": True,
-                                "schema": {"title": "Team Id", "type": "integer"},
-                                "name": "team_id",
-                                "in": "path",
-                            }
-                        ],
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/TeamPublic"
-                                        }
-                                    }
-                                },
-                            },
-                            "422": {
-                                "description": "Validation Error",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HTTPValidationError"
-                                        }
-                                    }
-                                },
-                            },
-                        },
-                    },
-                    "delete": {
-                        "summary": "Delete Team",
-                        "operationId": "delete_team_teams__team_id__delete",
-                        "parameters": [
-                            {
-                                "required": True,
-                                "schema": {"title": "Team Id", "type": "integer"},
-                                "name": "team_id",
-                                "in": "path",
-                            }
-                        ],
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {"application/json": {"schema": {}}},
-                            },
-                            "422": {
-                                "description": "Validation Error",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HTTPValidationError"
-                                        }
-                                    }
-                                },
-                            },
-                        },
-                    },
-                    "patch": {
-                        "summary": "Update Team",
-                        "operationId": "update_team_teams__team_id__patch",
-                        "parameters": [
-                            {
-                                "required": True,
-                                "schema": {"title": "Team Id", "type": "integer"},
-                                "name": "team_id",
-                                "in": "path",
-                            }
-                        ],
-                        "requestBody": {
-                            "content": {
-                                "application/json": {
-                                    "schema": {
-                                        "$ref": "#/components/schemas/TeamUpdate"
-                                    }
-                                }
-                            },
-                            "required": True,
-                        },
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/TeamPublic"
-                                        }
-                                    }
-                                },
-                            },
-                            "422": {
-                                "description": "Validation Error",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HTTPValidationError"
-                                        }
-                                    }
-                                },
-                            },
-                        },
-                    },
-                },
-            },
-            "components": {
-                "schemas": {
-                    "HTTPValidationError": {
-                        "title": "HTTPValidationError",
-                        "type": "object",
-                        "properties": {
-                            "detail": {
-                                "title": "Detail",
-                                "type": "array",
-                                "items": {
-                                    "$ref": "#/components/schemas/ValidationError"
-                                },
-                            }
-                        },
-                    },
-                    "HeroCreate": {
-                        "title": "HeroCreate",
-                        "required": ["name", "secret_name"],
-                        "type": "object",
-                        "properties": {
-                            "name": {"title": "Name", "type": "string"},
-                            "secret_name": {"title": "Secret Name", "type": "string"},
-                            "age": IsDict(
-                                {
-                                    "title": "Age",
-                                    "anyOf": [{"type": "integer"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Age", "type": "integer"}
-                            ),
-                            "team_id": IsDict(
-                                {
-                                    "title": "Team Id",
-                                    "anyOf": [{"type": "integer"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Team Id", "type": "integer"}
-                            ),
-                        },
-                    },
-                    "HeroPublic": {
-                        "title": "HeroPublic",
-                        "required": ["name", "secret_name", "id"],
-                        "type": "object",
-                        "properties": {
-                            "name": {"title": "Name", "type": "string"},
-                            "secret_name": {"title": "Secret Name", "type": "string"},
-                            "age": IsDict(
-                                {
-                                    "title": "Age",
-                                    "anyOf": [{"type": "integer"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Age", "type": "integer"}
-                            ),
-                            "team_id": IsDict(
-                                {
-                                    "title": "Team Id",
-                                    "anyOf": [{"type": "integer"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Team Id", "type": "integer"}
-                            ),
-                            "id": {"title": "Id", "type": "integer"},
-                        },
-                    },
-                    "HeroUpdate": {
-                        "title": "HeroUpdate",
-                        "type": "object",
-                        "properties": {
-                            "name": IsDict(
-                                {
-                                    "title": "Name",
-                                    "anyOf": [{"type": "string"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Name", "type": "string"}
-                            ),
-                            "secret_name": IsDict(
-                                {
-                                    "title": "Secret Name",
-                                    "anyOf": [{"type": "string"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Secret Name", "type": "string"}
-                            ),
-                            "age": IsDict(
-                                {
-                                    "title": "Age",
-                                    "anyOf": [{"type": "integer"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Age", "type": "integer"}
-                            ),
-                            "team_id": IsDict(
-                                {
-                                    "title": "Team Id",
-                                    "anyOf": [{"type": "integer"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Team Id", "type": "integer"}
-                            ),
-                        },
-                    },
-                    "TeamCreate": {
-                        "title": "TeamCreate",
-                        "required": ["name", "headquarters"],
-                        "type": "object",
-                        "properties": {
-                            "name": {"title": "Name", "type": "string"},
-                            "headquarters": {"title": "Headquarters", "type": "string"},
-                        },
-                    },
-                    "TeamPublic": {
-                        "title": "TeamPublic",
-                        "required": ["name", "headquarters", "id"],
-                        "type": "object",
-                        "properties": {
-                            "name": {"title": "Name", "type": "string"},
-                            "headquarters": {"title": "Headquarters", "type": "string"},
-                            "id": {"title": "Id", "type": "integer"},
-                        },
-                    },
-                    "TeamUpdate": {
-                        "title": "TeamUpdate",
-                        "type": "object",
-                        "properties": {
-                            "name": IsDict(
-                                {
-                                    "title": "Name",
-                                    "anyOf": [{"type": "string"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Name", "type": "string"}
-                            ),
-                            "headquarters": IsDict(
-                                {
-                                    "title": "Headquarters",
-                                    "anyOf": [{"type": "string"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Headquarters", "type": "string"}
-                            ),
-                        },
-                    },
-                    "ValidationError": {
-                        "title": "ValidationError",
-                        "required": ["loc", "msg", "type"],
-                        "type": "object",
-                        "properties": {
-                            "loc": {
-                                "title": "Location",
-                                "type": "array",
-                                "items": {
-                                    "anyOf": [{"type": "string"}, {"type": "integer"}]
-                                },
-                            },
-                            "msg": {"title": "Message", "type": "string"},
-                            "type": {"title": "Error Type", "type": "string"},
-                        },
-                    },
-                }
-            },
-        }
diff --git a/tests/test_tutorial/test_fastapi/test_teams/test_tutorial001_py39.py b/tests/test_tutorial/test_fastapi/test_teams/test_tutorial001_py39.py
deleted file mode 100644 (file)
index 30b68e0..0000000
+++ /dev/null
@@ -1,686 +0,0 @@
-from dirty_equals import IsDict
-from fastapi.testclient import TestClient
-from sqlmodel import create_engine
-from sqlmodel.pool import StaticPool
-
-from ....conftest import needs_py39
-
-
-@needs_py39
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.fastapi.teams import tutorial001_py39 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(
-        mod.sqlite_url, connect_args=mod.connect_args, poolclass=StaticPool
-    )
-
-    with TestClient(mod.app) as client:
-        hero1_data = {"name": "Deadpond", "secret_name": "Dive Wilson"}
-        hero2_data = {
-            "name": "Spider-Boy",
-            "secret_name": "Pedro Parqueador",
-            "id": 9000,
-        }
-        hero3_data = {
-            "name": "Rusty-Man",
-            "secret_name": "Tommy Sharp",
-            "age": 48,
-        }
-        response = client.post("/heroes/", json=hero1_data)
-        assert response.status_code == 200, response.text
-        response = client.post("/heroes/", json=hero2_data)
-        assert response.status_code == 200, response.text
-        hero2 = response.json()
-        hero2_id = hero2["id"]
-        response = client.post("/heroes/", json=hero3_data)
-        assert response.status_code == 200, response.text
-        response = client.get(f"/heroes/{hero2_id}")
-        assert response.status_code == 200, response.text
-        response = client.get("/heroes/9000")
-        assert response.status_code == 404, response.text
-        response = client.get("/heroes/")
-        assert response.status_code == 200, response.text
-        data = response.json()
-        assert len(data) == 3
-        response = client.patch(
-            f"/heroes/{hero2_id}", json={"secret_name": "Spider-Youngster"}
-        )
-        assert response.status_code == 200, response.text
-        response = client.patch("/heroes/9001", json={"name": "Dragon Cube X"})
-        assert response.status_code == 404, response.text
-        response = client.delete(f"/heroes/{hero2_id}")
-        assert response.status_code == 200, response.text
-        response = client.get("/heroes/")
-        assert response.status_code == 200, response.text
-        data = response.json()
-        assert len(data) == 2
-        response = client.delete("/heroes/9000")
-        assert response.status_code == 404, response.text
-
-        team_preventers = {"name": "Preventers", "headquarters": "Sharp Tower"}
-        team_z_force = {"name": "Z-Force", "headquarters": "Sister Margaret's Bar"}
-        response = client.post("/teams/", json=team_preventers)
-        assert response.status_code == 200, response.text
-        team_preventers_data = response.json()
-        team_preventers_id = team_preventers_data["id"]
-        response = client.post("/teams/", json=team_z_force)
-        assert response.status_code == 200, response.text
-        team_z_force_data = response.json()
-        team_z_force_data["id"]
-        response = client.get("/teams/")
-        data = response.json()
-        assert len(data) == 2
-        response = client.get(f"/teams/{team_preventers_id}")
-        data = response.json()
-        assert response.status_code == 200, response.text
-        assert data == team_preventers_data
-        response = client.get("/teams/9000")
-        assert response.status_code == 404, response.text
-        response = client.patch(
-            f"/teams/{team_preventers_id}", json={"headquarters": "Preventers Tower"}
-        )
-        data = response.json()
-        assert response.status_code == 200, response.text
-        assert data["name"] == team_preventers["name"]
-        assert data["headquarters"] == "Preventers Tower"
-        response = client.patch("/teams/9000", json={"name": "Freedom League"})
-        assert response.status_code == 404, response.text
-        response = client.delete(f"/teams/{team_preventers_id}")
-        assert response.status_code == 200, response.text
-        response = client.delete("/teams/9000")
-        assert response.status_code == 404, response.text
-        response = client.get("/teams/")
-        assert response.status_code == 200, response.text
-        data = response.json()
-        assert len(data) == 1
-
-        response = client.get("/openapi.json")
-        assert response.status_code == 200, response.text
-        assert response.json() == {
-            "openapi": "3.1.0",
-            "info": {"title": "FastAPI", "version": "0.1.0"},
-            "paths": {
-                "/heroes/": {
-                    "get": {
-                        "summary": "Read Heroes",
-                        "operationId": "read_heroes_heroes__get",
-                        "parameters": [
-                            {
-                                "required": False,
-                                "schema": {
-                                    "title": "Offset",
-                                    "type": "integer",
-                                    "default": 0,
-                                },
-                                "name": "offset",
-                                "in": "query",
-                            },
-                            {
-                                "required": False,
-                                "schema": {
-                                    "title": "Limit",
-                                    "maximum": 100.0,
-                                    "type": "integer",
-                                    "default": 100,
-                                },
-                                "name": "limit",
-                                "in": "query",
-                            },
-                        ],
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "title": "Response Read Heroes Heroes  Get",
-                                            "type": "array",
-                                            "items": {
-                                                "$ref": "#/components/schemas/HeroPublic"
-                                            },
-                                        }
-                                    }
-                                },
-                            },
-                            "422": {
-                                "description": "Validation Error",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HTTPValidationError"
-                                        }
-                                    }
-                                },
-                            },
-                        },
-                    },
-                    "post": {
-                        "summary": "Create Hero",
-                        "operationId": "create_hero_heroes__post",
-                        "requestBody": {
-                            "content": {
-                                "application/json": {
-                                    "schema": {
-                                        "$ref": "#/components/schemas/HeroCreate"
-                                    }
-                                }
-                            },
-                            "required": True,
-                        },
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HeroPublic"
-                                        }
-                                    }
-                                },
-                            },
-                            "422": {
-                                "description": "Validation Error",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HTTPValidationError"
-                                        }
-                                    }
-                                },
-                            },
-                        },
-                    },
-                },
-                "/heroes/{hero_id}": {
-                    "get": {
-                        "summary": "Read Hero",
-                        "operationId": "read_hero_heroes__hero_id__get",
-                        "parameters": [
-                            {
-                                "required": True,
-                                "schema": {"title": "Hero Id", "type": "integer"},
-                                "name": "hero_id",
-                                "in": "path",
-                            }
-                        ],
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HeroPublic"
-                                        }
-                                    }
-                                },
-                            },
-                            "422": {
-                                "description": "Validation Error",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HTTPValidationError"
-                                        }
-                                    }
-                                },
-                            },
-                        },
-                    },
-                    "delete": {
-                        "summary": "Delete Hero",
-                        "operationId": "delete_hero_heroes__hero_id__delete",
-                        "parameters": [
-                            {
-                                "required": True,
-                                "schema": {"title": "Hero Id", "type": "integer"},
-                                "name": "hero_id",
-                                "in": "path",
-                            }
-                        ],
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {"application/json": {"schema": {}}},
-                            },
-                            "422": {
-                                "description": "Validation Error",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HTTPValidationError"
-                                        }
-                                    }
-                                },
-                            },
-                        },
-                    },
-                    "patch": {
-                        "summary": "Update Hero",
-                        "operationId": "update_hero_heroes__hero_id__patch",
-                        "parameters": [
-                            {
-                                "required": True,
-                                "schema": {"title": "Hero Id", "type": "integer"},
-                                "name": "hero_id",
-                                "in": "path",
-                            }
-                        ],
-                        "requestBody": {
-                            "content": {
-                                "application/json": {
-                                    "schema": {
-                                        "$ref": "#/components/schemas/HeroUpdate"
-                                    }
-                                }
-                            },
-                            "required": True,
-                        },
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HeroPublic"
-                                        }
-                                    }
-                                },
-                            },
-                            "422": {
-                                "description": "Validation Error",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HTTPValidationError"
-                                        }
-                                    }
-                                },
-                            },
-                        },
-                    },
-                },
-                "/teams/": {
-                    "get": {
-                        "summary": "Read Teams",
-                        "operationId": "read_teams_teams__get",
-                        "parameters": [
-                            {
-                                "required": False,
-                                "schema": {
-                                    "title": "Offset",
-                                    "type": "integer",
-                                    "default": 0,
-                                },
-                                "name": "offset",
-                                "in": "query",
-                            },
-                            {
-                                "required": False,
-                                "schema": {
-                                    "title": "Limit",
-                                    "maximum": 100.0,
-                                    "type": "integer",
-                                    "default": 100,
-                                },
-                                "name": "limit",
-                                "in": "query",
-                            },
-                        ],
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "title": "Response Read Teams Teams  Get",
-                                            "type": "array",
-                                            "items": {
-                                                "$ref": "#/components/schemas/TeamPublic"
-                                            },
-                                        }
-                                    }
-                                },
-                            },
-                            "422": {
-                                "description": "Validation Error",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HTTPValidationError"
-                                        }
-                                    }
-                                },
-                            },
-                        },
-                    },
-                    "post": {
-                        "summary": "Create Team",
-                        "operationId": "create_team_teams__post",
-                        "requestBody": {
-                            "content": {
-                                "application/json": {
-                                    "schema": {
-                                        "$ref": "#/components/schemas/TeamCreate"
-                                    }
-                                }
-                            },
-                            "required": True,
-                        },
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/TeamPublic"
-                                        }
-                                    }
-                                },
-                            },
-                            "422": {
-                                "description": "Validation Error",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HTTPValidationError"
-                                        }
-                                    }
-                                },
-                            },
-                        },
-                    },
-                },
-                "/teams/{team_id}": {
-                    "get": {
-                        "summary": "Read Team",
-                        "operationId": "read_team_teams__team_id__get",
-                        "parameters": [
-                            {
-                                "required": True,
-                                "schema": {"title": "Team Id", "type": "integer"},
-                                "name": "team_id",
-                                "in": "path",
-                            }
-                        ],
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/TeamPublic"
-                                        }
-                                    }
-                                },
-                            },
-                            "422": {
-                                "description": "Validation Error",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HTTPValidationError"
-                                        }
-                                    }
-                                },
-                            },
-                        },
-                    },
-                    "delete": {
-                        "summary": "Delete Team",
-                        "operationId": "delete_team_teams__team_id__delete",
-                        "parameters": [
-                            {
-                                "required": True,
-                                "schema": {"title": "Team Id", "type": "integer"},
-                                "name": "team_id",
-                                "in": "path",
-                            }
-                        ],
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {"application/json": {"schema": {}}},
-                            },
-                            "422": {
-                                "description": "Validation Error",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HTTPValidationError"
-                                        }
-                                    }
-                                },
-                            },
-                        },
-                    },
-                    "patch": {
-                        "summary": "Update Team",
-                        "operationId": "update_team_teams__team_id__patch",
-                        "parameters": [
-                            {
-                                "required": True,
-                                "schema": {"title": "Team Id", "type": "integer"},
-                                "name": "team_id",
-                                "in": "path",
-                            }
-                        ],
-                        "requestBody": {
-                            "content": {
-                                "application/json": {
-                                    "schema": {
-                                        "$ref": "#/components/schemas/TeamUpdate"
-                                    }
-                                }
-                            },
-                            "required": True,
-                        },
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/TeamPublic"
-                                        }
-                                    }
-                                },
-                            },
-                            "422": {
-                                "description": "Validation Error",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HTTPValidationError"
-                                        }
-                                    }
-                                },
-                            },
-                        },
-                    },
-                },
-            },
-            "components": {
-                "schemas": {
-                    "HTTPValidationError": {
-                        "title": "HTTPValidationError",
-                        "type": "object",
-                        "properties": {
-                            "detail": {
-                                "title": "Detail",
-                                "type": "array",
-                                "items": {
-                                    "$ref": "#/components/schemas/ValidationError"
-                                },
-                            }
-                        },
-                    },
-                    "HeroCreate": {
-                        "title": "HeroCreate",
-                        "required": ["name", "secret_name"],
-                        "type": "object",
-                        "properties": {
-                            "name": {"title": "Name", "type": "string"},
-                            "secret_name": {"title": "Secret Name", "type": "string"},
-                            "age": IsDict(
-                                {
-                                    "title": "Age",
-                                    "anyOf": [{"type": "integer"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Age", "type": "integer"}
-                            ),
-                            "team_id": IsDict(
-                                {
-                                    "title": "Team Id",
-                                    "anyOf": [{"type": "integer"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Team Id", "type": "integer"}
-                            ),
-                        },
-                    },
-                    "HeroPublic": {
-                        "title": "HeroPublic",
-                        "required": ["name", "secret_name", "id"],
-                        "type": "object",
-                        "properties": {
-                            "name": {"title": "Name", "type": "string"},
-                            "secret_name": {"title": "Secret Name", "type": "string"},
-                            "age": IsDict(
-                                {
-                                    "title": "Age",
-                                    "anyOf": [{"type": "integer"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Age", "type": "integer"}
-                            ),
-                            "team_id": IsDict(
-                                {
-                                    "title": "Team Id",
-                                    "anyOf": [{"type": "integer"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Team Id", "type": "integer"}
-                            ),
-                            "id": {"title": "Id", "type": "integer"},
-                        },
-                    },
-                    "HeroUpdate": {
-                        "title": "HeroUpdate",
-                        "type": "object",
-                        "properties": {
-                            "name": IsDict(
-                                {
-                                    "title": "Name",
-                                    "anyOf": [{"type": "string"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Name", "type": "string"}
-                            ),
-                            "secret_name": IsDict(
-                                {
-                                    "title": "Secret Name",
-                                    "anyOf": [{"type": "string"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Secret Name", "type": "string"}
-                            ),
-                            "age": IsDict(
-                                {
-                                    "title": "Age",
-                                    "anyOf": [{"type": "integer"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Age", "type": "integer"}
-                            ),
-                            "team_id": IsDict(
-                                {
-                                    "title": "Team Id",
-                                    "anyOf": [{"type": "integer"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Team Id", "type": "integer"}
-                            ),
-                        },
-                    },
-                    "TeamCreate": {
-                        "title": "TeamCreate",
-                        "required": ["name", "headquarters"],
-                        "type": "object",
-                        "properties": {
-                            "name": {"title": "Name", "type": "string"},
-                            "headquarters": {"title": "Headquarters", "type": "string"},
-                        },
-                    },
-                    "TeamPublic": {
-                        "title": "TeamPublic",
-                        "required": ["name", "headquarters", "id"],
-                        "type": "object",
-                        "properties": {
-                            "name": {"title": "Name", "type": "string"},
-                            "headquarters": {"title": "Headquarters", "type": "string"},
-                            "id": {"title": "Id", "type": "integer"},
-                        },
-                    },
-                    "TeamUpdate": {
-                        "title": "TeamUpdate",
-                        "type": "object",
-                        "properties": {
-                            "name": IsDict(
-                                {
-                                    "title": "Name",
-                                    "anyOf": [{"type": "string"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Name", "type": "string"}
-                            ),
-                            "headquarters": IsDict(
-                                {
-                                    "title": "Headquarters",
-                                    "anyOf": [{"type": "string"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Headquarters", "type": "string"}
-                            ),
-                        },
-                    },
-                    "ValidationError": {
-                        "title": "ValidationError",
-                        "required": ["loc", "msg", "type"],
-                        "type": "object",
-                        "properties": {
-                            "loc": {
-                                "title": "Location",
-                                "type": "array",
-                                "items": {
-                                    "anyOf": [{"type": "string"}, {"type": "integer"}]
-                                },
-                            },
-                            "msg": {"title": "Message", "type": "string"},
-                            "type": {"title": "Error Type", "type": "string"},
-                        },
-                    },
-                }
-            },
-        }
index 6f3856912e84dd3381d5221e83b3c08cd1f6189c..b6ee27611f32d42d3d27580f7a8b5d1433f0cf80 100644 (file)
@@ -1,18 +1,34 @@
+import importlib
+from types import ModuleType
+
+import pytest
 from dirty_equals import IsDict
 from fastapi.testclient import TestClient
 from sqlmodel import create_engine
 from sqlmodel.pool import StaticPool
 
+from tests.conftest import needs_py39, needs_py310
 
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.fastapi.update import tutorial001 as mod
 
+@pytest.fixture(
+    name="module",
+    params=[
+        "tutorial001",
+        pytest.param("tutorial001_py39", marks=needs_py39),
+        pytest.param("tutorial001_py310", marks=needs_py310),
+    ],
+)
+def get_module(request: pytest.FixtureRequest) -> ModuleType:
+    mod = importlib.import_module(f"docs_src.tutorial.fastapi.update.{request.param}")
     mod.sqlite_url = "sqlite://"
     mod.engine = create_engine(
         mod.sqlite_url, connect_args=mod.connect_args, poolclass=StaticPool
     )
+    return mod
+
 
-    with TestClient(mod.app) as client:
+def test_tutorial(module: ModuleType):
+    with TestClient(module.app) as client:
         hero1_data = {"name": "Deadpond", "secret_name": "Dive Wilson"}
         hero2_data = {
             "name": "Spider-Boy",
diff --git a/tests/test_tutorial/test_fastapi/test_update/test_tutorial001_py310.py b/tests/test_tutorial/test_fastapi/test_update/test_tutorial001_py310.py
deleted file mode 100644 (file)
index 119634d..0000000
+++ /dev/null
@@ -1,356 +0,0 @@
-from dirty_equals import IsDict
-from fastapi.testclient import TestClient
-from sqlmodel import create_engine
-from sqlmodel.pool import StaticPool
-
-from ....conftest import needs_py310
-
-
-@needs_py310
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.fastapi.update import tutorial001_py310 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(
-        mod.sqlite_url, connect_args=mod.connect_args, poolclass=StaticPool
-    )
-
-    with TestClient(mod.app) as client:
-        hero1_data = {"name": "Deadpond", "secret_name": "Dive Wilson"}
-        hero2_data = {
-            "name": "Spider-Boy",
-            "secret_name": "Pedro Parqueador",
-            "id": 9000,
-        }
-        hero3_data = {
-            "name": "Rusty-Man",
-            "secret_name": "Tommy Sharp",
-            "age": 48,
-        }
-        response = client.post("/heroes/", json=hero1_data)
-        assert response.status_code == 200, response.text
-        response = client.post("/heroes/", json=hero2_data)
-        assert response.status_code == 200, response.text
-        hero2 = response.json()
-        hero2_id = hero2["id"]
-        response = client.post("/heroes/", json=hero3_data)
-        assert response.status_code == 200, response.text
-        hero3 = response.json()
-        hero3_id = hero3["id"]
-        response = client.get(f"/heroes/{hero2_id}")
-        assert response.status_code == 200, response.text
-        response = client.get("/heroes/9000")
-        assert response.status_code == 404, response.text
-        response = client.get("/heroes/")
-        assert response.status_code == 200, response.text
-        data = response.json()
-        assert len(data) == 3
-
-        response = client.patch(
-            f"/heroes/{hero2_id}", json={"secret_name": "Spider-Youngster"}
-        )
-        data = response.json()
-        assert response.status_code == 200, response.text
-        assert data["name"] == hero2_data["name"], "The name should not be set to none"
-        assert data["secret_name"] == "Spider-Youngster", (
-            "The secret name should be updated"
-        )
-
-        response = client.patch(f"/heroes/{hero3_id}", json={"age": None})
-        data = response.json()
-        assert response.status_code == 200, response.text
-        assert data["name"] == hero3_data["name"]
-        assert data["age"] is None, (
-            "A field should be updatable to None, even if that's the default"
-        )
-
-        response = client.patch("/heroes/9001", json={"name": "Dragon Cube X"})
-        assert response.status_code == 404, response.text
-
-        response = client.get("/openapi.json")
-        assert response.status_code == 200, response.text
-        assert response.json() == {
-            "openapi": "3.1.0",
-            "info": {"title": "FastAPI", "version": "0.1.0"},
-            "paths": {
-                "/heroes/": {
-                    "get": {
-                        "summary": "Read Heroes",
-                        "operationId": "read_heroes_heroes__get",
-                        "parameters": [
-                            {
-                                "required": False,
-                                "schema": {
-                                    "title": "Offset",
-                                    "type": "integer",
-                                    "default": 0,
-                                },
-                                "name": "offset",
-                                "in": "query",
-                            },
-                            {
-                                "required": False,
-                                "schema": {
-                                    "title": "Limit",
-                                    "maximum": 100.0,
-                                    "type": "integer",
-                                    "default": 100,
-                                },
-                                "name": "limit",
-                                "in": "query",
-                            },
-                        ],
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "title": "Response Read Heroes Heroes  Get",
-                                            "type": "array",
-                                            "items": {
-                                                "$ref": "#/components/schemas/HeroPublic"
-                                            },
-                                        }
-                                    }
-                                },
-                            },
-                            "422": {
-                                "description": "Validation Error",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HTTPValidationError"
-                                        }
-                                    }
-                                },
-                            },
-                        },
-                    },
-                    "post": {
-                        "summary": "Create Hero",
-                        "operationId": "create_hero_heroes__post",
-                        "requestBody": {
-                            "content": {
-                                "application/json": {
-                                    "schema": {
-                                        "$ref": "#/components/schemas/HeroCreate"
-                                    }
-                                }
-                            },
-                            "required": True,
-                        },
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HeroPublic"
-                                        }
-                                    }
-                                },
-                            },
-                            "422": {
-                                "description": "Validation Error",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HTTPValidationError"
-                                        }
-                                    }
-                                },
-                            },
-                        },
-                    },
-                },
-                "/heroes/{hero_id}": {
-                    "get": {
-                        "summary": "Read Hero",
-                        "operationId": "read_hero_heroes__hero_id__get",
-                        "parameters": [
-                            {
-                                "required": True,
-                                "schema": {"title": "Hero Id", "type": "integer"},
-                                "name": "hero_id",
-                                "in": "path",
-                            }
-                        ],
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HeroPublic"
-                                        }
-                                    }
-                                },
-                            },
-                            "422": {
-                                "description": "Validation Error",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HTTPValidationError"
-                                        }
-                                    }
-                                },
-                            },
-                        },
-                    },
-                    "patch": {
-                        "summary": "Update Hero",
-                        "operationId": "update_hero_heroes__hero_id__patch",
-                        "parameters": [
-                            {
-                                "required": True,
-                                "schema": {"title": "Hero Id", "type": "integer"},
-                                "name": "hero_id",
-                                "in": "path",
-                            }
-                        ],
-                        "requestBody": {
-                            "content": {
-                                "application/json": {
-                                    "schema": {
-                                        "$ref": "#/components/schemas/HeroUpdate"
-                                    }
-                                }
-                            },
-                            "required": True,
-                        },
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HeroPublic"
-                                        }
-                                    }
-                                },
-                            },
-                            "422": {
-                                "description": "Validation Error",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HTTPValidationError"
-                                        }
-                                    }
-                                },
-                            },
-                        },
-                    },
-                },
-            },
-            "components": {
-                "schemas": {
-                    "HTTPValidationError": {
-                        "title": "HTTPValidationError",
-                        "type": "object",
-                        "properties": {
-                            "detail": {
-                                "title": "Detail",
-                                "type": "array",
-                                "items": {
-                                    "$ref": "#/components/schemas/ValidationError"
-                                },
-                            }
-                        },
-                    },
-                    "HeroCreate": {
-                        "title": "HeroCreate",
-                        "required": ["name", "secret_name"],
-                        "type": "object",
-                        "properties": {
-                            "name": {"title": "Name", "type": "string"},
-                            "secret_name": {"title": "Secret Name", "type": "string"},
-                            "age": IsDict(
-                                {
-                                    "title": "Age",
-                                    "anyOf": [{"type": "integer"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Age", "type": "integer"}
-                            ),
-                        },
-                    },
-                    "HeroPublic": {
-                        "title": "HeroPublic",
-                        "required": ["name", "secret_name", "id"],
-                        "type": "object",
-                        "properties": {
-                            "name": {"title": "Name", "type": "string"},
-                            "secret_name": {"title": "Secret Name", "type": "string"},
-                            "age": IsDict(
-                                {
-                                    "title": "Age",
-                                    "anyOf": [{"type": "integer"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Age", "type": "integer"}
-                            ),
-                            "id": {"title": "Id", "type": "integer"},
-                        },
-                    },
-                    "HeroUpdate": {
-                        "title": "HeroUpdate",
-                        "type": "object",
-                        "properties": {
-                            "name": IsDict(
-                                {
-                                    "title": "Name",
-                                    "anyOf": [{"type": "string"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Name", "type": "string"}
-                            ),
-                            "secret_name": IsDict(
-                                {
-                                    "title": "Secret Name",
-                                    "anyOf": [{"type": "string"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Secret Name", "type": "string"}
-                            ),
-                            "age": IsDict(
-                                {
-                                    "title": "Age",
-                                    "anyOf": [{"type": "integer"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Age", "type": "integer"}
-                            ),
-                        },
-                    },
-                    "ValidationError": {
-                        "title": "ValidationError",
-                        "required": ["loc", "msg", "type"],
-                        "type": "object",
-                        "properties": {
-                            "loc": {
-                                "title": "Location",
-                                "type": "array",
-                                "items": {
-                                    "anyOf": [{"type": "string"}, {"type": "integer"}]
-                                },
-                            },
-                            "msg": {"title": "Message", "type": "string"},
-                            "type": {"title": "Error Type", "type": "string"},
-                        },
-                    },
-                }
-            },
-        }
diff --git a/tests/test_tutorial/test_fastapi/test_update/test_tutorial001_py39.py b/tests/test_tutorial/test_fastapi/test_update/test_tutorial001_py39.py
deleted file mode 100644 (file)
index 455480f..0000000
+++ /dev/null
@@ -1,356 +0,0 @@
-from dirty_equals import IsDict
-from fastapi.testclient import TestClient
-from sqlmodel import create_engine
-from sqlmodel.pool import StaticPool
-
-from ....conftest import needs_py39
-
-
-@needs_py39
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.fastapi.update import tutorial001_py39 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(
-        mod.sqlite_url, connect_args=mod.connect_args, poolclass=StaticPool
-    )
-
-    with TestClient(mod.app) as client:
-        hero1_data = {"name": "Deadpond", "secret_name": "Dive Wilson"}
-        hero2_data = {
-            "name": "Spider-Boy",
-            "secret_name": "Pedro Parqueador",
-            "id": 9000,
-        }
-        hero3_data = {
-            "name": "Rusty-Man",
-            "secret_name": "Tommy Sharp",
-            "age": 48,
-        }
-        response = client.post("/heroes/", json=hero1_data)
-        assert response.status_code == 200, response.text
-        response = client.post("/heroes/", json=hero2_data)
-        assert response.status_code == 200, response.text
-        hero2 = response.json()
-        hero2_id = hero2["id"]
-        response = client.post("/heroes/", json=hero3_data)
-        assert response.status_code == 200, response.text
-        hero3 = response.json()
-        hero3_id = hero3["id"]
-        response = client.get(f"/heroes/{hero2_id}")
-        assert response.status_code == 200, response.text
-        response = client.get("/heroes/9000")
-        assert response.status_code == 404, response.text
-        response = client.get("/heroes/")
-        assert response.status_code == 200, response.text
-        data = response.json()
-        assert len(data) == 3
-
-        response = client.patch(
-            f"/heroes/{hero2_id}", json={"secret_name": "Spider-Youngster"}
-        )
-        data = response.json()
-        assert response.status_code == 200, response.text
-        assert data["name"] == hero2_data["name"], "The name should not be set to none"
-        assert data["secret_name"] == "Spider-Youngster", (
-            "The secret name should be updated"
-        )
-
-        response = client.patch(f"/heroes/{hero3_id}", json={"age": None})
-        data = response.json()
-        assert response.status_code == 200, response.text
-        assert data["name"] == hero3_data["name"]
-        assert data["age"] is None, (
-            "A field should be updatable to None, even if that's the default"
-        )
-
-        response = client.patch("/heroes/9001", json={"name": "Dragon Cube X"})
-        assert response.status_code == 404, response.text
-
-        response = client.get("/openapi.json")
-        assert response.status_code == 200, response.text
-        assert response.json() == {
-            "openapi": "3.1.0",
-            "info": {"title": "FastAPI", "version": "0.1.0"},
-            "paths": {
-                "/heroes/": {
-                    "get": {
-                        "summary": "Read Heroes",
-                        "operationId": "read_heroes_heroes__get",
-                        "parameters": [
-                            {
-                                "required": False,
-                                "schema": {
-                                    "title": "Offset",
-                                    "type": "integer",
-                                    "default": 0,
-                                },
-                                "name": "offset",
-                                "in": "query",
-                            },
-                            {
-                                "required": False,
-                                "schema": {
-                                    "title": "Limit",
-                                    "maximum": 100.0,
-                                    "type": "integer",
-                                    "default": 100,
-                                },
-                                "name": "limit",
-                                "in": "query",
-                            },
-                        ],
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "title": "Response Read Heroes Heroes  Get",
-                                            "type": "array",
-                                            "items": {
-                                                "$ref": "#/components/schemas/HeroPublic"
-                                            },
-                                        }
-                                    }
-                                },
-                            },
-                            "422": {
-                                "description": "Validation Error",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HTTPValidationError"
-                                        }
-                                    }
-                                },
-                            },
-                        },
-                    },
-                    "post": {
-                        "summary": "Create Hero",
-                        "operationId": "create_hero_heroes__post",
-                        "requestBody": {
-                            "content": {
-                                "application/json": {
-                                    "schema": {
-                                        "$ref": "#/components/schemas/HeroCreate"
-                                    }
-                                }
-                            },
-                            "required": True,
-                        },
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HeroPublic"
-                                        }
-                                    }
-                                },
-                            },
-                            "422": {
-                                "description": "Validation Error",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HTTPValidationError"
-                                        }
-                                    }
-                                },
-                            },
-                        },
-                    },
-                },
-                "/heroes/{hero_id}": {
-                    "get": {
-                        "summary": "Read Hero",
-                        "operationId": "read_hero_heroes__hero_id__get",
-                        "parameters": [
-                            {
-                                "required": True,
-                                "schema": {"title": "Hero Id", "type": "integer"},
-                                "name": "hero_id",
-                                "in": "path",
-                            }
-                        ],
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HeroPublic"
-                                        }
-                                    }
-                                },
-                            },
-                            "422": {
-                                "description": "Validation Error",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HTTPValidationError"
-                                        }
-                                    }
-                                },
-                            },
-                        },
-                    },
-                    "patch": {
-                        "summary": "Update Hero",
-                        "operationId": "update_hero_heroes__hero_id__patch",
-                        "parameters": [
-                            {
-                                "required": True,
-                                "schema": {"title": "Hero Id", "type": "integer"},
-                                "name": "hero_id",
-                                "in": "path",
-                            }
-                        ],
-                        "requestBody": {
-                            "content": {
-                                "application/json": {
-                                    "schema": {
-                                        "$ref": "#/components/schemas/HeroUpdate"
-                                    }
-                                }
-                            },
-                            "required": True,
-                        },
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HeroPublic"
-                                        }
-                                    }
-                                },
-                            },
-                            "422": {
-                                "description": "Validation Error",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HTTPValidationError"
-                                        }
-                                    }
-                                },
-                            },
-                        },
-                    },
-                },
-            },
-            "components": {
-                "schemas": {
-                    "HTTPValidationError": {
-                        "title": "HTTPValidationError",
-                        "type": "object",
-                        "properties": {
-                            "detail": {
-                                "title": "Detail",
-                                "type": "array",
-                                "items": {
-                                    "$ref": "#/components/schemas/ValidationError"
-                                },
-                            }
-                        },
-                    },
-                    "HeroCreate": {
-                        "title": "HeroCreate",
-                        "required": ["name", "secret_name"],
-                        "type": "object",
-                        "properties": {
-                            "name": {"title": "Name", "type": "string"},
-                            "secret_name": {"title": "Secret Name", "type": "string"},
-                            "age": IsDict(
-                                {
-                                    "title": "Age",
-                                    "anyOf": [{"type": "integer"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Age", "type": "integer"}
-                            ),
-                        },
-                    },
-                    "HeroPublic": {
-                        "title": "HeroPublic",
-                        "required": ["name", "secret_name", "id"],
-                        "type": "object",
-                        "properties": {
-                            "name": {"title": "Name", "type": "string"},
-                            "secret_name": {"title": "Secret Name", "type": "string"},
-                            "age": IsDict(
-                                {
-                                    "title": "Age",
-                                    "anyOf": [{"type": "integer"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Age", "type": "integer"}
-                            ),
-                            "id": {"title": "Id", "type": "integer"},
-                        },
-                    },
-                    "HeroUpdate": {
-                        "title": "HeroUpdate",
-                        "type": "object",
-                        "properties": {
-                            "name": IsDict(
-                                {
-                                    "title": "Name",
-                                    "anyOf": [{"type": "string"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Name", "type": "string"}
-                            ),
-                            "secret_name": IsDict(
-                                {
-                                    "title": "Secret Name",
-                                    "anyOf": [{"type": "string"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Secret Name", "type": "string"}
-                            ),
-                            "age": IsDict(
-                                {
-                                    "title": "Age",
-                                    "anyOf": [{"type": "integer"}, {"type": "null"}],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "Age", "type": "integer"}
-                            ),
-                        },
-                    },
-                    "ValidationError": {
-                        "title": "ValidationError",
-                        "required": ["loc", "msg", "type"],
-                        "type": "object",
-                        "properties": {
-                            "loc": {
-                                "title": "Location",
-                                "type": "array",
-                                "items": {
-                                    "anyOf": [{"type": "string"}, {"type": "integer"}]
-                                },
-                            },
-                            "msg": {"title": "Message", "type": "string"},
-                            "type": {"title": "Error Type", "type": "string"},
-                        },
-                    },
-                }
-            },
-        }
index 2a929f6dae77ca5adc2b7dcd1ec8281d0093b2df..a9312651b706fa07d23ecdd183512370586415bb 100644 (file)
@@ -1,18 +1,34 @@
+import importlib
+from types import ModuleType
+
+import pytest
 from dirty_equals import IsDict
 from fastapi.testclient import TestClient
 from sqlmodel import Session, create_engine
 from sqlmodel.pool import StaticPool
 
+from tests.conftest import needs_py39, needs_py310
 
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.fastapi.update import tutorial002 as mod
 
+@pytest.fixture(
+    name="module",
+    params=[
+        "tutorial002",
+        pytest.param("tutorial002_py39", marks=needs_py39),
+        pytest.param("tutorial002_py310", marks=needs_py310),
+    ],
+)
+def get_module(request: pytest.FixtureRequest) -> ModuleType:
+    mod = importlib.import_module(f"docs_src.tutorial.fastapi.update.{request.param}")
     mod.sqlite_url = "sqlite://"
     mod.engine = create_engine(
         mod.sqlite_url, connect_args=mod.connect_args, poolclass=StaticPool
     )
+    return mod
+
 
-    with TestClient(mod.app) as client:
+def test_tutorial(module: ModuleType):
+    with TestClient(module.app) as client:
         hero1_data = {
             "name": "Deadpond",
             "secret_name": "Dive Wilson",
@@ -60,16 +76,16 @@ def test_tutorial(clear_sqlmodel):
             assert "hashed_password" not in response_hero
 
         # Test hashed passwords
-        with Session(mod.engine) as session:
-            hero1_db = session.get(mod.Hero, hero1_id)
+        with Session(module.engine) as session:
+            hero1_db = session.get(module.Hero, hero1_id)
             assert hero1_db
             assert not hasattr(hero1_db, "password")
             assert hero1_db.hashed_password == "not really hashed chimichanga hehehe"
-            hero2_db = session.get(mod.Hero, hero2_id)
+            hero2_db = session.get(module.Hero, hero2_id)
             assert hero2_db
             assert not hasattr(hero2_db, "password")
             assert hero2_db.hashed_password == "not really hashed auntmay hehehe"
-            hero3_db = session.get(mod.Hero, hero3_id)
+            hero3_db = session.get(module.Hero, hero3_id)
             assert hero3_db
             assert not hasattr(hero3_db, "password")
             assert hero3_db.hashed_password == "not really hashed bestpreventer hehehe"
@@ -85,8 +101,8 @@ def test_tutorial(clear_sqlmodel):
         )
         assert "password" not in data
         assert "hashed_password" not in data
-        with Session(mod.engine) as session:
-            hero2b_db = session.get(mod.Hero, hero2_id)
+        with Session(module.engine) as session:
+            hero2b_db = session.get(module.Hero, hero2_id)
             assert hero2b_db
             assert not hasattr(hero2b_db, "password")
             assert hero2b_db.hashed_password == "not really hashed auntmay hehehe"
@@ -100,8 +116,8 @@ def test_tutorial(clear_sqlmodel):
         )
         assert "password" not in data
         assert "hashed_password" not in data
-        with Session(mod.engine) as session:
-            hero3b_db = session.get(mod.Hero, hero3_id)
+        with Session(module.engine) as session:
+            hero3b_db = session.get(module.Hero, hero3_id)
             assert hero3b_db
             assert not hasattr(hero3b_db, "password")
             assert hero3b_db.hashed_password == "not really hashed bestpreventer hehehe"
@@ -116,8 +132,8 @@ def test_tutorial(clear_sqlmodel):
         assert data["age"] is None
         assert "password" not in data
         assert "hashed_password" not in data
-        with Session(mod.engine) as session:
-            hero3b_db = session.get(mod.Hero, hero3_id)
+        with Session(module.engine) as session:
+            hero3b_db = session.get(module.Hero, hero3_id)
             assert hero3b_db
             assert not hasattr(hero3b_db, "password")
             assert (
diff --git a/tests/test_tutorial/test_fastapi/test_update/test_tutorial002_py310.py b/tests/test_tutorial/test_fastapi/test_update/test_tutorial002_py310.py
deleted file mode 100644 (file)
index 7617f14..0000000
+++ /dev/null
@@ -1,430 +0,0 @@
-from dirty_equals import IsDict
-from fastapi.testclient import TestClient
-from sqlmodel import Session, create_engine
-from sqlmodel.pool import StaticPool
-
-from ....conftest import needs_py310
-
-
-@needs_py310
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.fastapi.update import tutorial002_py310 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(
-        mod.sqlite_url, connect_args=mod.connect_args, poolclass=StaticPool
-    )
-
-    with TestClient(mod.app) as client:
-        hero1_data = {
-            "name": "Deadpond",
-            "secret_name": "Dive Wilson",
-            "password": "chimichanga",
-        }
-        hero2_data = {
-            "name": "Spider-Boy",
-            "secret_name": "Pedro Parqueador",
-            "id": 9000,
-            "password": "auntmay",
-        }
-        hero3_data = {
-            "name": "Rusty-Man",
-            "secret_name": "Tommy Sharp",
-            "age": 48,
-            "password": "bestpreventer",
-        }
-        response = client.post("/heroes/", json=hero1_data)
-        assert response.status_code == 200, response.text
-        hero1 = response.json()
-        assert "password" not in hero1
-        assert "hashed_password" not in hero1
-        hero1_id = hero1["id"]
-        response = client.post("/heroes/", json=hero2_data)
-        assert response.status_code == 200, response.text
-        hero2 = response.json()
-        hero2_id = hero2["id"]
-        response = client.post("/heroes/", json=hero3_data)
-        assert response.status_code == 200, response.text
-        hero3 = response.json()
-        hero3_id = hero3["id"]
-        response = client.get(f"/heroes/{hero2_id}")
-        assert response.status_code == 200, response.text
-        fetched_hero2 = response.json()
-        assert "password" not in fetched_hero2
-        assert "hashed_password" not in fetched_hero2
-        response = client.get("/heroes/9000")
-        assert response.status_code == 404, response.text
-        response = client.get("/heroes/")
-        assert response.status_code == 200, response.text
-        data = response.json()
-        assert len(data) == 3
-        for response_hero in data:
-            assert "password" not in response_hero
-            assert "hashed_password" not in response_hero
-
-        # Test hashed passwords
-        with Session(mod.engine) as session:
-            hero1_db = session.get(mod.Hero, hero1_id)
-            assert hero1_db
-            assert not hasattr(hero1_db, "password")
-            assert hero1_db.hashed_password == "not really hashed chimichanga hehehe"
-            hero2_db = session.get(mod.Hero, hero2_id)
-            assert hero2_db
-            assert not hasattr(hero2_db, "password")
-            assert hero2_db.hashed_password == "not really hashed auntmay hehehe"
-            hero3_db = session.get(mod.Hero, hero3_id)
-            assert hero3_db
-            assert not hasattr(hero3_db, "password")
-            assert hero3_db.hashed_password == "not really hashed bestpreventer hehehe"
-
-        response = client.patch(
-            f"/heroes/{hero2_id}", json={"secret_name": "Spider-Youngster"}
-        )
-        data = response.json()
-        assert response.status_code == 200, response.text
-        assert data["name"] == hero2_data["name"], "The name should not be set to none"
-        assert data["secret_name"] == "Spider-Youngster", (
-            "The secret name should be updated"
-        )
-        assert "password" not in data
-        assert "hashed_password" not in data
-        with Session(mod.engine) as session:
-            hero2b_db = session.get(mod.Hero, hero2_id)
-            assert hero2b_db
-            assert not hasattr(hero2b_db, "password")
-            assert hero2b_db.hashed_password == "not really hashed auntmay hehehe"
-
-        response = client.patch(f"/heroes/{hero3_id}", json={"age": None})
-        data = response.json()
-        assert response.status_code == 200, response.text
-        assert data["name"] == hero3_data["name"]
-        assert data["age"] is None, (
-            "A field should be updatable to None, even if that's the default"
-        )
-        assert "password" not in data
-        assert "hashed_password" not in data
-        with Session(mod.engine) as session:
-            hero3b_db = session.get(mod.Hero, hero3_id)
-            assert hero3b_db
-            assert not hasattr(hero3b_db, "password")
-            assert hero3b_db.hashed_password == "not really hashed bestpreventer hehehe"
-
-        # Test update dict, hashed_password
-        response = client.patch(
-            f"/heroes/{hero3_id}", json={"password": "philantroplayboy"}
-        )
-        data = response.json()
-        assert response.status_code == 200, response.text
-        assert data["name"] == hero3_data["name"]
-        assert data["age"] is None
-        assert "password" not in data
-        assert "hashed_password" not in data
-        with Session(mod.engine) as session:
-            hero3b_db = session.get(mod.Hero, hero3_id)
-            assert hero3b_db
-            assert not hasattr(hero3b_db, "password")
-            assert (
-                hero3b_db.hashed_password == "not really hashed philantroplayboy hehehe"
-            )
-
-        response = client.patch("/heroes/9001", json={"name": "Dragon Cube X"})
-        assert response.status_code == 404, response.text
-
-        response = client.get("/openapi.json")
-        assert response.status_code == 200, response.text
-        assert response.json() == {
-            "openapi": "3.1.0",
-            "info": {"title": "FastAPI", "version": "0.1.0"},
-            "paths": {
-                "/heroes/": {
-                    "get": {
-                        "summary": "Read Heroes",
-                        "operationId": "read_heroes_heroes__get",
-                        "parameters": [
-                            {
-                                "required": False,
-                                "schema": {
-                                    "title": "Offset",
-                                    "type": "integer",
-                                    "default": 0,
-                                },
-                                "name": "offset",
-                                "in": "query",
-                            },
-                            {
-                                "required": False,
-                                "schema": {
-                                    "title": "Limit",
-                                    "maximum": 100,
-                                    "type": "integer",
-                                    "default": 100,
-                                },
-                                "name": "limit",
-                                "in": "query",
-                            },
-                        ],
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "title": "Response Read Heroes Heroes  Get",
-                                            "type": "array",
-                                            "items": {
-                                                "$ref": "#/components/schemas/HeroPublic"
-                                            },
-                                        }
-                                    }
-                                },
-                            },
-                            "422": {
-                                "description": "Validation Error",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HTTPValidationError"
-                                        }
-                                    }
-                                },
-                            },
-                        },
-                    },
-                    "post": {
-                        "summary": "Create Hero",
-                        "operationId": "create_hero_heroes__post",
-                        "requestBody": {
-                            "content": {
-                                "application/json": {
-                                    "schema": {
-                                        "$ref": "#/components/schemas/HeroCreate"
-                                    }
-                                }
-                            },
-                            "required": True,
-                        },
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HeroPublic"
-                                        }
-                                    }
-                                },
-                            },
-                            "422": {
-                                "description": "Validation Error",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HTTPValidationError"
-                                        }
-                                    }
-                                },
-                            },
-                        },
-                    },
-                },
-                "/heroes/{hero_id}": {
-                    "get": {
-                        "summary": "Read Hero",
-                        "operationId": "read_hero_heroes__hero_id__get",
-                        "parameters": [
-                            {
-                                "required": True,
-                                "schema": {"title": "Hero Id", "type": "integer"},
-                                "name": "hero_id",
-                                "in": "path",
-                            }
-                        ],
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HeroPublic"
-                                        }
-                                    }
-                                },
-                            },
-                            "422": {
-                                "description": "Validation Error",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HTTPValidationError"
-                                        }
-                                    }
-                                },
-                            },
-                        },
-                    },
-                    "patch": {
-                        "summary": "Update Hero",
-                        "operationId": "update_hero_heroes__hero_id__patch",
-                        "parameters": [
-                            {
-                                "required": True,
-                                "schema": {"title": "Hero Id", "type": "integer"},
-                                "name": "hero_id",
-                                "in": "path",
-                            }
-                        ],
-                        "requestBody": {
-                            "content": {
-                                "application/json": {
-                                    "schema": {
-                                        "$ref": "#/components/schemas/HeroUpdate"
-                                    }
-                                }
-                            },
-                            "required": True,
-                        },
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HeroPublic"
-                                        }
-                                    }
-                                },
-                            },
-                            "422": {
-                                "description": "Validation Error",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HTTPValidationError"
-                                        }
-                                    }
-                                },
-                            },
-                        },
-                    },
-                },
-            },
-            "components": {
-                "schemas": {
-                    "HTTPValidationError": {
-                        "title": "HTTPValidationError",
-                        "type": "object",
-                        "properties": {
-                            "detail": {
-                                "title": "Detail",
-                                "type": "array",
-                                "items": {
-                                    "$ref": "#/components/schemas/ValidationError"
-                                },
-                            }
-                        },
-                    },
-                    "HeroCreate": {
-                        "title": "HeroCreate",
-                        "required": ["name", "secret_name", "password"],
-                        "type": "object",
-                        "properties": {
-                            "name": {"title": "Name", "type": "string"},
-                            "secret_name": {"title": "Secret Name", "type": "string"},
-                            "age": IsDict(
-                                {
-                                    "anyOf": [{"type": "integer"}, {"type": "null"}],
-                                    "title": "Age",
-                                }
-                            )
-                            | IsDict(
-                                # TODO: Remove when deprecating Pydantic v1
-                                {"title": "Age", "type": "integer"}
-                            ),
-                            "password": {"type": "string", "title": "Password"},
-                        },
-                    },
-                    "HeroPublic": {
-                        "title": "HeroPublic",
-                        "required": ["name", "secret_name", "id"],
-                        "type": "object",
-                        "properties": {
-                            "name": {"title": "Name", "type": "string"},
-                            "secret_name": {"title": "Secret Name", "type": "string"},
-                            "age": IsDict(
-                                {
-                                    "anyOf": [{"type": "integer"}, {"type": "null"}],
-                                    "title": "Age",
-                                }
-                            )
-                            | IsDict(
-                                # TODO: Remove when deprecating Pydantic v1
-                                {"title": "Age", "type": "integer"}
-                            ),
-                            "id": {"title": "Id", "type": "integer"},
-                        },
-                    },
-                    "HeroUpdate": {
-                        "title": "HeroUpdate",
-                        "type": "object",
-                        "properties": {
-                            "name": IsDict(
-                                {
-                                    "anyOf": [{"type": "string"}, {"type": "null"}],
-                                    "title": "Name",
-                                }
-                            )
-                            | IsDict(
-                                # TODO: Remove when deprecating Pydantic v1
-                                {"title": "Name", "type": "string"}
-                            ),
-                            "secret_name": IsDict(
-                                {
-                                    "anyOf": [{"type": "string"}, {"type": "null"}],
-                                    "title": "Secret Name",
-                                }
-                            )
-                            | IsDict(
-                                # TODO: Remove when deprecating Pydantic v1
-                                {"title": "Secret Name", "type": "string"}
-                            ),
-                            "age": IsDict(
-                                {
-                                    "anyOf": [{"type": "integer"}, {"type": "null"}],
-                                    "title": "Age",
-                                }
-                            )
-                            | IsDict(
-                                # TODO: Remove when deprecating Pydantic v1
-                                {"title": "Age", "type": "integer"}
-                            ),
-                            "password": IsDict(
-                                {
-                                    "anyOf": [{"type": "string"}, {"type": "null"}],
-                                    "title": "Password",
-                                }
-                            )
-                            | IsDict(
-                                # TODO: Remove when deprecating Pydantic v1
-                                {"title": "Password", "type": "string"}
-                            ),
-                        },
-                    },
-                    "ValidationError": {
-                        "title": "ValidationError",
-                        "required": ["loc", "msg", "type"],
-                        "type": "object",
-                        "properties": {
-                            "loc": {
-                                "title": "Location",
-                                "type": "array",
-                                "items": {
-                                    "anyOf": [{"type": "string"}, {"type": "integer"}]
-                                },
-                            },
-                            "msg": {"title": "Message", "type": "string"},
-                            "type": {"title": "Error Type", "type": "string"},
-                        },
-                    },
-                }
-            },
-        }
diff --git a/tests/test_tutorial/test_fastapi/test_update/test_tutorial002_py39.py b/tests/test_tutorial/test_fastapi/test_update/test_tutorial002_py39.py
deleted file mode 100644 (file)
index dc788a2..0000000
+++ /dev/null
@@ -1,430 +0,0 @@
-from dirty_equals import IsDict
-from fastapi.testclient import TestClient
-from sqlmodel import Session, create_engine
-from sqlmodel.pool import StaticPool
-
-from ....conftest import needs_py39
-
-
-@needs_py39
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.fastapi.update import tutorial002_py39 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(
-        mod.sqlite_url, connect_args=mod.connect_args, poolclass=StaticPool
-    )
-
-    with TestClient(mod.app) as client:
-        hero1_data = {
-            "name": "Deadpond",
-            "secret_name": "Dive Wilson",
-            "password": "chimichanga",
-        }
-        hero2_data = {
-            "name": "Spider-Boy",
-            "secret_name": "Pedro Parqueador",
-            "id": 9000,
-            "password": "auntmay",
-        }
-        hero3_data = {
-            "name": "Rusty-Man",
-            "secret_name": "Tommy Sharp",
-            "age": 48,
-            "password": "bestpreventer",
-        }
-        response = client.post("/heroes/", json=hero1_data)
-        assert response.status_code == 200, response.text
-        hero1 = response.json()
-        assert "password" not in hero1
-        assert "hashed_password" not in hero1
-        hero1_id = hero1["id"]
-        response = client.post("/heroes/", json=hero2_data)
-        assert response.status_code == 200, response.text
-        hero2 = response.json()
-        hero2_id = hero2["id"]
-        response = client.post("/heroes/", json=hero3_data)
-        assert response.status_code == 200, response.text
-        hero3 = response.json()
-        hero3_id = hero3["id"]
-        response = client.get(f"/heroes/{hero2_id}")
-        assert response.status_code == 200, response.text
-        fetched_hero2 = response.json()
-        assert "password" not in fetched_hero2
-        assert "hashed_password" not in fetched_hero2
-        response = client.get("/heroes/9000")
-        assert response.status_code == 404, response.text
-        response = client.get("/heroes/")
-        assert response.status_code == 200, response.text
-        data = response.json()
-        assert len(data) == 3
-        for response_hero in data:
-            assert "password" not in response_hero
-            assert "hashed_password" not in response_hero
-
-        # Test hashed passwords
-        with Session(mod.engine) as session:
-            hero1_db = session.get(mod.Hero, hero1_id)
-            assert hero1_db
-            assert not hasattr(hero1_db, "password")
-            assert hero1_db.hashed_password == "not really hashed chimichanga hehehe"
-            hero2_db = session.get(mod.Hero, hero2_id)
-            assert hero2_db
-            assert not hasattr(hero2_db, "password")
-            assert hero2_db.hashed_password == "not really hashed auntmay hehehe"
-            hero3_db = session.get(mod.Hero, hero3_id)
-            assert hero3_db
-            assert not hasattr(hero3_db, "password")
-            assert hero3_db.hashed_password == "not really hashed bestpreventer hehehe"
-
-        response = client.patch(
-            f"/heroes/{hero2_id}", json={"secret_name": "Spider-Youngster"}
-        )
-        data = response.json()
-        assert response.status_code == 200, response.text
-        assert data["name"] == hero2_data["name"], "The name should not be set to none"
-        assert data["secret_name"] == "Spider-Youngster", (
-            "The secret name should be updated"
-        )
-        assert "password" not in data
-        assert "hashed_password" not in data
-        with Session(mod.engine) as session:
-            hero2b_db = session.get(mod.Hero, hero2_id)
-            assert hero2b_db
-            assert not hasattr(hero2b_db, "password")
-            assert hero2b_db.hashed_password == "not really hashed auntmay hehehe"
-
-        response = client.patch(f"/heroes/{hero3_id}", json={"age": None})
-        data = response.json()
-        assert response.status_code == 200, response.text
-        assert data["name"] == hero3_data["name"]
-        assert data["age"] is None, (
-            "A field should be updatable to None, even if that's the default"
-        )
-        assert "password" not in data
-        assert "hashed_password" not in data
-        with Session(mod.engine) as session:
-            hero3b_db = session.get(mod.Hero, hero3_id)
-            assert hero3b_db
-            assert not hasattr(hero3b_db, "password")
-            assert hero3b_db.hashed_password == "not really hashed bestpreventer hehehe"
-
-        # Test update dict, hashed_password
-        response = client.patch(
-            f"/heroes/{hero3_id}", json={"password": "philantroplayboy"}
-        )
-        data = response.json()
-        assert response.status_code == 200, response.text
-        assert data["name"] == hero3_data["name"]
-        assert data["age"] is None
-        assert "password" not in data
-        assert "hashed_password" not in data
-        with Session(mod.engine) as session:
-            hero3b_db = session.get(mod.Hero, hero3_id)
-            assert hero3b_db
-            assert not hasattr(hero3b_db, "password")
-            assert (
-                hero3b_db.hashed_password == "not really hashed philantroplayboy hehehe"
-            )
-
-        response = client.patch("/heroes/9001", json={"name": "Dragon Cube X"})
-        assert response.status_code == 404, response.text
-
-        response = client.get("/openapi.json")
-        assert response.status_code == 200, response.text
-        assert response.json() == {
-            "openapi": "3.1.0",
-            "info": {"title": "FastAPI", "version": "0.1.0"},
-            "paths": {
-                "/heroes/": {
-                    "get": {
-                        "summary": "Read Heroes",
-                        "operationId": "read_heroes_heroes__get",
-                        "parameters": [
-                            {
-                                "required": False,
-                                "schema": {
-                                    "title": "Offset",
-                                    "type": "integer",
-                                    "default": 0,
-                                },
-                                "name": "offset",
-                                "in": "query",
-                            },
-                            {
-                                "required": False,
-                                "schema": {
-                                    "title": "Limit",
-                                    "maximum": 100,
-                                    "type": "integer",
-                                    "default": 100,
-                                },
-                                "name": "limit",
-                                "in": "query",
-                            },
-                        ],
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "title": "Response Read Heroes Heroes  Get",
-                                            "type": "array",
-                                            "items": {
-                                                "$ref": "#/components/schemas/HeroPublic"
-                                            },
-                                        }
-                                    }
-                                },
-                            },
-                            "422": {
-                                "description": "Validation Error",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HTTPValidationError"
-                                        }
-                                    }
-                                },
-                            },
-                        },
-                    },
-                    "post": {
-                        "summary": "Create Hero",
-                        "operationId": "create_hero_heroes__post",
-                        "requestBody": {
-                            "content": {
-                                "application/json": {
-                                    "schema": {
-                                        "$ref": "#/components/schemas/HeroCreate"
-                                    }
-                                }
-                            },
-                            "required": True,
-                        },
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HeroPublic"
-                                        }
-                                    }
-                                },
-                            },
-                            "422": {
-                                "description": "Validation Error",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HTTPValidationError"
-                                        }
-                                    }
-                                },
-                            },
-                        },
-                    },
-                },
-                "/heroes/{hero_id}": {
-                    "get": {
-                        "summary": "Read Hero",
-                        "operationId": "read_hero_heroes__hero_id__get",
-                        "parameters": [
-                            {
-                                "required": True,
-                                "schema": {"title": "Hero Id", "type": "integer"},
-                                "name": "hero_id",
-                                "in": "path",
-                            }
-                        ],
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HeroPublic"
-                                        }
-                                    }
-                                },
-                            },
-                            "422": {
-                                "description": "Validation Error",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HTTPValidationError"
-                                        }
-                                    }
-                                },
-                            },
-                        },
-                    },
-                    "patch": {
-                        "summary": "Update Hero",
-                        "operationId": "update_hero_heroes__hero_id__patch",
-                        "parameters": [
-                            {
-                                "required": True,
-                                "schema": {"title": "Hero Id", "type": "integer"},
-                                "name": "hero_id",
-                                "in": "path",
-                            }
-                        ],
-                        "requestBody": {
-                            "content": {
-                                "application/json": {
-                                    "schema": {
-                                        "$ref": "#/components/schemas/HeroUpdate"
-                                    }
-                                }
-                            },
-                            "required": True,
-                        },
-                        "responses": {
-                            "200": {
-                                "description": "Successful Response",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HeroPublic"
-                                        }
-                                    }
-                                },
-                            },
-                            "422": {
-                                "description": "Validation Error",
-                                "content": {
-                                    "application/json": {
-                                        "schema": {
-                                            "$ref": "#/components/schemas/HTTPValidationError"
-                                        }
-                                    }
-                                },
-                            },
-                        },
-                    },
-                },
-            },
-            "components": {
-                "schemas": {
-                    "HTTPValidationError": {
-                        "title": "HTTPValidationError",
-                        "type": "object",
-                        "properties": {
-                            "detail": {
-                                "title": "Detail",
-                                "type": "array",
-                                "items": {
-                                    "$ref": "#/components/schemas/ValidationError"
-                                },
-                            }
-                        },
-                    },
-                    "HeroCreate": {
-                        "title": "HeroCreate",
-                        "required": ["name", "secret_name", "password"],
-                        "type": "object",
-                        "properties": {
-                            "name": {"title": "Name", "type": "string"},
-                            "secret_name": {"title": "Secret Name", "type": "string"},
-                            "age": IsDict(
-                                {
-                                    "anyOf": [{"type": "integer"}, {"type": "null"}],
-                                    "title": "Age",
-                                }
-                            )
-                            | IsDict(
-                                # TODO: Remove when deprecating Pydantic v1
-                                {"title": "Age", "type": "integer"}
-                            ),
-                            "password": {"type": "string", "title": "Password"},
-                        },
-                    },
-                    "HeroPublic": {
-                        "title": "HeroPublic",
-                        "required": ["name", "secret_name", "id"],
-                        "type": "object",
-                        "properties": {
-                            "name": {"title": "Name", "type": "string"},
-                            "secret_name": {"title": "Secret Name", "type": "string"},
-                            "age": IsDict(
-                                {
-                                    "anyOf": [{"type": "integer"}, {"type": "null"}],
-                                    "title": "Age",
-                                }
-                            )
-                            | IsDict(
-                                # TODO: Remove when deprecating Pydantic v1
-                                {"title": "Age", "type": "integer"}
-                            ),
-                            "id": {"title": "Id", "type": "integer"},
-                        },
-                    },
-                    "HeroUpdate": {
-                        "title": "HeroUpdate",
-                        "type": "object",
-                        "properties": {
-                            "name": IsDict(
-                                {
-                                    "anyOf": [{"type": "string"}, {"type": "null"}],
-                                    "title": "Name",
-                                }
-                            )
-                            | IsDict(
-                                # TODO: Remove when deprecating Pydantic v1
-                                {"title": "Name", "type": "string"}
-                            ),
-                            "secret_name": IsDict(
-                                {
-                                    "anyOf": [{"type": "string"}, {"type": "null"}],
-                                    "title": "Secret Name",
-                                }
-                            )
-                            | IsDict(
-                                # TODO: Remove when deprecating Pydantic v1
-                                {"title": "Secret Name", "type": "string"}
-                            ),
-                            "age": IsDict(
-                                {
-                                    "anyOf": [{"type": "integer"}, {"type": "null"}],
-                                    "title": "Age",
-                                }
-                            )
-                            | IsDict(
-                                # TODO: Remove when deprecating Pydantic v1
-                                {"title": "Age", "type": "integer"}
-                            ),
-                            "password": IsDict(
-                                {
-                                    "anyOf": [{"type": "string"}, {"type": "null"}],
-                                    "title": "Password",
-                                }
-                            )
-                            | IsDict(
-                                # TODO: Remove when deprecating Pydantic v1
-                                {"title": "Password", "type": "string"}
-                            ),
-                        },
-                    },
-                    "ValidationError": {
-                        "title": "ValidationError",
-                        "required": ["loc", "msg", "type"],
-                        "type": "object",
-                        "properties": {
-                            "loc": {
-                                "title": "Location",
-                                "type": "array",
-                                "items": {
-                                    "anyOf": [{"type": "string"}, {"type": "integer"}]
-                                },
-                            },
-                            "msg": {"title": "Message", "type": "string"},
-                            "type": {"title": "Error Type", "type": "string"},
-                        },
-                    },
-                }
-            },
-        }
index f33db5bcc73c318edf2343197ff857282ee0acdf..b71f7ebd85125f2dd2192ab718cd7714ffd4c769 100644 (file)
@@ -1,24 +1,31 @@
-from unittest.mock import patch
+import importlib
+from types import ModuleType
 
+import pytest
 from sqlalchemy import inspect
 from sqlalchemy.engine.reflection import Inspector
 from sqlmodel import create_engine
 
-from ...conftest import get_testing_print_function
+from ...conftest import PrintMock, needs_py310
 
 
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.indexes import tutorial001 as mod
-
+@pytest.fixture(
+    name="mod",
+    params=[
+        "tutorial001",
+        pytest.param("tutorial001_py310", marks=needs_py310),
+    ],
+)
+def get_module(request: pytest.FixtureRequest) -> ModuleType:
+    mod = importlib.import_module(f"docs_src.tutorial.indexes.{request.param}")
     mod.sqlite_url = "sqlite://"
     mod.engine = create_engine(mod.sqlite_url)
-    calls = []
+    return mod
 
-    new_print = get_testing_print_function(calls)
 
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == [
+def test_tutorial(print_mock: PrintMock, mod: ModuleType):
+    mod.main()
+    assert print_mock.calls == [
         [{"secret_name": "Dive Wilson", "age": None, "id": 1, "name": "Deadpond"}]
     ]
 
diff --git a/tests/test_tutorial/test_indexes/test_tutorial001_py310.py b/tests/test_tutorial/test_indexes/test_tutorial001_py310.py
deleted file mode 100644 (file)
index cfee262..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-from unittest.mock import patch
-
-from sqlalchemy import inspect
-from sqlalchemy.engine.reflection import Inspector
-from sqlmodel import create_engine
-
-from ...conftest import get_testing_print_function, needs_py310
-
-
-@needs_py310
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.indexes import tutorial001_py310 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == [
-        [{"secret_name": "Dive Wilson", "age": None, "id": 1, "name": "Deadpond"}]
-    ]
-
-    insp: Inspector = inspect(mod.engine)
-    indexes = insp.get_indexes(str(mod.Hero.__tablename__))
-    expected_indexes = [
-        {
-            "name": "ix_hero_name",
-            "dialect_options": {},
-            "column_names": ["name"],
-            "unique": 0,
-        },
-        {
-            "name": "ix_hero_age",
-            "dialect_options": {},
-            "column_names": ["age"],
-            "unique": 0,
-        },
-    ]
-    for index in expected_indexes:
-        assert index in indexes, "This expected index should be in the indexes in DB"
-        # Now that this index was checked, remove it from the list of indexes
-        indexes.pop(indexes.index(index))
-    assert len(indexes) == 0, "The database should only have the expected indexes"
index 893043dad16c75cf3b27e9d733360152712f0e9a..0aa88ea5dd928f0d701a753b69894672581f0786 100644 (file)
@@ -1,24 +1,31 @@
-from unittest.mock import patch
+import importlib
+from types import ModuleType
 
+import pytest
 from sqlalchemy import inspect
 from sqlalchemy.engine.reflection import Inspector
 from sqlmodel import create_engine
 
-from ...conftest import get_testing_print_function
+from ...conftest import PrintMock, needs_py310
 
 
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.indexes import tutorial002 as mod
-
+@pytest.fixture(
+    name="mod",
+    params=[
+        "tutorial002",
+        pytest.param("tutorial002_py310", marks=needs_py310),
+    ],
+)
+def get_module(request: pytest.FixtureRequest) -> ModuleType:
+    mod = importlib.import_module(f"docs_src.tutorial.indexes.{request.param}")
     mod.sqlite_url = "sqlite://"
     mod.engine = create_engine(mod.sqlite_url)
-    calls = []
+    return mod
 
-    new_print = get_testing_print_function(calls)
 
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == [
+def test_tutorial(print_mock: PrintMock, mod: ModuleType):
+    mod.main()
+    assert print_mock.calls == [
         [{"name": "Tarantula", "secret_name": "Natalia Roman-on", "age": 32, "id": 4}],
         [{"name": "Black Lion", "secret_name": "Trevor Challa", "age": 35, "id": 5}],
     ]
diff --git a/tests/test_tutorial/test_indexes/test_tutorial002_py310.py b/tests/test_tutorial/test_indexes/test_tutorial002_py310.py
deleted file mode 100644 (file)
index 089b682..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-from unittest.mock import patch
-
-from sqlalchemy import inspect
-from sqlalchemy.engine.reflection import Inspector
-from sqlmodel import create_engine
-
-from ...conftest import get_testing_print_function, needs_py310
-
-
-@needs_py310
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.indexes import tutorial002_py310 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == [
-        [{"name": "Tarantula", "secret_name": "Natalia Roman-on", "age": 32, "id": 4}],
-        [{"name": "Black Lion", "secret_name": "Trevor Challa", "age": 35, "id": 5}],
-    ]
-
-    insp: Inspector = inspect(mod.engine)
-    indexes = insp.get_indexes(str(mod.Hero.__tablename__))
-    expected_indexes = [
-        {
-            "name": "ix_hero_name",
-            "dialect_options": {},
-            "column_names": ["name"],
-            "unique": 0,
-        },
-        {
-            "name": "ix_hero_age",
-            "dialect_options": {},
-            "column_names": ["age"],
-            "unique": 0,
-        },
-    ]
-    for index in expected_indexes:
-        assert index in indexes, "This expected index should be in the indexes in DB"
-        # Now that this index was checked, remove it from the list of indexes
-        indexes.pop(indexes.index(index))
-    assert len(indexes) == 0, "The database should only have the expected indexes"
index 3a5162c08a93603a808e1ec6bfb2ec9d8aa1e3aa..1673a7075396f80f34576b50d190b0b8023f9066 100644 (file)
@@ -1,11 +1,27 @@
+import importlib
+from types import ModuleType
+
+import pytest
 from sqlmodel import Session, create_engine, select
 
+from ...conftest import needs_py310
 
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.insert import tutorial001 as mod
 
+@pytest.fixture(
+    name="mod",
+    params=[
+        "tutorial001",
+        pytest.param("tutorial001_py310", marks=needs_py310),
+    ],
+)
+def get_module(request: pytest.FixtureRequest) -> ModuleType:
+    mod = importlib.import_module(f"docs_src.tutorial.insert.{request.param}")
     mod.sqlite_url = "sqlite://"
     mod.engine = create_engine(mod.sqlite_url)
+    return mod
+
+
+def test_tutorial(mod: ModuleType):
     mod.main()
     with Session(mod.engine) as session:
         heroes = session.exec(select(mod.Hero)).all()
diff --git a/tests/test_tutorial/test_insert/test_tutorial001_py310.py b/tests/test_tutorial/test_insert/test_tutorial001_py310.py
deleted file mode 100644 (file)
index 47cbc4c..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-from sqlmodel import Session, create_engine, select
-
-from ...conftest import needs_py310
-
-
-@needs_py310
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.insert import tutorial001_py310 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    mod.main()
-    with Session(mod.engine) as session:
-        heroes = session.exec(select(mod.Hero)).all()
-    heroes_by_name = {hero.name: hero for hero in heroes}
-    deadpond = heroes_by_name["Deadpond"]
-    spider_boy = heroes_by_name["Spider-Boy"]
-    rusty_man = heroes_by_name["Rusty-Man"]
-    assert deadpond.name == "Deadpond"
-    assert deadpond.age is None
-    assert deadpond.id is not None
-    assert deadpond.secret_name == "Dive Wilson"
-    assert spider_boy.name == "Spider-Boy"
-    assert spider_boy.age is None
-    assert spider_boy.id is not None
-    assert spider_boy.secret_name == "Pedro Parqueador"
-    assert rusty_man.name == "Rusty-Man"
-    assert rusty_man.age == 48
-    assert rusty_man.id is not None
-    assert rusty_man.secret_name == "Tommy Sharp"
index c450ec044d2bbb5e505464d4303394cddf893dc7..0cee7ef3b132b8155bcc3610e27df3582b074be1 100644 (file)
@@ -1,11 +1,27 @@
+import importlib
+from types import ModuleType
+
+import pytest
 from sqlmodel import Session, create_engine, select
 
+from ...conftest import needs_py310
 
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.insert import tutorial002 as mod
 
+@pytest.fixture(
+    name="mod",
+    params=[
+        "tutorial002",
+        pytest.param("tutorial002_py310", marks=needs_py310),
+    ],
+)
+def get_module(request: pytest.FixtureRequest) -> ModuleType:
+    mod = importlib.import_module(f"docs_src.tutorial.insert.{request.param}")
     mod.sqlite_url = "sqlite://"
     mod.engine = create_engine(mod.sqlite_url)
+    return mod
+
+
+def test_tutorial(mod: ModuleType):
     mod.main()
     with Session(mod.engine) as session:
         heroes = session.exec(select(mod.Hero)).all()
diff --git a/tests/test_tutorial/test_insert/test_tutorial002_py310.py b/tests/test_tutorial/test_insert/test_tutorial002_py310.py
deleted file mode 100644 (file)
index fb62810..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-from sqlmodel import Session, create_engine, select
-
-from ...conftest import needs_py310
-
-
-@needs_py310
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.insert import tutorial002_py310 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    mod.main()
-    with Session(mod.engine) as session:
-        heroes = session.exec(select(mod.Hero)).all()
-    heroes_by_name = {hero.name: hero for hero in heroes}
-    deadpond = heroes_by_name["Deadpond"]
-    spider_boy = heroes_by_name["Spider-Boy"]
-    rusty_man = heroes_by_name["Rusty-Man"]
-    assert deadpond.name == "Deadpond"
-    assert deadpond.age is None
-    assert deadpond.id is not None
-    assert deadpond.secret_name == "Dive Wilson"
-    assert spider_boy.name == "Spider-Boy"
-    assert spider_boy.age is None
-    assert spider_boy.id is not None
-    assert spider_boy.secret_name == "Pedro Parqueador"
-    assert rusty_man.name == "Rusty-Man"
-    assert rusty_man.age == 48
-    assert rusty_man.id is not None
-    assert rusty_man.secret_name == "Tommy Sharp"
index df2112b25a0e63e97a91161ba4c849fb47d993c7..7f80585875d43c3d1f7ef96c6815edf0821c7c29 100644 (file)
@@ -1,11 +1,27 @@
+import importlib
+from types import ModuleType
+
+import pytest
 from sqlmodel import Session, create_engine, select
 
+from ...conftest import needs_py310
 
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.insert import tutorial003 as mod
 
+@pytest.fixture(
+    name="mod",
+    params=[
+        "tutorial003",
+        pytest.param("tutorial003_py310", marks=needs_py310),
+    ],
+)
+def get_module(request: pytest.FixtureRequest) -> ModuleType:
+    mod = importlib.import_module(f"docs_src.tutorial.insert.{request.param}")
     mod.sqlite_url = "sqlite://"
     mod.engine = create_engine(mod.sqlite_url)
+    return mod
+
+
+def test_tutorial(mod: ModuleType):
     mod.main()
     with Session(mod.engine) as session:
         heroes = session.exec(select(mod.Hero)).all()
diff --git a/tests/test_tutorial/test_insert/test_tutorial003_py310.py b/tests/test_tutorial/test_insert/test_tutorial003_py310.py
deleted file mode 100644 (file)
index 5bca713..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-from sqlmodel import Session, create_engine, select
-
-from ...conftest import needs_py310
-
-
-@needs_py310
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.insert import tutorial003_py310 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    mod.main()
-    with Session(mod.engine) as session:
-        heroes = session.exec(select(mod.Hero)).all()
-    heroes_by_name = {hero.name: hero for hero in heroes}
-    deadpond = heroes_by_name["Deadpond"]
-    spider_boy = heroes_by_name["Spider-Boy"]
-    rusty_man = heroes_by_name["Rusty-Man"]
-    assert deadpond.name == "Deadpond"
-    assert deadpond.age is None
-    assert deadpond.id is not None
-    assert deadpond.secret_name == "Dive Wilson"
-    assert spider_boy.name == "Spider-Boy"
-    assert spider_boy.age is None
-    assert spider_boy.id is not None
-    assert spider_boy.secret_name == "Pedro Parqueador"
-    assert rusty_man.name == "Rusty-Man"
-    assert rusty_man.age == 48
-    assert rusty_man.id is not None
-    assert rusty_man.secret_name == "Tommy Sharp"
index 244f91083f78e56a4294e849718233d0de3d1a01..d33713cde36a38e2d36b6ccba2ccef67ee8f579b 100644 (file)
@@ -1,8 +1,25 @@
-from unittest.mock import patch
+import importlib
+from types import ModuleType
 
+import pytest
 from sqlmodel import create_engine
 
-from ...conftest import get_testing_print_function
+from ...conftest import PrintMock, needs_py310
+
+
+@pytest.fixture(
+    name="mod",
+    params=[
+        "tutorial001",
+        pytest.param("tutorial001_py310", marks=needs_py310),
+    ],
+)
+def get_module(request: pytest.FixtureRequest) -> ModuleType:
+    mod = importlib.import_module(f"docs_src.tutorial.offset_and_limit.{request.param}")
+    mod.sqlite_url = "sqlite://"
+    mod.engine = create_engine(mod.sqlite_url)
+    return mod
+
 
 expected_calls = [
     [
@@ -20,15 +37,6 @@ expected_calls = [
 ]
 
 
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.offset_and_limit import tutorial001 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == expected_calls
+def test_tutorial(print_mock: PrintMock, mod: ModuleType):
+    mod.main()
+    assert print_mock.calls == expected_calls
diff --git a/tests/test_tutorial/test_limit_and_offset/test_tutorial001_py310.py b/tests/test_tutorial/test_limit_and_offset/test_tutorial001_py310.py
deleted file mode 100644 (file)
index 4f4974c..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-from unittest.mock import patch
-
-from sqlmodel import create_engine
-
-from ...conftest import get_testing_print_function, needs_py310
-
-expected_calls = [
-    [
-        [
-            {"id": 1, "name": "Deadpond", "secret_name": "Dive Wilson", "age": None},
-            {
-                "id": 2,
-                "name": "Spider-Boy",
-                "secret_name": "Pedro Parqueador",
-                "age": None,
-            },
-            {"id": 3, "name": "Rusty-Man", "secret_name": "Tommy Sharp", "age": 48},
-        ]
-    ]
-]
-
-
-@needs_py310
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.offset_and_limit import tutorial001_py310 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == expected_calls
index e9dee0cb35840e176ab45fc9a1b3b4c9e416803c..c73f701cd123309ec41dc709be4a0c992de39dbb 100644 (file)
@@ -1,8 +1,25 @@
-from unittest.mock import patch
+import importlib
+from types import ModuleType
 
+import pytest
 from sqlmodel import create_engine
 
-from ...conftest import get_testing_print_function
+from ...conftest import PrintMock, needs_py310
+
+
+@pytest.fixture(
+    name="mod",
+    params=[
+        "tutorial002",
+        pytest.param("tutorial002_py310", marks=needs_py310),
+    ],
+)
+def get_module(request: pytest.FixtureRequest) -> ModuleType:
+    mod = importlib.import_module(f"docs_src.tutorial.offset_and_limit.{request.param}")
+    mod.sqlite_url = "sqlite://"
+    mod.engine = create_engine(mod.sqlite_url)
+    return mod
+
 
 expected_calls = [
     [
@@ -20,15 +37,6 @@ expected_calls = [
 ]
 
 
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.offset_and_limit import tutorial002 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == expected_calls
+def test_tutorial(print_mock: PrintMock, mod: ModuleType):
+    mod.main()
+    assert print_mock.calls == expected_calls
diff --git a/tests/test_tutorial/test_limit_and_offset/test_tutorial002_py310.py b/tests/test_tutorial/test_limit_and_offset/test_tutorial002_py310.py
deleted file mode 100644 (file)
index 1f86d19..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-from unittest.mock import patch
-
-from sqlmodel import create_engine
-
-from ...conftest import get_testing_print_function, needs_py310
-
-expected_calls = [
-    [
-        [
-            {
-                "id": 4,
-                "name": "Tarantula",
-                "secret_name": "Natalia Roman-on",
-                "age": 32,
-            },
-            {"id": 5, "name": "Black Lion", "secret_name": "Trevor Challa", "age": 35},
-            {"id": 6, "name": "Dr. Weird", "secret_name": "Steve Weird", "age": 36},
-        ]
-    ]
-]
-
-
-@needs_py310
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.offset_and_limit import tutorial002_py310 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == expected_calls
index 7192f7ef437cb7b4a13253322d0d853499ef104a..a33cf49f063b482723f5dc7ab9285d0d5d2e9f45 100644 (file)
@@ -1,8 +1,25 @@
-from unittest.mock import patch
+import importlib
+from types import ModuleType
 
+import pytest
 from sqlmodel import create_engine
 
-from ...conftest import get_testing_print_function
+from ...conftest import PrintMock, needs_py310
+
+
+@pytest.fixture(
+    name="mod",
+    params=[
+        "tutorial003",
+        pytest.param("tutorial003_py310", marks=needs_py310),
+    ],
+)
+def get_module(request: pytest.FixtureRequest) -> ModuleType:
+    mod = importlib.import_module(f"docs_src.tutorial.offset_and_limit.{request.param}")
+    mod.sqlite_url = "sqlite://"
+    mod.engine = create_engine(mod.sqlite_url)
+    return mod
+
 
 expected_calls = [
     [
@@ -18,15 +35,6 @@ expected_calls = [
 ]
 
 
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.offset_and_limit import tutorial003 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == expected_calls
+def test_tutorial(print_mock: PrintMock, mod: ModuleType):
+    mod.main()
+    assert print_mock.calls == expected_calls
diff --git a/tests/test_tutorial/test_limit_and_offset/test_tutorial003_py310.py b/tests/test_tutorial/test_limit_and_offset/test_tutorial003_py310.py
deleted file mode 100644 (file)
index 9939991..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-from unittest.mock import patch
-
-from sqlmodel import create_engine
-
-from ...conftest import get_testing_print_function, needs_py310
-
-expected_calls = [
-    [
-        [
-            {
-                "id": 7,
-                "name": "Captain North America",
-                "secret_name": "Esteban Rogelios",
-                "age": 93,
-            }
-        ]
-    ]
-]
-
-
-@needs_py310
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.offset_and_limit import tutorial003_py310 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == expected_calls
index eb15a1560e2a459abbdaf97ec2e625b11e7979ab..15322c4089a18bb0298c45b7c49b752d86466330 100644 (file)
@@ -1,22 +1,29 @@
-from unittest.mock import patch
+import importlib
+from types import ModuleType
 
+import pytest
 from sqlmodel import create_engine
 
-from ...conftest import get_testing_print_function
+from ...conftest import PrintMock, needs_py310
 
 
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.offset_and_limit import tutorial004 as mod
-
+@pytest.fixture(
+    name="mod",
+    params=[
+        "tutorial004",
+        pytest.param("tutorial004_py310", marks=needs_py310),
+    ],
+)
+def get_module(request: pytest.FixtureRequest) -> ModuleType:
+    mod = importlib.import_module(f"docs_src.tutorial.offset_and_limit.{request.param}")
     mod.sqlite_url = "sqlite://"
     mod.engine = create_engine(mod.sqlite_url)
-    calls = []
+    return mod
 
-    new_print = get_testing_print_function(calls)
 
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == [
+def test_tutorial(print_mock: PrintMock, mod: ModuleType):
+    mod.main()
+    assert print_mock.calls == [
         [
             [
                 {"name": "Dr. Weird", "secret_name": "Steve Weird", "age": 36, "id": 6},
diff --git a/tests/test_tutorial/test_limit_and_offset/test_tutorial004_py310.py b/tests/test_tutorial/test_limit_and_offset/test_tutorial004_py310.py
deleted file mode 100644 (file)
index 4ca7365..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-from unittest.mock import patch
-
-from sqlmodel import create_engine
-
-from ...conftest import get_testing_print_function, needs_py310
-
-
-@needs_py310
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.offset_and_limit import tutorial004_py310 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == [
-        [
-            [
-                {"name": "Dr. Weird", "secret_name": "Steve Weird", "age": 36, "id": 6},
-                {"name": "Rusty-Man", "secret_name": "Tommy Sharp", "age": 48, "id": 3},
-            ]
-        ]
-    ]
index 70bfe9a64937b3904c16807b45e699e33a8af08c..b84626d9cff89090cb95e63c4a9091d7e64d7eaf 100644 (file)
@@ -1,8 +1,26 @@
-from unittest.mock import patch
+import importlib
+from types import ModuleType
 
+import pytest
 from sqlmodel import create_engine
 
-from ...conftest import get_testing_print_function
+from ...conftest import PrintMock, needs_py39, needs_py310
+
+
+@pytest.fixture(
+    name="mod",
+    params=[
+        "tutorial001",
+        pytest.param("tutorial001_py39", marks=needs_py39),
+        pytest.param("tutorial001_py310", marks=needs_py310),
+    ],
+)
+def get_module(request: pytest.FixtureRequest) -> ModuleType:
+    mod = importlib.import_module(f"docs_src.tutorial.many_to_many.{request.param}")
+    mod.sqlite_url = "sqlite://"
+    mod.engine = create_engine(mod.sqlite_url)
+    return mod
+
 
 expected_calls = [
     [
@@ -35,15 +53,6 @@ expected_calls = [
 ]
 
 
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.many_to_many import tutorial001 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == expected_calls
+def test_tutorial(print_mock: PrintMock, mod: ModuleType):
+    mod.main()
+    assert print_mock.calls == expected_calls
diff --git a/tests/test_tutorial/test_many_to_many/test_tutorial001_py310.py b/tests/test_tutorial/test_many_to_many/test_tutorial001_py310.py
deleted file mode 100644 (file)
index bf31d9c..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-from unittest.mock import patch
-
-from sqlmodel import create_engine
-
-from ...conftest import get_testing_print_function, needs_py310
-
-expected_calls = [
-    [
-        "Deadpond:",
-        {"id": 1, "secret_name": "Dive Wilson", "age": None, "name": "Deadpond"},
-    ],
-    [
-        "Deadpond teams:",
-        [
-            {"id": 1, "name": "Z-Force", "headquarters": "Sister Margaret's Bar"},
-            {"id": 2, "name": "Preventers", "headquarters": "Sharp Tower"},
-        ],
-    ],
-    [
-        "Rusty-Man:",
-        {"id": 2, "secret_name": "Tommy Sharp", "age": 48, "name": "Rusty-Man"},
-    ],
-    [
-        "Rusty-Man Teams:",
-        [{"id": 2, "name": "Preventers", "headquarters": "Sharp Tower"}],
-    ],
-    [
-        "Spider-Boy:",
-        {"id": 3, "secret_name": "Pedro Parqueador", "age": None, "name": "Spider-Boy"},
-    ],
-    [
-        "Spider-Boy Teams:",
-        [{"id": 2, "name": "Preventers", "headquarters": "Sharp Tower"}],
-    ],
-]
-
-
-@needs_py310
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.many_to_many import tutorial001_py310 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == expected_calls
diff --git a/tests/test_tutorial/test_many_to_many/test_tutorial001_py39.py b/tests/test_tutorial/test_many_to_many/test_tutorial001_py39.py
deleted file mode 100644 (file)
index cb7a4d8..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-from unittest.mock import patch
-
-from sqlmodel import create_engine
-
-from ...conftest import get_testing_print_function, needs_py39
-
-expected_calls = [
-    [
-        "Deadpond:",
-        {"id": 1, "secret_name": "Dive Wilson", "age": None, "name": "Deadpond"},
-    ],
-    [
-        "Deadpond teams:",
-        [
-            {"id": 1, "name": "Z-Force", "headquarters": "Sister Margaret's Bar"},
-            {"id": 2, "name": "Preventers", "headquarters": "Sharp Tower"},
-        ],
-    ],
-    [
-        "Rusty-Man:",
-        {"id": 2, "secret_name": "Tommy Sharp", "age": 48, "name": "Rusty-Man"},
-    ],
-    [
-        "Rusty-Man Teams:",
-        [{"id": 2, "name": "Preventers", "headquarters": "Sharp Tower"}],
-    ],
-    [
-        "Spider-Boy:",
-        {"id": 3, "secret_name": "Pedro Parqueador", "age": None, "name": "Spider-Boy"},
-    ],
-    [
-        "Spider-Boy Teams:",
-        [{"id": 2, "name": "Preventers", "headquarters": "Sharp Tower"}],
-    ],
-]
-
-
-@needs_py39
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.many_to_many import tutorial001_py39 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == expected_calls
index d4d7d95e89daa4e3e45cd40007a060434a621eb1..b5562f416d5b2df5f4b4c14c0a752bb6fd0c7dc4 100644 (file)
@@ -1,8 +1,26 @@
-from unittest.mock import patch
+import importlib
+from types import ModuleType
 
+import pytest
 from sqlmodel import create_engine
 
-from ...conftest import get_testing_print_function
+from ...conftest import PrintMock, needs_py39, needs_py310
+
+
+@pytest.fixture(
+    name="mod",
+    params=[
+        "tutorial002",
+        pytest.param("tutorial002_py39", marks=needs_py39),
+        pytest.param("tutorial002_py310", marks=needs_py310),
+    ],
+)
+def get_module(request: pytest.FixtureRequest) -> ModuleType:
+    mod = importlib.import_module(f"docs_src.tutorial.many_to_many.{request.param}")
+    mod.sqlite_url = "sqlite://"
+    mod.engine = create_engine(mod.sqlite_url)
+    return mod
+
 
 expected_calls = [
     [
@@ -62,15 +80,6 @@ expected_calls = [
 ]
 
 
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.many_to_many import tutorial002 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == expected_calls
+def test_tutorial(print_mock: PrintMock, mod: ModuleType):
+    mod.main()
+    assert print_mock.calls == expected_calls
diff --git a/tests/test_tutorial/test_many_to_many/test_tutorial002_py310.py b/tests/test_tutorial/test_many_to_many/test_tutorial002_py310.py
deleted file mode 100644 (file)
index ad7c892..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-from unittest.mock import patch
-
-from sqlmodel import create_engine
-
-from ...conftest import get_testing_print_function, needs_py310
-
-expected_calls = [
-    [
-        "Deadpond:",
-        {"id": 1, "secret_name": "Dive Wilson", "age": None, "name": "Deadpond"},
-    ],
-    [
-        "Deadpond teams:",
-        [
-            {"id": 1, "name": "Z-Force", "headquarters": "Sister Margaret's Bar"},
-            {"id": 2, "name": "Preventers", "headquarters": "Sharp Tower"},
-        ],
-    ],
-    [
-        "Rusty-Man:",
-        {"id": 2, "secret_name": "Tommy Sharp", "age": 48, "name": "Rusty-Man"},
-    ],
-    [
-        "Rusty-Man Teams:",
-        [{"id": 2, "name": "Preventers", "headquarters": "Sharp Tower"}],
-    ],
-    [
-        "Spider-Boy:",
-        {"id": 3, "secret_name": "Pedro Parqueador", "age": None, "name": "Spider-Boy"},
-    ],
-    [
-        "Spider-Boy Teams:",
-        [{"id": 2, "name": "Preventers", "headquarters": "Sharp Tower"}],
-    ],
-    [
-        "Updated Spider-Boy's Teams:",
-        [
-            {"id": 2, "name": "Preventers", "headquarters": "Sharp Tower"},
-            {"id": 1, "name": "Z-Force", "headquarters": "Sister Margaret's Bar"},
-        ],
-    ],
-    [
-        "Z-Force heroes:",
-        [
-            {"id": 1, "secret_name": "Dive Wilson", "age": None, "name": "Deadpond"},
-            {
-                "id": 3,
-                "secret_name": "Pedro Parqueador",
-                "age": None,
-                "name": "Spider-Boy",
-            },
-        ],
-    ],
-    [
-        "Reverted Z-Force's heroes:",
-        [{"id": 1, "secret_name": "Dive Wilson", "age": None, "name": "Deadpond"}],
-    ],
-    [
-        "Reverted Spider-Boy's teams:",
-        [{"id": 2, "name": "Preventers", "headquarters": "Sharp Tower"}],
-    ],
-]
-
-
-@needs_py310
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.many_to_many import tutorial002_py310 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == expected_calls
diff --git a/tests/test_tutorial/test_many_to_many/test_tutorial002_py39.py b/tests/test_tutorial/test_many_to_many/test_tutorial002_py39.py
deleted file mode 100644 (file)
index c0df48d..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-from unittest.mock import patch
-
-from sqlmodel import create_engine
-
-from ...conftest import get_testing_print_function, needs_py39
-
-expected_calls = [
-    [
-        "Deadpond:",
-        {"id": 1, "secret_name": "Dive Wilson", "age": None, "name": "Deadpond"},
-    ],
-    [
-        "Deadpond teams:",
-        [
-            {"id": 1, "name": "Z-Force", "headquarters": "Sister Margaret's Bar"},
-            {"id": 2, "name": "Preventers", "headquarters": "Sharp Tower"},
-        ],
-    ],
-    [
-        "Rusty-Man:",
-        {"id": 2, "secret_name": "Tommy Sharp", "age": 48, "name": "Rusty-Man"},
-    ],
-    [
-        "Rusty-Man Teams:",
-        [{"id": 2, "name": "Preventers", "headquarters": "Sharp Tower"}],
-    ],
-    [
-        "Spider-Boy:",
-        {"id": 3, "secret_name": "Pedro Parqueador", "age": None, "name": "Spider-Boy"},
-    ],
-    [
-        "Spider-Boy Teams:",
-        [{"id": 2, "name": "Preventers", "headquarters": "Sharp Tower"}],
-    ],
-    [
-        "Updated Spider-Boy's Teams:",
-        [
-            {"id": 2, "name": "Preventers", "headquarters": "Sharp Tower"},
-            {"id": 1, "name": "Z-Force", "headquarters": "Sister Margaret's Bar"},
-        ],
-    ],
-    [
-        "Z-Force heroes:",
-        [
-            {"id": 1, "secret_name": "Dive Wilson", "age": None, "name": "Deadpond"},
-            {
-                "id": 3,
-                "secret_name": "Pedro Parqueador",
-                "age": None,
-                "name": "Spider-Boy",
-            },
-        ],
-    ],
-    [
-        "Reverted Z-Force's heroes:",
-        [{"id": 1, "secret_name": "Dive Wilson", "age": None, "name": "Deadpond"}],
-    ],
-    [
-        "Reverted Spider-Boy's teams:",
-        [{"id": 2, "name": "Preventers", "headquarters": "Sharp Tower"}],
-    ],
-]
-
-
-@needs_py39
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.many_to_many import tutorial002_py39 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == expected_calls
index 35489b01ce5ef5bd092bb7e967265310e57f522b..ad1168e3baef32309103f9378afb215966a4ed90 100644 (file)
@@ -1,8 +1,26 @@
-from unittest.mock import patch
+import importlib
+from types import ModuleType
 
+import pytest
 from sqlmodel import create_engine
 
-from ...conftest import get_testing_print_function
+from ...conftest import PrintMock, needs_py39, needs_py310
+
+
+@pytest.fixture(
+    name="mod",
+    params=[
+        "tutorial003",
+        pytest.param("tutorial003_py39", marks=needs_py39),
+        pytest.param("tutorial003_py310", marks=needs_py310),
+    ],
+)
+def get_module(request: pytest.FixtureRequest) -> ModuleType:
+    mod = importlib.import_module(f"docs_src.tutorial.many_to_many.{request.param}")
+    mod.sqlite_url = "sqlite://"
+    mod.engine = create_engine(mod.sqlite_url)
+    return mod
+
 
 expected_calls = [
     [
@@ -58,15 +76,6 @@ expected_calls = [
 ]
 
 
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.many_to_many import tutorial003 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == expected_calls
+def test_tutorial(print_mock: PrintMock, mod: ModuleType):
+    mod.main()
+    assert print_mock.calls == expected_calls
diff --git a/tests/test_tutorial/test_many_to_many/test_tutorial003_py310.py b/tests/test_tutorial/test_many_to_many/test_tutorial003_py310.py
deleted file mode 100644 (file)
index 78a699c..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-from unittest.mock import patch
-
-from sqlmodel import create_engine
-
-from ...conftest import get_testing_print_function, needs_py310
-
-expected_calls = [
-    [
-        "Z-Force hero:",
-        {"name": "Deadpond", "secret_name": "Dive Wilson", "id": 1, "age": None},
-        "is training:",
-        False,
-    ],
-    [
-        "Preventers hero:",
-        {"name": "Deadpond", "secret_name": "Dive Wilson", "id": 1, "age": None},
-        "is training:",
-        True,
-    ],
-    [
-        "Preventers hero:",
-        {"name": "Spider-Boy", "secret_name": "Pedro Parqueador", "id": 2, "age": None},
-        "is training:",
-        True,
-    ],
-    [
-        "Preventers hero:",
-        {"name": "Rusty-Man", "secret_name": "Tommy Sharp", "id": 3, "age": 48},
-        "is training:",
-        False,
-    ],
-    [
-        "Updated Spider-Boy's Teams:",
-        [
-            {"team_id": 2, "is_training": True, "hero_id": 2},
-            {"team_id": 1, "is_training": True, "hero_id": 2},
-        ],
-    ],
-    [
-        "Z-Force heroes:",
-        [
-            {"team_id": 1, "is_training": False, "hero_id": 1},
-            {"team_id": 1, "is_training": True, "hero_id": 2},
-        ],
-    ],
-    [
-        "Spider-Boy team:",
-        {"headquarters": "Sharp Tower", "id": 2, "name": "Preventers"},
-        "is training:",
-        False,
-    ],
-    [
-        "Spider-Boy team:",
-        {"headquarters": "Sister Margaret's Bar", "id": 1, "name": "Z-Force"},
-        "is training:",
-        True,
-    ],
-]
-
-
-@needs_py310
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.many_to_many import tutorial003_py310 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == expected_calls
diff --git a/tests/test_tutorial/test_many_to_many/test_tutorial003_py39.py b/tests/test_tutorial/test_many_to_many/test_tutorial003_py39.py
deleted file mode 100644 (file)
index 8fed921..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-from unittest.mock import patch
-
-from sqlmodel import create_engine
-
-from ...conftest import get_testing_print_function, needs_py39
-
-expected_calls = [
-    [
-        "Z-Force hero:",
-        {"name": "Deadpond", "secret_name": "Dive Wilson", "id": 1, "age": None},
-        "is training:",
-        False,
-    ],
-    [
-        "Preventers hero:",
-        {"name": "Deadpond", "secret_name": "Dive Wilson", "id": 1, "age": None},
-        "is training:",
-        True,
-    ],
-    [
-        "Preventers hero:",
-        {"name": "Spider-Boy", "secret_name": "Pedro Parqueador", "id": 2, "age": None},
-        "is training:",
-        True,
-    ],
-    [
-        "Preventers hero:",
-        {"name": "Rusty-Man", "secret_name": "Tommy Sharp", "id": 3, "age": 48},
-        "is training:",
-        False,
-    ],
-    [
-        "Updated Spider-Boy's Teams:",
-        [
-            {"team_id": 2, "is_training": True, "hero_id": 2},
-            {"team_id": 1, "is_training": True, "hero_id": 2},
-        ],
-    ],
-    [
-        "Z-Force heroes:",
-        [
-            {"team_id": 1, "is_training": False, "hero_id": 1},
-            {"team_id": 1, "is_training": True, "hero_id": 2},
-        ],
-    ],
-    [
-        "Spider-Boy team:",
-        {"headquarters": "Sharp Tower", "id": 2, "name": "Preventers"},
-        "is training:",
-        False,
-    ],
-    [
-        "Spider-Boy team:",
-        {"headquarters": "Sister Margaret's Bar", "id": 1, "name": "Z-Force"},
-        "is training:",
-        True,
-    ],
-]
-
-
-@needs_py39
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.many_to_many import tutorial003_py39 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == expected_calls
index deb133b98598566ec338e4e08335e52a1ad39a8a..2f6f1c9e8916a53a1e458e44c1c75d57756cd579 100644 (file)
@@ -1,22 +1,29 @@
-from unittest.mock import patch
+import importlib
+from types import ModuleType
 
+import pytest
 from sqlmodel import create_engine
 
-from ...conftest import get_testing_print_function
+from ...conftest import PrintMock, needs_py310
 
 
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.one import tutorial001 as mod
-
+@pytest.fixture(
+    name="mod",
+    params=[
+        "tutorial001",
+        pytest.param("tutorial001_py310", marks=needs_py310),
+    ],
+)
+def get_module(request: pytest.FixtureRequest) -> ModuleType:
+    mod = importlib.import_module(f"docs_src.tutorial.one.{request.param}")
     mod.sqlite_url = "sqlite://"
     mod.engine = create_engine(mod.sqlite_url)
-    calls = []
+    return mod
 
-    new_print = get_testing_print_function(calls)
 
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == [
+def test_tutorial(print_mock: PrintMock, mod: ModuleType):
+    mod.main()
+    assert print_mock.calls == [
         [
             "Hero:",
             {
diff --git a/tests/test_tutorial/test_one/test_tutorial001_py310.py b/tests/test_tutorial/test_one/test_tutorial001_py310.py
deleted file mode 100644 (file)
index 6de8780..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-from unittest.mock import patch
-
-from sqlmodel import create_engine
-
-from ...conftest import get_testing_print_function, needs_py310
-
-
-@needs_py310
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.one import tutorial001_py310 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == [
-        [
-            "Hero:",
-            {
-                "name": "Tarantula",
-                "secret_name": "Natalia Roman-on",
-                "age": 32,
-                "id": 4,
-            },
-        ]
-    ]
index 7106564122f57c48c8eedcaf6c407d3b235698d7..267ead8939f91f854ecb52365925e287e96ac4a5 100644 (file)
@@ -1,19 +1,26 @@
-from unittest.mock import patch
+import importlib
+from types import ModuleType
 
+import pytest
 from sqlmodel import create_engine
 
-from ...conftest import get_testing_print_function
+from ...conftest import PrintMock, needs_py310
 
 
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.one import tutorial002 as mod
-
+@pytest.fixture(
+    name="mod",
+    params=[
+        "tutorial002",
+        pytest.param("tutorial002_py310", marks=needs_py310),
+    ],
+)
+def get_module(request: pytest.FixtureRequest) -> ModuleType:
+    mod = importlib.import_module(f"docs_src.tutorial.one.{request.param}")
     mod.sqlite_url = "sqlite://"
     mod.engine = create_engine(mod.sqlite_url)
-    calls = []
+    return mod
 
-    new_print = get_testing_print_function(calls)
 
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == [["Hero:", None]]
+def test_tutorial(print_mock: PrintMock, mod: ModuleType):
+    mod.main()
+    assert print_mock.calls == [["Hero:", None]]
diff --git a/tests/test_tutorial/test_one/test_tutorial002_py310.py b/tests/test_tutorial/test_one/test_tutorial002_py310.py
deleted file mode 100644 (file)
index afdfc54..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-from unittest.mock import patch
-
-from sqlmodel import create_engine
-
-from ...conftest import get_testing_print_function, needs_py310
-
-
-@needs_py310
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.one import tutorial002_py310 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == [["Hero:", None]]
index 40a73d042b813644ab42ab5702b4d0c1c4c86786..de2e529aea114c9d1c78ec1d72303ef779716c2e 100644 (file)
@@ -1,22 +1,29 @@
-from unittest.mock import patch
+import importlib
+from types import ModuleType
 
+import pytest
 from sqlmodel import create_engine
 
-from ...conftest import get_testing_print_function
+from ...conftest import PrintMock, needs_py310
 
 
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.one import tutorial003 as mod
-
+@pytest.fixture(
+    name="mod",
+    params=[
+        "tutorial003",
+        pytest.param("tutorial003_py310", marks=needs_py310),
+    ],
+)
+def get_module(request: pytest.FixtureRequest) -> ModuleType:
+    mod = importlib.import_module(f"docs_src.tutorial.one.{request.param}")
     mod.sqlite_url = "sqlite://"
     mod.engine = create_engine(mod.sqlite_url)
-    calls = []
+    return mod
 
-    new_print = get_testing_print_function(calls)
 
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == [
+def test_tutorial(print_mock: PrintMock, mod: ModuleType):
+    mod.main()
+    assert print_mock.calls == [
         [
             "Hero:",
             {"name": "Deadpond", "secret_name": "Dive Wilson", "age": None, "id": 1},
diff --git a/tests/test_tutorial/test_one/test_tutorial003_py310.py b/tests/test_tutorial/test_one/test_tutorial003_py310.py
deleted file mode 100644 (file)
index 8eb8b86..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-from unittest.mock import patch
-
-from sqlmodel import create_engine
-
-from ...conftest import get_testing_print_function, needs_py310
-
-
-@needs_py310
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.one import tutorial003_py310 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == [
-        [
-            "Hero:",
-            {"name": "Deadpond", "secret_name": "Dive Wilson", "age": None, "id": 1},
-        ]
-    ]
index 5bd652577dc4b289e475478143d5963716a27a8c..9df91fbb4177ccacae7be900ecdae3c0499423a0 100644 (file)
@@ -1,17 +1,28 @@
-from unittest.mock import patch
+import importlib
+from types import ModuleType
 
 import pytest
 from sqlalchemy.exc import MultipleResultsFound
 from sqlmodel import Session, create_engine, delete
 
-from ...conftest import get_testing_print_function
+from ...conftest import PrintMock, needs_py310
 
 
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.one import tutorial004 as mod
-
+@pytest.fixture(
+    name="mod",
+    params=[
+        "tutorial004",
+        pytest.param("tutorial004_py310", marks=needs_py310),
+    ],
+)
+def get_module(request: pytest.FixtureRequest) -> ModuleType:
+    mod = importlib.import_module(f"docs_src.tutorial.one.{request.param}")
     mod.sqlite_url = "sqlite://"
     mod.engine = create_engine(mod.sqlite_url)
+    return mod
+
+
+def test_tutorial(print_mock: PrintMock, mod: ModuleType):
     with pytest.raises(MultipleResultsFound):
         mod.main()
     with Session(mod.engine) as session:
@@ -21,13 +32,8 @@ def test_tutorial(clear_sqlmodel):
         session.add(mod.Hero(name="Test Hero", secret_name="Secret Test Hero", age=24))
         session.commit()
 
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.select_heroes()
-    assert calls == [
+    mod.select_heroes()
+    assert print_mock.calls == [
         [
             "Hero:",
             {
diff --git a/tests/test_tutorial/test_one/test_tutorial004_py310.py b/tests/test_tutorial/test_one/test_tutorial004_py310.py
deleted file mode 100644 (file)
index cf365a4..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-from unittest.mock import patch
-
-import pytest
-from sqlalchemy.exc import MultipleResultsFound
-from sqlmodel import Session, create_engine, delete
-
-from ...conftest import get_testing_print_function, needs_py310
-
-
-@needs_py310
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.one import tutorial004_py310 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    with pytest.raises(MultipleResultsFound):
-        mod.main()
-    with Session(mod.engine) as session:
-        # TODO: create delete() function
-        # TODO: add overloads for .exec() with delete object
-        session.exec(delete(mod.Hero))
-        session.add(mod.Hero(name="Test Hero", secret_name="Secret Test Hero", age=24))
-        session.commit()
-
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.select_heroes()
-    assert calls == [
-        [
-            "Hero:",
-            {
-                "id": 1,
-                "name": "Test Hero",
-                "secret_name": "Secret Test Hero",
-                "age": 24,
-            },
-        ]
-    ]
index 0c25ffa39de4db1d49ebca7156077529d465db54..fa569020a131b0c4cd837ff260a40790986ced75 100644 (file)
@@ -1,17 +1,28 @@
-from unittest.mock import patch
+import importlib
+from types import ModuleType
 
 import pytest
 from sqlalchemy.exc import NoResultFound
 from sqlmodel import Session, create_engine, delete
 
-from ...conftest import get_testing_print_function
+from ...conftest import PrintMock, needs_py310
 
 
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.one import tutorial005 as mod
-
+@pytest.fixture(
+    name="mod",
+    params=[
+        "tutorial005",
+        pytest.param("tutorial005_py310", marks=needs_py310),
+    ],
+)
+def get_module(request: pytest.FixtureRequest) -> ModuleType:
+    mod = importlib.import_module(f"docs_src.tutorial.one.{request.param}")
     mod.sqlite_url = "sqlite://"
     mod.engine = create_engine(mod.sqlite_url)
+    return mod
+
+
+def test_tutorial(print_mock: PrintMock, mod: ModuleType):
     with pytest.raises(NoResultFound):
         mod.main()
     with Session(mod.engine) as session:
@@ -21,13 +32,8 @@ def test_tutorial(clear_sqlmodel):
         session.add(mod.Hero(name="Test Hero", secret_name="Secret Test Hero", age=24))
         session.commit()
 
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.select_heroes()
-    assert calls == [
+    mod.select_heroes()
+    assert print_mock.calls == [
         [
             "Hero:",
             {
diff --git a/tests/test_tutorial/test_one/test_tutorial005_py310.py b/tests/test_tutorial/test_one/test_tutorial005_py310.py
deleted file mode 100644 (file)
index f1fce7d..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-from unittest.mock import patch
-
-import pytest
-from sqlalchemy.exc import NoResultFound
-from sqlmodel import Session, create_engine, delete
-
-from ...conftest import get_testing_print_function, needs_py310
-
-
-@needs_py310
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.one import tutorial005_py310 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    with pytest.raises(NoResultFound):
-        mod.main()
-    with Session(mod.engine) as session:
-        # TODO: create delete() function
-        # TODO: add overloads for .exec() with delete object
-        session.exec(delete(mod.Hero))
-        session.add(mod.Hero(name="Test Hero", secret_name="Secret Test Hero", age=24))
-        session.commit()
-
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.select_heroes()
-    assert calls == [
-        [
-            "Hero:",
-            {
-                "id": 1,
-                "name": "Test Hero",
-                "secret_name": "Secret Test Hero",
-                "age": 24,
-            },
-        ]
-    ]
index 01c1af460242271622453d74077d9b803e324b59..1c6c663dc502a9c1af344d7a3fa7edfcc7baabea 100644 (file)
@@ -1,22 +1,29 @@
-from unittest.mock import patch
+import importlib
+from types import ModuleType
 
+import pytest
 from sqlmodel import create_engine
 
-from ...conftest import get_testing_print_function
+from ...conftest import PrintMock, needs_py310
 
 
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.one import tutorial006 as mod
-
+@pytest.fixture(
+    name="mod",
+    params=[
+        "tutorial006",
+        pytest.param("tutorial006_py310", marks=needs_py310),
+    ],
+)
+def get_module(request: pytest.FixtureRequest) -> ModuleType:
+    mod = importlib.import_module(f"docs_src.tutorial.one.{request.param}")
     mod.sqlite_url = "sqlite://"
     mod.engine = create_engine(mod.sqlite_url)
-    calls = []
+    return mod
 
-    new_print = get_testing_print_function(calls)
 
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == [
+def test_tutorial(print_mock: PrintMock, mod: ModuleType):
+    mod.main()
+    assert print_mock.calls == [
         [
             "Hero:",
             {"name": "Deadpond", "secret_name": "Dive Wilson", "age": None, "id": 1},
diff --git a/tests/test_tutorial/test_one/test_tutorial006_py310.py b/tests/test_tutorial/test_one/test_tutorial006_py310.py
deleted file mode 100644 (file)
index ad8577c..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-from unittest.mock import patch
-
-from sqlmodel import create_engine
-
-from ...conftest import get_testing_print_function, needs_py310
-
-
-@needs_py310
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.one import tutorial006_py310 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == [
-        [
-            "Hero:",
-            {"name": "Deadpond", "secret_name": "Dive Wilson", "age": None, "id": 1},
-        ]
-    ]
index e8b984b0509d7570313d43b19bee54a9c5152ae3..ca4a5310a56302b06e971d28c7e53c6da37938eb 100644 (file)
@@ -1,22 +1,29 @@
-from unittest.mock import patch
+import importlib
+from types import ModuleType
 
+import pytest
 from sqlmodel import create_engine
 
-from ...conftest import get_testing_print_function
+from ...conftest import PrintMock, needs_py310
 
 
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.one import tutorial007 as mod
-
+@pytest.fixture(
+    name="mod",
+    params=[
+        "tutorial007",
+        pytest.param("tutorial007_py310", marks=needs_py310),
+    ],
+)
+def get_module(request: pytest.FixtureRequest) -> ModuleType:
+    mod = importlib.import_module(f"docs_src.tutorial.one.{request.param}")
     mod.sqlite_url = "sqlite://"
     mod.engine = create_engine(mod.sqlite_url)
-    calls = []
+    return mod
 
-    new_print = get_testing_print_function(calls)
 
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == [
+def test_tutorial(print_mock: PrintMock, mod: ModuleType):
+    mod.main()
+    assert print_mock.calls == [
         [
             "Hero:",
             {"name": "Deadpond", "secret_name": "Dive Wilson", "age": None, "id": 1},
diff --git a/tests/test_tutorial/test_one/test_tutorial007_py310.py b/tests/test_tutorial/test_one/test_tutorial007_py310.py
deleted file mode 100644 (file)
index 15b2306..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-from unittest.mock import patch
-
-from sqlmodel import create_engine
-
-from ...conftest import get_testing_print_function, needs_py310
-
-
-@needs_py310
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.one import tutorial007_py310 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == [
-        [
-            "Hero:",
-            {"name": "Deadpond", "secret_name": "Dive Wilson", "age": None, "id": 1},
-        ]
-    ]
index e0ea766f37aa43168f922353f61cdcd95e4f076b..da451fbaa2477a4958de32c007ce0fdf5e7deb4f 100644 (file)
@@ -1,22 +1,29 @@
-from unittest.mock import patch
+import importlib
+from types import ModuleType
 
+import pytest
 from sqlmodel import create_engine
 
-from ...conftest import get_testing_print_function
+from ...conftest import PrintMock, needs_py310
 
 
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.one import tutorial008 as mod
-
+@pytest.fixture(
+    name="mod",
+    params=[
+        "tutorial008",
+        pytest.param("tutorial008_py310", marks=needs_py310),
+    ],
+)
+def get_module(request: pytest.FixtureRequest) -> ModuleType:
+    mod = importlib.import_module(f"docs_src.tutorial.one.{request.param}")
     mod.sqlite_url = "sqlite://"
     mod.engine = create_engine(mod.sqlite_url)
-    calls = []
+    return mod
 
-    new_print = get_testing_print_function(calls)
 
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == [
+def test_tutorial(print_mock: PrintMock, mod: ModuleType):
+    mod.main()
+    assert print_mock.calls == [
         [
             "Hero:",
             {"name": "Deadpond", "secret_name": "Dive Wilson", "age": None, "id": 1},
diff --git a/tests/test_tutorial/test_one/test_tutorial008_py310.py b/tests/test_tutorial/test_one/test_tutorial008_py310.py
deleted file mode 100644 (file)
index c7d1fe5..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-from unittest.mock import patch
-
-from sqlmodel import create_engine
-
-from ...conftest import get_testing_print_function, needs_py310
-
-
-@needs_py310
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.one import tutorial008_py310 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == [
-        [
-            "Hero:",
-            {"name": "Deadpond", "secret_name": "Dive Wilson", "age": None, "id": 1},
-        ]
-    ]
index 63e01fe741f23b52dcf490ad76dc4111205d0916..0cf3a6267fc5c5a7a97c3e9746be1efaee406b2d 100644 (file)
@@ -1,19 +1,26 @@
-from unittest.mock import patch
+import importlib
+from types import ModuleType
 
+import pytest
 from sqlmodel import create_engine
 
-from ...conftest import get_testing_print_function
+from ...conftest import PrintMock, needs_py310
 
 
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.one import tutorial009 as mod
-
+@pytest.fixture(
+    name="mod",
+    params=[
+        "tutorial009",
+        pytest.param("tutorial009_py310", marks=needs_py310),
+    ],
+)
+def get_module(request: pytest.FixtureRequest) -> ModuleType:
+    mod = importlib.import_module(f"docs_src.tutorial.one.{request.param}")
     mod.sqlite_url = "sqlite://"
     mod.engine = create_engine(mod.sqlite_url)
-    calls = []
+    return mod
 
-    new_print = get_testing_print_function(calls)
 
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == [["Hero:", None]]
+def test_tutorial(print_mock: PrintMock, mod: ModuleType):
+    mod.main()
+    assert print_mock.calls == [["Hero:", None]]
diff --git a/tests/test_tutorial/test_one/test_tutorial009_py310.py b/tests/test_tutorial/test_one/test_tutorial009_py310.py
deleted file mode 100644 (file)
index 8e9fda5..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-from unittest.mock import patch
-
-from sqlmodel import create_engine
-
-from ...conftest import get_testing_print_function, needs_py310
-
-
-@needs_py310
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.one import tutorial009_py310 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == [["Hero:", None]]
index 30ec9fdc3642e5dd7f96d9953dc85dcab9bc3760..698a7af2cb5e4a9b5fc9d6ae261f44c02f010889 100644 (file)
@@ -1,10 +1,29 @@
-from unittest.mock import patch
+import importlib
+from types import ModuleType
 
 import pytest
 from sqlalchemy.exc import SAWarning
 from sqlmodel import create_engine
 
-from ....conftest import get_testing_print_function
+from ....conftest import PrintMock, needs_py39, needs_py310
+
+
+@pytest.fixture(
+    name="mod",
+    params=[
+        "tutorial001",
+        pytest.param("tutorial001_py39", marks=needs_py39),
+        pytest.param("tutorial001_py310", marks=needs_py310),
+    ],
+)
+def get_module(request: pytest.FixtureRequest) -> ModuleType:
+    mod = importlib.import_module(
+        f"docs_src.tutorial.relationship_attributes.back_populates.{request.param}"
+    )
+    mod.sqlite_url = "sqlite://"
+    mod.engine = create_engine(mod.sqlite_url)
+    return mod
+
 
 expected_calls = [
     [
@@ -272,18 +291,7 @@ expected_calls = [
 ]
 
 
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.relationship_attributes.back_populates import (
-        tutorial001 as mod,
-    )
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        with pytest.warns(SAWarning):
-            mod.main()
-    assert calls == expected_calls
+def test_tutorial(print_mock: PrintMock, mod: ModuleType):
+    with pytest.warns(SAWarning):
+        mod.main()
+    assert print_mock.calls == expected_calls
diff --git a/tests/test_tutorial/test_relationship_attributes/test_back_populates/test_tutorial001_py310.py b/tests/test_tutorial/test_relationship_attributes/test_back_populates/test_tutorial001_py310.py
deleted file mode 100644 (file)
index 384056a..0000000
+++ /dev/null
@@ -1,290 +0,0 @@
-from unittest.mock import patch
-
-import pytest
-from sqlalchemy.exc import SAWarning
-from sqlmodel import create_engine
-
-from ....conftest import get_testing_print_function, needs_py310
-
-expected_calls = [
-    [
-        "Created hero:",
-        {
-            "age": None,
-            "id": 1,
-            "secret_name": "Dive Wilson",
-            "team_id": 1,
-            "name": "Deadpond",
-        },
-    ],
-    [
-        "Created hero:",
-        {
-            "age": 48,
-            "id": 2,
-            "secret_name": "Tommy Sharp",
-            "team_id": 2,
-            "name": "Rusty-Man",
-        },
-    ],
-    [
-        "Created hero:",
-        {
-            "age": None,
-            "id": 3,
-            "secret_name": "Pedro Parqueador",
-            "team_id": None,
-            "name": "Spider-Boy",
-        },
-    ],
-    [
-        "Updated hero:",
-        {
-            "age": None,
-            "id": 3,
-            "secret_name": "Pedro Parqueador",
-            "team_id": 2,
-            "name": "Spider-Boy",
-        },
-    ],
-    [
-        "Team Wakaland:",
-        {"headquarters": "Wakaland Capital City", "id": 3, "name": "Wakaland"},
-    ],
-    [
-        "Preventers new hero:",
-        {
-            "age": 32,
-            "id": 6,
-            "secret_name": "Natalia Roman-on",
-            "team_id": 2,
-            "name": "Tarantula",
-        },
-    ],
-    [
-        "Preventers new hero:",
-        {
-            "age": 36,
-            "id": 7,
-            "secret_name": "Steve Weird",
-            "team_id": 2,
-            "name": "Dr. Weird",
-        },
-    ],
-    [
-        "Preventers new hero:",
-        {
-            "age": 93,
-            "id": 8,
-            "secret_name": "Esteban Rogelios",
-            "team_id": 2,
-            "name": "Captain North America",
-        },
-    ],
-    [
-        "Preventers heroes:",
-        [
-            {
-                "age": 48,
-                "id": 2,
-                "secret_name": "Tommy Sharp",
-                "team_id": 2,
-                "name": "Rusty-Man",
-            },
-            {
-                "age": None,
-                "id": 3,
-                "secret_name": "Pedro Parqueador",
-                "team_id": 2,
-                "name": "Spider-Boy",
-            },
-            {
-                "age": 32,
-                "id": 6,
-                "secret_name": "Natalia Roman-on",
-                "team_id": 2,
-                "name": "Tarantula",
-            },
-            {
-                "age": 36,
-                "id": 7,
-                "secret_name": "Steve Weird",
-                "team_id": 2,
-                "name": "Dr. Weird",
-            },
-            {
-                "age": 93,
-                "id": 8,
-                "secret_name": "Esteban Rogelios",
-                "team_id": 2,
-                "name": "Captain North America",
-            },
-        ],
-    ],
-    [
-        "Hero Spider-Boy:",
-        {
-            "age": None,
-            "id": 3,
-            "secret_name": "Pedro Parqueador",
-            "team_id": 2,
-            "name": "Spider-Boy",
-        },
-    ],
-    [
-        "Preventers Team:",
-        {"headquarters": "Sharp Tower", "id": 2, "name": "Preventers"},
-    ],
-    [
-        "Preventers Team Heroes:",
-        [
-            {
-                "age": 48,
-                "id": 2,
-                "secret_name": "Tommy Sharp",
-                "team_id": 2,
-                "name": "Rusty-Man",
-            },
-            {
-                "age": None,
-                "id": 3,
-                "secret_name": "Pedro Parqueador",
-                "team_id": 2,
-                "name": "Spider-Boy",
-            },
-            {
-                "age": 32,
-                "id": 6,
-                "secret_name": "Natalia Roman-on",
-                "team_id": 2,
-                "name": "Tarantula",
-            },
-            {
-                "age": 36,
-                "id": 7,
-                "secret_name": "Steve Weird",
-                "team_id": 2,
-                "name": "Dr. Weird",
-            },
-            {
-                "age": 93,
-                "id": 8,
-                "secret_name": "Esteban Rogelios",
-                "team_id": 2,
-                "name": "Captain North America",
-            },
-        ],
-    ],
-    [
-        "Spider-Boy without team:",
-        {
-            "age": None,
-            "id": 3,
-            "secret_name": "Pedro Parqueador",
-            "team_id": 2,
-            "name": "Spider-Boy",
-        },
-    ],
-    [
-        "Preventers Team Heroes again:",
-        [
-            {
-                "age": 48,
-                "id": 2,
-                "secret_name": "Tommy Sharp",
-                "team_id": 2,
-                "name": "Rusty-Man",
-            },
-            {
-                "age": None,
-                "id": 3,
-                "secret_name": "Pedro Parqueador",
-                "team_id": 2,
-                "name": "Spider-Boy",
-            },
-            {
-                "age": 32,
-                "id": 6,
-                "secret_name": "Natalia Roman-on",
-                "team_id": 2,
-                "name": "Tarantula",
-            },
-            {
-                "age": 36,
-                "id": 7,
-                "secret_name": "Steve Weird",
-                "team_id": 2,
-                "name": "Dr. Weird",
-            },
-            {
-                "age": 93,
-                "id": 8,
-                "secret_name": "Esteban Rogelios",
-                "team_id": 2,
-                "name": "Captain North America",
-            },
-        ],
-    ],
-    ["After committing"],
-    [
-        "Spider-Boy after commit:",
-        {
-            "age": None,
-            "id": 3,
-            "secret_name": "Pedro Parqueador",
-            "team_id": None,
-            "name": "Spider-Boy",
-        },
-    ],
-    [
-        "Preventers Team Heroes after commit:",
-        [
-            {
-                "age": 48,
-                "id": 2,
-                "secret_name": "Tommy Sharp",
-                "team_id": 2,
-                "name": "Rusty-Man",
-            },
-            {
-                "age": 32,
-                "id": 6,
-                "secret_name": "Natalia Roman-on",
-                "team_id": 2,
-                "name": "Tarantula",
-            },
-            {
-                "age": 36,
-                "id": 7,
-                "secret_name": "Steve Weird",
-                "team_id": 2,
-                "name": "Dr. Weird",
-            },
-            {
-                "age": 93,
-                "id": 8,
-                "secret_name": "Esteban Rogelios",
-                "team_id": 2,
-                "name": "Captain North America",
-            },
-        ],
-    ],
-]
-
-
-@needs_py310
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.relationship_attributes.back_populates import (
-        tutorial001_py310 as mod,
-    )
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        with pytest.warns(SAWarning):
-            mod.main()
-    assert calls == expected_calls
diff --git a/tests/test_tutorial/test_relationship_attributes/test_back_populates/test_tutorial001_py39.py b/tests/test_tutorial/test_relationship_attributes/test_back_populates/test_tutorial001_py39.py
deleted file mode 100644 (file)
index 0597a88..0000000
+++ /dev/null
@@ -1,290 +0,0 @@
-from unittest.mock import patch
-
-import pytest
-from sqlalchemy.exc import SAWarning
-from sqlmodel import create_engine
-
-from ....conftest import get_testing_print_function, needs_py39
-
-expected_calls = [
-    [
-        "Created hero:",
-        {
-            "age": None,
-            "id": 1,
-            "secret_name": "Dive Wilson",
-            "team_id": 1,
-            "name": "Deadpond",
-        },
-    ],
-    [
-        "Created hero:",
-        {
-            "age": 48,
-            "id": 2,
-            "secret_name": "Tommy Sharp",
-            "team_id": 2,
-            "name": "Rusty-Man",
-        },
-    ],
-    [
-        "Created hero:",
-        {
-            "age": None,
-            "id": 3,
-            "secret_name": "Pedro Parqueador",
-            "team_id": None,
-            "name": "Spider-Boy",
-        },
-    ],
-    [
-        "Updated hero:",
-        {
-            "age": None,
-            "id": 3,
-            "secret_name": "Pedro Parqueador",
-            "team_id": 2,
-            "name": "Spider-Boy",
-        },
-    ],
-    [
-        "Team Wakaland:",
-        {"headquarters": "Wakaland Capital City", "id": 3, "name": "Wakaland"},
-    ],
-    [
-        "Preventers new hero:",
-        {
-            "age": 32,
-            "id": 6,
-            "secret_name": "Natalia Roman-on",
-            "team_id": 2,
-            "name": "Tarantula",
-        },
-    ],
-    [
-        "Preventers new hero:",
-        {
-            "age": 36,
-            "id": 7,
-            "secret_name": "Steve Weird",
-            "team_id": 2,
-            "name": "Dr. Weird",
-        },
-    ],
-    [
-        "Preventers new hero:",
-        {
-            "age": 93,
-            "id": 8,
-            "secret_name": "Esteban Rogelios",
-            "team_id": 2,
-            "name": "Captain North America",
-        },
-    ],
-    [
-        "Preventers heroes:",
-        [
-            {
-                "age": 48,
-                "id": 2,
-                "secret_name": "Tommy Sharp",
-                "team_id": 2,
-                "name": "Rusty-Man",
-            },
-            {
-                "age": None,
-                "id": 3,
-                "secret_name": "Pedro Parqueador",
-                "team_id": 2,
-                "name": "Spider-Boy",
-            },
-            {
-                "age": 32,
-                "id": 6,
-                "secret_name": "Natalia Roman-on",
-                "team_id": 2,
-                "name": "Tarantula",
-            },
-            {
-                "age": 36,
-                "id": 7,
-                "secret_name": "Steve Weird",
-                "team_id": 2,
-                "name": "Dr. Weird",
-            },
-            {
-                "age": 93,
-                "id": 8,
-                "secret_name": "Esteban Rogelios",
-                "team_id": 2,
-                "name": "Captain North America",
-            },
-        ],
-    ],
-    [
-        "Hero Spider-Boy:",
-        {
-            "age": None,
-            "id": 3,
-            "secret_name": "Pedro Parqueador",
-            "team_id": 2,
-            "name": "Spider-Boy",
-        },
-    ],
-    [
-        "Preventers Team:",
-        {"headquarters": "Sharp Tower", "id": 2, "name": "Preventers"},
-    ],
-    [
-        "Preventers Team Heroes:",
-        [
-            {
-                "age": 48,
-                "id": 2,
-                "secret_name": "Tommy Sharp",
-                "team_id": 2,
-                "name": "Rusty-Man",
-            },
-            {
-                "age": None,
-                "id": 3,
-                "secret_name": "Pedro Parqueador",
-                "team_id": 2,
-                "name": "Spider-Boy",
-            },
-            {
-                "age": 32,
-                "id": 6,
-                "secret_name": "Natalia Roman-on",
-                "team_id": 2,
-                "name": "Tarantula",
-            },
-            {
-                "age": 36,
-                "id": 7,
-                "secret_name": "Steve Weird",
-                "team_id": 2,
-                "name": "Dr. Weird",
-            },
-            {
-                "age": 93,
-                "id": 8,
-                "secret_name": "Esteban Rogelios",
-                "team_id": 2,
-                "name": "Captain North America",
-            },
-        ],
-    ],
-    [
-        "Spider-Boy without team:",
-        {
-            "age": None,
-            "id": 3,
-            "secret_name": "Pedro Parqueador",
-            "team_id": 2,
-            "name": "Spider-Boy",
-        },
-    ],
-    [
-        "Preventers Team Heroes again:",
-        [
-            {
-                "age": 48,
-                "id": 2,
-                "secret_name": "Tommy Sharp",
-                "team_id": 2,
-                "name": "Rusty-Man",
-            },
-            {
-                "age": None,
-                "id": 3,
-                "secret_name": "Pedro Parqueador",
-                "team_id": 2,
-                "name": "Spider-Boy",
-            },
-            {
-                "age": 32,
-                "id": 6,
-                "secret_name": "Natalia Roman-on",
-                "team_id": 2,
-                "name": "Tarantula",
-            },
-            {
-                "age": 36,
-                "id": 7,
-                "secret_name": "Steve Weird",
-                "team_id": 2,
-                "name": "Dr. Weird",
-            },
-            {
-                "age": 93,
-                "id": 8,
-                "secret_name": "Esteban Rogelios",
-                "team_id": 2,
-                "name": "Captain North America",
-            },
-        ],
-    ],
-    ["After committing"],
-    [
-        "Spider-Boy after commit:",
-        {
-            "age": None,
-            "id": 3,
-            "secret_name": "Pedro Parqueador",
-            "team_id": None,
-            "name": "Spider-Boy",
-        },
-    ],
-    [
-        "Preventers Team Heroes after commit:",
-        [
-            {
-                "age": 48,
-                "id": 2,
-                "secret_name": "Tommy Sharp",
-                "team_id": 2,
-                "name": "Rusty-Man",
-            },
-            {
-                "age": 32,
-                "id": 6,
-                "secret_name": "Natalia Roman-on",
-                "team_id": 2,
-                "name": "Tarantula",
-            },
-            {
-                "age": 36,
-                "id": 7,
-                "secret_name": "Steve Weird",
-                "team_id": 2,
-                "name": "Dr. Weird",
-            },
-            {
-                "age": 93,
-                "id": 8,
-                "secret_name": "Esteban Rogelios",
-                "team_id": 2,
-                "name": "Captain North America",
-            },
-        ],
-    ],
-]
-
-
-@needs_py39
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.relationship_attributes.back_populates import (
-        tutorial001_py39 as mod,
-    )
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        with pytest.warns(SAWarning):
-            mod.main()
-    assert calls == expected_calls
index 98c01a9d54f3bf95329e884a3469facde8a8c537..8ce54be46c4b94c1907a07efc93afac072aca0bb 100644 (file)
@@ -1,8 +1,28 @@
-from unittest.mock import patch
+import importlib
+from types import ModuleType
 
+import pytest
 from sqlmodel import create_engine
 
-from ....conftest import get_testing_print_function
+from ....conftest import PrintMock, needs_py39, needs_py310
+
+
+@pytest.fixture(
+    name="mod",
+    params=[
+        "tutorial002",
+        pytest.param("tutorial002_py39", marks=needs_py39),
+        pytest.param("tutorial002_py310", marks=needs_py310),
+    ],
+)
+def get_module(request: pytest.FixtureRequest) -> ModuleType:
+    mod = importlib.import_module(
+        f"docs_src.tutorial.relationship_attributes.back_populates.{request.param}"
+    )
+    mod.sqlite_url = "sqlite://"
+    mod.engine = create_engine(mod.sqlite_url)
+    return mod
+
 
 expected_calls = [
     [
@@ -263,17 +283,6 @@ expected_calls = [
 ]
 
 
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.relationship_attributes.back_populates import (
-        tutorial002 as mod,
-    )
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == expected_calls
+def test_tutorial(print_mock: PrintMock, mod: ModuleType):
+    mod.main()
+    assert print_mock.calls == expected_calls
diff --git a/tests/test_tutorial/test_relationship_attributes/test_back_populates/test_tutorial002_py310.py b/tests/test_tutorial/test_relationship_attributes/test_back_populates/test_tutorial002_py310.py
deleted file mode 100644 (file)
index 50a891f..0000000
+++ /dev/null
@@ -1,280 +0,0 @@
-from unittest.mock import patch
-
-from sqlmodel import create_engine
-
-from ....conftest import get_testing_print_function, needs_py310
-
-expected_calls = [
-    [
-        "Created hero:",
-        {
-            "age": None,
-            "id": 1,
-            "secret_name": "Dive Wilson",
-            "team_id": 1,
-            "name": "Deadpond",
-        },
-    ],
-    [
-        "Created hero:",
-        {
-            "age": 48,
-            "id": 2,
-            "secret_name": "Tommy Sharp",
-            "team_id": 2,
-            "name": "Rusty-Man",
-        },
-    ],
-    [
-        "Created hero:",
-        {
-            "age": None,
-            "id": 3,
-            "secret_name": "Pedro Parqueador",
-            "team_id": None,
-            "name": "Spider-Boy",
-        },
-    ],
-    [
-        "Updated hero:",
-        {
-            "age": None,
-            "id": 3,
-            "secret_name": "Pedro Parqueador",
-            "team_id": 2,
-            "name": "Spider-Boy",
-        },
-    ],
-    [
-        "Team Wakaland:",
-        {"id": 3, "name": "Wakaland", "headquarters": "Wakaland Capital City"},
-    ],
-    [
-        "Preventers new hero:",
-        {
-            "age": 32,
-            "id": 6,
-            "secret_name": "Natalia Roman-on",
-            "team_id": 2,
-            "name": "Tarantula",
-        },
-    ],
-    [
-        "Preventers new hero:",
-        {
-            "age": 36,
-            "id": 7,
-            "secret_name": "Steve Weird",
-            "team_id": 2,
-            "name": "Dr. Weird",
-        },
-    ],
-    [
-        "Preventers new hero:",
-        {
-            "age": 93,
-            "id": 8,
-            "secret_name": "Esteban Rogelios",
-            "team_id": 2,
-            "name": "Captain North America",
-        },
-    ],
-    [
-        "Preventers heroes:",
-        [
-            {
-                "age": 48,
-                "id": 2,
-                "secret_name": "Tommy Sharp",
-                "team_id": 2,
-                "name": "Rusty-Man",
-            },
-            {
-                "age": None,
-                "id": 3,
-                "secret_name": "Pedro Parqueador",
-                "team_id": 2,
-                "name": "Spider-Boy",
-            },
-            {
-                "age": 32,
-                "id": 6,
-                "secret_name": "Natalia Roman-on",
-                "team_id": 2,
-                "name": "Tarantula",
-            },
-            {
-                "age": 36,
-                "id": 7,
-                "secret_name": "Steve Weird",
-                "team_id": 2,
-                "name": "Dr. Weird",
-            },
-            {
-                "age": 93,
-                "id": 8,
-                "secret_name": "Esteban Rogelios",
-                "team_id": 2,
-                "name": "Captain North America",
-            },
-        ],
-    ],
-    [
-        "Hero Spider-Boy:",
-        {
-            "age": None,
-            "id": 3,
-            "secret_name": "Pedro Parqueador",
-            "team_id": 2,
-            "name": "Spider-Boy",
-        },
-    ],
-    [
-        "Preventers Team:",
-        {"id": 2, "name": "Preventers", "headquarters": "Sharp Tower"},
-    ],
-    [
-        "Preventers Team Heroes:",
-        [
-            {
-                "age": 48,
-                "id": 2,
-                "secret_name": "Tommy Sharp",
-                "team_id": 2,
-                "name": "Rusty-Man",
-            },
-            {
-                "age": None,
-                "id": 3,
-                "secret_name": "Pedro Parqueador",
-                "team_id": 2,
-                "name": "Spider-Boy",
-            },
-            {
-                "age": 32,
-                "id": 6,
-                "secret_name": "Natalia Roman-on",
-                "team_id": 2,
-                "name": "Tarantula",
-            },
-            {
-                "age": 36,
-                "id": 7,
-                "secret_name": "Steve Weird",
-                "team_id": 2,
-                "name": "Dr. Weird",
-            },
-            {
-                "age": 93,
-                "id": 8,
-                "secret_name": "Esteban Rogelios",
-                "team_id": 2,
-                "name": "Captain North America",
-            },
-        ],
-    ],
-    [
-        "Spider-Boy without team:",
-        {
-            "age": None,
-            "id": 3,
-            "secret_name": "Pedro Parqueador",
-            "team_id": 2,
-            "name": "Spider-Boy",
-        },
-    ],
-    [
-        "Preventers Team Heroes again:",
-        [
-            {
-                "age": 48,
-                "id": 2,
-                "secret_name": "Tommy Sharp",
-                "team_id": 2,
-                "name": "Rusty-Man",
-            },
-            {
-                "age": 32,
-                "id": 6,
-                "secret_name": "Natalia Roman-on",
-                "team_id": 2,
-                "name": "Tarantula",
-            },
-            {
-                "age": 36,
-                "id": 7,
-                "secret_name": "Steve Weird",
-                "team_id": 2,
-                "name": "Dr. Weird",
-            },
-            {
-                "age": 93,
-                "id": 8,
-                "secret_name": "Esteban Rogelios",
-                "team_id": 2,
-                "name": "Captain North America",
-            },
-        ],
-    ],
-    ["After committing"],
-    [
-        "Spider-Boy after commit:",
-        {
-            "age": None,
-            "id": 3,
-            "secret_name": "Pedro Parqueador",
-            "team_id": None,
-            "name": "Spider-Boy",
-        },
-    ],
-    [
-        "Preventers Team Heroes after commit:",
-        [
-            {
-                "age": 48,
-                "id": 2,
-                "secret_name": "Tommy Sharp",
-                "team_id": 2,
-                "name": "Rusty-Man",
-            },
-            {
-                "age": 32,
-                "id": 6,
-                "secret_name": "Natalia Roman-on",
-                "team_id": 2,
-                "name": "Tarantula",
-            },
-            {
-                "age": 36,
-                "id": 7,
-                "secret_name": "Steve Weird",
-                "team_id": 2,
-                "name": "Dr. Weird",
-            },
-            {
-                "age": 93,
-                "id": 8,
-                "secret_name": "Esteban Rogelios",
-                "team_id": 2,
-                "name": "Captain North America",
-            },
-        ],
-    ],
-]
-
-
-@needs_py310
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.relationship_attributes.back_populates import (
-        tutorial002_py310 as mod,
-    )
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == expected_calls
diff --git a/tests/test_tutorial/test_relationship_attributes/test_back_populates/test_tutorial002_py39.py b/tests/test_tutorial/test_relationship_attributes/test_back_populates/test_tutorial002_py39.py
deleted file mode 100644 (file)
index 3da6ce4..0000000
+++ /dev/null
@@ -1,280 +0,0 @@
-from unittest.mock import patch
-
-from sqlmodel import create_engine
-
-from ....conftest import get_testing_print_function, needs_py39
-
-expected_calls = [
-    [
-        "Created hero:",
-        {
-            "age": None,
-            "id": 1,
-            "secret_name": "Dive Wilson",
-            "team_id": 1,
-            "name": "Deadpond",
-        },
-    ],
-    [
-        "Created hero:",
-        {
-            "age": 48,
-            "id": 2,
-            "secret_name": "Tommy Sharp",
-            "team_id": 2,
-            "name": "Rusty-Man",
-        },
-    ],
-    [
-        "Created hero:",
-        {
-            "age": None,
-            "id": 3,
-            "secret_name": "Pedro Parqueador",
-            "team_id": None,
-            "name": "Spider-Boy",
-        },
-    ],
-    [
-        "Updated hero:",
-        {
-            "age": None,
-            "id": 3,
-            "secret_name": "Pedro Parqueador",
-            "team_id": 2,
-            "name": "Spider-Boy",
-        },
-    ],
-    [
-        "Team Wakaland:",
-        {"id": 3, "name": "Wakaland", "headquarters": "Wakaland Capital City"},
-    ],
-    [
-        "Preventers new hero:",
-        {
-            "age": 32,
-            "id": 6,
-            "secret_name": "Natalia Roman-on",
-            "team_id": 2,
-            "name": "Tarantula",
-        },
-    ],
-    [
-        "Preventers new hero:",
-        {
-            "age": 36,
-            "id": 7,
-            "secret_name": "Steve Weird",
-            "team_id": 2,
-            "name": "Dr. Weird",
-        },
-    ],
-    [
-        "Preventers new hero:",
-        {
-            "age": 93,
-            "id": 8,
-            "secret_name": "Esteban Rogelios",
-            "team_id": 2,
-            "name": "Captain North America",
-        },
-    ],
-    [
-        "Preventers heroes:",
-        [
-            {
-                "age": 48,
-                "id": 2,
-                "secret_name": "Tommy Sharp",
-                "team_id": 2,
-                "name": "Rusty-Man",
-            },
-            {
-                "age": None,
-                "id": 3,
-                "secret_name": "Pedro Parqueador",
-                "team_id": 2,
-                "name": "Spider-Boy",
-            },
-            {
-                "age": 32,
-                "id": 6,
-                "secret_name": "Natalia Roman-on",
-                "team_id": 2,
-                "name": "Tarantula",
-            },
-            {
-                "age": 36,
-                "id": 7,
-                "secret_name": "Steve Weird",
-                "team_id": 2,
-                "name": "Dr. Weird",
-            },
-            {
-                "age": 93,
-                "id": 8,
-                "secret_name": "Esteban Rogelios",
-                "team_id": 2,
-                "name": "Captain North America",
-            },
-        ],
-    ],
-    [
-        "Hero Spider-Boy:",
-        {
-            "age": None,
-            "id": 3,
-            "secret_name": "Pedro Parqueador",
-            "team_id": 2,
-            "name": "Spider-Boy",
-        },
-    ],
-    [
-        "Preventers Team:",
-        {"id": 2, "name": "Preventers", "headquarters": "Sharp Tower"},
-    ],
-    [
-        "Preventers Team Heroes:",
-        [
-            {
-                "age": 48,
-                "id": 2,
-                "secret_name": "Tommy Sharp",
-                "team_id": 2,
-                "name": "Rusty-Man",
-            },
-            {
-                "age": None,
-                "id": 3,
-                "secret_name": "Pedro Parqueador",
-                "team_id": 2,
-                "name": "Spider-Boy",
-            },
-            {
-                "age": 32,
-                "id": 6,
-                "secret_name": "Natalia Roman-on",
-                "team_id": 2,
-                "name": "Tarantula",
-            },
-            {
-                "age": 36,
-                "id": 7,
-                "secret_name": "Steve Weird",
-                "team_id": 2,
-                "name": "Dr. Weird",
-            },
-            {
-                "age": 93,
-                "id": 8,
-                "secret_name": "Esteban Rogelios",
-                "team_id": 2,
-                "name": "Captain North America",
-            },
-        ],
-    ],
-    [
-        "Spider-Boy without team:",
-        {
-            "age": None,
-            "id": 3,
-            "secret_name": "Pedro Parqueador",
-            "team_id": 2,
-            "name": "Spider-Boy",
-        },
-    ],
-    [
-        "Preventers Team Heroes again:",
-        [
-            {
-                "age": 48,
-                "id": 2,
-                "secret_name": "Tommy Sharp",
-                "team_id": 2,
-                "name": "Rusty-Man",
-            },
-            {
-                "age": 32,
-                "id": 6,
-                "secret_name": "Natalia Roman-on",
-                "team_id": 2,
-                "name": "Tarantula",
-            },
-            {
-                "age": 36,
-                "id": 7,
-                "secret_name": "Steve Weird",
-                "team_id": 2,
-                "name": "Dr. Weird",
-            },
-            {
-                "age": 93,
-                "id": 8,
-                "secret_name": "Esteban Rogelios",
-                "team_id": 2,
-                "name": "Captain North America",
-            },
-        ],
-    ],
-    ["After committing"],
-    [
-        "Spider-Boy after commit:",
-        {
-            "age": None,
-            "id": 3,
-            "secret_name": "Pedro Parqueador",
-            "team_id": None,
-            "name": "Spider-Boy",
-        },
-    ],
-    [
-        "Preventers Team Heroes after commit:",
-        [
-            {
-                "age": 48,
-                "id": 2,
-                "secret_name": "Tommy Sharp",
-                "team_id": 2,
-                "name": "Rusty-Man",
-            },
-            {
-                "age": 32,
-                "id": 6,
-                "secret_name": "Natalia Roman-on",
-                "team_id": 2,
-                "name": "Tarantula",
-            },
-            {
-                "age": 36,
-                "id": 7,
-                "secret_name": "Steve Weird",
-                "team_id": 2,
-                "name": "Dr. Weird",
-            },
-            {
-                "age": 93,
-                "id": 8,
-                "secret_name": "Esteban Rogelios",
-                "team_id": 2,
-                "name": "Captain North America",
-            },
-        ],
-    ],
-]
-
-
-@needs_py39
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.relationship_attributes.back_populates import (
-        tutorial002_py39 as mod,
-    )
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == expected_calls
index 2ed66f76ca6abe7ccb2e1e32702d6b20622ad708..d30c71c3c2d51a6ac2d70c31a2633812f696f5a0 100644 (file)
@@ -1,15 +1,32 @@
+import importlib
+from types import ModuleType
+
+import pytest
 from sqlalchemy import inspect
 from sqlalchemy.engine.reflection import Inspector
 from sqlmodel import create_engine
 
+from ....conftest import needs_py39, needs_py310
 
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.relationship_attributes.back_populates import (
-        tutorial003 as mod,
-    )
 
+@pytest.fixture(
+    name="mod",
+    params=[
+        "tutorial003",
+        pytest.param("tutorial003_py39", marks=needs_py39),
+        pytest.param("tutorial003_py310", marks=needs_py310),
+    ],
+)
+def get_module(request: pytest.FixtureRequest) -> ModuleType:
+    mod = importlib.import_module(
+        f"docs_src.tutorial.relationship_attributes.back_populates.{request.param}"
+    )
     mod.sqlite_url = "sqlite://"
     mod.engine = create_engine(mod.sqlite_url)
+    return mod
+
+
+def test_tutorial(mod: ModuleType):
     mod.main()
     insp: Inspector = inspect(mod.engine)
     assert insp.has_table(str(mod.Hero.__tablename__))
diff --git a/tests/test_tutorial/test_relationship_attributes/test_back_populates/test_tutorial003_py310.py b/tests/test_tutorial/test_relationship_attributes/test_back_populates/test_tutorial003_py310.py
deleted file mode 100644 (file)
index 82e0c1c..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-from sqlalchemy import inspect
-from sqlalchemy.engine.reflection import Inspector
-from sqlmodel import create_engine
-
-from ....conftest import needs_py310
-
-
-@needs_py310
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.relationship_attributes.back_populates import (
-        tutorial003_py310 as mod,
-    )
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    mod.main()
-    insp: Inspector = inspect(mod.engine)
-    assert insp.has_table(str(mod.Hero.__tablename__))
-    assert insp.has_table(str(mod.Weapon.__tablename__))
-    assert insp.has_table(str(mod.Power.__tablename__))
-    assert insp.has_table(str(mod.Team.__tablename__))
diff --git a/tests/test_tutorial/test_relationship_attributes/test_back_populates/test_tutorial003_py39.py b/tests/test_tutorial/test_relationship_attributes/test_back_populates/test_tutorial003_py39.py
deleted file mode 100644 (file)
index d6059cb..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-from sqlalchemy import inspect
-from sqlalchemy.engine.reflection import Inspector
-from sqlmodel import create_engine
-
-from ....conftest import needs_py39
-
-
-@needs_py39
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.relationship_attributes.back_populates import (
-        tutorial003_py39 as mod,
-    )
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    mod.main()
-    insp: Inspector = inspect(mod.engine)
-    assert insp.has_table(str(mod.Hero.__tablename__))
-    assert insp.has_table(str(mod.Weapon.__tablename__))
-    assert insp.has_table(str(mod.Power.__tablename__))
-    assert insp.has_table(str(mod.Team.__tablename__))
index 7ced57c8350f6e893574ab4e59566ae0ecdf4f56..0c6a229178e7b82c8ef684b119483ce840c40ab8 100644 (file)
@@ -1,8 +1,28 @@
-from unittest.mock import patch
+import importlib
+from types import ModuleType
 
+import pytest
 from sqlmodel import create_engine
 
-from ....conftest import get_testing_print_function
+from ....conftest import PrintMock, needs_py39, needs_py310
+
+
+@pytest.fixture(
+    name="mod",
+    params=[
+        "tutorial001",
+        pytest.param("tutorial001_py39", marks=needs_py39),
+        pytest.param("tutorial001_py310", marks=needs_py310),
+    ],
+)
+def get_module(request: pytest.FixtureRequest) -> ModuleType:
+    mod = importlib.import_module(
+        f"docs_src.tutorial.relationship_attributes.create_and_update_relationships.{request.param}"
+    )
+    mod.sqlite_url = "sqlite://"
+    mod.engine = create_engine(mod.sqlite_url)
+    return mod
+
 
 expected_calls = [
     [
@@ -82,17 +102,6 @@ expected_calls = [
 ]
 
 
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.relationship_attributes.create_and_update_relationships import (
-        tutorial001 as mod,
-    )
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == expected_calls
+def test_tutorial(print_mock: PrintMock, mod: ModuleType):
+    mod.main()
+    assert print_mock.calls == expected_calls
diff --git a/tests/test_tutorial/test_relationship_attributes/test_create_and_update_relationships/test_tutorial001_py310.py b/tests/test_tutorial/test_relationship_attributes/test_create_and_update_relationships/test_tutorial001_py310.py
deleted file mode 100644 (file)
index c239b6d..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-from unittest.mock import patch
-
-from sqlmodel import create_engine
-
-from ....conftest import get_testing_print_function, needs_py310
-
-expected_calls = [
-    [
-        "Created hero:",
-        {
-            "age": None,
-            "id": 1,
-            "secret_name": "Dive Wilson",
-            "team_id": 1,
-            "name": "Deadpond",
-        },
-    ],
-    [
-        "Created hero:",
-        {
-            "age": 48,
-            "id": 2,
-            "secret_name": "Tommy Sharp",
-            "team_id": 2,
-            "name": "Rusty-Man",
-        },
-    ],
-    [
-        "Created hero:",
-        {
-            "age": None,
-            "id": 3,
-            "secret_name": "Pedro Parqueador",
-            "team_id": None,
-            "name": "Spider-Boy",
-        },
-    ],
-    [
-        "Updated hero:",
-        {
-            "age": None,
-            "id": 3,
-            "secret_name": "Pedro Parqueador",
-            "team_id": 2,
-            "name": "Spider-Boy",
-        },
-    ],
-    [
-        "Team Wakaland:",
-        {"id": 3, "headquarters": "Wakaland Capital City", "name": "Wakaland"},
-    ],
-    [
-        "Preventers new hero:",
-        {
-            "age": 32,
-            "id": 6,
-            "secret_name": "Natalia Roman-on",
-            "team_id": 2,
-            "name": "Tarantula",
-        },
-    ],
-    [
-        "Preventers new hero:",
-        {
-            "age": 36,
-            "id": 7,
-            "secret_name": "Steve Weird",
-            "team_id": 2,
-            "name": "Dr. Weird",
-        },
-    ],
-    [
-        "Preventers new hero:",
-        {
-            "age": 93,
-            "id": 8,
-            "secret_name": "Esteban Rogelios",
-            "team_id": 2,
-            "name": "Captain North America",
-        },
-    ],
-]
-
-
-@needs_py310
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.relationship_attributes.create_and_update_relationships import (
-        tutorial001_py310 as mod,
-    )
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == expected_calls
diff --git a/tests/test_tutorial/test_relationship_attributes/test_create_and_update_relationships/test_tutorial001_py39.py b/tests/test_tutorial/test_relationship_attributes/test_create_and_update_relationships/test_tutorial001_py39.py
deleted file mode 100644 (file)
index c569eed..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-from unittest.mock import patch
-
-from sqlmodel import create_engine
-
-from ....conftest import get_testing_print_function, needs_py39
-
-expected_calls = [
-    [
-        "Created hero:",
-        {
-            "age": None,
-            "id": 1,
-            "secret_name": "Dive Wilson",
-            "team_id": 1,
-            "name": "Deadpond",
-        },
-    ],
-    [
-        "Created hero:",
-        {
-            "age": 48,
-            "id": 2,
-            "secret_name": "Tommy Sharp",
-            "team_id": 2,
-            "name": "Rusty-Man",
-        },
-    ],
-    [
-        "Created hero:",
-        {
-            "age": None,
-            "id": 3,
-            "secret_name": "Pedro Parqueador",
-            "team_id": None,
-            "name": "Spider-Boy",
-        },
-    ],
-    [
-        "Updated hero:",
-        {
-            "age": None,
-            "id": 3,
-            "secret_name": "Pedro Parqueador",
-            "team_id": 2,
-            "name": "Spider-Boy",
-        },
-    ],
-    [
-        "Team Wakaland:",
-        {"id": 3, "headquarters": "Wakaland Capital City", "name": "Wakaland"},
-    ],
-    [
-        "Preventers new hero:",
-        {
-            "age": 32,
-            "id": 6,
-            "secret_name": "Natalia Roman-on",
-            "team_id": 2,
-            "name": "Tarantula",
-        },
-    ],
-    [
-        "Preventers new hero:",
-        {
-            "age": 36,
-            "id": 7,
-            "secret_name": "Steve Weird",
-            "team_id": 2,
-            "name": "Dr. Weird",
-        },
-    ],
-    [
-        "Preventers new hero:",
-        {
-            "age": 93,
-            "id": 8,
-            "secret_name": "Esteban Rogelios",
-            "team_id": 2,
-            "name": "Captain North America",
-        },
-    ],
-]
-
-
-@needs_py39
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.relationship_attributes.create_and_update_relationships import (
-        tutorial001_py39 as mod,
-    )
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == expected_calls
index 14b38ca52e2ac2f7561bff2b8e33694a68b96900..96cf8bcc49808c2e24294d05da8568e4e141a739 100644 (file)
@@ -1,8 +1,28 @@
-from unittest.mock import patch
+import importlib
+from types import ModuleType
 
+import pytest
 from sqlmodel import create_engine
 
-from ....conftest import get_testing_print_function
+from ....conftest import PrintMock, needs_py39, needs_py310
+
+
+@pytest.fixture(
+    name="mod",
+    params=[
+        "tutorial001",
+        pytest.param("tutorial001_py39", marks=needs_py39),
+        pytest.param("tutorial001_py310", marks=needs_py310),
+    ],
+)
+def get_module(request: pytest.FixtureRequest) -> ModuleType:
+    mod = importlib.import_module(
+        f"docs_src.tutorial.relationship_attributes.define_relationship_attributes.{request.param}"
+    )
+    mod.sqlite_url = "sqlite://"
+    mod.engine = create_engine(mod.sqlite_url)
+    return mod
+
 
 expected_calls = [
     [
@@ -38,17 +58,6 @@ expected_calls = [
 ]
 
 
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.relationship_attributes.define_relationship_attributes import (
-        tutorial001 as mod,
-    )
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == expected_calls
+def test_tutorial(print_mock: PrintMock, mod: ModuleType):
+    mod.main()
+    assert print_mock.calls == expected_calls
diff --git a/tests/test_tutorial/test_relationship_attributes/test_define_relationship_attributes/test_tutorial001_py310.py b/tests/test_tutorial/test_relationship_attributes/test_define_relationship_attributes/test_tutorial001_py310.py
deleted file mode 100644 (file)
index f595dca..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-from unittest.mock import patch
-
-from sqlmodel import create_engine
-
-from ....conftest import get_testing_print_function, needs_py310
-
-expected_calls = [
-    [
-        "Created hero:",
-        {
-            "name": "Deadpond",
-            "age": None,
-            "team_id": 1,
-            "id": 1,
-            "secret_name": "Dive Wilson",
-        },
-    ],
-    [
-        "Created hero:",
-        {
-            "name": "Rusty-Man",
-            "age": 48,
-            "team_id": 2,
-            "id": 2,
-            "secret_name": "Tommy Sharp",
-        },
-    ],
-    [
-        "Created hero:",
-        {
-            "name": "Spider-Boy",
-            "age": None,
-            "team_id": None,
-            "id": 3,
-            "secret_name": "Pedro Parqueador",
-        },
-    ],
-]
-
-
-@needs_py310
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.relationship_attributes.define_relationship_attributes import (
-        tutorial001_py310 as mod,
-    )
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == expected_calls
diff --git a/tests/test_tutorial/test_relationship_attributes/test_define_relationship_attributes/test_tutorial001_py39.py b/tests/test_tutorial/test_relationship_attributes/test_define_relationship_attributes/test_tutorial001_py39.py
deleted file mode 100644 (file)
index d54c610..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-from unittest.mock import patch
-
-from sqlmodel import create_engine
-
-from ....conftest import get_testing_print_function, needs_py39
-
-expected_calls = [
-    [
-        "Created hero:",
-        {
-            "name": "Deadpond",
-            "age": None,
-            "team_id": 1,
-            "id": 1,
-            "secret_name": "Dive Wilson",
-        },
-    ],
-    [
-        "Created hero:",
-        {
-            "name": "Rusty-Man",
-            "age": 48,
-            "team_id": 2,
-            "id": 2,
-            "secret_name": "Tommy Sharp",
-        },
-    ],
-    [
-        "Created hero:",
-        {
-            "name": "Spider-Boy",
-            "age": None,
-            "team_id": None,
-            "id": 3,
-            "secret_name": "Pedro Parqueador",
-        },
-    ],
-]
-
-
-@needs_py39
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.relationship_attributes.define_relationship_attributes import (
-        tutorial001_py39 as mod,
-    )
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == expected_calls
index 863a84eb1c876ea9ab91e2aefa2eb1880777b1ec..5e43f80c4ce286a9b3b24b94432a27e8298e2b44 100644 (file)
@@ -1,24 +1,32 @@
-from unittest.mock import patch
+import importlib
+from types import ModuleType
 
+import pytest
 from sqlmodel import create_engine
 
-from ....conftest import get_testing_print_function
+from ....conftest import PrintMock, needs_py39, needs_py310
 
 
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.relationship_attributes.cascade_delete_relationships import (
-        tutorial001 as mod,
+@pytest.fixture(
+    name="mod",
+    params=[
+        "tutorial001",
+        pytest.param("tutorial001_py39", marks=needs_py39),
+        pytest.param("tutorial001_py310", marks=needs_py310),
+    ],
+)
+def get_module(request: pytest.FixtureRequest) -> ModuleType:
+    mod = importlib.import_module(
+        f"docs_src.tutorial.relationship_attributes.cascade_delete_relationships.{request.param}"
     )
-
     mod.sqlite_url = "sqlite://"
     mod.engine = create_engine(mod.sqlite_url)
-    calls = []
+    return mod
 
-    new_print = get_testing_print_function(calls)
 
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == [
+def test_tutorial(print_mock: PrintMock, mod: ModuleType):
+    mod.main()
+    assert print_mock.calls == [
         [
             "Created hero:",
             {
diff --git a/tests/test_tutorial/test_relationship_attributes/test_delete_records_relationship/test_tutorial001_py310.py b/tests/test_tutorial/test_relationship_attributes/test_delete_records_relationship/test_tutorial001_py310.py
deleted file mode 100644 (file)
index 3262d2b..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-from unittest.mock import patch
-
-from sqlmodel import create_engine
-
-from ....conftest import get_testing_print_function, needs_py310
-
-
-@needs_py310
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.relationship_attributes.cascade_delete_relationships import (
-        tutorial001_py310 as mod,
-    )
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == [
-        [
-            "Created hero:",
-            {
-                "name": "Deadpond",
-                "secret_name": "Dive Wilson",
-                "team_id": 1,
-                "id": 1,
-                "age": None,
-            },
-        ],
-        [
-            "Created hero:",
-            {
-                "name": "Rusty-Man",
-                "secret_name": "Tommy Sharp",
-                "team_id": 2,
-                "id": 2,
-                "age": 48,
-            },
-        ],
-        [
-            "Created hero:",
-            {
-                "name": "Spider-Boy",
-                "secret_name": "Pedro Parqueador",
-                "team_id": None,
-                "id": 3,
-                "age": None,
-            },
-        ],
-        [
-            "Updated hero:",
-            {
-                "name": "Spider-Boy",
-                "secret_name": "Pedro Parqueador",
-                "team_id": 2,
-                "id": 3,
-                "age": None,
-            },
-        ],
-        [
-            "Team Wakaland:",
-            {"name": "Wakaland", "id": 3, "headquarters": "Wakaland Capital City"},
-        ],
-        [
-            "Deleted team:",
-            {"name": "Wakaland", "id": 3, "headquarters": "Wakaland Capital City"},
-        ],
-        ["Black Lion not found:", None],
-        ["Princess Sure-E not found:", None],
-    ]
diff --git a/tests/test_tutorial/test_relationship_attributes/test_delete_records_relationship/test_tutorial001_py39.py b/tests/test_tutorial/test_relationship_attributes/test_delete_records_relationship/test_tutorial001_py39.py
deleted file mode 100644 (file)
index 840c354..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-from unittest.mock import patch
-
-from sqlmodel import create_engine
-
-from ....conftest import get_testing_print_function, needs_py39
-
-
-@needs_py39
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.relationship_attributes.cascade_delete_relationships import (
-        tutorial001_py39 as mod,
-    )
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == [
-        [
-            "Created hero:",
-            {
-                "name": "Deadpond",
-                "secret_name": "Dive Wilson",
-                "team_id": 1,
-                "id": 1,
-                "age": None,
-            },
-        ],
-        [
-            "Created hero:",
-            {
-                "name": "Rusty-Man",
-                "secret_name": "Tommy Sharp",
-                "team_id": 2,
-                "id": 2,
-                "age": 48,
-            },
-        ],
-        [
-            "Created hero:",
-            {
-                "name": "Spider-Boy",
-                "secret_name": "Pedro Parqueador",
-                "team_id": None,
-                "id": 3,
-                "age": None,
-            },
-        ],
-        [
-            "Updated hero:",
-            {
-                "name": "Spider-Boy",
-                "secret_name": "Pedro Parqueador",
-                "team_id": 2,
-                "id": 3,
-                "age": None,
-            },
-        ],
-        [
-            "Team Wakaland:",
-            {"name": "Wakaland", "id": 3, "headquarters": "Wakaland Capital City"},
-        ],
-        [
-            "Deleted team:",
-            {"name": "Wakaland", "id": 3, "headquarters": "Wakaland Capital City"},
-        ],
-        ["Black Lion not found:", None],
-        ["Princess Sure-E not found:", None],
-    ]
index a7d7a2636422af0ff2e56ea0894bb9a539ce7f86..cb3907afd7cc654b5661444ae147e1ecf7f5355e 100644 (file)
@@ -1,24 +1,32 @@
-from unittest.mock import patch
+import importlib
+from types import ModuleType
 
+import pytest
 from sqlmodel import create_engine
 
-from ....conftest import get_testing_print_function
+from ....conftest import PrintMock, needs_py39, needs_py310
 
 
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.relationship_attributes.cascade_delete_relationships import (
-        tutorial002 as mod,
+@pytest.fixture(
+    name="mod",
+    params=[
+        "tutorial002",
+        pytest.param("tutorial002_py39", marks=needs_py39),
+        pytest.param("tutorial002_py310", marks=needs_py310),
+    ],
+)
+def get_module(request: pytest.FixtureRequest) -> ModuleType:
+    mod = importlib.import_module(
+        f"docs_src.tutorial.relationship_attributes.cascade_delete_relationships.{request.param}"
     )
-
     mod.sqlite_url = "sqlite://"
     mod.engine = create_engine(mod.sqlite_url)
-    calls = []
+    return mod
 
-    new_print = get_testing_print_function(calls)
 
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == [
+def test_tutorial(print_mock: PrintMock, mod: ModuleType):
+    mod.main()
+    assert print_mock.calls == [
         [
             "Created hero:",
             {
diff --git a/tests/test_tutorial/test_relationship_attributes/test_delete_records_relationship/test_tutorial002_py310.py b/tests/test_tutorial/test_relationship_attributes/test_delete_records_relationship/test_tutorial002_py310.py
deleted file mode 100644 (file)
index 5c755f3..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-from unittest.mock import patch
-
-from sqlmodel import create_engine
-
-from ....conftest import get_testing_print_function, needs_py310
-
-
-@needs_py310
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.relationship_attributes.cascade_delete_relationships import (
-        tutorial002_py310 as mod,
-    )
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == [
-        [
-            "Created hero:",
-            {
-                "age": None,
-                "id": 1,
-                "name": "Deadpond",
-                "secret_name": "Dive Wilson",
-                "team_id": 1,
-            },
-        ],
-        [
-            "Created hero:",
-            {
-                "age": 48,
-                "id": 2,
-                "name": "Rusty-Man",
-                "secret_name": "Tommy Sharp",
-                "team_id": 2,
-            },
-        ],
-        [
-            "Created hero:",
-            {
-                "age": None,
-                "id": 3,
-                "name": "Spider-Boy",
-                "secret_name": "Pedro Parqueador",
-                "team_id": None,
-            },
-        ],
-        [
-            "Updated hero:",
-            {
-                "age": None,
-                "id": 3,
-                "name": "Spider-Boy",
-                "secret_name": "Pedro Parqueador",
-                "team_id": 2,
-            },
-        ],
-        [
-            "Team Wakaland:",
-            {"headquarters": "Wakaland Capital City", "id": 3, "name": "Wakaland"},
-        ],
-        [
-            "Deleted team:",
-            {"headquarters": "Wakaland Capital City", "id": 3, "name": "Wakaland"},
-        ],
-        [
-            "Black Lion has no team:",
-            {
-                "age": 35,
-                "id": 4,
-                "name": "Black Lion",
-                "secret_name": "Trevor Challa",
-                "team_id": None,
-            },
-        ],
-        [
-            "Princess Sure-E has no team:",
-            {
-                "age": None,
-                "id": 5,
-                "name": "Princess Sure-E",
-                "secret_name": "Sure-E",
-                "team_id": None,
-            },
-        ],
-    ]
diff --git a/tests/test_tutorial/test_relationship_attributes/test_delete_records_relationship/test_tutorial002_py39.py b/tests/test_tutorial/test_relationship_attributes/test_delete_records_relationship/test_tutorial002_py39.py
deleted file mode 100644 (file)
index 9937f6d..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-from unittest.mock import patch
-
-from sqlmodel import create_engine
-
-from ....conftest import get_testing_print_function, needs_py39
-
-
-@needs_py39
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.relationship_attributes.cascade_delete_relationships import (
-        tutorial002_py39 as mod,
-    )
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == [
-        [
-            "Created hero:",
-            {
-                "age": None,
-                "id": 1,
-                "name": "Deadpond",
-                "secret_name": "Dive Wilson",
-                "team_id": 1,
-            },
-        ],
-        [
-            "Created hero:",
-            {
-                "age": 48,
-                "id": 2,
-                "name": "Rusty-Man",
-                "secret_name": "Tommy Sharp",
-                "team_id": 2,
-            },
-        ],
-        [
-            "Created hero:",
-            {
-                "age": None,
-                "id": 3,
-                "name": "Spider-Boy",
-                "secret_name": "Pedro Parqueador",
-                "team_id": None,
-            },
-        ],
-        [
-            "Updated hero:",
-            {
-                "age": None,
-                "id": 3,
-                "name": "Spider-Boy",
-                "secret_name": "Pedro Parqueador",
-                "team_id": 2,
-            },
-        ],
-        [
-            "Team Wakaland:",
-            {"headquarters": "Wakaland Capital City", "id": 3, "name": "Wakaland"},
-        ],
-        [
-            "Deleted team:",
-            {"headquarters": "Wakaland Capital City", "id": 3, "name": "Wakaland"},
-        ],
-        [
-            "Black Lion has no team:",
-            {
-                "age": 35,
-                "id": 4,
-                "name": "Black Lion",
-                "secret_name": "Trevor Challa",
-                "team_id": None,
-            },
-        ],
-        [
-            "Princess Sure-E has no team:",
-            {
-                "age": None,
-                "id": 5,
-                "name": "Princess Sure-E",
-                "secret_name": "Sure-E",
-                "team_id": None,
-            },
-        ],
-    ]
index a3d3bc0f0592c0dbc6f81a3a75d162dd9d424c3d..e063630f9638a2207d65c59210fc034840d72625 100644 (file)
@@ -1,24 +1,32 @@
-from unittest.mock import patch
+import importlib
+from types import ModuleType
 
+import pytest
 from sqlmodel import create_engine
 
-from tests.conftest import get_testing_print_function
+from ....conftest import PrintMock, needs_py39, needs_py310
 
 
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.relationship_attributes.cascade_delete_relationships import (
-        tutorial003 as mod,
+@pytest.fixture(
+    name="mod",
+    params=[
+        "tutorial003",
+        pytest.param("tutorial003_py39", marks=needs_py39),
+        pytest.param("tutorial003_py310", marks=needs_py310),
+    ],
+)
+def get_module(request: pytest.FixtureRequest) -> ModuleType:
+    mod = importlib.import_module(
+        f"docs_src.tutorial.relationship_attributes.cascade_delete_relationships.{request.param}"
     )
-
     mod.sqlite_url = "sqlite://"
     mod.engine = create_engine(mod.sqlite_url)
-    calls = []
+    return mod
 
-    new_print = get_testing_print_function(calls)
 
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == [
+def test_tutorial(print_mock: PrintMock, mod: ModuleType):
+    mod.main()
+    assert print_mock.calls == [
         [
             "Created hero:",
             {
diff --git a/tests/test_tutorial/test_relationship_attributes/test_delete_records_relationship/test_tutorial003_py310.py b/tests/test_tutorial/test_relationship_attributes/test_delete_records_relationship/test_tutorial003_py310.py
deleted file mode 100644 (file)
index f9975f2..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-from unittest.mock import patch
-
-from sqlmodel import create_engine
-
-from ....conftest import get_testing_print_function, needs_py310
-
-
-@needs_py310
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.relationship_attributes.cascade_delete_relationships import (
-        tutorial003_py310 as mod,
-    )
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == [
-        [
-            "Created hero:",
-            {
-                "age": None,
-                "id": 1,
-                "name": "Deadpond",
-                "secret_name": "Dive Wilson",
-                "team_id": 1,
-            },
-        ],
-        [
-            "Created hero:",
-            {
-                "age": 48,
-                "id": 2,
-                "name": "Rusty-Man",
-                "secret_name": "Tommy Sharp",
-                "team_id": 2,
-            },
-        ],
-        [
-            "Created hero:",
-            {
-                "age": None,
-                "id": 3,
-                "name": "Spider-Boy",
-                "secret_name": "Pedro Parqueador",
-                "team_id": None,
-            },
-        ],
-        [
-            "Updated hero:",
-            {
-                "age": None,
-                "id": 3,
-                "name": "Spider-Boy",
-                "secret_name": "Pedro Parqueador",
-                "team_id": 2,
-            },
-        ],
-        [
-            "Team Wakaland:",
-            {"id": 3, "headquarters": "Wakaland Capital City", "name": "Wakaland"},
-        ],
-        [
-            "Deleted team:",
-            {"id": 3, "headquarters": "Wakaland Capital City", "name": "Wakaland"},
-        ],
-        [
-            "Black Lion has no team:",
-            {
-                "age": 35,
-                "id": 4,
-                "name": "Black Lion",
-                "secret_name": "Trevor Challa",
-                "team_id": None,
-            },
-        ],
-        [
-            "Princess Sure-E has no team:",
-            {
-                "age": None,
-                "id": 5,
-                "name": "Princess Sure-E",
-                "secret_name": "Sure-E",
-                "team_id": None,
-            },
-        ],
-    ]
diff --git a/tests/test_tutorial/test_relationship_attributes/test_delete_records_relationship/test_tutorial003_py39.py b/tests/test_tutorial/test_relationship_attributes/test_delete_records_relationship/test_tutorial003_py39.py
deleted file mode 100644 (file)
index b68bc62..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-from unittest.mock import patch
-
-from sqlmodel import create_engine
-
-from ....conftest import get_testing_print_function, needs_py39
-
-
-@needs_py39
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.relationship_attributes.cascade_delete_relationships import (
-        tutorial003_py39 as mod,
-    )
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == [
-        [
-            "Created hero:",
-            {
-                "age": None,
-                "id": 1,
-                "name": "Deadpond",
-                "secret_name": "Dive Wilson",
-                "team_id": 1,
-            },
-        ],
-        [
-            "Created hero:",
-            {
-                "age": 48,
-                "id": 2,
-                "name": "Rusty-Man",
-                "secret_name": "Tommy Sharp",
-                "team_id": 2,
-            },
-        ],
-        [
-            "Created hero:",
-            {
-                "age": None,
-                "id": 3,
-                "name": "Spider-Boy",
-                "secret_name": "Pedro Parqueador",
-                "team_id": None,
-            },
-        ],
-        [
-            "Updated hero:",
-            {
-                "age": None,
-                "id": 3,
-                "name": "Spider-Boy",
-                "secret_name": "Pedro Parqueador",
-                "team_id": 2,
-            },
-        ],
-        [
-            "Team Wakaland:",
-            {"id": 3, "headquarters": "Wakaland Capital City", "name": "Wakaland"},
-        ],
-        [
-            "Deleted team:",
-            {"id": 3, "headquarters": "Wakaland Capital City", "name": "Wakaland"},
-        ],
-        [
-            "Black Lion has no team:",
-            {
-                "age": 35,
-                "id": 4,
-                "name": "Black Lion",
-                "secret_name": "Trevor Challa",
-                "team_id": None,
-            },
-        ],
-        [
-            "Princess Sure-E has no team:",
-            {
-                "age": None,
-                "id": 5,
-                "name": "Princess Sure-E",
-                "secret_name": "Sure-E",
-                "team_id": None,
-            },
-        ],
-    ]
index d5da12e6a521f4f7782f58884375b68d98340ce3..8b6c101fb8c9df7ea3af275ab0dead6577ea740f 100644 (file)
@@ -1,36 +1,41 @@
-from unittest.mock import patch
+import importlib
+from types import ModuleType
 
 import pytest
 from sqlalchemy.exc import IntegrityError
 from sqlmodel import Session, create_engine, select
 
-from tests.conftest import get_testing_print_function
+from ....conftest import PrintMock, needs_py39, needs_py310
 
 
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.relationship_attributes.cascade_delete_relationships import (
-        tutorial004 as mod,
+@pytest.fixture(
+    name="mod",
+    params=[
+        "tutorial004",
+        pytest.param("tutorial004_py39", marks=needs_py39),
+        pytest.param("tutorial004_py310", marks=needs_py310),
+    ],
+)
+def get_module(request: pytest.FixtureRequest) -> ModuleType:
+    mod = importlib.import_module(
+        f"docs_src.tutorial.relationship_attributes.cascade_delete_relationships.{request.param}"
     )
-
     mod.sqlite_url = "sqlite://"
     mod.engine = create_engine(mod.sqlite_url)
-    calls = []
+    return mod
 
-    new_print = get_testing_print_function(calls)
 
-    with patch("builtins.print", new=new_print):
-        mod.create_db_and_tables()
-        mod.create_heroes()
-        mod.select_deleted_heroes()
-        with Session(mod.engine) as session:
-            team = session.exec(
-                select(mod.Team).where(mod.Team.name == "Wakaland")
-            ).one()
-            team.heroes.clear()
-            session.add(team)
-            session.commit()
-        mod.delete_team()
-    assert calls == [
+def test_tutorial(print_mock: PrintMock, mod: ModuleType):
+    mod.create_db_and_tables()
+    mod.create_heroes()
+    mod.select_deleted_heroes()
+    with Session(mod.engine) as session:
+        team = session.exec(select(mod.Team).where(mod.Team.name == "Wakaland")).one()
+        team.heroes.clear()
+        session.add(team)
+        session.commit()
+    mod.delete_team()
+    assert print_mock.calls == [
         [
             "Created hero:",
             {
diff --git a/tests/test_tutorial/test_relationship_attributes/test_delete_records_relationship/test_tutorial004_py310.py b/tests/test_tutorial/test_relationship_attributes/test_delete_records_relationship/test_tutorial004_py310.py
deleted file mode 100644 (file)
index 3ce3770..0000000
+++ /dev/null
@@ -1,107 +0,0 @@
-from unittest.mock import patch
-
-import pytest
-from sqlalchemy.exc import IntegrityError
-from sqlmodel import Session, create_engine, select
-
-from tests.conftest import get_testing_print_function, needs_py310
-
-
-@needs_py310
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.relationship_attributes.cascade_delete_relationships import (
-        tutorial004_py310 as mod,
-    )
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.create_db_and_tables()
-        mod.create_heroes()
-        mod.select_deleted_heroes()
-        with Session(mod.engine) as session:
-            team = session.exec(
-                select(mod.Team).where(mod.Team.name == "Wakaland")
-            ).one()
-            team.heroes.clear()
-            session.add(team)
-            session.commit()
-        mod.delete_team()
-    assert calls == [
-        [
-            "Created hero:",
-            {
-                "age": None,
-                "id": 1,
-                "name": "Deadpond",
-                "secret_name": "Dive Wilson",
-                "team_id": 1,
-            },
-        ],
-        [
-            "Created hero:",
-            {
-                "age": 48,
-                "id": 2,
-                "name": "Rusty-Man",
-                "secret_name": "Tommy Sharp",
-                "team_id": 2,
-            },
-        ],
-        [
-            "Created hero:",
-            {
-                "age": None,
-                "id": 3,
-                "name": "Spider-Boy",
-                "secret_name": "Pedro Parqueador",
-                "team_id": None,
-            },
-        ],
-        [
-            "Updated hero:",
-            {
-                "age": None,
-                "id": 3,
-                "name": "Spider-Boy",
-                "secret_name": "Pedro Parqueador",
-                "team_id": 2,
-            },
-        ],
-        [
-            "Team Wakaland:",
-            {"headquarters": "Wakaland Capital City", "id": 3, "name": "Wakaland"},
-        ],
-        [
-            "Black Lion has no team:",
-            {
-                "age": 35,
-                "id": 4,
-                "name": "Black Lion",
-                "secret_name": "Trevor Challa",
-                "team_id": 3,
-            },
-        ],
-        [
-            "Princess Sure-E has no team:",
-            {
-                "age": None,
-                "id": 5,
-                "name": "Princess Sure-E",
-                "secret_name": "Sure-E",
-                "team_id": 3,
-            },
-        ],
-        [
-            "Deleted team:",
-            {"headquarters": "Wakaland Capital City", "id": 3, "name": "Wakaland"},
-        ],
-    ]
-
-    with pytest.raises(IntegrityError) as exc:
-        mod.main()
-    assert "FOREIGN KEY constraint failed" in str(exc.value)
diff --git a/tests/test_tutorial/test_relationship_attributes/test_delete_records_relationship/test_tutorial004_py39.py b/tests/test_tutorial/test_relationship_attributes/test_delete_records_relationship/test_tutorial004_py39.py
deleted file mode 100644 (file)
index 1c51fc0..0000000
+++ /dev/null
@@ -1,107 +0,0 @@
-from unittest.mock import patch
-
-import pytest
-from sqlalchemy.exc import IntegrityError
-from sqlmodel import Session, create_engine, select
-
-from tests.conftest import get_testing_print_function, needs_py39
-
-
-@needs_py39
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.relationship_attributes.cascade_delete_relationships import (
-        tutorial004_py39 as mod,
-    )
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.create_db_and_tables()
-        mod.create_heroes()
-        mod.select_deleted_heroes()
-        with Session(mod.engine) as session:
-            team = session.exec(
-                select(mod.Team).where(mod.Team.name == "Wakaland")
-            ).one()
-            team.heroes.clear()
-            session.add(team)
-            session.commit()
-        mod.delete_team()
-    assert calls == [
-        [
-            "Created hero:",
-            {
-                "age": None,
-                "id": 1,
-                "name": "Deadpond",
-                "secret_name": "Dive Wilson",
-                "team_id": 1,
-            },
-        ],
-        [
-            "Created hero:",
-            {
-                "age": 48,
-                "id": 2,
-                "name": "Rusty-Man",
-                "secret_name": "Tommy Sharp",
-                "team_id": 2,
-            },
-        ],
-        [
-            "Created hero:",
-            {
-                "age": None,
-                "id": 3,
-                "name": "Spider-Boy",
-                "secret_name": "Pedro Parqueador",
-                "team_id": None,
-            },
-        ],
-        [
-            "Updated hero:",
-            {
-                "age": None,
-                "id": 3,
-                "name": "Spider-Boy",
-                "secret_name": "Pedro Parqueador",
-                "team_id": 2,
-            },
-        ],
-        [
-            "Team Wakaland:",
-            {"headquarters": "Wakaland Capital City", "id": 3, "name": "Wakaland"},
-        ],
-        [
-            "Black Lion has no team:",
-            {
-                "age": 35,
-                "id": 4,
-                "name": "Black Lion",
-                "secret_name": "Trevor Challa",
-                "team_id": 3,
-            },
-        ],
-        [
-            "Princess Sure-E has no team:",
-            {
-                "age": None,
-                "id": 5,
-                "name": "Princess Sure-E",
-                "secret_name": "Sure-E",
-                "team_id": 3,
-            },
-        ],
-        [
-            "Deleted team:",
-            {"headquarters": "Wakaland Capital City", "id": 3, "name": "Wakaland"},
-        ],
-    ]
-
-    with pytest.raises(IntegrityError) as exc:
-        mod.main()
-    assert "FOREIGN KEY constraint failed" in str(exc.value)
index a6a00608a9091cf68afca18dc0bed78a4e205150..273007770ba3645de18086688ccfd188a1ea83ec 100644 (file)
@@ -1,24 +1,32 @@
-from unittest.mock import patch
+import importlib
+from types import ModuleType
 
+import pytest
 from sqlmodel import create_engine
 
-from tests.conftest import get_testing_print_function
+from ....conftest import PrintMock, needs_py39, needs_py310
 
 
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.relationship_attributes.cascade_delete_relationships import (
-        tutorial005 as mod,
+@pytest.fixture(
+    name="mod",
+    params=[
+        "tutorial005",
+        pytest.param("tutorial005_py39", marks=needs_py39),
+        pytest.param("tutorial005_py310", marks=needs_py310),
+    ],
+)
+def get_module(request: pytest.FixtureRequest) -> ModuleType:
+    mod = importlib.import_module(
+        f"docs_src.tutorial.relationship_attributes.cascade_delete_relationships.{request.param}"
     )
-
     mod.sqlite_url = "sqlite://"
     mod.engine = create_engine(mod.sqlite_url)
-    calls = []
+    return mod
 
-    new_print = get_testing_print_function(calls)
 
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == [
+def test_tutorial(print_mock: PrintMock, mod: ModuleType):
+    mod.main()
+    assert print_mock.calls == [
         [
             "Created hero:",
             {
diff --git a/tests/test_tutorial/test_relationship_attributes/test_delete_records_relationship/test_tutorial005_py310.py b/tests/test_tutorial/test_relationship_attributes/test_delete_records_relationship/test_tutorial005_py310.py
deleted file mode 100644 (file)
index 54ad1b7..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-from unittest.mock import patch
-
-from sqlmodel import create_engine
-
-from tests.conftest import get_testing_print_function, needs_py310
-
-
-@needs_py310
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.relationship_attributes.cascade_delete_relationships import (
-        tutorial005_py310 as mod,
-    )
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == [
-        [
-            "Created hero:",
-            {
-                "name": "Deadpond",
-                "secret_name": "Dive Wilson",
-                "team_id": 1,
-                "id": 1,
-                "age": None,
-            },
-        ],
-        [
-            "Created hero:",
-            {
-                "name": "Rusty-Man",
-                "secret_name": "Tommy Sharp",
-                "team_id": 2,
-                "id": 2,
-                "age": 48,
-            },
-        ],
-        [
-            "Created hero:",
-            {
-                "name": "Spider-Boy",
-                "secret_name": "Pedro Parqueador",
-                "team_id": None,
-                "id": 3,
-                "age": None,
-            },
-        ],
-        [
-            "Updated hero:",
-            {
-                "name": "Spider-Boy",
-                "secret_name": "Pedro Parqueador",
-                "team_id": 2,
-                "id": 3,
-                "age": None,
-            },
-        ],
-        [
-            "Team Wakaland:",
-            {"id": 3, "headquarters": "Wakaland Capital City", "name": "Wakaland"},
-        ],
-        [
-            "Team with removed heroes:",
-            {"id": 3, "headquarters": "Wakaland Capital City", "name": "Wakaland"},
-        ],
-        [
-            "Deleted team:",
-            {"id": 3, "headquarters": "Wakaland Capital City", "name": "Wakaland"},
-        ],
-        [
-            "Black Lion has no team:",
-            {
-                "name": "Black Lion",
-                "secret_name": "Trevor Challa",
-                "team_id": None,
-                "id": 4,
-                "age": 35,
-            },
-        ],
-        [
-            "Princess Sure-E has no team:",
-            {
-                "name": "Princess Sure-E",
-                "secret_name": "Sure-E",
-                "team_id": None,
-                "id": 5,
-                "age": None,
-            },
-        ],
-    ]
diff --git a/tests/test_tutorial/test_relationship_attributes/test_delete_records_relationship/test_tutorial005_py39.py b/tests/test_tutorial/test_relationship_attributes/test_delete_records_relationship/test_tutorial005_py39.py
deleted file mode 100644 (file)
index 8151ab9..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-from unittest.mock import patch
-
-from sqlmodel import create_engine
-
-from tests.conftest import get_testing_print_function, needs_py39
-
-
-@needs_py39
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.relationship_attributes.cascade_delete_relationships import (
-        tutorial005_py39 as mod,
-    )
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == [
-        [
-            "Created hero:",
-            {
-                "name": "Deadpond",
-                "secret_name": "Dive Wilson",
-                "team_id": 1,
-                "id": 1,
-                "age": None,
-            },
-        ],
-        [
-            "Created hero:",
-            {
-                "name": "Rusty-Man",
-                "secret_name": "Tommy Sharp",
-                "team_id": 2,
-                "id": 2,
-                "age": 48,
-            },
-        ],
-        [
-            "Created hero:",
-            {
-                "name": "Spider-Boy",
-                "secret_name": "Pedro Parqueador",
-                "team_id": None,
-                "id": 3,
-                "age": None,
-            },
-        ],
-        [
-            "Updated hero:",
-            {
-                "name": "Spider-Boy",
-                "secret_name": "Pedro Parqueador",
-                "team_id": 2,
-                "id": 3,
-                "age": None,
-            },
-        ],
-        [
-            "Team Wakaland:",
-            {"id": 3, "headquarters": "Wakaland Capital City", "name": "Wakaland"},
-        ],
-        [
-            "Team with removed heroes:",
-            {"id": 3, "headquarters": "Wakaland Capital City", "name": "Wakaland"},
-        ],
-        [
-            "Deleted team:",
-            {"id": 3, "headquarters": "Wakaland Capital City", "name": "Wakaland"},
-        ],
-        [
-            "Black Lion has no team:",
-            {
-                "name": "Black Lion",
-                "secret_name": "Trevor Challa",
-                "team_id": None,
-                "id": 4,
-                "age": 35,
-            },
-        ],
-        [
-            "Princess Sure-E has no team:",
-            {
-                "name": "Princess Sure-E",
-                "secret_name": "Sure-E",
-                "team_id": None,
-                "id": 5,
-                "age": None,
-            },
-        ],
-    ]
index 9fc70012d8c0c638d48aa0af7e31b8c0b4c8f5b3..1b2caaa9c52feb65e2aa0de6b2ebad3b70e6d308 100644 (file)
@@ -1,8 +1,28 @@
-from unittest.mock import patch
+import importlib
+from types import ModuleType
 
+import pytest
 from sqlmodel import create_engine
 
-from ....conftest import get_testing_print_function
+from ....conftest import PrintMock, needs_py39, needs_py310
+
+
+@pytest.fixture(
+    name="mod",
+    params=[
+        "tutorial001",
+        pytest.param("tutorial001_py39", marks=needs_py39),
+        pytest.param("tutorial001_py310", marks=needs_py310),
+    ],
+)
+def get_module(request: pytest.FixtureRequest) -> ModuleType:
+    mod = importlib.import_module(
+        f"docs_src.tutorial.relationship_attributes.read_relationships.{request.param}"
+    )
+    mod.sqlite_url = "sqlite://"
+    mod.engine = create_engine(mod.sqlite_url)
+    return mod
+
 
 expected_calls = [
     [
@@ -90,17 +110,6 @@ expected_calls = [
 ]
 
 
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.relationship_attributes.read_relationships import (
-        tutorial001 as mod,
-    )
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == expected_calls
+def test_tutorial(print_mock: PrintMock, mod: ModuleType):
+    mod.main()
+    assert print_mock.calls == expected_calls
diff --git a/tests/test_tutorial/test_relationship_attributes/test_read_relationships/test_tutorial001_py310.py b/tests/test_tutorial/test_relationship_attributes/test_read_relationships/test_tutorial001_py310.py
deleted file mode 100644 (file)
index 9a4e3cc..0000000
+++ /dev/null
@@ -1,107 +0,0 @@
-from unittest.mock import patch
-
-from sqlmodel import create_engine
-
-from ....conftest import get_testing_print_function, needs_py310
-
-expected_calls = [
-    [
-        "Created hero:",
-        {
-            "age": None,
-            "id": 1,
-            "secret_name": "Dive Wilson",
-            "team_id": 1,
-            "name": "Deadpond",
-        },
-    ],
-    [
-        "Created hero:",
-        {
-            "age": 48,
-            "id": 2,
-            "secret_name": "Tommy Sharp",
-            "team_id": 2,
-            "name": "Rusty-Man",
-        },
-    ],
-    [
-        "Created hero:",
-        {
-            "age": None,
-            "id": 3,
-            "secret_name": "Pedro Parqueador",
-            "team_id": None,
-            "name": "Spider-Boy",
-        },
-    ],
-    [
-        "Updated hero:",
-        {
-            "age": None,
-            "id": 3,
-            "secret_name": "Pedro Parqueador",
-            "team_id": 2,
-            "name": "Spider-Boy",
-        },
-    ],
-    [
-        "Team Wakaland:",
-        {"headquarters": "Wakaland Capital City", "id": 3, "name": "Wakaland"},
-    ],
-    [
-        "Preventers new hero:",
-        {
-            "age": 32,
-            "id": 6,
-            "secret_name": "Natalia Roman-on",
-            "team_id": 2,
-            "name": "Tarantula",
-        },
-    ],
-    [
-        "Preventers new hero:",
-        {
-            "age": 36,
-            "id": 7,
-            "secret_name": "Steve Weird",
-            "team_id": 2,
-            "name": "Dr. Weird",
-        },
-    ],
-    [
-        "Preventers new hero:",
-        {
-            "age": 93,
-            "id": 8,
-            "secret_name": "Esteban Rogelios",
-            "team_id": 2,
-            "name": "Captain North America",
-        },
-    ],
-    [
-        "Spider-Boy's team:",
-        {"headquarters": "Sharp Tower", "id": 2, "name": "Preventers"},
-    ],
-    [
-        "Spider-Boy's team again:",
-        {"headquarters": "Sharp Tower", "id": 2, "name": "Preventers"},
-    ],
-]
-
-
-@needs_py310
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.relationship_attributes.read_relationships import (
-        tutorial001_py310 as mod,
-    )
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == expected_calls
diff --git a/tests/test_tutorial/test_relationship_attributes/test_read_relationships/test_tutorial001_py39.py b/tests/test_tutorial/test_relationship_attributes/test_read_relationships/test_tutorial001_py39.py
deleted file mode 100644 (file)
index 6b23980..0000000
+++ /dev/null
@@ -1,107 +0,0 @@
-from unittest.mock import patch
-
-from sqlmodel import create_engine
-
-from ....conftest import get_testing_print_function, needs_py39
-
-expected_calls = [
-    [
-        "Created hero:",
-        {
-            "age": None,
-            "id": 1,
-            "secret_name": "Dive Wilson",
-            "team_id": 1,
-            "name": "Deadpond",
-        },
-    ],
-    [
-        "Created hero:",
-        {
-            "age": 48,
-            "id": 2,
-            "secret_name": "Tommy Sharp",
-            "team_id": 2,
-            "name": "Rusty-Man",
-        },
-    ],
-    [
-        "Created hero:",
-        {
-            "age": None,
-            "id": 3,
-            "secret_name": "Pedro Parqueador",
-            "team_id": None,
-            "name": "Spider-Boy",
-        },
-    ],
-    [
-        "Updated hero:",
-        {
-            "age": None,
-            "id": 3,
-            "secret_name": "Pedro Parqueador",
-            "team_id": 2,
-            "name": "Spider-Boy",
-        },
-    ],
-    [
-        "Team Wakaland:",
-        {"headquarters": "Wakaland Capital City", "id": 3, "name": "Wakaland"},
-    ],
-    [
-        "Preventers new hero:",
-        {
-            "age": 32,
-            "id": 6,
-            "secret_name": "Natalia Roman-on",
-            "team_id": 2,
-            "name": "Tarantula",
-        },
-    ],
-    [
-        "Preventers new hero:",
-        {
-            "age": 36,
-            "id": 7,
-            "secret_name": "Steve Weird",
-            "team_id": 2,
-            "name": "Dr. Weird",
-        },
-    ],
-    [
-        "Preventers new hero:",
-        {
-            "age": 93,
-            "id": 8,
-            "secret_name": "Esteban Rogelios",
-            "team_id": 2,
-            "name": "Captain North America",
-        },
-    ],
-    [
-        "Spider-Boy's team:",
-        {"headquarters": "Sharp Tower", "id": 2, "name": "Preventers"},
-    ],
-    [
-        "Spider-Boy's team again:",
-        {"headquarters": "Sharp Tower", "id": 2, "name": "Preventers"},
-    ],
-]
-
-
-@needs_py39
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.relationship_attributes.read_relationships import (
-        tutorial001_py39 as mod,
-    )
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == expected_calls
index d827b1ff154205abf7c6ce868945a888841458be..68ee2cc1d8e5cb1982f3bfa2414f5e13bcf06921 100644 (file)
@@ -1,8 +1,28 @@
-from unittest.mock import patch
+import importlib
+from types import ModuleType
 
+import pytest
 from sqlmodel import create_engine
 
-from ....conftest import get_testing_print_function
+from ....conftest import PrintMock, needs_py39, needs_py310
+
+
+@pytest.fixture(
+    name="mod",
+    params=[
+        "tutorial002",
+        pytest.param("tutorial002_py39", marks=needs_py39),
+        pytest.param("tutorial002_py310", marks=needs_py310),
+    ],
+)
+def get_module(request: pytest.FixtureRequest) -> ModuleType:
+    mod = importlib.import_module(
+        f"docs_src.tutorial.relationship_attributes.read_relationships.{request.param}"
+    )
+    mod.sqlite_url = "sqlite://"
+    mod.engine = create_engine(mod.sqlite_url)
+    return mod
+
 
 expected_calls = [
     [
@@ -132,17 +152,6 @@ expected_calls = [
 ]
 
 
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.relationship_attributes.read_relationships import (
-        tutorial002 as mod,
-    )
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == expected_calls
+def test_tutorial(print_mock: PrintMock, mod: ModuleType):
+    mod.main()
+    assert print_mock.calls == expected_calls
diff --git a/tests/test_tutorial/test_relationship_attributes/test_read_relationships/test_tutorial002_py310.py b/tests/test_tutorial/test_relationship_attributes/test_read_relationships/test_tutorial002_py310.py
deleted file mode 100644 (file)
index 0cc9ae3..0000000
+++ /dev/null
@@ -1,149 +0,0 @@
-from unittest.mock import patch
-
-from sqlmodel import create_engine
-
-from ....conftest import get_testing_print_function, needs_py310
-
-expected_calls = [
-    [
-        "Created hero:",
-        {
-            "age": None,
-            "id": 1,
-            "secret_name": "Dive Wilson",
-            "team_id": 1,
-            "name": "Deadpond",
-        },
-    ],
-    [
-        "Created hero:",
-        {
-            "age": 48,
-            "id": 2,
-            "secret_name": "Tommy Sharp",
-            "team_id": 2,
-            "name": "Rusty-Man",
-        },
-    ],
-    [
-        "Created hero:",
-        {
-            "age": None,
-            "id": 3,
-            "secret_name": "Pedro Parqueador",
-            "team_id": None,
-            "name": "Spider-Boy",
-        },
-    ],
-    [
-        "Updated hero:",
-        {
-            "age": None,
-            "id": 3,
-            "secret_name": "Pedro Parqueador",
-            "team_id": 2,
-            "name": "Spider-Boy",
-        },
-    ],
-    [
-        "Team Wakaland:",
-        {"id": 3, "name": "Wakaland", "headquarters": "Wakaland Capital City"},
-    ],
-    [
-        "Preventers new hero:",
-        {
-            "age": 32,
-            "id": 6,
-            "secret_name": "Natalia Roman-on",
-            "team_id": 2,
-            "name": "Tarantula",
-        },
-    ],
-    [
-        "Preventers new hero:",
-        {
-            "age": 36,
-            "id": 7,
-            "secret_name": "Steve Weird",
-            "team_id": 2,
-            "name": "Dr. Weird",
-        },
-    ],
-    [
-        "Preventers new hero:",
-        {
-            "age": 93,
-            "id": 8,
-            "secret_name": "Esteban Rogelios",
-            "team_id": 2,
-            "name": "Captain North America",
-        },
-    ],
-    [
-        "Preventers heroes:",
-        [
-            {
-                "age": 48,
-                "id": 2,
-                "secret_name": "Tommy Sharp",
-                "team_id": 2,
-                "name": "Rusty-Man",
-            },
-            {
-                "age": None,
-                "id": 3,
-                "secret_name": "Pedro Parqueador",
-                "team_id": 2,
-                "name": "Spider-Boy",
-            },
-            {
-                "age": 32,
-                "id": 6,
-                "secret_name": "Natalia Roman-on",
-                "team_id": 2,
-                "name": "Tarantula",
-            },
-            {
-                "age": 36,
-                "id": 7,
-                "secret_name": "Steve Weird",
-                "team_id": 2,
-                "name": "Dr. Weird",
-            },
-            {
-                "age": 93,
-                "id": 8,
-                "secret_name": "Esteban Rogelios",
-                "team_id": 2,
-                "name": "Captain North America",
-            },
-        ],
-    ],
-    [
-        "Spider-Boy without team:",
-        {
-            "age": None,
-            "id": 3,
-            "secret_name": "Pedro Parqueador",
-            "team_id": None,
-            "name": "Spider-Boy",
-        },
-    ],
-]
-
-
-@needs_py310
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.relationship_attributes.read_relationships import (
-        tutorial002_py310 as mod,
-    )
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == expected_calls
diff --git a/tests/test_tutorial/test_relationship_attributes/test_read_relationships/test_tutorial002_py39.py b/tests/test_tutorial/test_relationship_attributes/test_read_relationships/test_tutorial002_py39.py
deleted file mode 100644 (file)
index 891f4ca..0000000
+++ /dev/null
@@ -1,149 +0,0 @@
-from unittest.mock import patch
-
-from sqlmodel import create_engine
-
-from ....conftest import get_testing_print_function, needs_py39
-
-expected_calls = [
-    [
-        "Created hero:",
-        {
-            "age": None,
-            "id": 1,
-            "secret_name": "Dive Wilson",
-            "team_id": 1,
-            "name": "Deadpond",
-        },
-    ],
-    [
-        "Created hero:",
-        {
-            "age": 48,
-            "id": 2,
-            "secret_name": "Tommy Sharp",
-            "team_id": 2,
-            "name": "Rusty-Man",
-        },
-    ],
-    [
-        "Created hero:",
-        {
-            "age": None,
-            "id": 3,
-            "secret_name": "Pedro Parqueador",
-            "team_id": None,
-            "name": "Spider-Boy",
-        },
-    ],
-    [
-        "Updated hero:",
-        {
-            "age": None,
-            "id": 3,
-            "secret_name": "Pedro Parqueador",
-            "team_id": 2,
-            "name": "Spider-Boy",
-        },
-    ],
-    [
-        "Team Wakaland:",
-        {"id": 3, "name": "Wakaland", "headquarters": "Wakaland Capital City"},
-    ],
-    [
-        "Preventers new hero:",
-        {
-            "age": 32,
-            "id": 6,
-            "secret_name": "Natalia Roman-on",
-            "team_id": 2,
-            "name": "Tarantula",
-        },
-    ],
-    [
-        "Preventers new hero:",
-        {
-            "age": 36,
-            "id": 7,
-            "secret_name": "Steve Weird",
-            "team_id": 2,
-            "name": "Dr. Weird",
-        },
-    ],
-    [
-        "Preventers new hero:",
-        {
-            "age": 93,
-            "id": 8,
-            "secret_name": "Esteban Rogelios",
-            "team_id": 2,
-            "name": "Captain North America",
-        },
-    ],
-    [
-        "Preventers heroes:",
-        [
-            {
-                "age": 48,
-                "id": 2,
-                "secret_name": "Tommy Sharp",
-                "team_id": 2,
-                "name": "Rusty-Man",
-            },
-            {
-                "age": None,
-                "id": 3,
-                "secret_name": "Pedro Parqueador",
-                "team_id": 2,
-                "name": "Spider-Boy",
-            },
-            {
-                "age": 32,
-                "id": 6,
-                "secret_name": "Natalia Roman-on",
-                "team_id": 2,
-                "name": "Tarantula",
-            },
-            {
-                "age": 36,
-                "id": 7,
-                "secret_name": "Steve Weird",
-                "team_id": 2,
-                "name": "Dr. Weird",
-            },
-            {
-                "age": 93,
-                "id": 8,
-                "secret_name": "Esteban Rogelios",
-                "team_id": 2,
-                "name": "Captain North America",
-            },
-        ],
-    ],
-    [
-        "Spider-Boy without team:",
-        {
-            "age": None,
-            "id": 3,
-            "secret_name": "Pedro Parqueador",
-            "team_id": None,
-            "name": "Spider-Boy",
-        },
-    ],
-]
-
-
-@needs_py39
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.relationship_attributes.read_relationships import (
-        tutorial002_py39 as mod,
-    )
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == expected_calls
diff --git a/tests/test_tutorial/test_select/test_tutorial001_py310_tutorial002_py310.py b/tests/test_tutorial/test_select/test_tutorial001_py310_tutorial002_py310.py
deleted file mode 100644 (file)
index 7521b6b..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-from typing import Any, Dict, List, Union
-from unittest.mock import patch
-
-from sqlmodel import create_engine
-
-from ...conftest import get_testing_print_function, needs_py310
-
-
-def check_calls(calls: List[List[Union[str, Dict[str, Any]]]]):
-    assert calls[0][0] == {
-        "name": "Deadpond",
-        "secret_name": "Dive Wilson",
-        "age": None,
-        "id": 1,
-    }
-    assert calls[1][0] == {
-        "name": "Spider-Boy",
-        "secret_name": "Pedro Parqueador",
-        "age": None,
-        "id": 2,
-    }
-    assert calls[2][0] == {
-        "name": "Rusty-Man",
-        "secret_name": "Tommy Sharp",
-        "age": 48,
-        "id": 3,
-    }
-
-
-@needs_py310
-def test_tutorial_001(clear_sqlmodel):
-    from docs_src.tutorial.select import tutorial001_py310 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    check_calls(calls)
-
-
-@needs_py310
-def test_tutorial_002(clear_sqlmodel):
-    from docs_src.tutorial.select import tutorial002_py310 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    check_calls(calls)
index fc8d546a1915737ccc6dc586f33e15aae28d80b2..a3f5e90d46cccd475b82c52baf555f8da330dc74 100644 (file)
@@ -1,9 +1,11 @@
+import importlib
+from types import ModuleType
 from typing import Any, Dict, List, Union
-from unittest.mock import patch
 
+import pytest
 from sqlmodel import create_engine
 
-from ...conftest import get_testing_print_function
+from ...conftest import PrintMock, needs_py310
 
 
 def check_calls(calls: List[List[Union[str, Dict[str, Any]]]]):
@@ -27,29 +29,35 @@ def check_calls(calls: List[List[Union[str, Dict[str, Any]]]]):
     }
 
 
-def test_tutorial_001(clear_sqlmodel):
-    from docs_src.tutorial.select import tutorial001 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    check_calls(calls)
-
-
-def test_tutorial_002(clear_sqlmodel):
-    from docs_src.tutorial.select import tutorial002 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    check_calls(calls)
+@pytest.fixture(name="module")
+def get_module(request: pytest.FixtureRequest) -> ModuleType:
+    module = importlib.import_module(f"docs_src.tutorial.select.{request.param}")
+    module.sqlite_url = "sqlite://"
+    module.engine = create_engine(module.sqlite_url)
+    return module
+
+
+@pytest.mark.parametrize(
+    "module",
+    [
+        "tutorial001",
+        pytest.param("tutorial001_py310", marks=needs_py310),
+    ],
+    indirect=True,
+)
+def test_tutorial_001(print_mock: PrintMock, module: ModuleType):
+    module.main()
+    check_calls(print_mock.calls)
+
+
+@pytest.mark.parametrize(
+    "module",
+    [
+        "tutorial002",
+        pytest.param("tutorial002_py310", marks=needs_py310),
+    ],
+    indirect=True,
+)
+def test_tutorial_002(print_mock: PrintMock, module: ModuleType):
+    module.main()
+    check_calls(print_mock.calls)
diff --git a/tests/test_tutorial/test_select/test_tutorial003_py310_tutorial004_py310.py b/tests/test_tutorial/test_select/test_tutorial003_py310_tutorial004_py310.py
deleted file mode 100644 (file)
index 0fa69df..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-from typing import Any, Dict, List, Union
-from unittest.mock import patch
-
-from sqlmodel import create_engine
-
-from ...conftest import get_testing_print_function, needs_py310
-
-
-def check_calls(calls: List[List[Union[str, Dict[str, Any]]]]):
-    assert calls[0][0] == [
-        {
-            "name": "Deadpond",
-            "secret_name": "Dive Wilson",
-            "age": None,
-            "id": 1,
-        },
-        {
-            "name": "Spider-Boy",
-            "secret_name": "Pedro Parqueador",
-            "age": None,
-            "id": 2,
-        },
-        {
-            "name": "Rusty-Man",
-            "secret_name": "Tommy Sharp",
-            "age": 48,
-            "id": 3,
-        },
-    ]
-
-
-@needs_py310
-def test_tutorial_003(clear_sqlmodel):
-    from docs_src.tutorial.select import tutorial003_py310 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    check_calls(calls)
-
-
-@needs_py310
-def test_tutorial_002(clear_sqlmodel):
-    from docs_src.tutorial.select import tutorial004_py310 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    check_calls(calls)
index bfda0cb189a742325a416e48d8234a4d58ba2dd5..967ecdbd50d5d93ad5daa2432536b0f9b8adfe1d 100644 (file)
@@ -1,9 +1,11 @@
+import importlib
+from types import ModuleType
 from typing import Any, Dict, List, Union
-from unittest.mock import patch
 
+import pytest
 from sqlmodel import create_engine
 
-from ...conftest import get_testing_print_function
+from ...conftest import PrintMock, needs_py310
 
 
 def check_calls(calls: List[List[Union[str, Dict[str, Any]]]]):
@@ -29,29 +31,35 @@ def check_calls(calls: List[List[Union[str, Dict[str, Any]]]]):
     ]
 
 
-def test_tutorial_003(clear_sqlmodel):
-    from docs_src.tutorial.select import tutorial003 as mod
+@pytest.fixture(name="module")
+def get_module(request: pytest.FixtureRequest) -> ModuleType:
+    module = importlib.import_module(f"docs_src.tutorial.select.{request.param}")
+    module.sqlite_url = "sqlite://"
+    module.engine = create_engine(module.sqlite_url)
+    return module
 
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
 
-    new_print = get_testing_print_function(calls)
+@pytest.mark.parametrize(
+    "module",
+    [
+        "tutorial003",
+        pytest.param("tutorial003_py310", marks=needs_py310),
+    ],
+    indirect=True,
+)
+def test_tutorial_003(print_mock: PrintMock, module: ModuleType):
+    module.main()
+    check_calls(print_mock.calls)
 
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    check_calls(calls)
 
-
-def test_tutorial_002(clear_sqlmodel):
-    from docs_src.tutorial.select import tutorial004 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    check_calls(calls)
+@pytest.mark.parametrize(
+    "module",
+    [
+        "tutorial004",
+        pytest.param("tutorial004_py310", marks=needs_py310),
+    ],
+    indirect=True,
+)
+def test_tutorial_004(print_mock: PrintMock, module: ModuleType):
+    module.main()
+    check_calls(print_mock.calls)
diff --git a/tests/test_tutorial/test_update/test_tutorial001_py310_tutorial002_py310.py b/tests/test_tutorial/test_update/test_tutorial001_py310_tutorial002_py310.py
deleted file mode 100644 (file)
index cefb75f..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-from unittest.mock import patch
-
-from sqlmodel import create_engine
-
-from ...conftest import get_testing_print_function, needs_py310
-
-expected_calls = [
-    [
-        "Hero:",
-        {
-            "id": 2,
-            "name": "Spider-Boy",
-            "secret_name": "Pedro Parqueador",
-            "age": None,
-        },
-    ],
-    [
-        "Updated hero:",
-        {
-            "id": 2,
-            "name": "Spider-Boy",
-            "secret_name": "Pedro Parqueador",
-            "age": 16,
-        },
-    ],
-]
-
-
-@needs_py310
-def test_tutorial001(clear_sqlmodel):
-    from docs_src.tutorial.update import tutorial001_py310 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == expected_calls
-
-
-@needs_py310
-def test_tutorial002(clear_sqlmodel):
-    from docs_src.tutorial.update import tutorial002_py310 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == expected_calls
index be81f410bf55b002d305d72059cb635806cf35af..ef12a8d950ce098f762bbeb1630c2e320cfe04d0 100644 (file)
@@ -1,8 +1,10 @@
-from unittest.mock import patch
+import importlib
+from types import ModuleType
 
+import pytest
 from sqlmodel import create_engine
 
-from ...conftest import get_testing_print_function
+from ...conftest import PrintMock, needs_py310
 
 expected_calls = [
     [
@@ -26,29 +28,35 @@ expected_calls = [
 ]
 
 
-def test_tutorial001(clear_sqlmodel):
-    from docs_src.tutorial.update import tutorial001 as mod
+@pytest.fixture(name="module")
+def get_module(request: pytest.FixtureRequest) -> ModuleType:
+    module = importlib.import_module(f"docs_src.tutorial.update.{request.param}")
+    module.sqlite_url = "sqlite://"
+    module.engine = create_engine(module.sqlite_url)
+    return module
 
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
 
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == expected_calls
-
-
-def test_tutorial002(clear_sqlmodel):
-    from docs_src.tutorial.update import tutorial002 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
+@pytest.mark.parametrize(
+    "module",
+    [
+        "tutorial001",
+        pytest.param("tutorial001_py310", marks=needs_py310),
+    ],
+    indirect=True,
+)
+def test_tutorial001(print_mock: PrintMock, module: ModuleType):
+    module.main()
+    assert print_mock.calls == expected_calls
 
-    new_print = get_testing_print_function(calls)
 
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == expected_calls
+@pytest.mark.parametrize(
+    "module",
+    [
+        "tutorial002",
+        pytest.param("tutorial002_py310", marks=needs_py310),
+    ],
+    indirect=True,
+)
+def test_tutorial002(print_mock: PrintMock, module: ModuleType):
+    module.main()
+    assert print_mock.calls == expected_calls
diff --git a/tests/test_tutorial/test_update/test_tutorial003_py310_tutorial004_py310.py b/tests/test_tutorial/test_update/test_tutorial003_py310_tutorial004_py310.py
deleted file mode 100644 (file)
index 31dc601..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-from unittest.mock import patch
-
-from sqlmodel import create_engine
-
-from ...conftest import get_testing_print_function, needs_py310
-
-expected_calls = [
-    [
-        "Hero 1:",
-        {"id": 2, "name": "Spider-Boy", "secret_name": "Pedro Parqueador", "age": None},
-    ],
-    [
-        "Hero 2:",
-        {
-            "id": 7,
-            "name": "Captain North America",
-            "secret_name": "Esteban Rogelios",
-            "age": 93,
-        },
-    ],
-    [
-        "Updated hero 1:",
-        {
-            "id": 2,
-            "name": "Spider-Youngster",
-            "secret_name": "Pedro Parqueador",
-            "age": 16,
-        },
-    ],
-    [
-        "Updated hero 2:",
-        {
-            "id": 7,
-            "name": "Captain North America Except Canada",
-            "secret_name": "Esteban Rogelios",
-            "age": 110,
-        },
-    ],
-]
-
-
-@needs_py310
-def test_tutorial003(clear_sqlmodel):
-    from docs_src.tutorial.update import tutorial003_py310 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == expected_calls
-
-
-@needs_py310
-def test_tutorial004(clear_sqlmodel):
-    from docs_src.tutorial.update import tutorial004_py310 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == expected_calls
index 0f705aa699bb79532777805af879319b2ea66ea8..76788c62cdf860763ebde4994afc45e22eaadf03 100644 (file)
@@ -1,8 +1,10 @@
-from unittest.mock import patch
+import importlib
+from types import ModuleType
 
+import pytest
 from sqlmodel import create_engine
 
-from ...conftest import get_testing_print_function
+from ...conftest import PrintMock, needs_py310
 
 expected_calls = [
     [
@@ -39,29 +41,35 @@ expected_calls = [
 ]
 
 
-def test_tutorial003(clear_sqlmodel):
-    from docs_src.tutorial.update import tutorial003 as mod
+@pytest.fixture(name="module")
+def get_module(request: pytest.FixtureRequest) -> ModuleType:
+    module = importlib.import_module(f"docs_src.tutorial.update.{request.param}")
+    module.sqlite_url = "sqlite://"
+    module.engine = create_engine(module.sqlite_url)
+    return module
 
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
 
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == expected_calls
-
-
-def test_tutorial004(clear_sqlmodel):
-    from docs_src.tutorial.update import tutorial004 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
+@pytest.mark.parametrize(
+    "module",
+    [
+        "tutorial003",
+        pytest.param("tutorial003_py310", marks=needs_py310),
+    ],
+    indirect=True,
+)
+def test_tutorial003(print_mock: PrintMock, module: ModuleType):
+    module.main()
+    assert print_mock.calls == expected_calls
 
-    new_print = get_testing_print_function(calls)
 
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == expected_calls
+@pytest.mark.parametrize(
+    "module",
+    [
+        "tutorial004",
+        pytest.param("tutorial004_py310", marks=needs_py310),
+    ],
+    indirect=True,
+)
+def test_tutorial004(print_mock: PrintMock, module: ModuleType):
+    module.main()
+    assert print_mock.calls == expected_calls
index bba13269a1f0e25d8220702d9f9e5b20b6b14501..1a557deefc01ee67a5f23319cc2a1919b31eb474 100644 (file)
@@ -1,22 +1,29 @@
-from unittest.mock import patch
+import importlib
+from types import ModuleType
 
+import pytest
 from sqlmodel import create_engine
 
-from ...conftest import get_testing_print_function
+from ...conftest import PrintMock, needs_py310
 
 
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.where import tutorial001 as mod
-
+@pytest.fixture(
+    name="mod",
+    params=[
+        "tutorial001",
+        pytest.param("tutorial001_py310", marks=needs_py310),
+    ],
+)
+def get_module(request: pytest.FixtureRequest) -> ModuleType:
+    mod = importlib.import_module(f"docs_src.tutorial.where.{request.param}")
     mod.sqlite_url = "sqlite://"
     mod.engine = create_engine(mod.sqlite_url)
-    calls = []
+    return mod
 
-    new_print = get_testing_print_function(calls)
 
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == [
+def test_tutorial(print_mock: PrintMock, mod: ModuleType):
+    mod.main()
+    assert print_mock.calls == [
         [
             {
                 "name": "Deadpond",
diff --git a/tests/test_tutorial/test_where/test_tutorial001_py310.py b/tests/test_tutorial/test_where/test_tutorial001_py310.py
deleted file mode 100644 (file)
index 44e734a..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-from unittest.mock import patch
-
-from sqlmodel import create_engine
-
-from ...conftest import get_testing_print_function, needs_py310
-
-
-@needs_py310
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.where import tutorial001_py310 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == [
-        [
-            {
-                "name": "Deadpond",
-                "secret_name": "Dive Wilson",
-                "age": None,
-                "id": 1,
-            }
-        ]
-    ]
index 80d60ff5554d81575d5942ba1487ce95a3510c6a..1c96f76126fa7863bcfc6a72a867d4494a0c1a66 100644 (file)
@@ -1,22 +1,29 @@
-from unittest.mock import patch
+import importlib
+from types import ModuleType
 
+import pytest
 from sqlmodel import create_engine
 
-from ...conftest import get_testing_print_function
+from ...conftest import PrintMock, needs_py310
 
 
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.where import tutorial002 as mod
-
+@pytest.fixture(
+    name="mod",
+    params=[
+        "tutorial002",
+        pytest.param("tutorial002_py310", marks=needs_py310),
+    ],
+)
+def get_module(request: pytest.FixtureRequest) -> ModuleType:
+    mod = importlib.import_module(f"docs_src.tutorial.where.{request.param}")
     mod.sqlite_url = "sqlite://"
     mod.engine = create_engine(mod.sqlite_url)
-    calls = []
+    return mod
 
-    new_print = get_testing_print_function(calls)
 
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == [
+def test_tutorial(print_mock: PrintMock, mod: ModuleType):
+    mod.main()
+    assert print_mock.calls == [
         [
             {
                 "name": "Spider-Boy",
diff --git a/tests/test_tutorial/test_where/test_tutorial002_py310.py b/tests/test_tutorial/test_where/test_tutorial002_py310.py
deleted file mode 100644 (file)
index 00d88ec..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-from unittest.mock import patch
-
-from sqlmodel import create_engine
-
-from ...conftest import get_testing_print_function, needs_py310
-
-
-@needs_py310
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.where import tutorial002_py310 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == [
-        [
-            {
-                "name": "Spider-Boy",
-                "secret_name": "Pedro Parqueador",
-                "age": None,
-                "id": 2,
-            }
-        ],
-        [{"name": "Rusty-Man", "secret_name": "Tommy Sharp", "age": 48, "id": 3}],
-    ]
index 4794d846ff9e7a67e766eebce77ef748a3144232..6e90d22fc4e6ff70e1603e4ec8c9b1087ae6f712 100644 (file)
@@ -1,21 +1,28 @@
-from unittest.mock import patch
+import importlib
+from types import ModuleType
 
+import pytest
 from sqlmodel import create_engine
 
-from ...conftest import get_testing_print_function
+from ...conftest import PrintMock, needs_py310
 
 
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.where import tutorial003 as mod
-
+@pytest.fixture(
+    name="mod",
+    params=[
+        "tutorial003",
+        pytest.param("tutorial003_py310", marks=needs_py310),
+    ],
+)
+def get_module(request: pytest.FixtureRequest) -> ModuleType:
+    mod = importlib.import_module(f"docs_src.tutorial.where.{request.param}")
     mod.sqlite_url = "sqlite://"
     mod.engine = create_engine(mod.sqlite_url)
-    calls = []
+    return mod
 
-    new_print = get_testing_print_function(calls)
 
-    with patch("builtins.print", new=new_print):
-        mod.main()
+def test_tutorial(print_mock: PrintMock, mod: ModuleType):
+    mod.main()
 
     expected_calls = [
         [{"id": 6, "name": "Dr. Weird", "secret_name": "Steve Weird", "age": 36}],
@@ -29,6 +36,7 @@ def test_tutorial(clear_sqlmodel):
             }
         ],
     ]
+    calls = print_mock.calls
     for call in expected_calls:
         assert call in calls, "This expected item should be in the list"
         # Now that this item was checked, remove it from the list
diff --git a/tests/test_tutorial/test_where/test_tutorial003_py310.py b/tests/test_tutorial/test_where/test_tutorial003_py310.py
deleted file mode 100644 (file)
index 2d84c2c..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-from unittest.mock import patch
-
-from sqlmodel import create_engine
-
-from ...conftest import get_testing_print_function, needs_py310
-
-
-@needs_py310
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.where import tutorial003_py310 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.main()
-
-    expected_calls = [
-        [{"id": 6, "name": "Dr. Weird", "secret_name": "Steve Weird", "age": 36}],
-        [{"id": 3, "name": "Rusty-Man", "secret_name": "Tommy Sharp", "age": 48}],
-        [
-            {
-                "id": 7,
-                "name": "Captain North America",
-                "secret_name": "Esteban Rogelios",
-                "age": 93,
-            }
-        ],
-    ]
-    for call in expected_calls:
-        assert call in calls, "This expected item should be in the list"
-        # Now that this item was checked, remove it from the list
-        calls.pop(calls.index(call))
-    assert len(calls) == 0, "The list should only have the expected items"
index 682babd43aa3b13f1b15b6ddc199b5f81e371118..b7a1212b77f6a1742941a1359df662cec639ff34 100644 (file)
@@ -1,21 +1,28 @@
-from unittest.mock import patch
+import importlib
+from types import ModuleType
 
+import pytest
 from sqlmodel import create_engine
 
-from ...conftest import get_testing_print_function
+from ...conftest import PrintMock, needs_py310
 
 
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.where import tutorial004 as mod
-
+@pytest.fixture(
+    name="mod",
+    params=[
+        "tutorial004",
+        pytest.param("tutorial004_py310", marks=needs_py310),
+    ],
+)
+def get_module(request: pytest.FixtureRequest) -> ModuleType:
+    mod = importlib.import_module(f"docs_src.tutorial.where.{request.param}")
     mod.sqlite_url = "sqlite://"
     mod.engine = create_engine(mod.sqlite_url)
-    calls = []
+    return mod
 
-    new_print = get_testing_print_function(calls)
 
-    with patch("builtins.print", new=new_print):
-        mod.main()
+def test_tutorial(print_mock: PrintMock, mod: ModuleType):
+    mod.main()
     expected_calls = [
         [{"id": 5, "name": "Black Lion", "secret_name": "Trevor Challa", "age": 35}],
         [{"id": 6, "name": "Dr. Weird", "secret_name": "Steve Weird", "age": 36}],
@@ -29,6 +36,7 @@ def test_tutorial(clear_sqlmodel):
             }
         ],
     ]
+    calls = print_mock.calls
     for call in expected_calls:
         assert call in calls, "This expected item should be in the list"
         # Now that this item was checked, remove it from the list
diff --git a/tests/test_tutorial/test_where/test_tutorial004_py310.py b/tests/test_tutorial/test_where/test_tutorial004_py310.py
deleted file mode 100644 (file)
index 04566cb..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-from unittest.mock import patch
-
-from sqlmodel import create_engine
-
-from ...conftest import get_testing_print_function, needs_py310
-
-
-@needs_py310
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.where import tutorial004_py310 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    expected_calls = [
-        [{"id": 5, "name": "Black Lion", "secret_name": "Trevor Challa", "age": 35}],
-        [{"id": 6, "name": "Dr. Weird", "secret_name": "Steve Weird", "age": 36}],
-        [{"id": 3, "name": "Rusty-Man", "secret_name": "Tommy Sharp", "age": 48}],
-        [
-            {
-                "id": 7,
-                "name": "Captain North America",
-                "secret_name": "Esteban Rogelios",
-                "age": 93,
-            }
-        ],
-    ]
-    for call in expected_calls:
-        assert call in calls, "This expected item should be in the list"
-        # Now that this item was checked, remove it from the list
-        calls.pop(calls.index(call))
-    assert len(calls) == 0, "The list should only have the expected items"
index b6bfd2ce88e1839f877a5eb2b15295166b4fa5cb..9adbec74a280f27f8a207cdfaed4dc2541dd83ed 100644 (file)
@@ -1,21 +1,28 @@
-from unittest.mock import patch
+import importlib
+from types import ModuleType
 
+import pytest
 from sqlmodel import create_engine
 
-from ...conftest import get_testing_print_function
+from ...conftest import PrintMock, needs_py310
 
 
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.where import tutorial005 as mod
-
+@pytest.fixture(
+    name="mod",
+    params=[
+        "tutorial005",
+        pytest.param("tutorial005_py310", marks=needs_py310),
+    ],
+)
+def get_module(request: pytest.FixtureRequest) -> ModuleType:
+    mod = importlib.import_module(f"docs_src.tutorial.where.{request.param}")
     mod.sqlite_url = "sqlite://"
     mod.engine = create_engine(mod.sqlite_url)
-    calls = []
+    return mod
 
-    new_print = get_testing_print_function(calls)
 
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == [
+def test_tutorial(print_mock: PrintMock, mod: ModuleType):
+    mod.main()
+    assert print_mock.calls == [
         [{"name": "Tarantula", "secret_name": "Natalia Roman-on", "age": 32, "id": 4}]
     ]
diff --git a/tests/test_tutorial/test_where/test_tutorial005_py310.py b/tests/test_tutorial/test_where/test_tutorial005_py310.py
deleted file mode 100644 (file)
index d238fff..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-from unittest.mock import patch
-
-from sqlmodel import create_engine
-
-from ...conftest import get_testing_print_function, needs_py310
-
-
-@needs_py310
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.where import tutorial005_py310 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == [
-        [{"name": "Tarantula", "secret_name": "Natalia Roman-on", "age": 32, "id": 4}]
-    ]
index e5406dfbb0580b84eba96984753649a0eb700e22..e5d586a39aae55b85fabe47a7d024803bc513a84 100644 (file)
@@ -1,22 +1,29 @@
-from unittest.mock import patch
+import importlib
+from types import ModuleType
 
+import pytest
 from sqlmodel import create_engine
 
-from ...conftest import get_testing_print_function
+from ...conftest import PrintMock, needs_py310
 
 
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.where import tutorial006 as mod
-
+@pytest.fixture(
+    name="mod",
+    params=[
+        "tutorial006",
+        pytest.param("tutorial006_py310", marks=needs_py310),
+    ],
+)
+def get_module(request: pytest.FixtureRequest) -> ModuleType:
+    mod = importlib.import_module(f"docs_src.tutorial.where.{request.param}")
     mod.sqlite_url = "sqlite://"
     mod.engine = create_engine(mod.sqlite_url)
-    calls = []
+    return mod
 
-    new_print = get_testing_print_function(calls)
 
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == [
+def test_tutorial(print_mock: PrintMock, mod: ModuleType):
+    mod.main()
+    assert print_mock.calls == [
         [{"name": "Tarantula", "secret_name": "Natalia Roman-on", "age": 32, "id": 4}],
         [{"name": "Black Lion", "secret_name": "Trevor Challa", "age": 35, "id": 5}],
     ]
diff --git a/tests/test_tutorial/test_where/test_tutorial006_py310.py b/tests/test_tutorial/test_where/test_tutorial006_py310.py
deleted file mode 100644 (file)
index 8a4924f..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-from unittest.mock import patch
-
-from sqlmodel import create_engine
-
-from ...conftest import get_testing_print_function, needs_py310
-
-
-@needs_py310
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.where import tutorial006_py310 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == [
-        [{"name": "Tarantula", "secret_name": "Natalia Roman-on", "age": 32, "id": 4}],
-        [{"name": "Black Lion", "secret_name": "Trevor Challa", "age": 35, "id": 5}],
-    ]
index 878e81f932038bea84802f7f891cf5969ad7ec49..9a36279d381f3b0b10e8597a6589def9bb30f94f 100644 (file)
@@ -1,22 +1,29 @@
-from unittest.mock import patch
+import importlib
+from types import ModuleType
 
+import pytest
 from sqlmodel import create_engine
 
-from ...conftest import get_testing_print_function
+from ...conftest import PrintMock, needs_py310
 
 
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.where import tutorial007 as mod
-
+@pytest.fixture(
+    name="mod",
+    params=[
+        "tutorial007",
+        pytest.param("tutorial007_py310", marks=needs_py310),
+    ],
+)
+def get_module(request: pytest.FixtureRequest) -> ModuleType:
+    mod = importlib.import_module(f"docs_src.tutorial.where.{request.param}")
     mod.sqlite_url = "sqlite://"
     mod.engine = create_engine(mod.sqlite_url)
-    calls = []
+    return mod
 
-    new_print = get_testing_print_function(calls)
 
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == [
+def test_tutorial(print_mock: PrintMock, mod: ModuleType):
+    mod.main()
+    assert print_mock.calls == [
         [{"id": 5, "name": "Black Lion", "secret_name": "Trevor Challa", "age": 35}],
         [{"id": 6, "name": "Dr. Weird", "secret_name": "Steve Weird", "age": 36}],
     ]
diff --git a/tests/test_tutorial/test_where/test_tutorial007_py310.py b/tests/test_tutorial/test_where/test_tutorial007_py310.py
deleted file mode 100644 (file)
index a2110a1..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-from unittest.mock import patch
-
-from sqlmodel import create_engine
-
-from ...conftest import get_testing_print_function, needs_py310
-
-
-@needs_py310
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.where import tutorial007_py310 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == [
-        [{"id": 5, "name": "Black Lion", "secret_name": "Trevor Challa", "age": 35}],
-        [{"id": 6, "name": "Dr. Weird", "secret_name": "Steve Weird", "age": 36}],
-    ]
index 08f4c49b9d8109e52b9a2f85472c9f51609b2dee..a21e2ecbe3e83a75ec3182eee2e900ade24309be 100644 (file)
@@ -1,22 +1,29 @@
-from unittest.mock import patch
+import importlib
+from types import ModuleType
 
+import pytest
 from sqlmodel import create_engine
 
-from ...conftest import get_testing_print_function
+from ...conftest import PrintMock, needs_py310
 
 
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.where import tutorial008 as mod
-
+@pytest.fixture(
+    name="mod",
+    params=[
+        "tutorial008",
+        pytest.param("tutorial008_py310", marks=needs_py310),
+    ],
+)
+def get_module(request: pytest.FixtureRequest) -> ModuleType:
+    mod = importlib.import_module(f"docs_src.tutorial.where.{request.param}")
     mod.sqlite_url = "sqlite://"
     mod.engine = create_engine(mod.sqlite_url)
-    calls = []
+    return mod
 
-    new_print = get_testing_print_function(calls)
 
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == [
+def test_tutorial(print_mock: PrintMock, mod: ModuleType):
+    mod.main()
+    assert print_mock.calls == [
         [{"id": 5, "name": "Black Lion", "secret_name": "Trevor Challa", "age": 35}],
         [{"id": 6, "name": "Dr. Weird", "secret_name": "Steve Weird", "age": 36}],
     ]
diff --git a/tests/test_tutorial/test_where/test_tutorial008_py310.py b/tests/test_tutorial/test_where/test_tutorial008_py310.py
deleted file mode 100644 (file)
index 887ac70..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-from unittest.mock import patch
-
-from sqlmodel import create_engine
-
-from ...conftest import get_testing_print_function, needs_py310
-
-
-@needs_py310
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.where import tutorial008_py310 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == [
-        [{"id": 5, "name": "Black Lion", "secret_name": "Trevor Challa", "age": 35}],
-        [{"id": 6, "name": "Dr. Weird", "secret_name": "Steve Weird", "age": 36}],
-    ]
index 2583f330cbc3bab0eb41eefca72da818f2958317..8088045b02ef15a8db3118ab8919fcd306dc5b58 100644 (file)
@@ -1,22 +1,29 @@
-from unittest.mock import patch
+import importlib
+from types import ModuleType
 
+import pytest
 from sqlmodel import create_engine
 
-from ...conftest import get_testing_print_function
+from ...conftest import PrintMock, needs_py310
 
 
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.where import tutorial009 as mod
-
+@pytest.fixture(
+    name="mod",
+    params=[
+        "tutorial009",
+        pytest.param("tutorial009_py310", marks=needs_py310),
+    ],
+)
+def get_module(request: pytest.FixtureRequest) -> ModuleType:
+    mod = importlib.import_module(f"docs_src.tutorial.where.{request.param}")
     mod.sqlite_url = "sqlite://"
     mod.engine = create_engine(mod.sqlite_url)
-    calls = []
+    return mod
 
-    new_print = get_testing_print_function(calls)
 
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == [
+def test_tutorial(print_mock: PrintMock, mod: ModuleType):
+    mod.main()
+    assert print_mock.calls == [
         [{"name": "Tarantula", "secret_name": "Natalia Roman-on", "age": 32, "id": 4}],
         [{"name": "Black Lion", "secret_name": "Trevor Challa", "age": 35, "id": 5}],
         [
diff --git a/tests/test_tutorial/test_where/test_tutorial009_py310.py b/tests/test_tutorial/test_where/test_tutorial009_py310.py
deleted file mode 100644 (file)
index 9bbef9b..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-from unittest.mock import patch
-
-from sqlmodel import create_engine
-
-from ...conftest import get_testing_print_function, needs_py310
-
-
-@needs_py310
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.where import tutorial009_py310 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == [
-        [{"name": "Tarantula", "secret_name": "Natalia Roman-on", "age": 32, "id": 4}],
-        [{"name": "Black Lion", "secret_name": "Trevor Challa", "age": 35, "id": 5}],
-        [
-            {
-                "name": "Captain North America",
-                "secret_name": "Esteban Rogelios",
-                "age": 93,
-                "id": 7,
-            }
-        ],
-    ]
index 71ef75d3a4df9474eee3045c508a96960c792644..ea235ef708e4500661666ffde6150576cf928986 100644 (file)
@@ -1,22 +1,29 @@
-from unittest.mock import patch
+import importlib
+from types import ModuleType
 
+import pytest
 from sqlmodel import create_engine
 
-from ...conftest import get_testing_print_function
+from ...conftest import PrintMock, needs_py310
 
 
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.where import tutorial010 as mod
-
+@pytest.fixture(
+    name="mod",
+    params=[
+        "tutorial010",
+        pytest.param("tutorial010_py310", marks=needs_py310),
+    ],
+)
+def get_module(request: pytest.FixtureRequest) -> ModuleType:
+    mod = importlib.import_module(f"docs_src.tutorial.where.{request.param}")
     mod.sqlite_url = "sqlite://"
     mod.engine = create_engine(mod.sqlite_url)
-    calls = []
+    return mod
 
-    new_print = get_testing_print_function(calls)
 
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == [
+def test_tutorial(print_mock: PrintMock, mod: ModuleType):
+    mod.main()
+    assert print_mock.calls == [
         [{"name": "Tarantula", "secret_name": "Natalia Roman-on", "age": 32, "id": 4}],
         [{"name": "Black Lion", "secret_name": "Trevor Challa", "age": 35, "id": 5}],
         [
diff --git a/tests/test_tutorial/test_where/test_tutorial010_py310.py b/tests/test_tutorial/test_where/test_tutorial010_py310.py
deleted file mode 100644 (file)
index e990abe..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-from unittest.mock import patch
-
-from sqlmodel import create_engine
-
-from ...conftest import get_testing_print_function, needs_py310
-
-
-@needs_py310
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.where import tutorial010_py310 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    assert calls == [
-        [{"name": "Tarantula", "secret_name": "Natalia Roman-on", "age": 32, "id": 4}],
-        [{"name": "Black Lion", "secret_name": "Trevor Challa", "age": 35, "id": 5}],
-        [
-            {
-                "name": "Captain North America",
-                "secret_name": "Esteban Rogelios",
-                "age": 93,
-                "id": 7,
-            }
-        ],
-    ]
index 8006cd0708738494fbe80f96c01d76809e31c707..ba53550611f099902336505b6a99bbb10c23e999 100644 (file)
@@ -1,21 +1,28 @@
-from unittest.mock import patch
+import importlib
+from types import ModuleType
 
+import pytest
 from sqlmodel import create_engine
 
-from ...conftest import get_testing_print_function
+from ...conftest import PrintMock, needs_py310
 
 
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.where import tutorial011 as mod
-
+@pytest.fixture(
+    name="mod",
+    params=[
+        "tutorial011",
+        pytest.param("tutorial011_py310", marks=needs_py310),
+    ],
+)
+def get_module(request: pytest.FixtureRequest) -> ModuleType:
+    mod = importlib.import_module(f"docs_src.tutorial.where.{request.param}")
     mod.sqlite_url = "sqlite://"
     mod.engine = create_engine(mod.sqlite_url)
-    calls = []
+    return mod
 
-    new_print = get_testing_print_function(calls)
 
-    with patch("builtins.print", new=new_print):
-        mod.main()
+def test_tutorial(print_mock: PrintMock, mod: ModuleType):
+    mod.main()
     expected_calls = [
         [{"id": 5, "name": "Black Lion", "secret_name": "Trevor Challa", "age": 35}],
         [{"id": 6, "name": "Dr. Weird", "secret_name": "Steve Weird", "age": 36}],
@@ -29,6 +36,7 @@ def test_tutorial(clear_sqlmodel):
             }
         ],
     ]
+    calls = print_mock.calls
     for call in expected_calls:
         assert call in calls, "This expected item should be in the list"
         # Now that this item was checked, remove it from the list
diff --git a/tests/test_tutorial/test_where/test_tutorial011_py310.py b/tests/test_tutorial/test_where/test_tutorial011_py310.py
deleted file mode 100644 (file)
index aee809b..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-from unittest.mock import patch
-
-from sqlmodel import create_engine
-
-from ...conftest import get_testing_print_function, needs_py310
-
-
-@needs_py310
-def test_tutorial(clear_sqlmodel):
-    from docs_src.tutorial.where import tutorial011_py310 as mod
-
-    mod.sqlite_url = "sqlite://"
-    mod.engine = create_engine(mod.sqlite_url)
-    calls = []
-
-    new_print = get_testing_print_function(calls)
-
-    with patch("builtins.print", new=new_print):
-        mod.main()
-    expected_calls = [
-        [{"id": 5, "name": "Black Lion", "secret_name": "Trevor Challa", "age": 35}],
-        [{"id": 6, "name": "Dr. Weird", "secret_name": "Steve Weird", "age": 36}],
-        [{"id": 3, "name": "Rusty-Man", "secret_name": "Tommy Sharp", "age": 48}],
-        [
-            {
-                "id": 7,
-                "name": "Captain North America",
-                "secret_name": "Esteban Rogelios",
-                "age": 93,
-            }
-        ],
-    ]
-    for call in expected_calls:
-        assert call in calls, "This expected item should be in the list"
-        # Now that this item was checked, remove it from the list
-        calls.pop(calls.index(call))
-    assert len(calls) == 0, "The list should only have the expected items"