Files
ChronicleOfTheImmortalClan/tests/audit-fix-0.1.11.test.ts
T
thzxx 9bcb5d6af8 v0.1.11: 全源码审计 + 缺陷歼灭 + UI/UX 打磨
【引擎审计修复】
- P0:大比 once(原整年刷 12 场、奖励通胀);flag 年份键 3 年剪枝(长线膨胀)
- P1:飞升离世累加 feishengCount(飞升之资称号可达);圣者护族接消费(原死代码);
  大比/传薪挂能力卡门控;pending 抢渡劫时不再重设
- P2:version 硬编码统一 0.1.11;yearaxis 飞升归类;MonumentList 挂载

【UI 审计修复】
- P0:已故成员卡显示「已殁」(原秀活动 status);空队迎战禁用+提示(原静默失效)
- P1:指婚候选去截断(滚动列表);终局出口(回卷/主菜单按钮);saveNow 反馈;
  事件来临写入 feed(k-event 使用);遣队「最强 N 人/清空」一键;寻衅确认+联姻原因提示;
  未建建筑视觉 uc 类
- P2:speed 死代码;Modal 分层 z-index;FamilyPanel 在世/先人分隔

【UX 三件套】
- 警讯徽章(瓶颈/重伤/在外/媒缘/孤嗣之忧)顶栏一屏秒答「我该干嘛」
- 首启引导任务条(四步目标 + 完成推进,可跳不强制)
- 顶栏丹药瘦身(4 资源);数字千/万化;瓶颈卡红框高亮

【测试】905→923(urgency/guide/format 三模块 + 审计修复回归 6 项)
金钟罩三档重固化(0.1.11),typecheck/build 通过
2026-08-23 11:30:16 +08:00

94 lines
3.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { describe, expect, it } from 'vitest'
import { World } from '../src/renderer/game/engine/world'
import { applyEventChoice } from '../src/renderer/game/engine/systems/events'
import { computeUrgency } from '../src/renderer/game/core/urgency'
import { monthlyRate } from '../src/renderer/game/engine/systems/cultivation'
import { resetSaveBus, attachLogSink } from './world.helpers'
function baseWorld(seed: string): World {
const w = World.create({ seed, surname: '凌', familyName: '凌家', motto: 'm', difficulty: 'normal' })
resetSaveBus()
attachLogSink(w)
return w
}
describe('0.1.11 审计修复回归', () => {
it('大比 once:一季只触一次(不会整年刷 12 场)', () => {
const w = baseWorld('tourn-once')
w.state.year = 9
w.state.month = 12
w.advanceMonth() // year10 monthly
const seen: string[] = []
for (let i = 0; i < 24; i++) {
if (w.state.pendingEvent) {
if (w.state.pendingEvent.startsWith('ev-tournament-')) seen.push(w.state.pendingEvent)
applyEventChoice(w, w.state.pendingEvent, 0)
w.state.pendingEvent = undefined
}
w.advanceMonth()
}
expect(seen.filter((x) => x === 'ev-tournament-10').length).toBe(1)
})
it('飞升离世累加 feishengCount(可入飞升之资档)', () => {
const w = baseWorld('fs-count')
const c = w.state.members['x4']
c.realm = { major: 'spirit', minor: 1 }
applyEventChoice(w, 'ev-feisheng', 1) // 云游
expect(w.state.stats.feishengCount).toBe(1)
expect(w.state.family.flag['fengFeiBless']).toBe(true)
})
it('圣者护族对幼童有效(hasPatriarch 消费)', () => {
const w = baseWorld('patriarch')
const c = w.state.members['x5']
c.bornYear = 1 // 1 岁
const elder = w.state.members['x4']
elder.bornYear = 1 - 70
elder.realm = { major: 'foundation', minor: 1 }
const rate = monthlyRate(w, c)
expect(rate).toBeGreaterThan(0)
// 幼童本身速率低(<8 → ×0.65),此处只保证不为负
expect(rate).toBeGreaterThanOrEqual(0.1)
})
it('年份 flag 3 年后清理(pruneYearFlags', () => {
const w = baseWorld('prune')
w.state.year = 50
w.state.family.flag['auction-45'] = true
w.state.family.flag['auction-49'] = true
w.advanceMonth()
expect(w.state.family.flag['auction-45']).toBeUndefined()
expect(w.state.family.flag['auction-49']).toBe(true)
})
it('急事徽章 derived 正确(无继承人/重伤/瓶颈)', () => {
const w = baseWorld('urgent')
// 无继承人:除 x2 都死
w.state.members['x1'].alive = false
w.state.members['x3'].alive = false
w.state.members['x5'].alive = false
w.state.members['x4'].alive = false
const u = computeUrgency(w)
expect(u.noHeir).toBe(true)
// 重伤
const w2 = baseWorld('urgent2')
w2.state.members['x3'].health = 20
const u2 = computeUrgency(w2)
expect(u2.injuredCount).toBeGreaterThanOrEqual(1)
// 瓶颈
const w3 = baseWorld('urgent3')
w3.state.members['x3'].realmProgress = 100
const u3 = computeUrgency(w3)
expect(u3.blockedCount).toBeGreaterThanOrEqual(1)
})
it('王座 dead 成员不再显示活动 state(标签层修复)', () => {
const w = baseWorld('deadlabel')
const c = w.state.members['x3']
c.alive = false
// MemberCard 逻辑由 STATE_LABEL['dead'] 处理,引擎侧保证 alive=false 时 state 不变
expect(c.state === 'idle' || c.state === 'wounded' || c.state === 'meditation').toBe(true)
})
})