-
-
Notifications
You must be signed in to change notification settings - Fork 901
/
Copy pathtest_engine.py
131 lines (101 loc) · 4.35 KB
/
test_engine.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
from __future__ import annotations
import os.path
import typing as t
import unittest.mock
import pytest
import sqlalchemy as sa
import sqlalchemy.pool
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
def test_default_engine(app: Flask, db: SQLAlchemy[t.Any]) -> None:
with app.app_context():
assert db.engine is db.engines[None]
with pytest.raises(RuntimeError):
assert db.engine
@pytest.mark.usefixtures("app_ctx")
def test_engine_per_bind(app: Flask, model_class: t.Any) -> None:
app.config["SQLALCHEMY_BINDS"] = {"a": "sqlite://"}
db = SQLAlchemy(app, model_class=model_class)
assert db.engines["a"] is not db.engine
@pytest.mark.usefixtures("app_ctx")
def test_config_engine_options(app: Flask, model_class: t.Any) -> None:
app.config["SQLALCHEMY_ENGINE_OPTIONS"] = {"echo": True}
db = SQLAlchemy(app, model_class=model_class)
assert db.engine.echo
@pytest.mark.usefixtures("app_ctx")
def test_init_engine_options(app: Flask, model_class: t.Any) -> None:
app.config["SQLALCHEMY_ENGINE_OPTIONS"] = {"echo": False}
app.config["SQLALCHEMY_BINDS"] = {"a": "sqlite://"}
db = SQLAlchemy(app, engine_options={"echo": True}, model_class=model_class)
# init is default
assert db.engines["a"].echo
# config overrides init
assert not db.engine.echo
@pytest.mark.usefixtures("app_ctx")
def test_config_echo(app: Flask, model_class: t.Any) -> None:
app.config["SQLALCHEMY_ECHO"] = True
db = SQLAlchemy(app, model_class=model_class)
assert db.engine.echo
assert db.engine.pool.echo
@pytest.mark.usefixtures("app_ctx")
@pytest.mark.parametrize(
"value",
[
"sqlite://",
sa.engine.URL.create("sqlite"),
{"url": "sqlite://"},
{"url": sa.engine.URL.create("sqlite")},
],
)
def test_url_type(app: Flask, model_class: t.Any, value: str | sa.engine.URL) -> None:
app.config["SQLALCHEMY_BINDS"] = {"a": value}
db = SQLAlchemy(app, model_class=model_class)
assert str(db.engines["a"].url) == "sqlite://"
def test_no_binds_error(app: Flask, model_class: t.Any) -> None:
del app.config["SQLALCHEMY_DATABASE_URI"]
with pytest.raises(RuntimeError) as info:
SQLAlchemy(app, model_class=model_class)
e = "Either 'SQLALCHEMY_DATABASE_URI' or 'SQLALCHEMY_BINDS' must be set."
assert str(info.value) == e
@pytest.mark.usefixtures("app_ctx")
def test_no_default_url(app: Flask, model_class: t.Any) -> None:
del app.config["SQLALCHEMY_DATABASE_URI"]
app.config["SQLALCHEMY_BINDS"] = {"a": "sqlite://"}
db = SQLAlchemy(app, model_class=model_class, engine_options={"echo": True})
assert None not in db.engines
assert "a" in db.engines
@pytest.mark.usefixtures("app_ctx")
def test_sqlite_relative_path(app: Flask, model_class: t.Any) -> None:
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///test.db"
db = SQLAlchemy(app, model_class=model_class)
db.create_all()
assert not isinstance(db.engine.pool, sa.pool.StaticPool)
db_path = db.engine.url.database
assert db_path.startswith(app.instance_path) # type: ignore[union-attr]
assert os.path.exists(db_path) # type: ignore[arg-type]
@pytest.mark.usefixtures("app_ctx")
def test_sqlite_driver_level_uri(app: Flask, model_class: t.Any) -> None:
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///file:test.db?uri=true"
db = SQLAlchemy(app, model_class=model_class)
db.create_all()
db_path = db.engine.url.database
assert db_path is not None
assert db_path.startswith(f"file:{app.instance_path}")
assert os.path.exists(db_path[5:])
@unittest.mock.patch.object(SQLAlchemy, "_make_engine", autospec=True)
def test_sqlite_memory_defaults(
make_engine: unittest.mock.Mock, app: Flask, model_class: t.Any
) -> None:
SQLAlchemy(app, model_class=model_class)
options = make_engine.call_args[0][2]
assert options["poolclass"] is sa.pool.StaticPool
assert options["connect_args"]["check_same_thread"] is False
@unittest.mock.patch.object(SQLAlchemy, "_make_engine", autospec=True)
def test_mysql_defaults(
make_engine: unittest.mock.Mock, app: Flask, model_class: t.Any
) -> None:
app.config["SQLALCHEMY_DATABASE_URI"] = "mysql:///test"
SQLAlchemy(app, model_class=model_class)
options = make_engine.call_args[0][2]
assert options["pool_recycle"] == 7200
assert options["url"].query["charset"] == "utf8mb4"