Skip to content

Commit 640fb03

Browse files
committed
🪛 Refactor test folder and added filter by object
1 parent e70532d commit 640fb03

20 files changed

+1070
-515
lines changed

‎saffier/db/queryset.py‎

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -89,13 +89,6 @@ def _build_tables_select_from_relationship(self):
8989

9090
return tables, select_from
9191

92-
def _build_select_for_update(self):
93-
# breakpoint()
94-
expression = expression.with_for_update(
95-
nowait=self._select_for_update_nowait, of=self.model_class
96-
)
97-
return expression
98-
9992
def _build_select(self):
10093
"""
10194
Builds the query select based on the given parameters and filters.
@@ -124,10 +117,6 @@ def _build_select(self):
124117
if self.distinct_on:
125118
expression = self._build_select_distinct(self.distinct_on, expression=expression)
126119

127-
# breakpoint()
128-
if self._select_for_update:
129-
expression = self._build_select_for_update(expression=expression)
130-
131120
return expression
132121

133122
def _filter_query(self, exclude: bool = False, **kwargs):
@@ -243,8 +232,6 @@ def _clone(self) -> "QuerySet[SaffierModel]":
243232
queryset._order_by = copy.copy(self._order_by)
244233
queryset._group_by = copy.copy(self._group_by)
245234
queryset.distinct_on = copy.copy(self.distinct_on)
246-
queryset._select_for_update = self._select_for_update
247-
queryset._select_for_update_nowait = self._select_for_update_nowait
248235
return queryset
249236

250237

@@ -265,8 +252,6 @@ def __init__(
265252
order_by=None,
266253
group_by=None,
267254
distinct_on=None,
268-
select_for_update=False,
269-
select_for_update_nowait=False,
270255
):
271256
super().__init__(model_class=model_class)
272257
self.model_class = model_class
@@ -277,8 +262,6 @@ def __init__(
277262
self._order_by = [] if order_by is None else order_by
278263
self._group_by = [] if group_by is None else group_by
279264
self.distinct_on = [] if distinct_on is None else distinct_on
280-
self._select_for_update = select_for_update
281-
self._select_for_update_nowait = select_for_update_nowait
282265

283266
def __get__(self, instance, owner):
284267
return self.__class__(model_class=owner)
@@ -400,15 +383,6 @@ def select_related(self, related):
400383
queryset._select_related = related
401384
return queryset
402385

403-
def select_for_update(self, nowait: bool = False):
404-
"""
405-
Locks a record and allows to update
406-
"""
407-
queryset = self._clone()
408-
queryset._select_for_update = True
409-
queryset._select_for_update_nowait = nowait
410-
return queryset
411-
412386
async def exists(self) -> bool:
413387
"""
414388
Returns a boolean indicating if a record exists or not.
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
import pytest
2+
from tests.settings import DATABASE_URL
3+
4+
import saffier
5+
from saffier.db import fields
6+
from saffier.db.connection import Database
7+
from saffier.exceptions import DoesNotFound, MultipleObjectsReturned
8+
9+
database = Database(url=DATABASE_URL)
10+
models = saffier.Registry(database=database)
11+
12+
pytestmark = pytest.mark.anyio
13+
14+
15+
class User(saffier.Model):
16+
id = saffier.IntegerField(primary_key=True)
17+
name = saffier.CharField(max_length=100)
18+
language = saffier.CharField(max_length=200, null=True)
19+
20+
class Meta:
21+
registry = models
22+
23+
24+
class Product(saffier.Model):
25+
id = saffier.IntegerField(primary_key=True)
26+
name = saffier.CharField(max_length=100)
27+
rating = saffier.IntegerField(minimum=1, maximum=5)
28+
in_stock = saffier.BooleanField(default=False)
29+
30+
class Meta:
31+
registry = models
32+
name = "products"
33+
34+
35+
@pytest.fixture(autouse=True, scope="function")
36+
async def create_test_database():
37+
await models.create_all()
38+
yield
39+
await models.drop_all()
40+
41+
42+
@pytest.fixture(autouse=True)
43+
async def rollback_connections():
44+
with database.force_rollback():
45+
async with database:
46+
yield
47+
48+
49+
def test_model_class():
50+
assert list(User.fields.keys()) == ["id", "name", "language"]
51+
assert isinstance(User.fields["id"], saffier.IntegerField)
52+
assert User.fields["id"].primary_key is True
53+
assert isinstance(User.fields["name"], saffier.CharField)
54+
assert User.fields["name"].validator.max_length == 100
55+
56+
with pytest.raises(ValueError):
57+
User(invalid="123")
58+
59+
assert User(id=1) != Product(id=1)
60+
assert User(id=1) != User(id=2)
61+
assert User(id=1) == User(id=1)
62+
63+
assert str(User(id=1)) == "User(id=1)"
64+
assert repr(User(id=1)) == "<User: User(id=1)>"
65+
66+
assert isinstance(User.query.schema.fields["id"], fields.Integer)
67+
assert isinstance(User.query.schema.fields["name"], fields.String)
68+
69+
70+
def test_model_pk():
71+
user = User(pk=1)
72+
assert user.pk == 1
73+
assert user.id == 1
74+
assert User.query.pkname == "id"
75+
76+
77+
async def test_model_crud():
78+
users = await User.query.all()
79+
assert users == []
80+
81+
user = await User.query.create(name="Test")
82+
users = await User.query.all()
83+
assert user.name == "Test"
84+
assert user.pk is not None
85+
assert users == [user]
86+
87+
lookup = await User.query.get()
88+
assert lookup == user
89+
90+
await user.update(name="Jane")
91+
users = await User.query.all()
92+
assert user.name == "Jane"
93+
assert user.pk is not None
94+
assert users == [user]
95+
96+
await user.delete()
97+
users = await User.query.all()
98+
assert users == []
99+
100+
101+
async def test_model_get():
102+
with pytest.raises(DoesNotFound):
103+
await User.query.get()
104+
105+
user = await User.query.create(name="Test")
106+
lookup = await User.query.get()
107+
assert lookup == user
108+
109+
user = await User.query.create(name="Jane")
110+
with pytest.raises(MultipleObjectsReturned):
111+
await User.query.get()
112+
113+
same_user = await User.query.get(pk=user.id)
114+
assert same_user.id == user.id
115+
assert same_user.pk == user.pk

‎tests/models/test_model.py‎ renamed to ‎tests/models/test_model_count.py‎

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,30 +2,21 @@
22
from tests.settings import DATABASE_URL
33

44
import saffier
5-
from saffier import Registry
65
from saffier.db.connection import Database
76

87
database = Database(url=DATABASE_URL)
9-
models = Registry(database=database)
10-
nother = Registry(database=database)
8+
models = saffier.Registry(database=database)
119

1210
pytestmark = pytest.mark.anyio
1311

1412

15-
class BaseUser(saffier.Model):
13+
class User(saffier.Model):
14+
id = saffier.IntegerField(primary_key=True)
1615
name = saffier.CharField(max_length=100)
1716
language = saffier.CharField(max_length=200, null=True)
1817

1918
class Meta:
2019
registry = models
21-
abstract = True
22-
23-
24-
class Profile(BaseUser):
25-
age = saffier.IntegerField()
26-
27-
def __str__(self):
28-
return f"Age: {self.age}, Name:{self.name}"
2920

3021

3122
@pytest.fixture(autouse=True, scope="function")
@@ -42,9 +33,10 @@ async def rollback_connections():
4233
yield
4334

4435

45-
async def xtest_meta_inheritance_registry():
46-
profile = await Profile.query.create(name="test", language="EN", age=23)
47-
48-
results = await Profile.query.filter()
36+
async def test_model_count():
37+
await User.query.create(name="Test")
38+
await User.query.create(name="Jane")
39+
await User.query.create(name="Lucy")
4940

50-
len(results)
41+
assert await User.query.count() == 3
42+
assert await User.query.filter(name__icontains="T").count() == 1
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
import pytest
2+
from tests.settings import DATABASE_URL
3+
4+
import saffier
5+
from saffier.db.connection import Database
6+
7+
database = Database(url=DATABASE_URL)
8+
models = saffier.Registry(database=database)
9+
10+
pytestmark = pytest.mark.anyio
11+
12+
13+
class Product(saffier.Model):
14+
id = saffier.IntegerField(primary_key=True)
15+
name = saffier.CharField(max_length=100)
16+
rating = saffier.IntegerField(minimum=1, maximum=5)
17+
in_stock = saffier.BooleanField(default=False)
18+
19+
class Meta:
20+
registry = models
21+
name = "products"
22+
23+
24+
@pytest.fixture(autouse=True, scope="function")
25+
async def create_test_database():
26+
await models.create_all()
27+
yield
28+
await models.drop_all()
29+
30+
31+
@pytest.fixture(autouse=True)
32+
async def rollback_connections():
33+
with database.force_rollback():
34+
async with database:
35+
yield
36+
37+
38+
@pytest.mark.skipif(database.url.dialect == "mysql", reason="Not supported on MySQL")
39+
@pytest.mark.skipif(database.url.dialect == "sqlite", reason="Not supported on SQLite")
40+
async def test_distinct():
41+
await Product.query.create(name="test", rating=5, in_stock=True)
42+
await Product.query.create(name="test", rating=4, in_stock=True)
43+
await Product.query.create(name="test", rating=2, in_stock=True)
44+
45+
products = await Product.query.distinct("name").all()
46+
assert len(products) == 1
47+
48+
products = await Product.query.distinct("rating").all()
49+
assert len(products) == 3
50+
51+
products = await Product.query.distinct("name", "in_stock").all()
52+
assert len(products) == 1
53+
54+
products = await Product.query.distinct("in_stock").all()
55+
assert len(products) == 1
56+
57+
products = await Product.query.distinct("rating", "in_stock").all()
58+
assert len(products) == 3
59+
60+
61+
@pytest.mark.skipif(database.url.dialect == "mysql", reason="Not supported on MySQL")
62+
@pytest.mark.skipif(database.url.dialect == "sqlite", reason="Not supported on SQLite")
63+
async def test_distinct_two_without_all():
64+
await Product.query.create(name="test", rating=5, in_stock=True)
65+
await Product.query.create(name="test", rating=4, in_stock=True)
66+
await Product.query.create(name="test", rating=2, in_stock=True)
67+
68+
products = await Product.query.distinct("name")
69+
assert len(products) == 1
70+
71+
products = await Product.query.distinct("rating")
72+
assert len(products) == 3
73+
74+
products = await Product.query.distinct("name", "in_stock")
75+
assert len(products) == 1
76+
77+
products = await Product.query.distinct("in_stock")
78+
assert len(products) == 1
79+
80+
products = await Product.query.distinct("rating", "in_stock")
81+
assert len(products) == 3
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import pytest
2+
from tests.settings import DATABASE_URL
3+
4+
import saffier
5+
from saffier.db.connection import Database
6+
7+
database = Database(url=DATABASE_URL)
8+
models = saffier.Registry(database=database)
9+
10+
pytestmark = pytest.mark.anyio
11+
12+
13+
class User(saffier.Model):
14+
id = saffier.IntegerField(primary_key=True)
15+
name = saffier.CharField(max_length=100)
16+
language = saffier.CharField(max_length=200, null=True)
17+
18+
class Meta:
19+
registry = models
20+
21+
22+
@pytest.fixture(autouse=True, scope="function")
23+
async def create_test_database():
24+
await models.create_all()
25+
yield
26+
await models.drop_all()
27+
28+
29+
@pytest.fixture(autouse=True)
30+
async def rollback_connections():
31+
with database.force_rollback():
32+
async with database:
33+
yield
34+
35+
36+
async def test_model_exists():
37+
await User.query.create(name="Test")
38+
assert await User.query.filter(name="Test").exists() is True
39+
assert await User.query.filter(name="Jane").exists() is False
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import pytest
2+
from tests.settings import DATABASE_URL
3+
4+
import saffier
5+
from saffier.db.connection import Database
6+
7+
database = Database(url=DATABASE_URL)
8+
models = saffier.Registry(database=database)
9+
10+
pytestmark = pytest.mark.anyio
11+
12+
13+
class User(saffier.Model):
14+
id = saffier.IntegerField(primary_key=True)
15+
name = saffier.CharField(max_length=100)
16+
language = saffier.CharField(max_length=200, null=True)
17+
18+
class Meta:
19+
registry = models
20+
21+
22+
@pytest.fixture(autouse=True, scope="function")
23+
async def create_test_database():
24+
await models.create_all()
25+
yield
26+
await models.drop_all()
27+
28+
29+
@pytest.fixture(autouse=True)
30+
async def rollback_connections():
31+
with database.force_rollback():
32+
async with database:
33+
yield
34+
35+
36+
async def test_model_first():
37+
Test = await User.query.create(name="Test")
38+
jane = await User.query.create(name="Jane")
39+
40+
assert await User.query.first() == Test
41+
assert await User.query.first(name="Jane") == jane
42+
assert await User.query.filter(name="Jane").first() == jane
43+
assert await User.query.filter(name="Lucy").first() is None

0 commit comments

Comments
 (0)