Skip to content

Commit cd55acf

Browse files
committed
feat: update tests
1 parent 37e02c2 commit cd55acf

5 files changed

Lines changed: 138 additions & 155 deletions

File tree

commondao/commondao.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ def dump_entity_to_row(entity: BaseModel, *, exclude_none: bool) -> RowDict:
197197
result: dict[str, Any] = {}
198198
for key, value in data.items():
199199
if isinstance(value, (dict, list)):
200-
result[key] = orjson.dumps(value)
200+
result[key] = orjson.dumps(value).decode()
201201
elif isinstance(value, Enum):
202202
result[key] = value.value
203203
else:

tests/e2e/test_crud_operations.py

Lines changed: 67 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,19 @@
11
import os
2-
from typing import Any, Dict, Optional
2+
from typing import Annotated, Any, AsyncGenerator, Dict, Optional
33

44
import pytest
55
import pytest_asyncio
66
from pydantic import BaseModel
77

8-
from commondao import Commondao, connect
8+
from commondao import Commondao, connect, NotFoundError, is_row_dict
9+
from commondao.annotation import TableId
910

1011

1112
class User(BaseModel):
12-
id: Optional[int] = None
13+
id: Annotated[Optional[int], TableId('test_users')] = None
1314
name: str
1415
email: str
15-
age: int
16+
age: Optional[int] = None
1617

1718

1819
class TestCRUDOperations:
@@ -28,7 +29,7 @@ async def db_config(self) -> Dict[str, Any]:
2829
}
2930

3031
@pytest_asyncio.fixture
31-
async def db(self, db_config: Dict[str, Any]):
32+
async def db(self, db_config: Dict[str, Any]) -> AsyncGenerator[Commondao, None]:
3233
async with connect(**db_config) as db:
3334
await db.execute_mutation('''
3435
CREATE TABLE IF NOT EXISTS test_users (
@@ -45,133 +46,109 @@ async def db(self, db_config: Dict[str, Any]):
4546
@pytest.mark.asyncio
4647
async def test_insert(self, db: Commondao) -> None:
4748
# 测试基本插入
48-
affected_rows = await db.insert(
49-
'test_users',
50-
data={'name': 'Alice', 'email': 'alice@example.com', 'age': 30}
51-
)
49+
user = User(name='Alice', email='alice@example.com', age=30)
50+
affected_rows = await db.insert(user)
5251
assert affected_rows == 1
5352
# 验证数据已插入
5453
result = await db.execute_query("SELECT * FROM test_users WHERE name = 'Alice'")
5554
assert len(result) == 1
55+
assert is_row_dict(result[0])
5656
assert result[0]['email'] == 'alice@example.com'
5757
assert result[0]['age'] == 30
5858

5959
@pytest.mark.asyncio
6060
async def test_insert_ignore(self, db: Commondao) -> None:
6161
# 首先插入一条记录
62-
await db.insert(
63-
'test_users',
64-
data={'name': 'Bob', 'email': 'bob@example.com', 'age': 25}
65-
)
62+
user1 = User(name='Bob', email='bob@example.com', age=25)
63+
await db.insert(user1)
6664
# 尝试使用相同的email插入,应该被忽略
67-
affected_rows = await db.insert(
68-
'test_users',
69-
data={'name': 'Bob2', 'email': 'bob@example.com', 'age': 26},
70-
ignore=True
71-
)
65+
user2 = User(name='Bob2', email='bob@example.com', age=26)
66+
affected_rows = await db.insert(user2, ignore=True)
7267
assert affected_rows == 0
7368
# 验证原始数据未被修改
7469
result = await db.execute_query("SELECT * FROM test_users WHERE email = 'bob@example.com'")
7570
assert len(result) == 1
71+
assert is_row_dict(result[0])
7672
assert result[0]['name'] == 'Bob'
7773
assert result[0]['age'] == 25
7874

7975
@pytest.mark.asyncio
8076
async def test_insert_with_none_values(self, db: Commondao) -> None:
8177
# 测试包含None值的插入
82-
affected_rows = await db.insert(
83-
'test_users',
84-
data={'name': 'Charlie', 'email': 'charlie@example.com', 'age': None}
85-
)
78+
user = User(name='Charlie', email='charlie@example.com', age=None)
79+
affected_rows = await db.insert(user)
8680
assert affected_rows == 1
8781
# 验证数据已插入,且None值正确处理
8882
result = await db.execute_query("SELECT * FROM test_users WHERE name = 'Charlie'")
8983
assert len(result) == 1
84+
assert is_row_dict(result[0])
9085
assert result[0]['email'] == 'charlie@example.com'
9186
assert result[0]['age'] is None
9287

9388
@pytest.mark.asyncio
9489
async def test_update_by_key(self, db: Commondao) -> None:
9590
# 插入测试数据
96-
await db.insert(
97-
'test_users',
98-
data={'name': 'David', 'email': 'david@example.com', 'age': 40}
99-
)
91+
user = User(name='David', email='david@example.com', age=40)
92+
await db.insert(user)
10093
# 通过key更新数据
101-
affected_rows = await db.update_by_key(
102-
'test_users',
103-
key={'name': 'David'},
104-
data={'email': 'david.updated@example.com', 'age': 41}
105-
)
94+
updated_user = User(name='David', email='david.updated@example.com', age=41)
95+
affected_rows = await db.update_by_key(updated_user, key={'name': 'David'})
10696
assert affected_rows == 1
10797
# 验证数据已更新
10898
result = await db.execute_query("SELECT * FROM test_users WHERE name = 'David'")
10999
assert len(result) == 1
100+
assert is_row_dict(result[0])
110101
assert result[0]['email'] == 'david.updated@example.com'
111102
assert result[0]['age'] == 41
112103

113104
@pytest.mark.asyncio
114105
async def test_update_by_key_with_none_values(self, db: Commondao) -> None:
115106
# 插入测试数据
116-
await db.insert(
117-
'test_users',
118-
data={'name': 'Eve', 'email': 'eve@example.com', 'age': 22}
119-
)
107+
user = User(name='Eve', email='eve@example.com', age=22)
108+
await db.insert(user)
120109
# 使用包含None值的数据更新
121-
affected_rows = await db.update_by_key(
122-
'test_users',
123-
key={'name': 'Eve'},
124-
data={'email': 'eve.updated@example.com', 'age': None}
125-
)
110+
updated_user = User(name='Eve', email='eve.updated@example.com', age=None)
111+
affected_rows = await db.update_by_key(updated_user, key={'name': 'Eve'})
126112
assert affected_rows == 1
127113
# 验证数据已更新,但age保持原值未变
128114
result = await db.execute_query("SELECT * FROM test_users WHERE name = 'Eve'")
129115
assert len(result) == 1
116+
assert is_row_dict(result[0])
130117
assert result[0]['email'] == 'eve.updated@example.com'
131118
assert result[0]['age'] == 22 # 预期age保持原值,因为update_by_key跳过None值
132119

133120
@pytest.mark.asyncio
134121
async def test_update_by_key_no_change(self, db: Commondao) -> None:
135122
# 插入测试数据
136-
await db.insert(
137-
'test_users',
138-
data={'name': 'Frank', 'email': 'frank@example.com', 'age': 35}
139-
)
140-
# 使用全部为None的数据更新(不应有变化)
141-
affected_rows = await db.update_by_key(
142-
'test_users',
143-
key={'name': 'Frank'},
144-
data={'email': None, 'age': None}
145-
)
146-
assert affected_rows == 0
147-
# 验证数据未变
123+
user = User(name='Frank', email='frank@example.com', age=35)
124+
await db.insert(user)
125+
# Test updating with only None age field (exclude_none=True means only age is excluded)
126+
# Since email has the same value, it will still result in an UPDATE statement
127+
updated_user = User(name='Frank', email='frank@example.com', age=None)
128+
affected_rows = await db.update_by_key(updated_user, key={'name': 'Frank'})
129+
# This will be 1 because email field is included in the update even with same value
130+
assert affected_rows == 1
131+
# 验证数据保持相同值
148132
result = await db.execute_query("SELECT * FROM test_users WHERE name = 'Frank'")
149133
assert len(result) == 1
134+
assert is_row_dict(result[0])
150135
assert result[0]['email'] == 'frank@example.com'
151136
assert result[0]['age'] == 35
152137

153138
@pytest.mark.asyncio
154139
async def test_update_by_key_nonexistent(self, db: Commondao) -> None:
155140
# 尝试更新不存在的记录
156-
affected_rows = await db.update_by_key(
157-
'test_users',
158-
key={'name': 'NonExistent'},
159-
data={'email': 'new@example.com', 'age': 50}
160-
)
141+
updated_user = User(name='NonExistent', email='new@example.com', age=50)
142+
affected_rows = await db.update_by_key(updated_user, key={'name': 'NonExistent'})
161143
assert affected_rows == 0
162144

163145
@pytest.mark.asyncio
164146
async def test_delete_by_key(self, db: Commondao) -> None:
165147
# 插入测试数据
166-
await db.insert(
167-
'test_users',
168-
data={'name': 'Grace', 'email': 'grace@example.com', 'age': 28}
169-
)
148+
user = User(name='Grace', email='grace@example.com', age=28)
149+
await db.insert(user)
170150
# 通过key删除数据
171-
affected_rows = await db.delete_by_key(
172-
'test_users',
173-
key={'name': 'Grace'}
174-
)
151+
affected_rows = await db.delete_by_key(User, key={'name': 'Grace'})
175152
assert affected_rows == 1
176153
# 验证数据已删除
177154
result = await db.execute_query("SELECT * FROM test_users WHERE name = 'Grace'")
@@ -180,83 +157,70 @@ async def test_delete_by_key(self, db: Commondao) -> None:
180157
@pytest.mark.asyncio
181158
async def test_delete_by_key_composite_key(self, db: Commondao) -> None:
182159
# 插入两条测试数据
183-
await db.insert(
184-
'test_users',
185-
data={'name': 'Helen', 'email': 'helen@example.com', 'age': 32}
186-
)
187-
await db.insert(
188-
'test_users',
189-
data={'name': 'Helen', 'email': 'helen2@example.com', 'age': 33}
190-
)
160+
user1 = User(name='Helen', email='helen@example.com', age=32)
161+
user2 = User(name='Helen', email='helen2@example.com', age=33)
162+
await db.insert(user1)
163+
await db.insert(user2)
191164
# 使用组合键删除其中一条
192-
affected_rows = await db.delete_by_key(
193-
'test_users',
194-
key={'name': 'Helen', 'age': 32}
195-
)
165+
affected_rows = await db.delete_by_key(User, key={'name': 'Helen', 'age': 32})
196166
assert affected_rows == 1
197167
# 验证正确的数据被删除
198168
result = await db.execute_query("SELECT * FROM test_users WHERE name = 'Helen'")
199169
assert len(result) == 1
170+
assert is_row_dict(result[0])
200171
assert result[0]['email'] == 'helen2@example.com'
201172
assert result[0]['age'] == 33
202173

203174
@pytest.mark.asyncio
204175
async def test_delete_by_key_nonexistent(self, db: Commondao) -> None:
205176
# 尝试删除不存在的记录
206-
affected_rows = await db.delete_by_key(
207-
'test_users',
208-
key={'name': 'NonExistent'}
209-
)
177+
affected_rows = await db.delete_by_key(User, key={'name': 'NonExistent'})
210178
assert affected_rows == 0
211179

212180
@pytest.mark.asyncio
213181
async def test_get_by_key(self, db: Commondao) -> None:
214182
# 插入测试数据
215-
await db.insert(
216-
'test_users',
217-
data={'name': 'Ivan', 'email': 'ivan@example.com', 'age': 45}
218-
)
183+
user = User(name='Ivan', email='ivan@example.com', age=45)
184+
await db.insert(user)
219185
# 通过key获取数据
220-
result = await db.get_by_key('test_users', key={'name': 'Ivan'})
186+
result = await db.get_by_key(User, key={'name': 'Ivan'})
221187
# 验证结果
222188
assert result is not None
223-
assert result['email'] == 'ivan@example.com'
224-
assert result['age'] == 45
189+
assert result.email == 'ivan@example.com'
190+
assert result.age == 45
225191

226192
@pytest.mark.asyncio
227193
async def test_get_by_key_nonexistent(self, db: Commondao) -> None:
228194
# 尝试获取不存在的记录
229-
result = await db.get_by_key('test_users', key={'name': 'NonExistent'})
195+
result = await db.get_by_key(User, key={'name': 'NonExistent'})
230196
assert result is None
231197

232198
@pytest.mark.asyncio
233199
async def test_get_by_key_or_fail(self, db: Commondao) -> None:
234200
# 插入测试数据
235-
await db.insert(
236-
'test_users',
237-
data={'name': 'Jack', 'email': 'jack@example.com', 'age': 50}
238-
)
201+
user = User(name='Jack', email='jack@example.com', age=50)
202+
await db.insert(user)
239203
# 通过key获取数据
240-
result = await db.get_by_key_or_fail('test_users', key={'name': 'Jack'})
204+
result = await db.get_by_key_or_fail(User, key={'name': 'Jack'})
241205
# 验证结果
242206
assert result is not None
243-
assert result['email'] == 'jack@example.com'
244-
assert result['age'] == 50
207+
assert result.email == 'jack@example.com'
208+
assert result.age == 50
245209

246210
@pytest.mark.asyncio
247211
async def test_get_by_key_or_fail_nonexistent(self, db: Commondao) -> None:
248-
from commondao import NotFoundError
249-
250212
# 尝试获取不存在的记录,应抛出NotFoundError
251213
with pytest.raises(NotFoundError):
252-
await db.get_by_key_or_fail('test_users', key={'name': 'NonExistent'})
214+
await db.get_by_key_or_fail(User, key={'name': 'NonExistent'})
253215

254216
@pytest.mark.asyncio
255217
async def test_multiple_keys(self, db: Commondao) -> None:
256218
# 插入几条测试数据
257-
await db.insert('test_users', data={'name': 'Kate', 'email': 'kate@example.com', 'age': 28})
258-
await db.insert('test_users', data={'name': 'Kate', 'email': 'kate2@example.com', 'age': 29})
219+
user1 = User(name='Kate', email='kate@example.com', age=28)
220+
user2 = User(name='Kate', email='kate2@example.com', age=29)
221+
await db.insert(user1)
222+
await db.insert(user2)
259223
# 使用组合键获取特定记录
260-
result = await db.get_by_key('test_users', key={'name': 'Kate', 'age': 29})
224+
result = await db.get_by_key(User, key={'name': 'Kate', 'age': 29})
261225
assert result is not None
262-
assert result['email'] == 'kate2@example.com'
226+
assert result.email == 'kate2@example.com'

tests/e2e/test_error_handling.py

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,18 @@
11
import os
2-
from typing import Any, AsyncGenerator, Dict
2+
from typing import Annotated, Any, AsyncGenerator, Dict
33

44
import pytest
55
import pytest_asyncio
66
from pydantic import BaseModel
77

88
from commondao import Commondao, NotFoundError, connect
9+
from commondao.annotation import TableId
10+
11+
12+
class ErrorHandlingRecord(BaseModel):
13+
id: Annotated[int | None, TableId('test_error_handling')] = None
14+
name: str
15+
email: str | None = None
916

1017

1118
class TestErrorHandling:
@@ -37,7 +44,7 @@ async def db(self, db_config: Dict[str, Any]) -> AsyncGenerator[Commondao, None]
3744
@pytest.mark.asyncio
3845
async def test_get_by_key_or_fail_not_found(self, db: Commondao) -> None:
3946
with pytest.raises(NotFoundError):
40-
await db.get_by_key_or_fail('test_error_handling', key={'id': 999})
47+
await db.get_by_key_or_fail(ErrorHandlingRecord, key={'id': 999})
4148

4249
@pytest.mark.asyncio
4350
async def test_select_one_or_fail_not_found(self, db: Commondao) -> None:
@@ -57,7 +64,7 @@ class TestRecord(BaseModel):
5764

5865
@pytest.mark.asyncio
5966
async def test_get_by_key_returns_none(self, db: Commondao) -> None:
60-
result = await db.get_by_key('test_error_handling', key={'id': 999})
67+
result = await db.get_by_key(ErrorHandlingRecord, key={'id': 999})
6168
assert result is None
6269

6370
@pytest.mark.asyncio
@@ -78,14 +85,12 @@ class TestRecord(BaseModel):
7885
@pytest.mark.asyncio
7986
async def test_duplicate_key_error(self, db: Commondao) -> None:
8087
# 先插入一条记录
81-
await db.insert('test_error_handling', data={'name': 'Test User', 'email': 'test@example.com'})
88+
record1 = ErrorHandlingRecord(name='Test User', email='test@example.com')
89+
await db.insert(record1)
8290

8391
# 尝试插入相同的email (这应该是唯一的)
84-
affected_rows = await db.insert(
85-
'test_error_handling',
86-
data={'name': 'Another User', 'email': 'test@example.com'},
87-
ignore=True
88-
)
92+
record2 = ErrorHandlingRecord(name='Another User', email='test@example.com')
93+
affected_rows = await db.insert(record2, ignore=True)
8994

9095
# 使用ignore=True应该不会抛出异常,但也不会插入记录
9196
assert affected_rows == 0

0 commit comments

Comments
 (0)