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).
This commit is contained in:
@@ -0,0 +1,103 @@
|
||||
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());
|
||||
});
|
||||
Reference in New Issue
Block a user