import { describe, expect, it } from 'vitest'; import { LogCategory, LogFormat, LogScope, type Nation } from '@sammo-ts/logic'; import { InMemoryTurnWorld } from '../src/turn/inMemoryWorld.js'; import { createMonthlyDiplomacyHandler } from '../src/turn/monthlyNationStatsHandler.js'; import type { TurnDiplomacy, TurnWorldSnapshot, TurnWorldState } from '../src/turn/types.js'; const buildNation = (id: number, name: string, generalCount: number): Nation => ({ id, name, color: '#777777', capitalCityId: null, chiefGeneralId: null, gold: 0, rice: 0, power: 0, level: 1, typeCode: 'che_중립', meta: { gennum: generalCount }, }); const diplomacy: TurnDiplomacy[] = [ { fromNationId: 1, toNationId: 2, state: 1, term: 1, dead: 777, meta: {} }, { fromNationId: 2, toNationId: 1, state: 1, term: 1, dead: 888, meta: {} }, { fromNationId: 1, toNationId: 3, state: 0, term: 5, dead: 250, meta: {} }, { fromNationId: 3, toNationId: 1, state: 0, term: 5, dead: 50, meta: {} }, { fromNationId: 3, toNationId: 4, state: 0, term: 1, dead: 0, meta: {} }, { fromNationId: 4, toNationId: 3, state: 0, term: 1, dead: 0, meta: {} }, { fromNationId: 2, toNationId: 4, state: 7, term: 1, dead: 999, meta: {} }, ]; describe('monthly diplomacy post-update', () => { it('matches legacy casualty terms, state transitions, and global log order', async () => { const state: TurnWorldState = { id: 1, currentYear: 193, currentMonth: 1, tickSeconds: 600, lastTurnTime: new Date('0193-01-01T00:00:00.000Z'), meta: {}, }; const snapshot: TurnWorldSnapshot = { scenarioConfig: { stat: { total: 300, min: 10, max: 100, npcTotal: 150, npcMax: 50, npcMin: 10, chiefMin: 70 }, iconPath: '', map: {}, const: {}, environment: { mapName: 'test', unitSet: 'default' }, }, map: { id: 'test', name: 'test', cities: [] }, diplomacy, events: [], initialEvents: [], generals: [], cities: [], nations: [ buildNation(1, '갑국', 2), buildNation(2, '을국', 1), buildNation(3, '병국', 1), buildNation(4, '정국', 1), ], troops: [], }; let world: InMemoryTurnWorld | null = null; world = new InMemoryTurnWorld(state, snapshot, { schedule: { entries: [{ startMinute: 0, tickMinutes: 10 }] }, autoAdvanceDiplomacyMonth: false, calendarHandler: createMonthlyDiplomacyHandler({ getWorld: () => world }), }); await world.advanceMonth(new Date('0193-02-01T00:00:00.000Z')); const observedKeys = new Set(diplomacy.map((entry) => `${entry.fromNationId}:${entry.toNationId}`)); expect( world.listDiplomacy().filter((entry) => observedKeys.has(`${entry.fromNationId}:${entry.toNationId}`)) ).toEqual([ { fromNationId: 1, toNationId: 2, state: 0, term: 6, dead: 0, meta: {} }, { fromNationId: 2, toNationId: 1, state: 0, term: 6, dead: 0, meta: {} }, { fromNationId: 1, toNationId: 3, state: 0, term: 5, dead: 50, meta: {} }, { fromNationId: 3, toNationId: 1, state: 0, term: 4, dead: 50, meta: {} }, { fromNationId: 3, toNationId: 4, state: 2, term: 0, dead: 0, meta: {} }, { fromNationId: 4, toNationId: 3, state: 2, term: 0, dead: 0, meta: {} }, { fromNationId: 2, toNationId: 4, state: 2, term: 0, dead: 0, meta: {} }, ]); expect(world.consumeDirtyState().logs).toEqual([ { scope: LogScope.SYSTEM, category: LogCategory.HISTORY, text: '【개전】갑국을국전쟁을 시작합니다.', format: LogFormat.YEAR_MONTH, }, { scope: LogScope.SYSTEM, category: LogCategory.HISTORY, text: '【종전】병국정국종전합니다.', format: LogFormat.YEAR_MONTH, }, ]); }); });