fischer-agentkit/tests/unit/experts/test_board_team.py

248 lines
8.2 KiB
Python

"""BoardTeam 单元测试 — 私董会容器状态管理"""
from __future__ import annotations
import pytest
from agentkit.experts.board import BoardStatus, BoardTeam
from agentkit.experts.config import ExpertConfig
# ── 辅助函数 ──────────────────────────────────────────────
def _make_expert_configs(count: int = 3) -> list[ExpertConfig]:
"""创建测试用 ExpertConfig 列表"""
configs = []
for i in range(count):
configs.append(ExpertConfig(
name=f"expert_{i}",
agent_type="expert",
persona=f"测试专家 {i}",
thinking_style="analytical",
speaking_style="直接",
decision_framework="分析",
bound_skills=[],
is_lead=(i == 0),
task_mode="llm_generate",
prompt={"identity": f"Expert {i}"},
avatar="T",
color=f"#FF{i:02d}000",
))
return configs
# ── BoardStatus 枚举测试 ──────────────────────────────────
class TestBoardStatus:
"""BoardStatus 枚举测试"""
def test_status_values(self):
"""状态值正确"""
assert BoardStatus.FORMING.value == "forming"
assert BoardStatus.DISCUSSING.value == "discussing"
assert BoardStatus.CONCLUDING.value == "concluding"
assert BoardStatus.COMPLETED.value == "completed"
assert BoardStatus.DISSOLVED.value == "dissolved"
def test_status_is_string_enum(self):
"""BoardStatus 是 str enum"""
assert isinstance(BoardStatus.FORMING, str)
assert BoardStatus.FORMING == "forming"
# ── BoardTeam 初始化测试 ──────────────────────────────────
class TestBoardTeamInit:
"""BoardTeam 初始化测试"""
def test_default_init(self):
"""默认初始化"""
team = BoardTeam()
assert team.team_id # UUID 自动生成
assert team.status == BoardStatus.FORMING
assert team.moderator is None
assert team.experts == []
assert team.active_experts == []
assert team.member_experts == []
assert team.topic == ""
assert team.current_round == 0
assert team.max_rounds == 5
assert team.history == []
assert team.team_channel.startswith("board:")
def test_custom_max_rounds(self):
"""自定义最大轮次"""
team = BoardTeam(max_rounds=10)
assert team.max_rounds == 10
def test_custom_team_id(self):
"""自定义 team_id"""
team = BoardTeam(team_id="custom-board-123")
assert team.team_id == "custom-board-123"
assert team.team_channel == "board:custom-board-123"
# ── BoardTeam 讨论历史测试 ────────────────────────────────
class TestBoardTeamHistory:
"""BoardTeam 讨论历史管理测试"""
@pytest.mark.asyncio
async def test_add_to_history(self):
"""添加历史记录"""
team = BoardTeam()
await team.add_to_history(round=1, expert_name="expert_0", content="测试发言", role="expert")
history = team.history
assert len(history) == 1
assert history[0]["round"] == 1
assert history[0]["expert_name"] == "expert_0"
assert history[0]["content"] == "测试发言"
assert history[0]["role"] == "expert"
assert "timestamp" in history[0]
@pytest.mark.asyncio
async def test_add_multiple_to_history(self):
"""添加多条历史记录"""
team = BoardTeam()
await team.add_to_history(1, "expert_0", "发言1", "expert")
await team.add_to_history(1, "expert_1", "发言2", "expert")
await team.add_to_history(1, "expert_0", "小结", "moderator")
assert len(team.history) == 3
def test_get_history_text_empty(self):
"""空历史返回空字符串"""
team = BoardTeam()
assert team.get_history_text() == ""
@pytest.mark.asyncio
async def test_get_history_text_formatted(self):
"""历史文本格式化"""
team = BoardTeam()
await team.add_to_history(1, "elon_musk", "第一性原理", "expert")
await team.add_to_history(1, "moderator", "本轮小结", "moderator")
text = team.get_history_text()
assert "elon_musk" in text
assert "第一性原理" in text
assert "moderator" in text
assert "本轮小结" in text
assert "专家发言" in text
assert "主持人小结" in text
@pytest.mark.asyncio
async def test_get_history_text_up_to_round(self):
"""按轮次过滤历史"""
team = BoardTeam()
await team.add_to_history(1, "expert_0", "第一轮", "expert")
await team.add_to_history(2, "expert_0", "第二轮", "expert")
await team.add_to_history(3, "expert_0", "第三轮", "expert")
text = team.get_history_text(up_to_round=2)
assert "第一轮" in text
assert "第二轮" in text
assert "第三轮" not in text
# ── BoardTeam 用户干预测试 ────────────────────────────────
class TestBoardTeamIntervention:
"""BoardTeam 用户干预测试"""
@pytest.mark.asyncio
async def test_add_user_intervention(self):
"""添加用户干预"""
team = BoardTeam()
await team.add_user_intervention("请讨论AI伦理问题")
# 干预应出现在历史中
history = team.history
assert len(history) == 1
assert history[0]["expert_name"] == "user"
assert history[0]["content"] == "请讨论AI伦理问题"
assert history[0]["role"] == "user"
@pytest.mark.asyncio
async def test_consume_user_interventions(self):
"""消费用户干预(读取后清空)"""
team = BoardTeam()
await team.add_user_intervention("干预1")
await team.add_user_intervention("干预2")
interventions = team.consume_user_interventions()
assert len(interventions) == 2
assert "干预1" in interventions
assert "干预2" in interventions
# 再次消费应为空
assert team.consume_user_interventions() == []
# ── BoardTeam 轮次管理测试 ────────────────────────────────
class TestBoardTeamRound:
"""BoardTeam 轮次管理测试"""
def test_increment_round(self):
"""轮次递增"""
team = BoardTeam()
assert team.current_round == 0
r1 = team.increment_round()
assert r1 == 1
assert team.current_round == 1
r2 = team.increment_round()
assert r2 == 2
assert team.current_round == 2
# ── BoardTeam 状态管理测试 ────────────────────────────────
class TestBoardTeamStatus:
"""BoardTeam 状态管理测试"""
def test_set_status(self):
"""设置状态"""
team = BoardTeam()
assert team.status == BoardStatus.FORMING
team.set_status(BoardStatus.DISCUSSING)
assert team.status == BoardStatus.DISCUSSING
team.set_status(BoardStatus.COMPLETED)
assert team.status == BoardStatus.COMPLETED
team.set_status(BoardStatus.DISSOLVED)
assert team.status == BoardStatus.DISSOLVED
# ── BoardTeam 属性测试 ────────────────────────────────────
class TestBoardTeamProperties:
"""BoardTeam 属性测试"""
def test_handoff_transport_exists(self):
"""handoff_transport 存在"""
team = BoardTeam()
assert team.handoff_transport is not None
def test_workspace_exists(self):
"""workspace 存在"""
team = BoardTeam()
assert team.workspace is not None
def test_get_expert_not_found(self):
"""获取不存在的专家返回 None"""
team = BoardTeam()
assert team.get_expert("nonexistent") is None