Files
History/server/regions.test.ts
T
kamilkrzywda 1c64aa1da4 Tests: region-key contract (map rewrite + regions loader + engine) (v0.19 P1 of #16)
- map.test.ts: rewrite the fixture for region keys; the #6 regression guard now
  proves the owner resolves via properties.regionKey while the repacked numeric
  feature.id and the sub-region regionId do not.
- regions.test.ts (new): the loader sees 1,796 valid keys; FRA expands to its
  42 sub-region keys (all valid, all labelled '… (FRA)'); allTerritoryKeys
  unions correctly; and with no data it degrades to the raw input.
- engine.test.ts: buildUserPrompt includes a regions table only when provided;
  applyTurnResult with a validKeys set applies real keys and ignores bogus ones,
  and without one applies all (the legacy/unit path).
2026-10-14 09:14:24 +00:00

104 lines
3.5 KiB
TypeScript

import { afterAll, beforeEach, describe, expect, it } from 'vitest';
import { fileURLToPath } from 'node:url';
import {
allTerritoryKeys,
expandCountriesToKeys,
hasRegionData,
loadRegions,
referenceForKeys,
regionName,
resetRegions,
validKeys,
} from './regions';
import type { GameState } from '../shared/types';
// The repo root: this file lives in server/, so '..' is the directory holding
// public/region-keys.json and public/regions.geo.json. cwd-independent (mirrors
// how server/index.ts locates its root via import.meta.url).
const root = fileURLToPath(new URL('..', import.meta.url));
describe('regions (region-key loader, v0.19 #16 P1)', () => {
beforeEach(() => {
expect(loadRegions(root)).toBe(true);
});
it('loads the full manifest: 1,796 unique valid region keys', () => {
expect(hasRegionData()).toBe(true);
expect(validKeys().size).toBe(1796);
});
it('expands an ISO_A3 country to the region keys of all its sub-regions', () => {
const fra = expandCountriesToKeys(['FRA']);
// FRA has 42 sub-regions in the committed dataset.
expect(fra).toHaveLength(42);
// every expanded key is a real region key
for (const k of fra) expect(validKeys().has(k)).toBe(true);
// and the reference table labels each one with its parent country
const ref = referenceForKeys(fra);
expect(Object.keys(ref)).toHaveLength(42);
for (const [k, label] of Object.entries(ref)) {
expect(label.endsWith('(FRA)')).toBe(true);
expect(regionName(k)).toBeTruthy();
}
// sample known FRA keys, and their exact reference strings
expect(fra).toContain('ain-lqtt');
expect(ref['ain-lqtt']).toBe('Ain (FRA)');
expect(ref['aisne-gstu']).toBe('Aisne (FRA)');
});
it('referenceForKeys labels only known keys and omits unknown ones', () => {
const ref = referenceForKeys(['ain-lqtt', 'not-a-real-key-xyz']);
expect(ref['ain-lqtt']).toBe('Ain (FRA)');
expect(ref['not-a-real-key-xyz']).toBeUndefined();
});
it('allTerritoryKeys unions every nation\'s territory keys (no overlap)', () => {
const state: GameState = {
id: 'g',
presetId: 'p',
presetTitle: 'P',
playerNationId: 'uk',
turn: 1,
date: '1939-09-01',
nations: {
uk: {
id: 'uk',
name: 'UK',
type: 'major',
stats: { military: 80, economy: 70, stability: 60, population: 50 },
territory: expandCountriesToKeys(['GBR']),
relations: {},
},
fr: {
id: 'fr',
name: 'FR',
type: 'major',
stats: { military: 80, economy: 70, stability: 60, population: 50 },
territory: expandCountriesToKeys(['FRA']),
relations: {},
},
},
events: [],
pending: [],
version: 1,
};
// 16 GBR sub-regions + 42 FRA sub-regions, no overlap between the two.
expect(allTerritoryKeys(state).size).toBe(58);
});
describe('graceful degradation with no region data', () => {
beforeEach(() => resetRegions());
it('expands to the raw input, omits references, and reports no data', () => {
expect(hasRegionData()).toBe(false);
// no manifest -> the country list passes through unchanged (old model)
expect(expandCountriesToKeys(['FRA', 'GBR'])).toEqual(['FRA', 'GBR']);
expect(referenceForKeys(['FRA'])).toEqual({});
expect(validKeys().size).toBe(0);
expect(regionName('FRA')).toBeUndefined();
});
});
afterAll(() => resetRegions());
});