import { describe, expect, it } from 'vitest'; import type { BattleSimJobPayload } from '../src/battleSim/types.js'; import { processBattleSimJob } from '../src/battleSim/processor.js'; const buildPayload = (action: BattleSimJobPayload['action']): BattleSimJobPayload => ({ action, repeatCnt: 1, year: 200, month: 1, seed: 'test-seed', attackerGeneral: { no: 1, name: 'Attacker', nation: 1, turntime: '2026-01-01 00:00:00', personal: null, special2: null, crew: 1000, crewtype: 100, atmos: 100, train: 100, intel: 70, intel_exp: 0, book: null, strength: 70, strength_exp: 0, weapon: null, injury: 0, leadership: 70, leadership_exp: 0, horse: null, item: null, explevel: 0, experience: 100, dedication: 100, officer_level: 3, officer_city: 1, gold: 1000, rice: 1000, dex1: 0, dex2: 0, dex3: 0, dex4: 0, dex5: 0, defence_train: 0, recent_war: null, warnum: 0, killnum: 0, killcrew: 0, }, attackerCity: { city: 1, nation: 1, supply: 1, name: 'AttackerCity', pop: 10000, agri: 1000, comm: 1000, secu: 1000, def: 100, wall: 100, trust: 100, level: 2, pop_max: 10000, agri_max: 1000, comm_max: 1000, secu_max: 1000, def_max: 200, wall_max: 200, dead: 0, state: 0, conflict: '{}', }, attackerNation: { type: 'test', tech: 1000, level: 1, capital: 1, nation: 1, name: 'AttackerNation', gold: 1000, rice: 1000, gennum: 1, }, defenderGenerals: [ { no: 2, name: 'Defender', nation: 2, turntime: '2026-01-01 00:00:00', personal: null, special2: null, crew: 1000, crewtype: 100, atmos: 100, train: 100, intel: 60, intel_exp: 0, book: null, strength: 60, strength_exp: 0, weapon: null, injury: 0, leadership: 60, leadership_exp: 0, horse: null, item: null, explevel: 0, experience: 100, dedication: 100, officer_level: 3, officer_city: 2, gold: 1000, rice: 1000, dex1: 0, dex2: 0, dex3: 0, dex4: 0, dex5: 0, defence_train: 0, recent_war: null, warnum: 0, killnum: 0, killcrew: 0, }, ], defenderCity: { city: 2, nation: 2, supply: 1, name: 'DefenderCity', pop: 10000, agri: 1000, comm: 1000, secu: 1000, def: 100, wall: 100, trust: 100, level: 2, pop_max: 10000, agri_max: 1000, comm_max: 1000, secu_max: 1000, def_max: 200, wall_max: 200, dead: 0, state: 0, conflict: '{}', }, defenderNation: { type: 'test', tech: 1000, level: 1, capital: 2, nation: 2, name: 'DefenderNation', gold: 1000, rice: 1000, gennum: 1, }, unitSet: { id: 'test', name: 'test', crewTypes: [ { id: 100, armType: 1, name: '보병', attack: 100, defence: 100, speed: 7, avoid: 10, magicCoef: 0, cost: 9, rice: 9, requirements: [], attackCoef: {}, defenceCoef: {}, info: [], initSkillTrigger: null, phaseSkillTrigger: null, iActionList: null, }, { id: 999, armType: 9, name: '성벽', attack: 0, defence: 0, speed: 1, avoid: 0, magicCoef: 0, cost: 0, rice: 9, requirements: [], attackCoef: {}, defenceCoef: {}, info: [], initSkillTrigger: null, phaseSkillTrigger: null, iActionList: null, }, ], }, config: { armPerPhase: 500, maxTrainByCommand: 100, maxAtmosByCommand: 100, maxTrainByWar: 110, maxAtmosByWar: 150, castleCrewTypeId: 999, armTypes: { footman: 1, wizard: 4, siege: 5, misc: 6, castle: 9, }, }, time: { year: 200, month: 1, startYear: 180, }, }); describe('battle sim processor', () => { it('simulates battles and returns summary', () => { const payload = buildPayload('battle'); const result = processBattleSimJob(payload); expect(result.result).toBe(true); expect(result.reason).toBe('success'); expect(result.lastWarLog).toBeTruthy(); expect(result.phase).toBeTypeOf('number'); expect(result.attackerRice).toBeTypeOf('number'); }); it('returns defender order for reorder action', () => { const payload = buildPayload('reorder'); const result = processBattleSimJob(payload); expect(result.result).toBe(true); expect(result.order?.length).toBe(1); }); });