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:
2026-10-14 09:14:24 +00:00
parent 29927bae34
commit 1c64aa1da4
3 changed files with 189 additions and 35 deletions
+46
View File
@@ -318,6 +318,17 @@ describe('buildUserPrompt (batched round)', () => {
it('asks the model to keep its internal reasoning brief (concise-CoT constraint)', () => {
expect(buildSystemPrompt(preset)).toMatch(/reasoning brief|a few sentences/i);
});
it('includes a regions reference table only when one is provided', () => {
// with a reference table: the payload carries it (region key -> "name (parent)")
const withRef = JSON.parse(
buildUserPrompt(baseState(), [], { 'ain-lqtt': 'Ain (FRA)', 'wales-bbbb': 'Wales (GBR)' }),
) as { regions?: Record<string, string> };
expect(withRef.regions).toEqual({ 'ain-lqtt': 'Ain (FRA)', 'wales-bbbb': 'Wales (GBR)' });
// without one: the field is absent entirely (the legacy prompt shape is unchanged)
const withoutRef = JSON.parse(buildUserPrompt(baseState(), [])) as { regions?: Record<string, string> };
expect(withoutRef.regions).toBeUndefined();
});
});
describe('queueRoundItem', () => {
@@ -461,6 +472,41 @@ describe('applyTurnResult', () => {
expect(state.pending).toHaveLength(1); // original untouched
expect(state.version).toBe(1);
});
it('with a validKeys set: applies real region keys, ignores hallucinated ones', () => {
const state = baseState();
const result: TurnResult = {
date: '1939-09-03',
events: [],
stateChanges: [],
relations: [],
// 'wales-bbbb' is a real key (owned by uk in the fixture); 'not-a-region-xyz'
// is not a real key at all. Both are proposed as a gain by DE.
territoryChanges: [{ nation: 'de', gain: ['wales-bbbb', 'not-a-region-xyz'], lose: [] }],
};
const next = applyTurnResult(state, result, new Set(['wales-bbbb']));
// the valid key was gained (stolen from its owner); the bogus one was ignored
expect(next.nations.de.territory).toContain('wales-bbbb');
expect(next.nations.uk.territory).not.toContain('wales-bbbb');
// the bogus key never entered any nation's territory
for (const n of Object.values(next.nations)) {
expect(n.territory).not.toContain('not-a-region-xyz');
}
});
it('without a validKeys set: applies every listed key (legacy/unit path)', () => {
const state = baseState();
const result: TurnResult = {
date: '1939-09-03',
events: [],
stateChanges: [],
relations: [],
territoryChanges: [{ nation: 'de', gain: ['POL', 'wales-bbbb'], lose: [] }],
};
const next = applyTurnResult(state, result); // no validKeys -> nothing filtered
expect(next.nations.de.territory).toContain('POL');
expect(next.nations.de.territory).toContain('wales-bbbb');
});
});
describe('isMeaningful', () => {