""" Regression tests for the SQLite provider selection in db_utils. Guards the fix for the pod crash where ``pysqlite3`` was preferred even though its build lacked FTS5, causing ``no such module: fts5`` mid-init. """ import os import sqlite3 as stdlib_sqlite3 import sys import pytest # Add backend to path sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) import db_utils def test_selected_provider_supports_fts5_and_extensions(): """The provider db_utils actually selected must satisfy both requirements.""" assert db_utils._probe_fts5(db_utils.sqlite3) assert db_utils._probe_loadable_extensions(db_utils.sqlite3) def test_probe_fts5_true_for_stdlib_when_available(): # The test environment's stdlib sqlite3 is expected to have FTS5. assert db_utils._probe_fts5(stdlib_sqlite3) is True def test_probe_fts5_false_for_module_without_fts5(): class _FakeConn: def execute(self, _sql): raise stdlib_sqlite3.OperationalError("no such module: fts5") def close(self): pass class _FakeModule: def connect(self, _target): return _FakeConn() assert db_utils._probe_fts5(_FakeModule()) is False def test_probe_loadable_extensions_false_when_attr_missing(): class _FakeConn: # No enable_load_extension attribute. def close(self): pass class _FakeModule: def connect(self, _target): return _FakeConn() assert db_utils._probe_loadable_extensions(_FakeModule()) is False def test_select_falls_back_to_stdlib_when_pysqlite3_lacks_fts5(monkeypatch): """When pysqlite3 lacks FTS5 but stdlib has both, pick stdlib (the pod case).""" def fake_probe_fts5(module): # Simulate a pysqlite3 build without FTS5. if getattr(module, "_is_fake_pysqlite3", False): return False return module is stdlib_sqlite3 monkeypatch.setattr(db_utils, "_probe_fts5", fake_probe_fts5) monkeypatch.setattr(db_utils, "_probe_loadable_extensions", lambda module: True) class _FakePysqlite3: _is_fake_pysqlite3 = True fake_pysqlite3 = _FakePysqlite3() monkeypatch.setitem(sys.modules, "pysqlite3", fake_pysqlite3) selected = db_utils._select_sqlite_module() assert selected is stdlib_sqlite3 def test_select_raises_actionable_error_when_no_provider_has_fts5(monkeypatch): monkeypatch.setattr(db_utils, "_probe_fts5", lambda module: False) monkeypatch.setattr(db_utils, "_probe_loadable_extensions", lambda module: True) with pytest.raises(RuntimeError) as exc_info: db_utils._select_sqlite_module() message = str(exc_info.value) assert "FTS5" in message assert "pysqlite3-binary" in message # actionable fix is included