Skip to content

Commit b7d7340

Browse files
committed
test: add schema evolution
1 parent a41cc13 commit b7d7340

File tree

1 file changed

+77
-0
lines changed

1 file changed

+77
-0
lines changed

tests/test_schema_evolution.py

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
import pytest
2+
from pydantic import BaseModel, Field
3+
from memstate import MemoryStore, InMemoryStorage
4+
5+
6+
class UserProfileV1(BaseModel):
7+
username: str
8+
# the `role` field is missing yet
9+
10+
11+
class UserProfileV2(BaseModel):
12+
username: str
13+
role: str = Field(default="user")
14+
15+
16+
class UserProfileV3_Strict(BaseModel):
17+
username: str
18+
age: int # a new field without a default value
19+
20+
21+
class UserProfileV4(BaseModel):
22+
username: str
23+
24+
25+
@pytest.fixture
26+
def memory():
27+
return MemoryStore(InMemoryStorage())
28+
29+
30+
def test_schema_evolution_adding_field_with_default(memory):
31+
memory.register_schema("user", UserProfileV1)
32+
33+
id_v1 = memory.commit_model(UserProfileV1(username="legacy_user"))
34+
35+
memory.register_schema("user", UserProfileV2)
36+
37+
fact_data = memory.storage.load(id_v1)
38+
raw_payload = fact_data["payload"]
39+
40+
user_obj = UserProfileV2(**raw_payload)
41+
42+
assert user_obj.username == "legacy_user"
43+
assert user_obj.role == "user"
44+
45+
id_v2 = memory.commit_model(UserProfileV2(username="new_user", role="admin"))
46+
47+
raw_payload_v2 = memory.storage.load(id_v2)["payload"]
48+
assert raw_payload_v2["role"] == "admin"
49+
50+
51+
def test_schema_breaking_change(memory):
52+
memory.register_schema("user", UserProfileV1)
53+
id_v1 = memory.commit_model(UserProfileV1(username="young_user"))
54+
55+
memory.register_schema("user", UserProfileV3_Strict)
56+
57+
fact_data = memory.storage.load(id_v1)
58+
59+
with pytest.raises(ValueError) as excinfo:
60+
UserProfileV3_Strict(**fact_data["payload"])
61+
62+
assert "age" in str(excinfo.value)
63+
assert "Field required" in str(excinfo.value)
64+
65+
66+
def test_loading_rich_data_into_slim_model(memory):
67+
memory.register_schema("user", UserProfileV2)
68+
rich_id = memory.commit_model(UserProfileV2(username="rich_user", role="admin"))
69+
70+
memory.register_schema("user", UserProfileV4)
71+
72+
fact_data = memory.storage.load(rich_id)
73+
74+
user_obj = UserProfileV4(**fact_data["payload"])
75+
76+
assert user_obj.username == "rich_user"
77+
assert not hasattr(user_obj, "role")

0 commit comments

Comments
 (0)