| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,69 @@ | |||
| 1 | + import shutil | ||
| 2 | + import subprocess | ||
| 3 | + from pathlib import Path | ||
| 4 | + from typing import Any, Callable, Dict, List, Union | ||
| 5 | + import pytest | ||
| 6 | + from sqlmodel import SQLModel | ||
| 7 | + from sqlmodel.main import default_registry | ||
| 8 | + from pydantic import BaseModel | ||
| 9 | + | ||
| 10 | + top_level_path = Path(__file__).resolve().parent.parent | ||
| 11 | + docs_src_path = top_level_path / "docs_src" | ||
| 12 | + | ||
| 13 | + | ||
| 14 | + @pytest.fixture() | ||
| 15 | + def clear_sqlmodel(): | ||
| 16 | + # Clear the tables in the metadata for the default base model | ||
| 17 | + SQLModel.metadata.clear() | ||
| 18 | + # Clear the Models associated with the registry, to avoid warnings | ||
| 19 | + default_registry.dispose() | ||
| 20 | + yield | ||
| 21 | + SQLModel.metadata.clear() | ||
| 22 | + default_registry.dispose() | ||
| 23 | + | ||
| 24 | + | ||
| 25 | + @pytest.fixture() | ||
| 26 | + def cov_tmp_path(tmp_path: Path): | ||
| 27 | + yield tmp_path | ||
| 28 | + for coverage_path in tmp_path.glob(".coverage*"): | ||
| 29 | + coverage_destiny_path = top_level_path / coverage_path.name | ||
| 30 | + shutil.copy(coverage_path, coverage_destiny_path) | ||
| 31 | + | ||
| 32 | + | ||
| 33 | + def coverage_run(*, module: str, cwd: Union[str, Path]) -> subprocess.CompletedProcess: | ||
| 34 | + result = subprocess.run( | ||
| 35 | + [ | ||
| 36 | + "coverage", | ||
| 37 | + "run", | ||
| 38 | + "--parallel-mode", | ||
| 39 | + "--source=docs_src,tests,sqlmodel", | ||
| 40 | + "-m", | ||
| 41 | + module, | ||
| 42 | + ], | ||
| 43 | + cwd=str(cwd), | ||
| 44 | + stdout=subprocess.PIPE, | ||
| 45 | + stderr=subprocess.PIPE, | ||
| 46 | + encoding="utf-8", | ||
| 47 | + ) | ||
| 48 | + return result | ||
| 49 | + | ||
| 50 | + | ||
| 51 | + def get_testing_print_function( | ||
| 52 | + calls: List[List[Union[str, Dict[str, Any]]]] | ||
| 53 | + ) -> Callable[..., Any]: | ||
| 54 | + def new_print(*args): | ||
| 55 | + data = [] | ||
| 56 | + for arg in args: | ||
| 57 | + if isinstance(arg, BaseModel): | ||
| 58 | + data.append(arg.dict()) | ||
| 59 | + elif isinstance(arg, list): | ||
| 60 | + new_list = [] | ||
| 61 | + for item in arg: | ||
| 62 | + if isinstance(item, BaseModel): | ||
| 63 | + new_list.append(item.dict()) | ||
| 64 | + data.append(new_list) | ||
| 65 | + else: | ||
| 66 | + data.append(arg) | ||
| 67 | + calls.append(data) | ||
| 68 | + | ||
| 69 | + return new_print | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,44 @@ | |||
| 1 | + from sqlmodel.default import Default | ||
| 2 | + | ||
| 3 | + | ||
| 4 | + def test_default_bool() -> None: | ||
| 5 | + dt1 = Default(True) | ||
| 6 | + dt2 = Default(1) | ||
| 7 | + dt3 = Default("foo") | ||
| 8 | + dt4 = Default(["foo"]) | ||
| 9 | + df1 = Default(False) | ||
| 10 | + df2 = Default(0) | ||
| 11 | + df3 = Default("") | ||
| 12 | + df4: list = Default([]) | ||
| 13 | + df5 = Default(None) | ||
| 14 | + | ||
| 15 | + assert not not dt1 | ||
| 16 | + assert not not dt2 | ||
| 17 | + assert not not dt3 | ||
| 18 | + assert not not dt4 | ||
| 19 | + assert not df1 | ||
| 20 | + assert not df2 | ||
| 21 | + assert not df3 | ||
| 22 | + assert not df4 | ||
| 23 | + assert not df5 | ||
| 24 | + | ||
| 25 | + | ||
| 26 | + def test_equality() -> None: | ||
| 27 | + value1 = Default("foo") | ||
| 28 | + value2 = Default("foo") | ||
| 29 | + | ||
| 30 | + assert value1 == value2 | ||
| 31 | + | ||
| 32 | + | ||
| 33 | + def test_not_equality() -> None: | ||
| 34 | + value1 = Default("foo") | ||
| 35 | + value2 = Default("bar") | ||
| 36 | + | ||
| 37 | + assert not (value1 == value2) | ||
| 38 | + | ||
| 39 | + | ||
| 40 | + def test_not_equality_other() -> None: | ||
| 41 | + value1 = Default("foo") | ||
| 42 | + value2 = "foo" | ||
| 43 | + | ||
| 44 | + assert not (value1 == value2) | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,27 @@ | |||
| 1 | + from typing import Optional | ||
| 2 | + | ||
| 3 | + from sqlalchemy import create_engine, select | ||
| 4 | + from sqlalchemy.orm import Session | ||
| 5 | + from sqlmodel import Field, SQLModel | ||
| 6 | + | ||
| 7 | + | ||
| 8 | + def test_allow_instantiation_without_arguments(clear_sqlmodel): | ||
| 9 | + class Item(SQLModel): | ||
| 10 | + id: Optional[int] = Field(default=None, primary_key=True) | ||
| 11 | + name: str | ||
| 12 | + description: Optional[str] = None | ||
| 13 | + | ||
| 14 | + class Config: | ||
| 15 | + table = True | ||
| 16 | + | ||
| 17 | + engine = create_engine("sqlite:///:memory:") | ||
| 18 | + SQLModel.metadata.create_all(engine) | ||
| 19 | + with Session(engine) as db: | ||
| 20 | + item = Item() | ||
| 21 | + item.name = "Rick" | ||
| 22 | + db.add(item) | ||
| 23 | + db.commit() | ||
| 24 | + result = db.execute(select(Item)).scalars().all() | ||
| 25 | + assert len(result) == 1 | ||
| 26 | + assert isinstance(item.id, int) | ||
| 27 | + SQLModel.metadata.clear() | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,26 @@ | |||
| 1 | + from typing import Optional | ||
| 2 | + | ||
| 3 | + from sqlmodel import Field, Session, SQLModel, create_engine | ||
| 4 | + | ||
| 5 | + | ||
| 6 | + def test_query(clear_sqlmodel): | ||
| 7 | + class Hero(SQLModel, table=True): | ||
| 8 | + id: Optional[int] = Field(default=None, primary_key=True) | ||
| 9 | + name: str | ||
| 10 | + secret_name: str | ||
| 11 | + age: Optional[int] = None | ||
| 12 | + | ||
| 13 | + hero_1 = Hero(name="Deadpond", secret_name="Dive Wilson") | ||
| 14 | + | ||
| 15 | + engine = create_engine("sqlite://") | ||
| 16 | + | ||
| 17 | + SQLModel.metadata.create_all(engine) | ||
| 18 | + with Session(engine) as session: | ||
| 19 | + session.add(hero_1) | ||
| 20 | + session.commit() | ||
| 21 | + session.refresh(hero_1) | ||
| 22 | + | ||
| 23 | + with Session(engine) as session: | ||
| 24 | + query_hero = session.query(Hero).first() | ||
| 25 | + assert query_hero | ||
| 26 | + assert query_hero.name == hero_1.name | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,160 @@ | |||
| 1 | + from tests.conftest import get_testing_print_function | ||
| 2 | + from typing import Any, Dict, List, Union | ||
| 3 | + from unittest.mock import patch | ||
| 4 | + | ||
| 5 | + from sqlmodel import create_engine | ||
| 6 | + | ||
| 7 | + | ||
| 8 | + def check_calls(calls: List[List[Union[str, Dict[str, Any]]]]): | ||
| 9 | + assert calls[0] == ["Before interacting with the database"] | ||
| 10 | + assert calls[1] == [ | ||
| 11 | + "Hero 1:", | ||
| 12 | + { | ||
| 13 | + "id": None, | ||
| 14 | + "name": "Deadpond", | ||
| 15 | + "secret_name": "Dive Wilson", | ||
| 16 | + "age": None, | ||
| 17 | + }, | ||
| 18 | + ] | ||
| 19 | + assert calls[2] == [ | ||
| 20 | + "Hero 2:", | ||
| 21 | + { | ||
| 22 | + "id": None, | ||
| 23 | + "name": "Spider-Boy", | ||
| 24 | + "secret_name": "Pedro Parqueador", | ||
| 25 | + "age": None, | ||
| 26 | + }, | ||
| 27 | + ] | ||
| 28 | + assert calls[3] == [ | ||
| 29 | + "Hero 3:", | ||
| 30 | + { | ||
| 31 | + "id": None, | ||
| 32 | + "name": "Rusty-Man", | ||
| 33 | + "secret_name": "Tommy Sharp", | ||
| 34 | + "age": 48, | ||
| 35 | + }, | ||
| 36 | + ] | ||
| 37 | + assert calls[4] == ["After adding to the session"] | ||
| 38 | + assert calls[5] == [ | ||
| 39 | + "Hero 1:", | ||
| 40 | + { | ||
| 41 | + "id": None, | ||
| 42 | + "name": "Deadpond", | ||
| 43 | + "secret_name": "Dive Wilson", | ||
| 44 | + "age": None, | ||
| 45 | + }, | ||
| 46 | + ] | ||
| 47 | + assert calls[6] == [ | ||
| 48 | + "Hero 2:", | ||
| 49 | + { | ||
| 50 | + "id": None, | ||
| 51 | + "name": "Spider-Boy", | ||
| 52 | + "secret_name": "Pedro Parqueador", | ||
| 53 | + "age": None, | ||
| 54 | + }, | ||
| 55 | + ] | ||
| 56 | + assert calls[7] == [ | ||
| 57 | + "Hero 3:", | ||
| 58 | + { | ||
| 59 | + "id": None, | ||
| 60 | + "name": "Rusty-Man", | ||
| 61 | + "secret_name": "Tommy Sharp", | ||
| 62 | + "age": 48, | ||
| 63 | + }, | ||
| 64 | + ] | ||
| 65 | + assert calls[8] == ["After committing the session"] | ||
| 66 | + assert calls[9] == ["Hero 1:", {}] | ||
| 67 | + assert calls[10] == ["Hero 2:", {}] | ||
| 68 | + assert calls[11] == ["Hero 3:", {}] | ||
| 69 | + assert calls[12] == ["After committing the session, show IDs"] | ||
| 70 | + assert calls[13] == ["Hero 1 ID:", 1] | ||
| 71 | + assert calls[14] == ["Hero 2 ID:", 2] | ||
| 72 | + assert calls[15] == ["Hero 3 ID:", 3] | ||
| 73 | + assert calls[16] == ["After committing the session, show names"] | ||
| 74 | + assert calls[17] == ["Hero 1 name:", "Deadpond"] | ||
| 75 | + assert calls[18] == ["Hero 2 name:", "Spider-Boy"] | ||
| 76 | + assert calls[19] == ["Hero 3 name:", "Rusty-Man"] | ||
| 77 | + assert calls[20] == ["After refreshing the heroes"] | ||
| 78 | + assert calls[21] == [ | ||
| 79 | + "Hero 1:", | ||
| 80 | + { | ||
| 81 | + "id": 1, | ||
| 82 | + "name": "Deadpond", | ||
| 83 | + "secret_name": "Dive Wilson", | ||
| 84 | + "age": None, | ||
| 85 | + }, | ||
| 86 | + ] | ||
| 87 | + assert calls[22] == [ | ||
| 88 | + "Hero 2:", | ||
| 89 | + { | ||
| 90 | + "id": 2, | ||
| 91 | + "name": "Spider-Boy", | ||
| 92 | + "secret_name": "Pedro Parqueador", | ||
| 93 | + "age": None, | ||
| 94 | + }, | ||
| 95 | + ] | ||
| 96 | + assert calls[23] == [ | ||
| 97 | + "Hero 3:", | ||
| 98 | + { | ||
| 99 | + "id": 3, | ||
| 100 | + "name": "Rusty-Man", | ||
| 101 | + "secret_name": "Tommy Sharp", | ||
| 102 | + "age": 48, | ||
| 103 | + }, | ||
| 104 | + ] | ||
| 105 | + assert calls[24] == ["After the session closes"] | ||
| 106 | + assert calls[21] == [ | ||
| 107 | + "Hero 1:", | ||
| 108 | + { | ||
| 109 | + "id": 1, | ||
| 110 | + "name": "Deadpond", | ||
| 111 | + "secret_name": "Dive Wilson", | ||
| 112 | + "age": None, | ||
| 113 | + }, | ||
| 114 | + ] | ||
| 115 | + assert calls[22] == [ | ||
| 116 | + "Hero 2:", | ||
| 117 | + { | ||
| 118 | + "id": 2, | ||
| 119 | + "name": "Spider-Boy", | ||
| 120 | + "secret_name": "Pedro Parqueador", | ||
| 121 | + "age": None, | ||
| 122 | + }, | ||
| 123 | + ] | ||
| 124 | + assert calls[23] == [ | ||
| 125 | + "Hero 3:", | ||
| 126 | + { | ||
| 127 | + "id": 3, | ||
| 128 | + "name": "Rusty-Man", | ||
| 129 | + "secret_name": "Tommy Sharp", | ||
| 130 | + "age": 48, | ||
| 131 | + }, | ||
| 132 | + ] | ||
| 133 | + | ||
| 134 | + | ||
| 135 | + def test_tutorial_001(clear_sqlmodel): | ||
| 136 | + from docs_src.tutorial.automatic_id_none_refresh import tutorial001 as mod | ||
| 137 | + | ||
| 138 | + mod.sqlite_url = "sqlite://" | ||
| 139 | + mod.engine = create_engine(mod.sqlite_url) | ||
| 140 | + calls = [] | ||
| 141 | + | ||
| 142 | + new_print = get_testing_print_function(calls) | ||
| 143 | + | ||
| 144 | + with patch("builtins.print", new=new_print): | ||
| 145 | + mod.main() | ||
| 146 | + check_calls(calls) | ||
| 147 | + | ||
| 148 | + | ||
| 149 | + def test_tutorial_002(clear_sqlmodel): | ||
| 150 | + from docs_src.tutorial.automatic_id_none_refresh import tutorial002 as mod | ||
| 151 | + | ||
| 152 | + mod.sqlite_url = "sqlite://" | ||
| 153 | + mod.engine = create_engine(mod.sqlite_url) | ||
| 154 | + calls = [] | ||
| 155 | + | ||
| 156 | + new_print = get_testing_print_function(calls) | ||
| 157 | + | ||
| 158 | + with patch("builtins.print", new=new_print): | ||
| 159 | + mod.main() | ||
| 160 | + check_calls(calls) | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,41 @@ | |||
| 1 | + from typing import Any, Dict, List, Union | ||
| 2 | + from unittest.mock import patch | ||
| 3 | + | ||
| 4 | + from sqlalchemy import inspect | ||
| 5 | + from sqlalchemy.engine.reflection import Inspector | ||
| 6 | + from sqlmodel import create_engine | ||
| 7 | + from sqlmodel.pool import StaticPool | ||
| 8 | + | ||
| 9 | + from ...conftest import get_testing_print_function | ||
| 10 | + | ||
| 11 | + expected_calls = [ | ||
| 12 | + [ | ||
| 13 | + "Created hero:", | ||
| 14 | + { | ||
| 15 | + "id": 1, | ||
| 16 | + "name": "Deadpond", | ||
| 17 | + "age": None, | ||
| 18 | + "secret_name": "Dive Wilson", | ||
| 19 | + "team_id": 1, | ||
| 20 | + }, | ||
| 21 | + ], | ||
| 22 | + [ | ||
| 23 | + "Hero's team:", | ||
| 24 | + {"name": "Z-Force", "headquarters": "Sister Margaret’s Bar", "id": 1}, | ||
| 25 | + ], | ||
| 26 | + ] | ||
| 27 | + | ||
| 28 | + | ||
| 29 | + def test_tutorial(clear_sqlmodel): | ||
| 30 | + from docs_src.tutorial.code_structure.tutorial001 import app, database | ||
| 31 | + | ||
| 32 | + database.sqlite_url = "sqlite://" | ||
| 33 | + database.engine = create_engine(database.sqlite_url) | ||
| 34 | + app.engine = database.engine | ||
| 35 | + calls = [] | ||
| 36 | + | ||
| 37 | + new_print = get_testing_print_function(calls) | ||
| 38 | + | ||
| 39 | + with patch("builtins.print", new=new_print): | ||
| 40 | + app.main() | ||
| 41 | + assert calls == expected_calls | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments