refactor death

This commit is contained in:
bridge
2025-12-29 21:46:26 +08:00
parent aef6fe6f74
commit 6a4059280a
7 changed files with 192 additions and 19 deletions

150
tests/test_death.py Normal file
View File

@@ -0,0 +1,150 @@
import pytest
from unittest.mock import MagicMock
from src.classes.death_reason import DeathReason, DeathType
from src.classes.death import handle_death
from src.classes.relation import Relation, get_relations_strs
from src.classes.event import Event
def test_death_reason_str():
"""测试死因的字符串格式化"""
# 战死
reason_battle = DeathReason(DeathType.BATTLE, killer_name="张三")
assert str(reason_battle) == "被张三杀害"
# 战死(未知凶手)
reason_battle_unknown = DeathReason(DeathType.BATTLE)
assert str(reason_battle_unknown) == "被未知角色杀害"
# 重伤
reason_injury = DeathReason(DeathType.SERIOUS_INJURY)
assert str(reason_injury) == "重伤不治身亡"
# 老死
reason_old = DeathReason(DeathType.OLD_AGE)
assert str(reason_old) == "寿元耗尽而亡"
def test_handle_death(base_world, dummy_avatar):
"""测试死亡处理函数"""
reason = DeathReason(DeathType.BATTLE, killer_name="李四")
# 执行死亡处理
handle_death(base_world, dummy_avatar, reason)
# 验证状态
assert dummy_avatar.is_dead is True
assert dummy_avatar.death_info is not None
assert dummy_avatar.death_info["reason"] == "被李四杀害"
assert dummy_avatar.death_info["time"] == int(base_world.month_stamp)
assert dummy_avatar.death_info["location"] == (dummy_avatar.pos_x, dummy_avatar.pos_y)
# 验证清理工作
assert len(dummy_avatar.planned_actions) == 0
assert dummy_avatar.current_action is None
assert dummy_avatar.sect is None
def test_relation_display_with_death(base_world, dummy_avatar):
"""测试关系列表中的死亡显示"""
# 创建另一个角色作为朋友
from src.classes.avatar import Avatar, Gender
from src.classes.age import Age
from src.classes.cultivation import Realm
from src.utils.id_generator import get_avatar_id
from src.classes.root import Root
from src.classes.alignment import Alignment
from src.classes.calendar import create_month_stamp, Year, Month
friend = Avatar(
world=base_world,
name="Friend",
id=get_avatar_id(),
birth_month_stamp=create_month_stamp(Year(2000), Month.JANUARY),
age=Age(20, Realm.Qi_Refinement),
gender=Gender.MALE,
pos_x=0, pos_y=0,
root=Root.WOOD,
alignment=Alignment.RIGHTEOUS
)
# 建立关系
dummy_avatar.set_relation(friend, Relation.FRIEND)
# 初始状态:显示正常名字
strs_before = get_relations_strs(dummy_avatar)
assert "朋友Friend" in strs_before
# 朋友死亡(重伤)
reason = DeathReason(DeathType.SERIOUS_INJURY)
handle_death(base_world, friend, reason)
# 死亡后:显示带死因的名字
strs_after = get_relations_strs(dummy_avatar)
assert "朋友Friend(已故:重伤不治身亡)" in strs_after
@pytest.mark.asyncio
async def test_simulator_resolve_death(base_world, dummy_avatar):
"""测试模拟器的死亡结算阶段"""
from src.sim.simulator import Simulator
sim = Simulator(base_world)
base_world.avatar_manager.avatars[dummy_avatar.id] = dummy_avatar
# Case 1: 重伤死亡
dummy_avatar.hp.cur = -10
events = sim._phase_resolve_death()
assert dummy_avatar.is_dead is True
assert dummy_avatar.death_info["reason"] == "重伤不治身亡"
assert len(events) > 0
assert "重伤不治身亡" in str(events[0])
@pytest.mark.asyncio
async def test_simulator_evolve_relations_filter_dead(base_world, dummy_avatar):
"""测试关系演化阶段过滤死者"""
from src.sim.simulator import Simulator
sim = Simulator(base_world)
# 创建对手
from src.classes.avatar import Avatar, Gender
from src.classes.age import Age
from src.classes.cultivation import Realm
from src.utils.id_generator import get_avatar_id
from src.classes.root import Root
from src.classes.alignment import Alignment
from src.classes.calendar import create_month_stamp, Year, Month
target = Avatar(
world=base_world,
name="Target",
id=get_avatar_id(),
birth_month_stamp=create_month_stamp(Year(2000), Month.JANUARY),
age=Age(20, Realm.Qi_Refinement),
gender=Gender.MALE,
pos_x=0, pos_y=0,
root=Root.FIRE,
alignment=Alignment.EVIL
)
base_world.avatar_manager.avatars[dummy_avatar.id] = dummy_avatar
base_world.avatar_manager.avatars[target.id] = target
# 设置交互状态达到阈值
dummy_avatar.relation_interaction_states[target.id]["count"] = 100
# 让 Target 死亡
target.set_dead("测试死亡", base_world.month_stamp)
# Mock RelationResolver 防止真正调用 LLM
from unittest.mock import patch
with patch('src.classes.relation_resolver.RelationResolver.run_batch') as mock_run:
await sim._phase_evolve_relations()
# 验证:因为 target 已死,应该不会调用 run_batch
mock_run.assert_not_called()
# 如果 Target 活着,应该会调用
target.is_dead = False
with patch('src.classes.relation_resolver.RelationResolver.run_batch') as mock_run:
mock_run.return_value = []
await sim._phase_evolve_relations()
mock_run.assert_called_once()