Skip to content

Commit db1a2a3

Browse files
committed
feat: adds coverage
1 parent 56b2044 commit db1a2a3

File tree

1 file changed

+153
-0
lines changed

1 file changed

+153
-0
lines changed
+153
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
from __future__ import annotations
2+
3+
from pathlib import Path
4+
from typing import TYPE_CHECKING
5+
6+
import pytest
7+
from sqlalchemy import Column, ForeignKey, String, Table, create_engine, select
8+
from sqlalchemy.ext.associationproxy import AssociationProxy, association_proxy
9+
from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker, create_async_engine
10+
from sqlalchemy.orm import Mapped, Session, mapped_column, relationship, sessionmaker
11+
12+
if TYPE_CHECKING:
13+
from pytest import MonkeyPatch
14+
15+
16+
@pytest.mark.xdist_group("loader")
17+
def test_ap_sync(monkeypatch: MonkeyPatch, tmp_path: Path) -> None:
18+
from sqlalchemy.orm import DeclarativeBase
19+
20+
from advanced_alchemy import base, mixins
21+
22+
orm_registry = base.create_registry()
23+
24+
class NewIdentityBase(mixins.IdentityPrimaryKey, base.CommonTableAttributes, DeclarativeBase):
25+
registry = orm_registry
26+
27+
monkeypatch.setattr(base, "IdentityBase", NewIdentityBase)
28+
29+
product_tag_table = Table(
30+
"product_tag",
31+
orm_registry.metadata,
32+
Column("product_id", ForeignKey("product.id", ondelete="CASCADE"), primary_key=True), # pyright: ignore[reportUnknownArgumentType]
33+
Column("tag_id", ForeignKey("tag.id", ondelete="CASCADE"), primary_key=True), # pyright: ignore[reportUnknownArgumentType]
34+
)
35+
36+
class Tag(NewIdentityBase):
37+
name: Mapped[str] = mapped_column(index=True)
38+
products: Mapped[list[Product]] = relationship(
39+
secondary=lambda: product_tag_table,
40+
back_populates="product_tags",
41+
cascade="all, delete",
42+
passive_deletes=True,
43+
lazy="noload",
44+
)
45+
46+
class Product(NewIdentityBase):
47+
name: Mapped[str] = mapped_column(String(length=50)) # pyright: ignore
48+
product_tags: Mapped[list[Tag]] = relationship(
49+
secondary=lambda: product_tag_table,
50+
back_populates="products",
51+
cascade="all, delete",
52+
passive_deletes=True,
53+
lazy="joined",
54+
)
55+
tags: AssociationProxy[list[str]] = association_proxy(
56+
"product_tags",
57+
"name",
58+
creator=lambda name: Tag(name=name), # pyright: ignore[reportUnknownArgumentType,reportUnknownLambdaType]
59+
)
60+
61+
engine = create_engine(f"sqlite:///{tmp_path}/test.sqlite1.db", echo=True)
62+
session_factory: sessionmaker[Session] = sessionmaker(engine, expire_on_commit=False)
63+
64+
with engine.begin() as conn:
65+
Product.metadata.create_all(conn)
66+
67+
with session_factory() as db_session:
68+
product_1 = Product(name="Product 1", tags=["a new tag", "second tag"])
69+
db_session.add(product_1)
70+
71+
tags = db_session.execute(select(Tag)).unique().fetchall()
72+
assert len(tags) == 2
73+
74+
product_2 = Product(name="Product 2", tags=["third tag"])
75+
db_session.add(product_2)
76+
tags = db_session.execute(select(Tag)).unique().fetchall()
77+
assert len(tags) == 3
78+
79+
product_2.tags = []
80+
db_session.add(product_2)
81+
82+
product_2_validate = db_session.execute(select(Product).where(Product.name == "Product 2")).unique().fetchone()
83+
assert product_2_validate
84+
tags_2 = db_session.execute(select(Tag)).unique().fetchall()
85+
assert len(product_2_validate[0].product_tags) == 0
86+
assert len(tags_2) == 3
87+
# add more assertions
88+
89+
90+
@pytest.mark.xdist_group("loader")
91+
async def test_ap_async(monkeypatch: MonkeyPatch, tmp_path: Path) -> None:
92+
from sqlalchemy.orm import DeclarativeBase
93+
94+
from advanced_alchemy import base, mixins
95+
96+
orm_registry = base.create_registry()
97+
98+
class NewIdentityBase(mixins.IdentityPrimaryKey, base.CommonTableAttributes, DeclarativeBase):
99+
registry = orm_registry
100+
101+
monkeypatch.setattr(base, "IdentityBase", NewIdentityBase)
102+
103+
product_tag_table = Table(
104+
"product_tag",
105+
orm_registry.metadata,
106+
Column("product_id", ForeignKey("product.id", ondelete="CASCADE"), primary_key=True), # pyright: ignore[reportUnknownArgumentType]
107+
Column("tag_id", ForeignKey("tag.id", ondelete="CASCADE"), primary_key=True), # pyright: ignore[reportUnknownArgumentType]
108+
)
109+
110+
class Tag(NewIdentityBase):
111+
name: Mapped[str] = mapped_column(index=True)
112+
products: Mapped[list[Product]] = relationship(
113+
secondary=lambda: product_tag_table,
114+
back_populates="product_tags",
115+
cascade="all, delete",
116+
passive_deletes=True,
117+
lazy="noload",
118+
)
119+
120+
class Product(NewIdentityBase):
121+
name: Mapped[str] = mapped_column(String(length=50)) # pyright: ignore
122+
product_tags: Mapped[list[Tag]] = relationship(
123+
secondary=lambda: product_tag_table,
124+
back_populates="products",
125+
cascade="all, delete",
126+
passive_deletes=True,
127+
lazy="joined",
128+
)
129+
tags: AssociationProxy[list[str]] = association_proxy(
130+
"product_tags",
131+
"name",
132+
creator=lambda name: Tag(name=name), # pyright: ignore[reportUnknownArgumentType,reportUnknownLambdaType]
133+
)
134+
135+
engine = create_async_engine(f"sqlite+aiosqlite:///{tmp_path}/test.sqlite2.db", echo=True)
136+
session_factory: async_sessionmaker[AsyncSession] = async_sessionmaker(engine, expire_on_commit=False)
137+
138+
async with engine.begin() as conn:
139+
await conn.run_sync(Tag.metadata.create_all)
140+
141+
async with session_factory() as db_session:
142+
product_1 = Product(name="Product 1 async", tags=["a new tag", "second tag"])
143+
db_session.add(product_1)
144+
145+
tags = await db_session.execute(select(Tag))
146+
assert len(tags.unique().fetchall()) == 2
147+
148+
product_2 = Product(name="Product 2 async", tags=["third tag"])
149+
db_session.add(product_2)
150+
tags = await db_session.execute(select(Tag))
151+
assert len(tags.unique().fetchall()) == 3
152+
153+
# add more assertions

0 commit comments

Comments
 (0)