ForcePilot/backend/test/unit/channels/contract/dtos/test_truncation.py
Kris 3ae9c0bd21 test: 批量修复与新增单元测试用例,清理废弃测试目录
1.  删除了 test/unit/external_systems/framework/ 下的废弃空测试目录
2.  修复多处测试断言逻辑、参数传递与测试数据构造
3.  新增日志级别、缓存令牌、流事件等DTO单元测试
4.  补充路由绑定、会话仓储、outbox仓储的测试覆盖
5.  更新测试用例中的异常类型、参数校验与业务逻辑断言
2026-07-11 21:43:16 +08:00

116 lines
3.6 KiB
Python

"""truncation.py DTO 单元测试。
覆盖 ``TruncationCandidate`` 与 ``TruncationResult`` 的字段赋值、默认值、
不可变语义与 ``__post_init__`` 校验逻辑。
"""
from __future__ import annotations
import dataclasses
import pytest
from yuxi.channels.contract.dtos.truncation import (
TruncationCandidate,
TruncationResult,
)
from yuxi.channels.contract.errors import ValidationError
pytestmark = pytest.mark.unit
@pytest.mark.unit
class TestTruncationCandidate:
"""截断候选 DTO 测试。"""
def test_fields_are_assigned(self):
# Arrange
# Act
candidate = TruncationCandidate(text="hello", source="user_message", length=5)
# Assert
assert candidate.text == "hello"
assert candidate.source == "user_message"
assert candidate.length == 5
def test_zero_length_is_valid(self):
# Arrange
# Act
candidate = TruncationCandidate(text="hello", source="user_message", length=0)
# Assert - length 为 0 是合法的(非负)
assert candidate.length == 0
def test_is_frozen(self):
# Arrange
candidate = TruncationCandidate(text="hello", source="user_message", length=5)
# Act / Assert
with pytest.raises(dataclasses.FrozenInstanceError):
candidate.text = "other" # type: ignore[misc]
def test_empty_text_raises_validation_error(self):
# Arrange
# Act / Assert
with pytest.raises(ValidationError) as exc_info:
TruncationCandidate(text="", source="user_message", length=5)
assert exc_info.value.field == "text"
def test_empty_source_raises_validation_error(self):
# Arrange
# Act / Assert
with pytest.raises(ValidationError) as exc_info:
TruncationCandidate(text="hello", source="", length=5)
assert exc_info.value.field == "source"
def test_negative_length_raises_validation_error(self):
# Arrange
# Act / Assert
with pytest.raises(ValidationError) as exc_info:
TruncationCandidate(text="hello", source="user_message", length=-1)
assert exc_info.value.field == "length"
@pytest.mark.unit
class TestTruncationResult:
"""截断结果 DTO 测试。"""
def test_required_fields_are_assigned(self):
# Arrange
# Act
result = TruncationResult(is_truncated=True)
# Assert
assert result.is_truncated is True
def test_defaults_are_correct(self):
# Arrange
# Act
result = TruncationResult(is_truncated=False)
# Assert
assert result.missing_content is None
assert result.fallback_to_persistent is False
assert result.completed_text is None
assert result.original_length is None
assert result.completed_length is None
def test_custom_values_are_assigned(self):
# Arrange
# Act
result = TruncationResult(
is_truncated=True,
missing_content="missing",
fallback_to_persistent=True,
completed_text="completed",
original_length=100,
completed_length=150,
)
# Assert
assert result.missing_content == "missing"
assert result.fallback_to_persistent is True
assert result.completed_text == "completed"
assert result.original_length == 100
assert result.completed_length == 150
def test_is_frozen(self):
# Arrange
result = TruncationResult(is_truncated=True)
# Act / Assert
with pytest.raises(dataclasses.FrozenInstanceError):
result.is_truncated = False # type: ignore[misc]