feat(T-002): 建立核心数据模型与状态枚举
- src/core/status.py: TaskStatus 六态枚举,英文成员 + display_name/from_display 中英映射(单一事实源),对齐 04-architecture.md §3.4。 - src/core/models.py: OrderTask dataclass,字段集合/类型对齐 §3.3;支付模式不挂模型。 - tests/test_models.py: 枚举完整性/双向映射/未知值报错/默认值/实例独立性。 - 文档同步:04 §3.4 约定补 from_display;tasks/progress/current-state 更新。 验证:compileall OK;unittest Ran 10 tests, OK。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
2863bf2750
commit
c41f37a27d
@@ -0,0 +1,88 @@
|
||||
"""核心数据模型与状态枚举测试(T-002)。"""
|
||||
import unittest
|
||||
from datetime import datetime
|
||||
from decimal import Decimal
|
||||
|
||||
from src.core.models import OrderTask
|
||||
from src.core.status import TaskStatus
|
||||
|
||||
|
||||
class TaskStatusTest(unittest.TestCase):
|
||||
# 与 04-architecture.md §3.4 中英映射表保持一致
|
||||
EXPECTED = {
|
||||
TaskStatus.PENDING: "待执行",
|
||||
TaskStatus.RUNNING: "执行中",
|
||||
TaskStatus.MANUAL: "待人工",
|
||||
TaskStatus.SUCCESS: "成功",
|
||||
TaskStatus.FAILED: "失败",
|
||||
TaskStatus.CANCELLED: "已取消",
|
||||
}
|
||||
|
||||
def test_members_complete(self):
|
||||
"""枚举成员恰好为文档定义的六个。"""
|
||||
self.assertEqual(set(TaskStatus), set(self.EXPECTED))
|
||||
|
||||
def test_display_name(self):
|
||||
for status, zh in self.EXPECTED.items():
|
||||
self.assertEqual(status.display_name, zh)
|
||||
|
||||
def test_display_names_unique(self):
|
||||
names = [s.display_name for s in TaskStatus]
|
||||
self.assertEqual(len(names), len(set(names)))
|
||||
|
||||
def test_from_display_roundtrip(self):
|
||||
for status in TaskStatus:
|
||||
self.assertIs(TaskStatus.from_display(status.display_name), status)
|
||||
|
||||
def test_from_display_unknown_raises(self):
|
||||
with self.assertRaises(ValueError):
|
||||
TaskStatus.from_display("不存在的状态")
|
||||
|
||||
|
||||
class OrderTaskTest(unittest.TestCase):
|
||||
def _minimal(self) -> OrderTask:
|
||||
return OrderTask(
|
||||
task_id="T1",
|
||||
row_index=2,
|
||||
product_url="https://example.com/p",
|
||||
sku_text="颜色=黑色;尺码=XL",
|
||||
quantity=1,
|
||||
)
|
||||
|
||||
def test_defaults(self):
|
||||
task = self._minimal()
|
||||
self.assertEqual(task.status, TaskStatus.PENDING)
|
||||
self.assertEqual(task.sku_items, {})
|
||||
self.assertIsNone(task.order_no)
|
||||
self.assertIsNone(task.expected_amount)
|
||||
|
||||
def test_sku_items_not_shared(self):
|
||||
"""default_factory 确保每个实例拥有独立 dict,不互相串改。"""
|
||||
a = self._minimal()
|
||||
b = self._minimal()
|
||||
a.sku_items["颜色"] = "黑色"
|
||||
self.assertEqual(b.sku_items, {})
|
||||
|
||||
def test_full_construction(self):
|
||||
task = OrderTask(
|
||||
task_id="T2",
|
||||
row_index=3,
|
||||
product_url="https://example.com/p2",
|
||||
sku_text="套餐=单件",
|
||||
quantity=2,
|
||||
sku_items={"套餐": "单件"},
|
||||
product_name="测试商品",
|
||||
expected_amount=Decimal("9.90"),
|
||||
max_pay_amount=Decimal("10.00"),
|
||||
status=TaskStatus.SUCCESS,
|
||||
order_no="2026000001",
|
||||
started_at=datetime(2026, 6, 24, 10, 0, 0),
|
||||
)
|
||||
self.assertEqual(task.quantity, 2)
|
||||
self.assertEqual(task.expected_amount, Decimal("9.90"))
|
||||
self.assertEqual(task.status, TaskStatus.SUCCESS)
|
||||
self.assertEqual(task.sku_items["套餐"], "单件")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user