247 lines
8.4 KiB
TypeScript
247 lines
8.4 KiB
TypeScript
import { describe, expect, it } from 'vitest';
|
|
|
|
import type { ScenarioDefinition } from '../src/scenario/types.js';
|
|
import type { MapDefinition, UnitSetDefinition } from '../src/world/types.js';
|
|
import { buildScenarioBootstrap } from '../src/world/bootstrap.js';
|
|
|
|
describe('scenario bootstrap', () => {
|
|
it('builds snapshot and seed from scenario/map inputs', () => {
|
|
const scenario: ScenarioDefinition = {
|
|
title: 'Test Scenario',
|
|
startYear: 200,
|
|
life: null,
|
|
fiction: null,
|
|
history: [],
|
|
config: {
|
|
stat: {
|
|
total: 100,
|
|
min: 10,
|
|
max: 70,
|
|
npcTotal: 80,
|
|
npcMax: 60,
|
|
npcMin: 5,
|
|
chiefMin: 50,
|
|
},
|
|
iconPath: '.',
|
|
map: {},
|
|
const: {},
|
|
environment: {
|
|
mapName: 'test-map',
|
|
unitSet: 'test-unit',
|
|
},
|
|
},
|
|
nations: [
|
|
{
|
|
id: 1,
|
|
name: 'TestNation',
|
|
color: '#123456',
|
|
gold: 5000,
|
|
rice: 3000,
|
|
infoText: 'Test nation',
|
|
tech: 100,
|
|
type: 'Test',
|
|
level: 3,
|
|
cities: ['Alpha'],
|
|
},
|
|
],
|
|
diplomacy: [],
|
|
generals: [
|
|
{
|
|
affinity: 10,
|
|
name: 'TestGeneral',
|
|
picture: 101,
|
|
nation: 1,
|
|
city: 'Alpha',
|
|
leadership: 50,
|
|
strength: 60,
|
|
intelligence: 55,
|
|
officerLevel: 1,
|
|
birthYear: 180,
|
|
deathYear: 240,
|
|
personality: 'Calm',
|
|
special: 'Special',
|
|
text: 'Test line',
|
|
},
|
|
],
|
|
generalsEx: [],
|
|
generalsNeutral: [],
|
|
cities: [],
|
|
events: [],
|
|
initialEvents: [],
|
|
ignoreDefaultEvents: false,
|
|
};
|
|
|
|
const map: MapDefinition = {
|
|
id: 'test-map',
|
|
name: 'test-map',
|
|
cities: [
|
|
{
|
|
id: 1,
|
|
name: 'Alpha',
|
|
level: 3,
|
|
region: 1,
|
|
position: { x: 10, y: 20 },
|
|
connections: [],
|
|
max: {
|
|
population: 100000,
|
|
agriculture: 20000,
|
|
commerce: 20000,
|
|
security: 15000,
|
|
defence: 5000,
|
|
wall: 3000,
|
|
},
|
|
initial: {
|
|
population: 50000,
|
|
agriculture: 10000,
|
|
commerce: 10000,
|
|
security: 8000,
|
|
defence: 2500,
|
|
wall: 1500,
|
|
},
|
|
},
|
|
],
|
|
};
|
|
|
|
const unitSet: UnitSetDefinition = {
|
|
id: 'test-unit',
|
|
name: 'test-unit',
|
|
defaultCrewTypeId: 1200,
|
|
};
|
|
|
|
const result = buildScenarioBootstrap({ scenario, map, unitSet });
|
|
|
|
expect(result.warnings).toHaveLength(0);
|
|
expect(result.snapshot.nations).toHaveLength(2);
|
|
expect(result.seed.nations).toHaveLength(1);
|
|
expect(result.snapshot.cities[0]?.nationId).toBe(1);
|
|
expect(result.seed.cities[0]?.nationId).toBe(1);
|
|
expect(result.snapshot.generals[0]?.cityId).toBe(1);
|
|
expect(result.snapshot.generals[0]?.crewTypeId).toBe(1200);
|
|
expect(result.snapshot.generals[0]?.role.specialDomestic).toBe('Special');
|
|
expect(result.snapshot.generals[0]?.role.specialWar).toBeNull();
|
|
expect(result.snapshot.generals[0]?.meta).toMatchObject({ specage: 25, specage2: 30 });
|
|
expect(result.seed.generals[0]?.meta).toMatchObject({ specage: 25, specage2: 30 });
|
|
expect(result.seed.generals[0]?.npcType).toBe(2);
|
|
expect(result.snapshot.scenarioMeta?.title).toBe('Test Scenario');
|
|
});
|
|
|
|
it('defers future generals into birth-year registration events and omits expired rows', () => {
|
|
const general = (
|
|
name: string,
|
|
birthYear: number,
|
|
deathYear: number,
|
|
nation: number | string | null = 1
|
|
): ScenarioDefinition['generals'][number] => ({
|
|
affinity: 0,
|
|
name,
|
|
picture: null,
|
|
nation,
|
|
city: null,
|
|
leadership: 50,
|
|
strength: 60,
|
|
intelligence: 40,
|
|
officerLevel: 3,
|
|
birthYear,
|
|
deathYear,
|
|
personality: null,
|
|
special: '',
|
|
text: '',
|
|
});
|
|
const scenario: ScenarioDefinition = {
|
|
title: 'Delayed generals',
|
|
startYear: 200,
|
|
life: null,
|
|
fiction: null,
|
|
history: [],
|
|
config: {
|
|
stat: { total: 100, min: 10, max: 70, npcTotal: 80, npcMax: 60, npcMin: 5, chiefMin: 50 },
|
|
iconPath: '.',
|
|
map: {},
|
|
const: {},
|
|
environment: { mapName: 'test-map', unitSet: 'test-unit' },
|
|
},
|
|
nations: [
|
|
{
|
|
id: 1,
|
|
name: 'TestNation',
|
|
color: '#123456',
|
|
gold: 5_000,
|
|
rice: 3_000,
|
|
infoText: '',
|
|
tech: 100,
|
|
type: 'Test',
|
|
level: 3,
|
|
cities: ['Alpha'],
|
|
},
|
|
],
|
|
diplomacy: [],
|
|
generals: [
|
|
general('현재', 180, 240),
|
|
general('미래1', 190, 250, 'TestNation'),
|
|
general('만료', 170, 200),
|
|
],
|
|
generalsEx: [general('미래확장', 190, 260)],
|
|
generalsNeutral: [general('미래재야', 191, 260, 0)],
|
|
cities: [],
|
|
events: [['Month', 500, ['Date', '>=', 200, 1], ['Existing']]],
|
|
initialEvents: [],
|
|
ignoreDefaultEvents: false,
|
|
};
|
|
const map: MapDefinition = {
|
|
id: 'test-map',
|
|
name: 'test-map',
|
|
cities: [
|
|
{
|
|
id: 1,
|
|
name: 'Alpha',
|
|
level: 3,
|
|
region: 1,
|
|
position: { x: 0, y: 0 },
|
|
connections: [],
|
|
max: {
|
|
population: 100_000,
|
|
agriculture: 20_000,
|
|
commerce: 20_000,
|
|
security: 15_000,
|
|
defence: 5_000,
|
|
wall: 3_000,
|
|
},
|
|
initial: {
|
|
population: 50_000,
|
|
agriculture: 10_000,
|
|
commerce: 10_000,
|
|
security: 8_000,
|
|
defence: 2_500,
|
|
wall: 1_500,
|
|
},
|
|
},
|
|
],
|
|
};
|
|
|
|
const result = buildScenarioBootstrap({ scenario, map });
|
|
|
|
expect(result.seed.generals.map((row) => row.name)).toEqual(['현재']);
|
|
expect(result.snapshot.generals.map((row) => row.name)).toEqual(['현재']);
|
|
expect(result.seed.events).toEqual([
|
|
['Month', 500, ['Date', '>=', 200, 1], ['Existing']],
|
|
[
|
|
'Month',
|
|
1_000,
|
|
['Date', '>=', 204, 1],
|
|
['RegNPC', 0, '미래1', null, 1, null, 50, 60, 40, 3, 190, 250, null, '', ''],
|
|
['RegNPC', 0, '미래확장', null, 1, null, 50, 60, 40, 3, 190, 260, null, '', ''],
|
|
['DeleteEvent'],
|
|
],
|
|
[
|
|
'Month',
|
|
1_000,
|
|
['Date', '>=', 205, 1],
|
|
['RegNeutralNPC', 0, '미래재야', null, 0, null, 50, 60, 40, 191, 260, null, '', ''],
|
|
['DeleteEvent'],
|
|
],
|
|
]);
|
|
expect(result.snapshot.events).toEqual(result.seed.events);
|
|
expect(result.seed.events.flat(3)).not.toContain('만료');
|
|
});
|
|
});
|