51 lines
1.7 KiB
Python
51 lines
1.7 KiB
Python
"""Base.to_dict()/__repr__ caching + behavior.
|
|
|
|
These run once per row when serializing ORM rows (e.g. every event in a
|
|
messages page), so the mapped-column reflection is cached per class. Behavior
|
|
must stay identical.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from sqlalchemy import Integer, MetaData, String
|
|
from sqlalchemy.orm import Mapped, mapped_column
|
|
|
|
from deerflow.persistence.base import Base, _column_keys
|
|
|
|
|
|
class _Widget(Base):
|
|
__tablename__ = "_widget_to_dict_test"
|
|
# Keep this test-only model out of the application metadata. Pytest imports
|
|
# test modules during collection, so registering it on ``Base.metadata``
|
|
# would leak the table into unrelated create_all/schema-parity tests.
|
|
metadata = MetaData()
|
|
|
|
id: Mapped[int] = mapped_column(Integer, primary_key=True)
|
|
name: Mapped[str] = mapped_column(String(32))
|
|
color: Mapped[str] = mapped_column(String(16))
|
|
|
|
|
|
def test_to_dict_returns_all_columns():
|
|
w = _Widget(id=1, name="gear", color="red")
|
|
assert w.to_dict() == {"id": 1, "name": "gear", "color": "red"}
|
|
|
|
|
|
def test_to_dict_exclude():
|
|
w = _Widget(id=2, name="cog", color="blue")
|
|
assert w.to_dict(exclude={"color"}) == {"id": 2, "name": "cog"}
|
|
# Empty exclude behaves like no exclude.
|
|
assert w.to_dict(exclude=set()) == {"id": 2, "name": "cog", "color": "blue"}
|
|
|
|
|
|
def test_column_keys_are_cached_per_class():
|
|
# Same tuple object returned across calls -> reflection ran once.
|
|
assert _column_keys(_Widget) is _column_keys(_Widget)
|
|
assert _column_keys(_Widget) == ("id", "name", "color")
|
|
|
|
|
|
def test_repr_lists_columns():
|
|
w = _Widget(id=3, name="bolt", color="green")
|
|
r = repr(w)
|
|
assert r.startswith("_Widget(")
|
|
assert "id=3" in r and "name='bolt'" in r and "color='green'" in r
|