5.5 KiB
5.5 KiB
Function 测试审计(2026-04-14)
补充更新:
- 本文记录的 2 个 bug 已在同日完成代码修复。
- 对应测试已经从“稳定复现旧行为”切换为“验证修复后行为”。
1. 本次新增测试
本轮新增了两组 function 相关测试:
src/data/stateFunctions.test.ts- 覆盖 state function 的运行时过滤、优先级、选项解析、排序逻辑。
src/data/functionCatalog/functionCatalog.test.ts- 覆盖 function 文档映射、flow helper、NPC helper modal 初始化逻辑。
这两组测试都直接挂在现有 vitest 体系里,没有新建独立测试框架。
2. 本次执行结果
本轮实际执行了以下测试:
npx vitest run src/data/stateFunctions.test.ts src/data/functionCatalog/functionCatalog.test.ts
npx vitest run src/data/npcInteractions.test.ts src/hooks/story/storyGenerationState.test.ts src/services/runtimeStoryService.test.ts
执行结果:
- 新增测试:
2个文件,12条测试,全部通过。 - 复跑已有 function 相关测试:
3个文件,17条测试,全部通过。 - 修复回归测试:
5个文件,30条测试,全部通过。 - 编码检查:
1516个文件全部通过。
说明:
- 本轮不是“测试全绿就代表没有问题”。
- 最初定位出的 2 个问题,已经在后续修复回合里转成了回归测试。
3. 历史 bug 与修复结果
3.1 battle_recover_breath
- 所在位置:
src/data/stateFunctions.ts - 状态:已修复
- 原始问题表现:
- 当
inBattle = true,但当前没有存活敌人时,battle_recover_breath仍会留在可执行 function 列表中。
- 当
- 直接原因:
matchesCategory对recovery分类只判断了是否处于战斗态,没有像battle/escape分类那样额外校验hasAliveMonsters(context.monsters)。
- 修复方式:
- 已在
matchesCategory的recovery分支中,为战斗恢复类 function 补上hasAliveMonsters(context.monsters)判断。
- 已在
- 修复前影响:
- 在“敌人已死但战斗态尚未清理干净”的边界帧里,界面仍可能出现战斗恢复类选项。
- 这会让 function 池和真实战斗状态产生残留错位。
- 当前验证方式:
inBattle = truemonsters = [{ hp: 0, ... }]- 调用
getExecutableFunctions(context) - 现在返回结果应为空,不再包含
battle_recover_breath
- 对应用例:
src/data/stateFunctions.test.ts- 用例名:
removes battle_recover_breath when combat has no living monsters
3.2 npc_trade
- 所在位置:
src/data/functionCatalog/npc/npcTrade.ts - 状态:已修复
- 原始问题表现:
- trade modal 初始化时,
selectedPlayerItemId直接取state.playerInventory[0]?.id。 - 如果玩家背包第一项数量为
0,modal 默认会选中一件不可出售物品。
- trade modal 初始化时,
- 直接原因:
buildNpcTradeModalState没有过滤quantity <= 0的物品,也没有寻找第一个可交易物品。
- 修复方式:
- 已改为优先选择
quantity > 0的可交易物品。 - 同时对 NPC 库存和玩家背包都使用同一条筛选规则,避免默认选中空物品。
- 已改为优先选择
- 修复前影响:
- 交易面板第一次打开时,默认状态可能就是不可确认的。
- 用户需要手动切换到第二件物品,才会进入可提交状态。
- 当前验证方式:
playerInventory[0].quantity = 0playerInventory[1].quantity > 0- 调用
buildNpcTradeModalState(...) - 现在
selectedPlayerItemId应该自动落到第一件可交易物品
- 对应用例:
src/data/functionCatalog/functionCatalog.test.ts- 用例名:
prefers the first tradable player item when zero-quantity items exist src/hooks/story/storyGenerationState.test.ts- 用例名:
skips zero-quantity player items when opening the trade modal
4. 本轮已验证通过的 function 能力
以下内容本轮已通过测试验证,没有发现新的明显问题:
- state function runtime 构建:
idle_follow_clue已正确从运行时候选池移除。idle_explore_forward的运行时文案覆盖仍然生效。
- state function 选项行为:
- 高压战斗下
battle_recover_breath会被正确提权。 - 营地场景会正确隐藏
idle_explore_forward。 idle_travel_next_scene会强制使用运行时建议 actionText。battle_all_in_crush会保留外部传入的自定义 actionText。- story option 排序仍保持“前 2 个 model 锁定 + 后续按 priority 排序”。
- 高压战斗下
- flow helper:
story_continue_adventurecamp_travel_home_scene
- NPC helper:
npc_preview_talknpc_giftnpc_recruit
- 文档映射:
- 当前
SERVER_RUNTIME_FUNCTION_IDS全部都能在 function catalog 文档中找到对应条目。 - 本轮扫描到的 function
source路径全部存在,没有出现失效引用。
- 当前
5. 本轮修复动作
battle_recover_breath- 已补充战斗恢复类 function 的存活敌人校验,避免战斗边界帧残留非法选项。
npc_trade- 已把 trade modal 默认选中逻辑改为优先寻找可交易物品,不再直接吃数组第一项。
- 回归测试
- 原先记录旧行为的测试已翻转为修复后预期,并额外补了一条
storyGenerationState接入层测试。
- 原先记录旧行为的测试已翻转为修复后预期,并额外补了一条
6. 备注
这次测试资产的意义分两步:
- 第一步先把 bug 稳定复现出来,避免问题只停留在口头描述。
- 第二步在修复后把断言翻转成“正确行为”,让它们正式成为回归测试。