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

1"""Optional backend dependency contract tests.""" 

2 

3from __future__ import annotations 

4 

5import subprocess 

6import sys 

7from importlib.metadata import metadata 

8 

9from snektest import assert_eq, assert_in, test 

10 

11 

12def _run_python(script: str) -> subprocess.CompletedProcess[str]: 

13 """Run an import-isolated Python snippet in the current test environment.""" 

14 

15 return subprocess.run( 

16 [sys.executable, "-c", script], 

17 check=False, 

18 capture_output=True, 

19 text=True, 

20 ) 

21 

22 

23@test(mark="medium") 

24def package_metadata_declares_backend_driver_extras() -> None: 

25 """SQLite and MariaDB drivers are optional backend extras.""" 

26 

27 package_metadata = metadata("snekql") 

28 extras = package_metadata.get_all("Provides-Extra") or [] 

29 requirements = package_metadata.get_all("Requires-Dist") or [] 

30 

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 ) 

46 

47 

48@test(mark="medium") 

49def public_imports_do_not_import_optional_drivers() -> None: 

50 """Public imports and configs do not load optional database drivers.""" 

51 

52 script = """ 

53import sys 

54import snekql 

55from snekql import mariadb, sqlite 

56from snekql.testing import mariadb as testing_mariadb 

57 

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""" 

67 

68 result = _run_python(script) 

69 

70 assert_eq(result.returncode, 0) 

71 assert_eq(result.stdout.strip(), "ok") 

72 

73 

74@test(mark="medium") 

75def sqlite_initialization_without_extra_reports_install_hint() -> None: 

76 """Runtime initialization explains how to install a missing SQLite driver.""" 

77 

78 script = """ 

79from __future__ import annotations 

80 

81import asyncio 

82import builtins 

83 

84import snekql 

85from snekql import Database, sqlite 

86from tests.helpers import NULL_LOGGER 

87 

88original_import = builtins.__import__ 

89 

90 

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) 

95 

96 

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 

108 

109 

110asyncio.run(main()) 

111""" 

112 

113 result = _run_python(script) 

114 

115 assert_eq(result.returncode, 0) 

116 assert_in("snekql[aiosqlite]", result.stdout)