"""领域实体测试:字段约束与「防未来函数」可见性判断。""" from __future__ import annotations from datetime import date from decimal import Decimal import pytest from app.domain.entities.market import ( DailyBar, FinancialIndicator, Stock, SyncLog, ) from pydantic import ValidationError class TestStock: def test_symbol_pattern_enforced(self) -> None: Stock(symbol="600519.SH", name="贵州茅台", list_date=date(2001, 8, 27)) with pytest.raises(ValidationError): Stock(symbol="600519", name="x", list_date=date(2001, 1, 1)) with pytest.raises(ValidationError): Stock(symbol="sh600519", name="x", list_date=date(2001, 1, 1)) class TestDailyBar: def test_is_complete(self) -> None: bar = DailyBar( symbol="600519.SH", trade_date=date(2024, 1, 2), open=Decimal("100"), high=Decimal("101"), low=Decimal("99"), close=Decimal("100.5"), volume=Decimal("10000"), amount=Decimal("1000000"), ) assert bar.is_complete assert not DailyBar(symbol="600519.SH", trade_date=date(2024, 1, 2)).is_complete class TestFinancialIndicator: def _fin(self, announce: date) -> FinancialIndicator: return FinancialIndicator( symbol="600519.SH", report_date=date(2024, 6, 30), announce_date=announce, eps=Decimal("1.2"), ) def test_announced_by_after_announce(self) -> None: fin = self._fin(date(2024, 8, 31)) # 公告日当天已可见;公告前不可见 assert fin.announced_by(date(2024, 8, 31)) assert not fin.announced_by(date(2024, 8, 30)) assert not fin.announced_by(date(2024, 6, 30)) # 报告期不代表公开 class TestSyncLog: def test_defaults(self) -> None: log = SyncLog(source="tushare", api="daily", success=True, row_count=5) assert log.request_time is not None assert log.data_start is None