Fix creation of new database, ensuring that a bootstrap record of the initial state is always written.
This commit is contained in:
@@ -70,6 +70,18 @@ def change_actions(path: Path, format_config) -> list[str]:
|
||||
return actions
|
||||
|
||||
|
||||
def read_changes(path: Path, format_config) -> list[ChangeRecord]:
|
||||
_, serializer_cls = format_config
|
||||
serializer = serializer_cls()
|
||||
framer = serializer.framer_cls()
|
||||
records: list[ChangeRecord] = []
|
||||
for is_snapshot, payload, _, _ in framer.iter_records(path.read_bytes(), 0):
|
||||
if is_snapshot:
|
||||
continue
|
||||
records.append(serializer.decode(payload, type=ChangeRecord))
|
||||
return records
|
||||
|
||||
|
||||
def make_migrations_module(name: str, fn_name: str, fn):
|
||||
mod = ModuleType(name)
|
||||
mod.__dict__[fn_name] = fn
|
||||
|
||||
@@ -17,6 +17,7 @@ from .support import (
|
||||
change_actions,
|
||||
fixed_change,
|
||||
make_kanta,
|
||||
read_changes,
|
||||
seed_single_change,
|
||||
)
|
||||
|
||||
@@ -30,6 +31,44 @@ async def test_load_empty(tmp_path, format_config):
|
||||
await kanta.close()
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_new_file_writes_bootstrap_record_without_handlers(
|
||||
tmp_path, format_config
|
||||
):
|
||||
path = tmp_path / "test.db"
|
||||
kanta = make_kanta(path, Data, format_config)
|
||||
await kanta.open()
|
||||
await kanta.close()
|
||||
|
||||
records = read_changes(path, format_config)
|
||||
assert len(records) == 1
|
||||
assert records[0].a == "bootstrap"
|
||||
assert records[0].diff == {"$replace": {"users": {}, "counter": 0}}
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_new_file_persists_initial_state_for_roundtrip(tmp_path, format_config):
|
||||
path = tmp_path / "test.db"
|
||||
kanta = make_kanta(
|
||||
path, Data(counter=5, users={"alice": User(name="Alice")}), format_config
|
||||
)
|
||||
await kanta.open()
|
||||
await kanta.close()
|
||||
|
||||
records = read_changes(path, format_config)
|
||||
assert len(records) == 1
|
||||
assert records[0].a == "bootstrap"
|
||||
assert records[0].diff == {
|
||||
"$replace": {"users": {"alice": {"name": "Alice", "age": 0}}, "counter": 5}
|
||||
}
|
||||
|
||||
kanta2 = make_kanta(path, Data, format_config)
|
||||
await kanta2.open()
|
||||
assert kanta2.data.counter == 5
|
||||
assert kanta2.data.users["alice"].name == "Alice"
|
||||
await kanta2.close()
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_open_overwrites_caller_owned_root_data(tmp_path, format_config):
|
||||
path = tmp_path / "test.db"
|
||||
|
||||
+3
-2
@@ -82,8 +82,9 @@ async def test_transaction_mtime_false_preserves_mtime(tmp_path, format_config):
|
||||
continue
|
||||
records.append(serializer.decode(payload, type=ChangeRecord))
|
||||
|
||||
assert records[0].m == first_m
|
||||
assert records[1].m is None
|
||||
assert records[0].a == "bootstrap"
|
||||
assert records[1].m == first_m
|
||||
assert records[2].m is None
|
||||
assert kanta.mtime == first_m
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user