import { describe, expect, it } from 'vitest' import { World } from '../src/renderer/game/engine/world' import { combatPowerOf } from '../src/renderer/game/engine/systems/combat' import { marketPrice, buyItem, sellItem, buyTechnique } from '../src/renderer/game/engine/market' import { resolveBreakthrough } from '../src/renderer/game/engine/systems/cultivation' import { matchesCondPub } from './events.helpers' describe('Combat power', () => { it('scales with realm', () => { const w = World.create({ seed: 'p', surname: '赵', familyName: '赵家', motto: 'm', difficulty: 'normal' }) const head = w.head() const power = combatPowerOf(w, head) expect(power).toBeGreaterThan(3) power > 0 }) it('higher realm beats lower realm', () => { const w = World.create({ seed: 'p2', surname: '赵', familyName: '赵家', motto: 'm', difficulty: 'normal' }) const low = w.state.members['x5'] const high = w.state.members['x4'] expect(combatPowerOf(w, high)).toBeGreaterThan(combatPowerOf(w, low)) }) }) describe('Market', () => { it('buy/sell roundtrip keeps stones consistent', () => { const w = World.create({ seed: 'mk', surname: '王', familyName: '王家', motto: 'm', difficulty: 'normal' }) const fam = w.state.family const price = marketPrice(w, 'lingcao') const stones0 = fam.stones const buyOk = buyItem(w, 'lingcao', 11) expect(buyOk).toBe(stones0 >= price * 11) if (buyOk) { expect(fam.inventory['lingcao']).toBe(60 + 11) expect(fam.stones).toBe(stones0 - price * 11) sellItem(w, 'lingcao', 11) expect(fam.stones).toBe(stones0) } }) it('cannot buy beyond treasury', () => { const w = World.create({ seed: 'mk2', surname: '王', familyName: '王家', motto: 'm', difficulty: 'hard' }) w.state.family.stones = 10 expect(buyItem(w, 'lingcao', 999)).toBe(false) }) it('buy technique adds to library once', () => { const w = World.create({ seed: 'mk3', surname: '王', familyName: '王家', motto: 'm', difficulty: 'normal' }) w.state.family.stones = 5000 expect(buyTechnique(w, 't-zhenyu', 700)).toBe(true) expect(w.state.family.techniques.includes('t-zhenyu')).toBe(true) expect(buyTechnique(w, 't-zhenyu', 700)).toBe(false) }) }) describe('Breakthrough', () => { it('advances realm on success', () => { const w = World.create({ seed: 'bt', surname: '李', familyName: '李家', motto: 'm', difficulty: 'easy' }) const c = w.state.members['x5'] c.realm = { major: 'mortal', minor: 0 } c.realmProgress = 100 c.perception = 9 c.mind = 9 resolveBreakthrough(w, c, 0.3) expect(c.realm.major).toBe('qi') }) it('failed breakthrough costs progress but not death', () => { const w = World.create({ seed: 'bt2', surname: '李', familyName: '李家', motto: 'm', difficulty: 'normal' }) const c = w.state.members['x5'] c.realm = { major: 'mortal', minor: 0 } c.realmProgress = 100 resolveBreakthrough(w, c, -0.5) // chance was min-clamped; both outcomes acceptable, but check invariants if (c.realm.major === 'mortal') { expect(c.realmProgress).toBeLessThan(100) } else { expect(c.realmProgress).toBe(0) } }) }) describe('Event conditions', () => { it('leading event ids exist', () => { const w = World.create({ seed: 'evc', surname: '刘', familyName: '刘家', motto: 'm', difficulty: 'normal' }) expect(matchesCondPub(w, { minBuilding: { id: 'lingtian', level: 1 } })).toBe(true) expect(matchesCondPub(w, { minBuilding: { id: 'danfang', level: 1 } })).toBe(false) expect(matchesCondPub(w, { minAdult: 3 })).toBe(true) expect(matchesCondPub(w, { maxAdult: 2 })).toBe(false) }) })