| """ |
| 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 |
|
|
| |
| 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(): |
| |
| 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: |
| |
| 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): |
| |
| 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 |
|
|