feat(backend): add PRAGMA user_version migration runner + 0001_initial
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
"""Tests for the PRAGMA user_version migration runner."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
import sqlalchemy as sa
|
||||
|
||||
from cyclone import db_migrate
|
||||
|
||||
|
||||
def _fresh_engine(tmp_path: Path) -> sa.Engine:
|
||||
return sa.create_engine(f"sqlite:///{tmp_path}/m.db", future=True)
|
||||
|
||||
|
||||
def _user_version(engine: sa.Engine) -> int:
|
||||
with engine.connect() as c:
|
||||
return c.exec_driver_sql("PRAGMA user_version").scalar() or 0
|
||||
|
||||
|
||||
def test_run_on_empty_db_bumps_to_latest(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
monkeypatch.setattr(db_migrate, "MIGRATIONS_DIR", tmp_path)
|
||||
(tmp_path / "0001_initial.sql").write_text("-- version: 1\nCREATE TABLE t (id INTEGER);\n")
|
||||
|
||||
engine = _fresh_engine(tmp_path)
|
||||
db_migrate.run(engine)
|
||||
|
||||
assert _user_version(engine) == 1
|
||||
with engine.connect() as c:
|
||||
rows = c.exec_driver_sql("SELECT name FROM sqlite_master WHERE type='table' AND name='t'").all()
|
||||
assert len(rows) == 1
|
||||
|
||||
|
||||
def test_run_is_idempotent(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
monkeypatch.setattr(db_migrate, "MIGRATIONS_DIR", tmp_path)
|
||||
(tmp_path / "0001_initial.sql").write_text("-- version: 1\nCREATE TABLE t (id INTEGER);\n")
|
||||
|
||||
engine = _fresh_engine(tmp_path)
|
||||
db_migrate.run(engine)
|
||||
db_migrate.run(engine) # second call should be a no-op
|
||||
|
||||
assert _user_version(engine) == 1
|
||||
|
||||
|
||||
def test_run_skips_already_applied_migrations(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
monkeypatch.setattr(db_migrate, "MIGRATIONS_DIR", tmp_path)
|
||||
(tmp_path / "0001_initial.sql").write_text("-- version: 1\nCREATE TABLE t1 (id INTEGER);\n")
|
||||
(tmp_path / "0002_add_col.sql").write_text("-- version: 2\nALTER TABLE t1 ADD COLUMN name TEXT;\n")
|
||||
|
||||
engine = _fresh_engine(tmp_path)
|
||||
db_migrate.run(engine)
|
||||
assert _user_version(engine) == 2
|
||||
|
||||
# Modify 0002 (a no-op for SQLite ALTER, but we want to verify the
|
||||
# runner doesn't re-run already-applied migrations).
|
||||
db_migrate.run(engine)
|
||||
assert _user_version(engine) == 2
|
||||
|
||||
|
||||
def test_run_raises_on_missing_version_header(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
monkeypatch.setattr(db_migrate, "MIGRATIONS_DIR", tmp_path)
|
||||
(tmp_path / "0001_bad.sql").write_text("CREATE TABLE t (id INTEGER);\n") # no header
|
||||
|
||||
engine = _fresh_engine(tmp_path)
|
||||
with pytest.raises(RuntimeError, match="missing '-- version"):
|
||||
db_migrate.run(engine)
|
||||
Reference in New Issue
Block a user