Coverage for tests/packaging/test_optional_dependencies.py: 100%
29 statements
« prev ^ index » next coverage.py v7.14.1, created at 2026-06-07 21:13 +0300
« prev ^ index » next coverage.py v7.14.1, created at 2026-06-07 21:13 +0300
1"""Optional backend dependency contract tests."""
3from __future__ import annotations
5import subprocess
6import sys
7from importlib.metadata import metadata
9from snektest import assert_eq, assert_in, test
12def _run_python(script: str) -> subprocess.CompletedProcess[str]:
13 """Run an import-isolated Python snippet in the current test environment."""
15 return subprocess.run(
16 [sys.executable, "-c", script],
17 check=False,
18 capture_output=True,
19 text=True,
20 )
23@test(mark="medium")
24def package_metadata_declares_backend_driver_extras() -> None:
25 """SQLite and MariaDB drivers are optional backend extras."""
27 package_metadata = metadata("snekql")
28 extras = package_metadata.get_all("Provides-Extra") or []
29 requirements = package_metadata.get_all("Requires-Dist") or []
31 assert_in("aiosqlite", extras)
32 assert_in("aiomysql", extras)
33 assert any(
34 requirement.startswith("aiosqlite") and "extra == 'aiosqlite'" in requirement
35 for requirement in requirements
36 )
37 assert any(
38 requirement.startswith("aiomysql") and "extra == 'aiomysql'" in requirement
39 for requirement in requirements
40 )
41 assert not any(
42 requirement.startswith(("aiosqlite", "aiomysql"))
43 and "extra ==" not in requirement
44 for requirement in requirements
45 )
48@test(mark="medium")
49def public_imports_do_not_import_optional_drivers() -> None:
50 """Public imports and configs do not load optional database drivers."""
52 script = """
53import sys
54import snekql
55from snekql import mariadb, sqlite
56from snekql.testing import mariadb as testing_mariadb
58if "aiosqlite" in sys.modules:
59 raise AssertionError("aiosqlite was imported")
60if "aiomysql" in sys.modules:
61 raise AssertionError("aiomysql was imported")
62_ = sqlite.Config(database=":memory:")
63_ = mariadb.Config(database="app", user="snekql")
64_ = testing_mariadb.temporary_mariadb_server()
65print("ok")
66"""
68 result = _run_python(script)
70 assert_eq(result.returncode, 0)
71 assert_eq(result.stdout.strip(), "ok")
74@test(mark="medium")
75def sqlite_initialization_without_extra_reports_install_hint() -> None:
76 """Runtime initialization explains how to install a missing SQLite driver."""
78 script = """
79from __future__ import annotations
81import asyncio
82import builtins
84import snekql
85from snekql import Database, sqlite
86from tests.helpers import NULL_LOGGER
88original_import = builtins.__import__
91def block_aiosqlite(name, globals=None, locals=None, fromlist=(), level=0):
92 if name == "aiosqlite" or name.startswith("aiosqlite."):
93 raise ModuleNotFoundError("No module named 'aiosqlite'", name="aiosqlite")
94 return original_import(name, globals, locals, fromlist, level)
97async def main() -> None:
98 builtins.__import__ = block_aiosqlite
99 try:
100 try:
101 _ = await Database.initialize(sqlite.Config(database=":memory:"), logger=NULL_LOGGER)
102 except snekql.DatabaseRuntimeError as error:
103 print(error)
104 return
105 raise AssertionError("SQLite initialization unexpectedly succeeded")
106 finally:
107 builtins.__import__ = original_import
110asyncio.run(main())
111"""
113 result = _run_python(script)
115 assert_eq(result.returncode, 0)
116 assert_in("snekql[aiosqlite]", result.stdout)