- 新增 _calculate_lane_conflicts_v2() 分開返回標籤重疊和線穿框分數 - 修改泳道選擇算法,優先選擇無標籤重疊的泳道 - 兩階段搜尋:優先側別無可用泳道則嘗試另一側 - 增強日誌輸出,顯示標籤範圍和詳細衝突分數 🤖 Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com>
147 lines
4.0 KiB
Python
147 lines
4.0 KiB
Python
"""
|
|
資料模型測試
|
|
|
|
測試 Pydantic schemas 的基本驗證功能
|
|
|
|
Version: 1.0.0
|
|
DocID: TDD-UT-SCHEMA-001
|
|
"""
|
|
|
|
import pytest
|
|
from datetime import datetime
|
|
from backend.schemas import Event, EventType, TimelineConfig, ExportOptions, ExportFormat
|
|
|
|
|
|
class TestEventModel:
|
|
"""Event 模型測試"""
|
|
|
|
def test_create_valid_event(self):
|
|
"""測試建立有效事件"""
|
|
event = Event(
|
|
id="test-001",
|
|
title="測試事件",
|
|
start=datetime(2024, 1, 1, 9, 0, 0),
|
|
end=datetime(2024, 1, 1, 17, 0, 0),
|
|
group="Phase 1",
|
|
description="這是一個測試事件",
|
|
color="#3B82F6",
|
|
event_type=EventType.RANGE
|
|
)
|
|
|
|
assert event.id == "test-001"
|
|
assert event.title == "測試事件"
|
|
assert event.group == "Phase 1"
|
|
assert event.color == "#3B82F6"
|
|
|
|
def test_event_end_before_start_validation(self):
|
|
"""測試結束時間早於開始時間的驗證"""
|
|
with pytest.raises(ValueError, match="結束時間必須晚於開始時間"):
|
|
Event(
|
|
id="test-002",
|
|
title="無效事件",
|
|
start=datetime(2024, 1, 2, 9, 0, 0),
|
|
end=datetime(2024, 1, 1, 9, 0, 0), # 結束早於開始
|
|
)
|
|
|
|
def test_event_with_invalid_color(self):
|
|
"""測試無效的顏色格式"""
|
|
with pytest.raises(ValueError):
|
|
Event(
|
|
id="test-003",
|
|
title="測試事件",
|
|
start=datetime(2024, 1, 1, 9, 0, 0),
|
|
color="invalid-color" # 無效的顏色格式
|
|
)
|
|
|
|
def test_event_optional_fields(self):
|
|
"""測試可選欄位"""
|
|
event = Event(
|
|
id="test-004",
|
|
title="最小事件",
|
|
start=datetime(2024, 1, 1, 9, 0, 0)
|
|
)
|
|
|
|
assert event.end is None
|
|
assert event.group is None
|
|
assert event.description is None
|
|
assert event.color is None
|
|
|
|
|
|
class TestTimelineConfig:
|
|
"""TimelineConfig 模型測試"""
|
|
|
|
def test_default_config(self):
|
|
"""測試預設配置"""
|
|
config = TimelineConfig()
|
|
|
|
assert config.direction == 'horizontal'
|
|
assert config.theme.value == 'modern'
|
|
assert config.show_grid is True
|
|
assert config.show_tooltip is True
|
|
|
|
def test_custom_config(self):
|
|
"""測試自訂配置"""
|
|
config = TimelineConfig(
|
|
direction='vertical',
|
|
theme='classic',
|
|
show_grid=False
|
|
)
|
|
|
|
assert config.direction == 'vertical'
|
|
assert config.theme.value == 'classic'
|
|
assert config.show_grid is False
|
|
|
|
|
|
class TestExportOptions:
|
|
"""ExportOptions 模型測試"""
|
|
|
|
def test_valid_export_options(self):
|
|
"""測試有效的匯出選項"""
|
|
options = ExportOptions(
|
|
fmt=ExportFormat.PDF,
|
|
dpi=300,
|
|
width=1920,
|
|
height=1080
|
|
)
|
|
|
|
assert options.fmt == ExportFormat.PDF
|
|
assert options.dpi == 300
|
|
assert options.width == 1920
|
|
assert options.height == 1080
|
|
|
|
def test_dpi_range_validation(self):
|
|
"""測試 DPI 範圍驗證"""
|
|
# DPI 太低
|
|
with pytest.raises(ValueError):
|
|
ExportOptions(
|
|
fmt=ExportFormat.PNG,
|
|
dpi=50 # < 72
|
|
)
|
|
|
|
# DPI 太高
|
|
with pytest.raises(ValueError):
|
|
ExportOptions(
|
|
fmt=ExportFormat.PNG,
|
|
dpi=700 # > 600
|
|
)
|
|
|
|
def test_dimension_validation(self):
|
|
"""測試尺寸範圍驗證"""
|
|
# 寬度太小
|
|
with pytest.raises(ValueError):
|
|
ExportOptions(
|
|
fmt=ExportFormat.PNG,
|
|
width=500 # < 800
|
|
)
|
|
|
|
# 高度太大
|
|
with pytest.raises(ValueError):
|
|
ExportOptions(
|
|
fmt=ExportFormat.PNG,
|
|
height=5000 # > 4096
|
|
)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
pytest.main([__file__, "-v"])
|