ForcePilot/backend/test/unit/channels/contract/dtos/test_streaming.py
Kris 08617091dc refactor: 整理项目包结构与导入路径
- 新增多个业务域的__init__.py模块文件,规范包导出结构
- 调整多个DTO文件的导入路径,统一模块组织方式
- 移除测试文件中多余的空行与导入语句
- 优化部分业务模块的包层级划分
2026-07-18 02:04:03 +08:00

144 lines
4.0 KiB
Python

"""streaming.py DTO 单元测试。
覆盖 ``ChunkMode`` / ``RenderStrategy`` / ``StreamChunk`` / ``ChunkResult`` /
``StreamingCompleted`` / ``StreamingCapability`` / ``StreamingConfig`` 的
字段赋值、默认值、不可变语义与 ``__post_init__`` 校验逻辑。
"""
from __future__ import annotations
import dataclasses
import pytest
from yuxi.channels.contract.dtos.messaging.streaming import (
ChunkMode,
ChunkResult,
RenderStrategy,
StreamChunk,
StreamingCapability,
StreamingCompleted,
StreamingConfig,
)
from yuxi.channels.contract.errors import ValidationError
pytestmark = pytest.mark.unit
@pytest.mark.unit
class TestChunkMode:
"""分块模式枚举测试。"""
def test_str_values(self):
assert ChunkMode.NONE == "none"
assert ChunkMode.TEXT == "text"
assert ChunkMode.BLOCK == "block"
assert ChunkMode.FULL_UPDATE == "full_update"
assert ChunkMode.PARTIAL_UPDATE == "partial_update"
@pytest.mark.unit
class TestRenderStrategy:
"""卡片渲染策略枚举测试。"""
def test_str_values(self):
assert RenderStrategy.APPEND == "append"
assert RenderStrategy.REPLACE == "replace"
assert RenderStrategy.MERGE == "merge"
@pytest.mark.unit
class TestStreamChunk:
"""流式分块 DTO 测试。"""
def test_fields_are_assigned_with_defaults(self):
# Act
chunk = StreamChunk(content="hello", sequence=0)
# Assert
assert chunk.is_final is False
def test_is_frozen(self):
# Arrange
chunk = StreamChunk(content="hello", sequence=0)
# Act / Assert
with pytest.raises(dataclasses.FrozenInstanceError):
chunk.content = "other" # type: ignore[misc]
def test_empty_content_raises(self):
# Act / Assert
with pytest.raises(ValidationError) as exc_info:
StreamChunk(content="", sequence=0)
assert exc_info.value.field == "content"
def test_negative_sequence_raises(self):
# Act / Assert
with pytest.raises(ValidationError) as exc_info:
StreamChunk(content="hello", sequence=-1)
assert exc_info.value.field == "sequence"
@pytest.mark.unit
class TestChunkResult:
"""分块结果 DTO 测试。"""
def test_fields_are_assigned_with_defaults(self):
# Act
result = ChunkResult(
chunk=StreamChunk(content="hello", sequence=0),
success=True,
)
# Assert
assert result.error is None
@pytest.mark.unit
class TestStreamingCompleted:
"""流式完成结果 DTO 测试。"""
def test_valid_construction(self):
# Act
result = StreamingCompleted(total_chunks=5, duration_ms=1000)
# Assert
assert result.total_chunks == 5
def test_zero_total_chunks_raises(self):
# Act / Assert
with pytest.raises(ValidationError) as exc_info:
StreamingCompleted(total_chunks=0, duration_ms=100)
assert exc_info.value.field == "total_chunks"
def test_negative_duration_raises(self):
# Act / Assert
with pytest.raises(ValidationError) as exc_info:
StreamingCompleted(total_chunks=1, duration_ms=-1)
assert exc_info.value.field == "duration_ms"
@pytest.mark.unit
class TestStreamingCapability:
"""流式能力 DTO 测试。"""
def test_defaults(self):
# Act
cap = StreamingCapability()
# Assert
assert cap.supports_streaming is False
assert cap.supports_typing_indicator is False
assert cap.chunk_mode == ChunkMode.NONE
assert cap.min_chunk_interval_ms == 0
assert cap.max_chunk_length == 0
@pytest.mark.unit
class TestStreamingConfig:
"""流式配置 DTO 测试。"""
def test_defaults(self):
# Act
config = StreamingConfig()
# Assert
assert config.streaming_enabled is False
assert config.enable_typing is True
assert config.min_chunk_interval_ms == 200
assert config.streaming_ttl_ms == 60000
assert config.typing_ttl_ms == 10000