test: 测试矩阵扩至 161 项(深度审计 + 5 处缺陷修复)
新增测试矩阵(12 文件 / 161 cases): - rng 12 / data 18 / pcgen+cultivation 20 / economy 12 / combat+missions 24 - marriage+diplomacy 13 / events 12 / world+lifecycle 8(含镜像一致)/ save 4+5 / audit 8 审计带出并修复的真实缺陷: 1. Rng.pick 空数组未报错(防空白数组进而崩溃难查) 2. combatPowerOf 未应用功法悟道品阶战力加成(0.1.2 设计缺口) 3. 重伤者即使不代表伤状态仍按满速修炼(health 进修炼公式) 4. 寡妇/鳏夫无法再婚:候选列表放着人执行层却拒婚(spouseId 死旧契约) 5. isWidowed 参数契约陷阱:传 id 静默 false(升级接受 Character|Id 双签名)
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import { World } from '../src/renderer/game/engine/world'
|
||||
import { createWorldState, NewGameOptions, findInheritor } from '../src/renderer/game/engine/creation'
|
||||
import { resetSaveBus, attachLogSink } from './world.helpers'
|
||||
|
||||
function opts(seed: string, difficulty: 'easy' | 'normal' | 'hard' = 'normal', surname = '彭'): NewGameOptions {
|
||||
return { seed, surname, familyName: `${surname}家`, motto: 'm', difficulty }
|
||||
}
|
||||
|
||||
describe('World 生命周期与初始态', () => {
|
||||
it('三种难度初始资源与 NPC 强度梯度正确', () => {
|
||||
const easy = createWorldState(opts('st-e', 'easy'))
|
||||
const normal = createWorldState(opts('st-n', 'normal'))
|
||||
const hard = createWorldState(opts('st-h', 'hard'))
|
||||
expect(easy.family.stones).toBeGreaterThan(normal.family.stones)
|
||||
expect(normal.family.stones).toBeGreaterThan(hard.family.stones)
|
||||
expect(easy.npcFamilies['n-nulei'].power).toBeLessThan(normal.npcFamilies['n-nulei'].power)
|
||||
expect(normal.npcFamilies['n-nulei'].power).toBeLessThan(hard.npcFamilies['n-nulei'].power)
|
||||
})
|
||||
|
||||
it('创建后基本不变量的存在性', () => {
|
||||
const w = World.create(opts('st-b'))
|
||||
const s = w.state
|
||||
expect(s.family.headId).toBe('x1')
|
||||
expect(s.family.buildings['lingtian']).toBe(1)
|
||||
expect(s.family.buildings['zongci']).toBe(1)
|
||||
expect(s.family.techniques.length).toBe(2)
|
||||
expect(s.seq).toBeGreaterThanOrEqual(10)
|
||||
expect(s.chronicle.length).toBe(1) // 立家
|
||||
})
|
||||
|
||||
it('findInheritor 子代优先,其次高境界', () => {
|
||||
const w = World.create(opts('st-fi'))
|
||||
const heir = findInheritor(w)
|
||||
expect(['x3', 'x5']).toContain(heir?.id)
|
||||
})
|
||||
})
|
||||
|
||||
describe('World 推进元心与数据保全', () => {
|
||||
it('推进后 seq/months/总tick 单调增长', () => {
|
||||
const w = World.create(opts('adv-a'))
|
||||
const seq0 = w.state.seq
|
||||
const t0 = w.state.totalTicks
|
||||
w.advanceMonth()
|
||||
expect(w.state.totalTicks).toBe(t0 + 1)
|
||||
expect(w.state.seq).toBeGreaterThanOrEqual(seq0)
|
||||
})
|
||||
|
||||
it('月份跨年正确且 yearStart 触发', () => {
|
||||
const w = World.create(opts('adv-b'))
|
||||
for (let i = 0; i < 11; i++) w.advanceMonth() // 到 12 月
|
||||
expect(w.state.month).toBe(12)
|
||||
w.advanceMonth() // 跨年
|
||||
expect(w.state.month).toBe(1)
|
||||
expect(w.state.year).toBe(2)
|
||||
expect(w.state.yearlyReports.length).toBe(1)
|
||||
})
|
||||
|
||||
it('gameOver 后 advance 不继续崩', () => {
|
||||
const w = World.create(opts('adv-c'))
|
||||
for (const c of Object.values(w.state.members)) c.alive = false
|
||||
w.advanceMonth()
|
||||
expect(w.state.gameOver).toBeTruthy()
|
||||
w.advanceMonth() // 不再抛
|
||||
expect(w.state.year).toBeGreaterThanOrEqual(1)
|
||||
})
|
||||
|
||||
it('年度报告的 power 值始终有效', () => {
|
||||
const w = World.create(opts('adv-d'))
|
||||
for (let i = 0; i < 30; i++) w.advanceMonth()
|
||||
expect(w.state.yearlyReports.every((r) => r.power > 0)).toBe(true)
|
||||
})
|
||||
})
|
||||
|
||||
describe('存档重建后继续运行一致性', () => {
|
||||
it('json 往返后 100 月演进无异常且继续确定', () => {
|
||||
const w = World.create(opts('rid-a'))
|
||||
for (let i = 0; i < 25; i++) w.advanceMonth()
|
||||
w.syncRng()
|
||||
const clone = JSON.parse(JSON.stringify(w.state))
|
||||
const w2 = new World(clone)
|
||||
for (let i = 0; i < 75; i++) {
|
||||
if (w.state.gameOver) break
|
||||
w.advanceMonth()
|
||||
w2.advanceMonth()
|
||||
}
|
||||
expect(w2.state.year).toBe(w.state.year)
|
||||
expect(w2.state.family.stones).toBe(w.state.family.stones)
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user