db-test-helpers-postgres 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- db_test_helpers_postgres-0.1.0/.gitignore +13 -0
- db_test_helpers_postgres-0.1.0/PKG-INFO +37 -0
- db_test_helpers_postgres-0.1.0/README.md +13 -0
- db_test_helpers_postgres-0.1.0/pyproject.toml +43 -0
- db_test_helpers_postgres-0.1.0/src/db_test_helpers/postgres/__init__.py +5 -0
- db_test_helpers_postgres-0.1.0/src/db_test_helpers/postgres/_adapter.py +57 -0
- db_test_helpers_postgres-0.1.0/src/db_test_helpers/postgres/_adapter_test.py +129 -0
- db_test_helpers_postgres-0.1.0/src/db_test_helpers/postgres/_e2e_test.py +162 -0
- db_test_helpers_postgres-0.1.0/src/db_test_helpers/postgres/conftest.py +32 -0
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: db-test-helpers-postgres
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: PostgreSQL adapter for db-test-helpers
|
|
5
|
+
Project-URL: Homepage, https://github.com/takaaa220/db-test-helpers
|
|
6
|
+
Project-URL: Repository, https://github.com/takaaa220/db-test-helpers
|
|
7
|
+
Project-URL: Issues, https://github.com/takaaa220/db-test-helpers/issues
|
|
8
|
+
Author: takaaa220
|
|
9
|
+
License-Expression: MIT
|
|
10
|
+
Keywords: database,postgresql,test-helpers,testing
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
+
Classifier: Topic :: Software Development :: Testing
|
|
17
|
+
Requires-Python: >=3.12
|
|
18
|
+
Requires-Dist: db-test-helpers<0.2.0,>=0.1.0
|
|
19
|
+
Requires-Dist: psycopg[binary]>=3.1
|
|
20
|
+
Provides-Extra: dev
|
|
21
|
+
Requires-Dist: pytest>=8.0; extra == 'dev'
|
|
22
|
+
Requires-Dist: ruff>=0.8; extra == 'dev'
|
|
23
|
+
Description-Content-Type: text/markdown
|
|
24
|
+
|
|
25
|
+
# db-test-helpers-postgres
|
|
26
|
+
|
|
27
|
+
PostgreSQL adapter for [db-test-helpers](https://github.com/takaaa220/db-test-helpers).
|
|
28
|
+
|
|
29
|
+
## Installation
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
pip install db-test-helpers-postgres
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Documentation
|
|
36
|
+
|
|
37
|
+
See the [main repository](https://github.com/takaaa220/db-test-helpers) for usage and documentation.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# db-test-helpers-postgres
|
|
2
|
+
|
|
3
|
+
PostgreSQL adapter for [db-test-helpers](https://github.com/takaaa220/db-test-helpers).
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install db-test-helpers-postgres
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Documentation
|
|
12
|
+
|
|
13
|
+
See the [main repository](https://github.com/takaaa220/db-test-helpers) for usage and documentation.
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "db-test-helpers-postgres"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "PostgreSQL adapter for db-test-helpers"
|
|
5
|
+
license = "MIT"
|
|
6
|
+
readme = "README.md"
|
|
7
|
+
authors = [{ name = "takaaa220" }]
|
|
8
|
+
keywords = ["testing", "database", "postgresql", "test-helpers"]
|
|
9
|
+
classifiers = [
|
|
10
|
+
"Development Status :: 3 - Alpha",
|
|
11
|
+
"Intended Audience :: Developers",
|
|
12
|
+
"License :: OSI Approved :: MIT License",
|
|
13
|
+
"Programming Language :: Python :: 3",
|
|
14
|
+
"Programming Language :: Python :: 3.12",
|
|
15
|
+
"Topic :: Software Development :: Testing",
|
|
16
|
+
]
|
|
17
|
+
requires-python = ">=3.12"
|
|
18
|
+
dependencies = [
|
|
19
|
+
"db-test-helpers>=0.1.0,<0.2.0",
|
|
20
|
+
"psycopg[binary]>=3.1",
|
|
21
|
+
]
|
|
22
|
+
|
|
23
|
+
[project.urls]
|
|
24
|
+
Homepage = "https://github.com/takaaa220/db-test-helpers"
|
|
25
|
+
Repository = "https://github.com/takaaa220/db-test-helpers"
|
|
26
|
+
Issues = "https://github.com/takaaa220/db-test-helpers/issues"
|
|
27
|
+
|
|
28
|
+
[project.optional-dependencies]
|
|
29
|
+
dev = [
|
|
30
|
+
"pytest>=8.0",
|
|
31
|
+
"ruff>=0.8",
|
|
32
|
+
]
|
|
33
|
+
|
|
34
|
+
[tool.uv.sources]
|
|
35
|
+
db-test-helpers = { workspace = true }
|
|
36
|
+
|
|
37
|
+
[build-system]
|
|
38
|
+
requires = ["hatchling"]
|
|
39
|
+
build-backend = "hatchling.build"
|
|
40
|
+
|
|
41
|
+
[tool.hatch.build.targets.wheel]
|
|
42
|
+
only-include = ["src/db_test_helpers/postgres"]
|
|
43
|
+
sources = ["src"]
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"""PostgreSQL adapter for db-test-helpers."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import Any
|
|
6
|
+
|
|
7
|
+
import psycopg
|
|
8
|
+
from psycopg import sql
|
|
9
|
+
from psycopg.rows import dict_row
|
|
10
|
+
|
|
11
|
+
from db_test_helpers.core._errors import UnsupportedError
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def _check_parent_path(parent_path: str) -> None:
|
|
15
|
+
if parent_path:
|
|
16
|
+
raise UnsupportedError("PostgresAdapter does not support parent_path")
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class PostgresAdapter:
|
|
20
|
+
"""DatabaseAdapter for PostgreSQL via psycopg.
|
|
21
|
+
|
|
22
|
+
Args:
|
|
23
|
+
conn: An open ``psycopg.Connection``.
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
def __init__(self, conn: psycopg.Connection) -> None:
|
|
27
|
+
self._conn = conn
|
|
28
|
+
|
|
29
|
+
def clear_group(self, group: str, parent_path: str) -> None:
|
|
30
|
+
_check_parent_path(parent_path)
|
|
31
|
+
self._conn.execute(sql.SQL("DELETE FROM {}").format(sql.Identifier(group)))
|
|
32
|
+
|
|
33
|
+
def write_record(self, group: str, parent_path: str, data: dict[str, Any]) -> dict[str, Any]:
|
|
34
|
+
_check_parent_path(parent_path)
|
|
35
|
+
if "__document_id__" in data:
|
|
36
|
+
raise UnsupportedError("PostgresAdapter does not support __document_id__")
|
|
37
|
+
with self._conn.cursor(row_factory=dict_row) as cur:
|
|
38
|
+
if not data:
|
|
39
|
+
cur.execute(sql.SQL("INSERT INTO {} DEFAULT VALUES RETURNING *").format(sql.Identifier(group)))
|
|
40
|
+
else:
|
|
41
|
+
columns = list(data.keys())
|
|
42
|
+
values = list(data.values())
|
|
43
|
+
query = sql.SQL("INSERT INTO {} ({}) VALUES ({}) RETURNING *").format(
|
|
44
|
+
sql.Identifier(group),
|
|
45
|
+
sql.SQL(", ").join(sql.Identifier(c) for c in columns),
|
|
46
|
+
sql.SQL(", ").join(sql.Placeholder() * len(values)),
|
|
47
|
+
)
|
|
48
|
+
cur.execute(query, values)
|
|
49
|
+
row = cur.fetchone()
|
|
50
|
+
assert row is not None
|
|
51
|
+
return row
|
|
52
|
+
|
|
53
|
+
def read_records(self, group: str, parent_path: str) -> list[dict[str, Any]]:
|
|
54
|
+
_check_parent_path(parent_path)
|
|
55
|
+
with self._conn.cursor(row_factory=dict_row) as cur:
|
|
56
|
+
cur.execute(sql.SQL("SELECT * FROM {}").format(sql.Identifier(group)))
|
|
57
|
+
return cur.fetchall()
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
"""Tests for PostgresAdapter."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import psycopg
|
|
6
|
+
import pytest
|
|
7
|
+
|
|
8
|
+
from db_test_helpers.core._errors import UnsupportedError
|
|
9
|
+
from db_test_helpers.postgres._adapter import PostgresAdapter
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def _create_table(conn: psycopg.Connection, ddl: str) -> None:
|
|
13
|
+
conn.execute(ddl)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def _insert(conn: psycopg.Connection, table: str, data: dict) -> None:
|
|
17
|
+
columns = list(data.keys())
|
|
18
|
+
values = list(data.values())
|
|
19
|
+
query = psycopg.sql.SQL("INSERT INTO {} ({}) VALUES ({})").format(
|
|
20
|
+
psycopg.sql.Identifier(table),
|
|
21
|
+
psycopg.sql.SQL(", ").join(psycopg.sql.Identifier(c) for c in columns),
|
|
22
|
+
psycopg.sql.SQL(", ").join(psycopg.sql.Placeholder() * len(values)),
|
|
23
|
+
)
|
|
24
|
+
conn.execute(query, values)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class TestDocumentIdGuard:
|
|
28
|
+
def test_rejects_document_id(self):
|
|
29
|
+
from unittest.mock import MagicMock
|
|
30
|
+
|
|
31
|
+
adapter = PostgresAdapter(MagicMock())
|
|
32
|
+
with pytest.raises(UnsupportedError, match="PostgresAdapter does not support __document_id__"):
|
|
33
|
+
adapter.write_record("t", "", {"__document_id__": "abc", "name": "Alice"})
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class TestParentPathGuard:
|
|
37
|
+
def test_clear_group_rejects_non_empty_parent_path(self):
|
|
38
|
+
from unittest.mock import MagicMock
|
|
39
|
+
|
|
40
|
+
adapter = PostgresAdapter(MagicMock())
|
|
41
|
+
with pytest.raises(UnsupportedError, match="does not support parent_path"):
|
|
42
|
+
adapter.clear_group("t", "some/path")
|
|
43
|
+
|
|
44
|
+
def test_write_record_rejects_non_empty_parent_path(self):
|
|
45
|
+
from unittest.mock import MagicMock
|
|
46
|
+
|
|
47
|
+
adapter = PostgresAdapter(MagicMock())
|
|
48
|
+
with pytest.raises(UnsupportedError, match="does not support parent_path"):
|
|
49
|
+
adapter.write_record("t", "some/path", {"x": 1})
|
|
50
|
+
|
|
51
|
+
def test_read_records_rejects_non_empty_parent_path(self):
|
|
52
|
+
from unittest.mock import MagicMock
|
|
53
|
+
|
|
54
|
+
adapter = PostgresAdapter(MagicMock())
|
|
55
|
+
with pytest.raises(UnsupportedError, match="does not support parent_path"):
|
|
56
|
+
adapter.read_records("t", "some/path")
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
class TestClearGroup:
|
|
60
|
+
def test_clear_deletes_all_rows(self, conn):
|
|
61
|
+
_create_table(conn, "CREATE TABLE users (id SERIAL PRIMARY KEY, name TEXT)")
|
|
62
|
+
_insert(conn, "users", {"name": "Alice"})
|
|
63
|
+
_insert(conn, "users", {"name": "Bob"})
|
|
64
|
+
|
|
65
|
+
adapter = PostgresAdapter(conn)
|
|
66
|
+
adapter.clear_group("users", "")
|
|
67
|
+
|
|
68
|
+
rows = conn.execute("SELECT * FROM users").fetchall()
|
|
69
|
+
assert rows == []
|
|
70
|
+
|
|
71
|
+
def test_clear_empty_table(self, conn):
|
|
72
|
+
_create_table(conn, "CREATE TABLE users (id SERIAL PRIMARY KEY, name TEXT)")
|
|
73
|
+
|
|
74
|
+
adapter = PostgresAdapter(conn)
|
|
75
|
+
adapter.clear_group("users", "")
|
|
76
|
+
|
|
77
|
+
rows = conn.execute("SELECT * FROM users").fetchall()
|
|
78
|
+
assert rows == []
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
class TestWriteRecord:
|
|
82
|
+
def test_write_inserts_row(self, conn):
|
|
83
|
+
_create_table(conn, "CREATE TABLE users (name TEXT, age INTEGER)")
|
|
84
|
+
|
|
85
|
+
adapter = PostgresAdapter(conn)
|
|
86
|
+
result = adapter.write_record("users", "", {"name": "Alice", "age": 30})
|
|
87
|
+
|
|
88
|
+
assert result["name"] == "Alice"
|
|
89
|
+
assert result["age"] == 30
|
|
90
|
+
|
|
91
|
+
def test_write_returns_db_defaults(self, conn):
|
|
92
|
+
_create_table(conn, "CREATE TABLE users (id SERIAL PRIMARY KEY, name TEXT)")
|
|
93
|
+
|
|
94
|
+
adapter = PostgresAdapter(conn)
|
|
95
|
+
result = adapter.write_record("users", "", {"name": "Alice"})
|
|
96
|
+
|
|
97
|
+
assert result["id"] is not None
|
|
98
|
+
assert result["name"] == "Alice"
|
|
99
|
+
|
|
100
|
+
def test_write_empty_data_uses_default_values(self, conn):
|
|
101
|
+
_create_table(conn, "CREATE TABLE users (id SERIAL PRIMARY KEY, name TEXT DEFAULT 'anonymous')")
|
|
102
|
+
|
|
103
|
+
adapter = PostgresAdapter(conn)
|
|
104
|
+
result = adapter.write_record("users", "", {})
|
|
105
|
+
|
|
106
|
+
assert result["id"] is not None
|
|
107
|
+
assert result["name"] == "anonymous"
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
class TestReadRecords:
|
|
111
|
+
def test_read_empty_table(self, conn):
|
|
112
|
+
_create_table(conn, "CREATE TABLE users (id SERIAL PRIMARY KEY, name TEXT)")
|
|
113
|
+
|
|
114
|
+
adapter = PostgresAdapter(conn)
|
|
115
|
+
result = adapter.read_records("users", "")
|
|
116
|
+
|
|
117
|
+
assert result == []
|
|
118
|
+
|
|
119
|
+
def test_read_multiple_records(self, conn):
|
|
120
|
+
_create_table(conn, "CREATE TABLE users (name TEXT, age INTEGER)")
|
|
121
|
+
_insert(conn, "users", {"name": "Alice", "age": 30})
|
|
122
|
+
_insert(conn, "users", {"name": "Bob", "age": 25})
|
|
123
|
+
|
|
124
|
+
adapter = PostgresAdapter(conn)
|
|
125
|
+
result = adapter.read_records("users", "")
|
|
126
|
+
|
|
127
|
+
assert len(result) == 2
|
|
128
|
+
names = {r["name"] for r in result}
|
|
129
|
+
assert names == {"Alice", "Bob"}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
"""E2E tests: set_db_data + verify_db_data with PostgreSQL."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import pytest
|
|
6
|
+
|
|
7
|
+
from db_test_helpers.core import Config, UnsupportedError, set_db_data, verify_db_data
|
|
8
|
+
from db_test_helpers.postgres import PostgresAdapter
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@pytest.fixture
|
|
12
|
+
def _users_table(conn):
|
|
13
|
+
conn.execute("CREATE TABLE users (name TEXT, age INTEGER, active BOOLEAN)")
|
|
14
|
+
yield
|
|
15
|
+
conn.execute("DROP TABLE IF EXISTS users")
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class TestE2eBasic:
|
|
19
|
+
@pytest.mark.usefixtures("_users_table")
|
|
20
|
+
def test_set_and_verify_order_independent(self, conn, tmp_path):
|
|
21
|
+
seed = tmp_path / "seed.yaml"
|
|
22
|
+
seed.write_text(
|
|
23
|
+
"""\
|
|
24
|
+
users:
|
|
25
|
+
- name: "Alice"
|
|
26
|
+
age: 30
|
|
27
|
+
active: true
|
|
28
|
+
- name: "Bob"
|
|
29
|
+
age: 25
|
|
30
|
+
active: false
|
|
31
|
+
"""
|
|
32
|
+
)
|
|
33
|
+
expected = tmp_path / "expected.yaml"
|
|
34
|
+
expected.write_text(
|
|
35
|
+
"""\
|
|
36
|
+
users:
|
|
37
|
+
- name: "Bob"
|
|
38
|
+
age: 25
|
|
39
|
+
active: false
|
|
40
|
+
- name: "Alice"
|
|
41
|
+
age: 30
|
|
42
|
+
active: true
|
|
43
|
+
"""
|
|
44
|
+
)
|
|
45
|
+
adapter = PostgresAdapter(conn)
|
|
46
|
+
set_db_data(adapter, str(seed))
|
|
47
|
+
verify_db_data(adapter, str(expected))
|
|
48
|
+
|
|
49
|
+
@pytest.mark.usefixtures("_users_table")
|
|
50
|
+
def test_set_replaces_existing(self, conn, tmp_path):
|
|
51
|
+
conn.execute("INSERT INTO users (name, age, active) VALUES ('OldUser', 99, true)")
|
|
52
|
+
|
|
53
|
+
seed = tmp_path / "seed.yaml"
|
|
54
|
+
seed.write_text(
|
|
55
|
+
"""\
|
|
56
|
+
users:
|
|
57
|
+
- name: "Alice"
|
|
58
|
+
age: 30
|
|
59
|
+
active: true
|
|
60
|
+
"""
|
|
61
|
+
)
|
|
62
|
+
adapter = PostgresAdapter(conn)
|
|
63
|
+
set_db_data(adapter, str(seed))
|
|
64
|
+
|
|
65
|
+
rows = conn.execute("SELECT * FROM users").fetchall()
|
|
66
|
+
assert len(rows) == 1
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
class TestE2eChildren:
|
|
70
|
+
@pytest.mark.usefixtures("_users_table")
|
|
71
|
+
def test_children_raises_not_implemented(self, conn, tmp_path):
|
|
72
|
+
seed = tmp_path / "seed.yaml"
|
|
73
|
+
seed.write_text(
|
|
74
|
+
"""\
|
|
75
|
+
users:
|
|
76
|
+
- name: "Alice"
|
|
77
|
+
age: 30
|
|
78
|
+
active: true
|
|
79
|
+
__children__:
|
|
80
|
+
posts:
|
|
81
|
+
- title: "Hello"
|
|
82
|
+
"""
|
|
83
|
+
)
|
|
84
|
+
adapter = PostgresAdapter(conn)
|
|
85
|
+
with pytest.raises(UnsupportedError, match="does not support __children__"):
|
|
86
|
+
set_db_data(adapter, str(seed))
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
class TestE2eDsl:
|
|
90
|
+
@pytest.mark.usefixtures("_users_table")
|
|
91
|
+
def test_var_and_any(self, conn, tmp_path):
|
|
92
|
+
seed = tmp_path / "seed.yaml"
|
|
93
|
+
seed.write_text(
|
|
94
|
+
"""\
|
|
95
|
+
users:
|
|
96
|
+
- name: "$var(user_name)"
|
|
97
|
+
age: 30
|
|
98
|
+
active: true
|
|
99
|
+
"""
|
|
100
|
+
)
|
|
101
|
+
expected = tmp_path / "expected.yaml"
|
|
102
|
+
expected.write_text(
|
|
103
|
+
"""\
|
|
104
|
+
users:
|
|
105
|
+
- name: "$var(user_name)"
|
|
106
|
+
age: "$any()"
|
|
107
|
+
active: true
|
|
108
|
+
"""
|
|
109
|
+
)
|
|
110
|
+
adapter = PostgresAdapter(conn)
|
|
111
|
+
config = Config(variables={"user_name": "Alice"})
|
|
112
|
+
set_db_data(adapter, str(seed), config)
|
|
113
|
+
verify_db_data(adapter, str(expected), config)
|
|
114
|
+
|
|
115
|
+
@pytest.mark.usefixtures("_users_table")
|
|
116
|
+
def test_matchers_in_verify(self, conn, tmp_path):
|
|
117
|
+
seed = tmp_path / "seed.yaml"
|
|
118
|
+
seed.write_text(
|
|
119
|
+
"""\
|
|
120
|
+
users:
|
|
121
|
+
- name: "Alice"
|
|
122
|
+
age: 30
|
|
123
|
+
active: true
|
|
124
|
+
"""
|
|
125
|
+
)
|
|
126
|
+
expected = tmp_path / "expected.yaml"
|
|
127
|
+
expected.write_text(
|
|
128
|
+
"""\
|
|
129
|
+
users:
|
|
130
|
+
- name: "$eq(Alice)"
|
|
131
|
+
age: "$and($gt(0),$lt(100))"
|
|
132
|
+
active: true
|
|
133
|
+
"""
|
|
134
|
+
)
|
|
135
|
+
adapter = PostgresAdapter(conn)
|
|
136
|
+
set_db_data(adapter, str(seed))
|
|
137
|
+
verify_db_data(adapter, str(expected))
|
|
138
|
+
|
|
139
|
+
@pytest.mark.usefixtures("_users_table")
|
|
140
|
+
def test_verify_failure(self, conn, tmp_path):
|
|
141
|
+
seed = tmp_path / "seed.yaml"
|
|
142
|
+
seed.write_text(
|
|
143
|
+
"""\
|
|
144
|
+
users:
|
|
145
|
+
- name: "Alice"
|
|
146
|
+
age: 30
|
|
147
|
+
active: true
|
|
148
|
+
"""
|
|
149
|
+
)
|
|
150
|
+
expected = tmp_path / "expected.yaml"
|
|
151
|
+
expected.write_text(
|
|
152
|
+
"""\
|
|
153
|
+
users:
|
|
154
|
+
- name: "Bob"
|
|
155
|
+
age: 30
|
|
156
|
+
active: true
|
|
157
|
+
"""
|
|
158
|
+
)
|
|
159
|
+
adapter = PostgresAdapter(conn)
|
|
160
|
+
set_db_data(adapter, str(seed))
|
|
161
|
+
with pytest.raises(AssertionError):
|
|
162
|
+
verify_db_data(adapter, str(expected))
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"""Shared fixtures for PostgreSQL adapter tests."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import os
|
|
6
|
+
|
|
7
|
+
import psycopg
|
|
8
|
+
import pytest
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@pytest.fixture
|
|
12
|
+
def conn():
|
|
13
|
+
port = os.environ.get("POSTGRES_PORT", "5432")
|
|
14
|
+
connection = psycopg.connect(
|
|
15
|
+
host="localhost",
|
|
16
|
+
port=int(port),
|
|
17
|
+
user="test",
|
|
18
|
+
password="test",
|
|
19
|
+
dbname="testdb",
|
|
20
|
+
autocommit=True,
|
|
21
|
+
)
|
|
22
|
+
yield connection
|
|
23
|
+
_drop_all_tables(connection)
|
|
24
|
+
connection.close()
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def _drop_all_tables(conn: psycopg.Connection) -> None:
|
|
28
|
+
rows = conn.execute(
|
|
29
|
+
"SELECT tablename FROM pg_tables WHERE schemaname = 'public'"
|
|
30
|
+
).fetchall()
|
|
31
|
+
for (table,) in rows:
|
|
32
|
+
conn.execute(psycopg.sql.SQL("DROP TABLE {} CASCADE").format(psycopg.sql.Identifier(table)))
|