import { describe, expect, it } from 'vitest' import { ITEMS, ARTIFACT_POWER } from '../src/renderer/game/data/items' import { TECHNIQUES } from '../src/renderer/game/data/techniques' import { BUILDINGS } from '../src/renderer/game/data/buildings' import { MISSIONS, ENEMIES } from '../src/renderer/game/data/secrets' import { NPCS } from '../src/renderer/game/data/npcs' import { EVENTS } from '../src/renderer/game/data/events' import { POSTS } from '../src/renderer/game/data/posts' import { TRAITS } from '../src/renderer/game/data/traits' import { ROOT_GRADES } from '../src/renderer/game/data/elements' import { MAJORS, MAJOR_ORDER } from '../src/renderer/game/data/realms' import { SEASON, seasonOf } from '../src/renderer/game/data/season' describe('物品表逐行矩阵', () => { it.each(Object.entries(ITEMS).map(([id, v]) => [id, v.name, v.basePrice, v.kind] as const))( '物品 %s 名称/价格/类别合法', (_id, name, price, kind) => { expect(name.length).toBeGreaterThan(0) expect(price).toBeGreaterThan(0) expect(['resource', 'pill', 'artifact']).toContain(kind) } ) it.each(Object.entries(ITEMS).filter(([, v]) => v.kind === 'artifact').map(([id]) => [id] as const))( '法器 %s 有战力修正', (id) => { expect(ARTIFACT_POWER[id]).toBeGreaterThan(0) } ) }) describe('功法表逐行矩阵', () => { it.each(TECHNIQUES.map((t) => [t.id, t.grade, t.powerBonus, t.expBonus, t.path] as const))( '功法 %s 参数板面合法', (id, grade, pow, exp, path) => { expect(id.startsWith('t-')).toBe(true) expect(grade).toBeGreaterThanOrEqual(1) expect(grade).toBeLessThanOrEqual(4) expect(pow).toBeGreaterThan(0) expect(exp).toBeGreaterThan(0) expect(path.length).toBeGreaterThan(0) } ) it('功法 id 全局唯一', () => { expect(new Set(TECHNIQUES.map((t) => t.id)).size).toBe(TECHNIQUES.length) }) }) describe('建筑表逐行矩阵', () => { it.each(Object.entries(BUILDINGS).map(([id, v]) => [id, v.maxLevel, v.kind] as const))( '建筑 %s 等级/类型合法', (id, max, kind) => { expect(id.length).toBeGreaterThan(1) expect(max).toBeGreaterThanOrEqual(3) expect(['produce', 'function']).toContain(kind) } ) it.each(Object.entries(BUILDINGS).map(([id, v]) => [id, v.upgradeCost(1), v.upgradeCost(v.maxLevel)] as const))( '建筑 %s 升级成本随级递增', (_id, c1, cMax) => { expect(cMax.stones).toBeGreaterThan(c1.stones) expect(cMax.lingkuang).toBeGreaterThan(c1.lingkuang) } ) }) describe('秘境表逐行矩阵', () => { it.each(MISSIONS.map((m) => [m.id, m.name] as const))('秘境 %s 存在启程摘要', (id, name) => { expect(id.startsWith('m-')).toBe(true) expect(name.length).toBeGreaterThan(1) }) it.each( MISSIONS.flatMap((m) => m.stages.map( (st, i) => [m.id, i, st.kind, st.months] as const ) ) )('秘境 %s 第%i 阶段类型/月数合法', (_id, _i, kind, months) => { expect(['event', 'combat', 'resource', 'boss']).toContain(kind) expect(months).toBeGreaterThan(0) }) it.each(ENEMIES.map((e) => [e.id, e.realm] as const))('敌人 %s 境界关联存在', (id, realm) => { expect(id.startsWith('e-')).toBe(true) expect(MAJOR_ORDER).toContain(realm) }) }) describe('势力表逐行矩阵', () => { it.each(NPCS.map((n) => [n.id, n.name] as const))('势力 %s 命名与风格', (id, name) => { expect(id.startsWith('n-')).toBe(true) expect(name).toContain('氏') }) it.each(NPCS.map((n) => [n.id, n.initialPower] as const))('势力 %s 初始战力为正', (_id, p) => { expect(p).toBeGreaterThan(0) }) it.each(NPCS.map((n) => [n.id, n.sells ?? [], n.buys ?? []] as const))('势力 %s 交易品类引用合法', (_id, sells, buys) => { for (const s of sells) { expect(ITEMS[s] ?? TECHNIQUES.find((t) => t.id === s)).toBeTruthy() } void buys }) }) describe('事件表逐选项矩阵', () => { it.each(EVENTS.flatMap((e) => e.options.map((o, idx) => [e.id, idx, o.label.length] as const)))( '事件 %s 选项%i 有文案', (_id, _idx, len) => { expect(len).toBeGreaterThan(0) } ) it.each(EVENTS.map((e) => [e.id, e.weight] as const))('事件 %s 权重为正', (_id, w) => { expect(w).toBeGreaterThan(0) }) it.each(EVENTS.filter((e) => e.cond?.minBuilding).map((e) => [e.id, e.cond!.minBuilding!.id] as const))( '事件 %s 建筑条件引用存在', (_id, b) => { expect(BUILDINGS[b]).toBeTruthy() } ) }) describe('职事/秉性/灵根/境界矩阵', () => { it.each(Object.values(POSTS).map((p) => [p.id, p.name, p.max] as const))('职事 %s %s 上限合法', (id, name, max) => { expect(id.length).toBeGreaterThan(0) expect(name.length).toBeGreaterThan(0) expect(max).toBeGreaterThanOrEqual(1) }) it.each(Object.entries(TRAITS).map(([id, t]) => [id, t.danger] as const))('秉性 %s 危险度在界', (_id, d) => { expect(d).toBeGreaterThanOrEqual(0) expect(d).toBeLessThanOrEqual(1) }) it.each(Object.entries(ROOT_GRADES).map(([k, v]) => [Number(k), v.expBonus] as const))('灵根品阶%i 加成递增', (grade, exp) => { expect(exp).toBeGreaterThan(0) if (grade > 0) { expect(exp).toBeGreaterThan(ROOT_GRADES[grade - 1].expBonus) } }) it.each(MAJOR_ORDER.map((m) => [m, MAJORS[m].lifespan] as const))('大境界 %s 寿元为正', (_m, l) => { expect(l).toBeGreaterThan(0) }) }) describe('时节数学矩阵', () => { it.each([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12].map((m) => [m, seasonOf(m)] as const))('%i月 归季 %s', (m, s) => { const mod = SEASON[s] expect(mod.name.length).toBeGreaterThan(0) }) })