import { strict as assert } from 'assert'; import { RELATION_FORMULAS, AFFINITY_INIMITY_MAP, POWER_INFLUENCE_MAP, AFFINITY_LABELS, INIMITY_LABELS, POWER_LABELS, INFLUENCE_LABELS, SPECIAL_CHARACTERISTICS_TABLE, } from '../data/allyEnemyTables.js'; import { mapRollToValue, getLabel, clamp } from '../allyEnemyGenerator.js'; let passed = 0; let failed = 0; function test(name, fn) { try { fn(); passed++; console.log(` PASS ${name}`); } catch (e) { failed++; console.error(` FAIL ${name}\n ${e.message}`); } } function assertEqual(actual, expected, msg) { assert.strictEqual(actual, expected, msg || `expected ${expected}, got ${actual}`); } // ────────────────────────────────────── console.log('\nmapRollToValue'); // ────────────────────────────────────── test('maps 2→0', () => assertEqual(mapRollToValue(2, AFFINITY_INIMITY_MAP), 0)); test('maps 3→1', () => assertEqual(mapRollToValue(3, AFFINITY_INIMITY_MAP), 1)); test('maps 5→2', () => assertEqual(mapRollToValue(5, AFFINITY_INIMITY_MAP), 2)); test('maps 7→3', () => assertEqual(mapRollToValue(7, AFFINITY_INIMITY_MAP), 3)); test('maps 9→4', () => assertEqual(mapRollToValue(9, AFFINITY_INIMITY_MAP), 4)); test('maps 11→5', () => assertEqual(mapRollToValue(11, AFFINITY_INIMITY_MAP), 5)); test('maps 12→6', () => assertEqual(mapRollToValue(12, AFFINITY_INIMITY_MAP), 6)); test('unknown roll → 0', () => assertEqual(mapRollToValue(13, AFFINITY_INIMITY_MAP), 0)); test('power 2-5→0', () => { assertEqual(mapRollToValue(2, POWER_INFLUENCE_MAP), 0); assertEqual(mapRollToValue(5, POWER_INFLUENCE_MAP), 0); }); test('power 6-7→1', () => { assertEqual(mapRollToValue(6, POWER_INFLUENCE_MAP), 1); assertEqual(mapRollToValue(7, POWER_INFLUENCE_MAP), 1); }); test('power 8→2', () => assertEqual(mapRollToValue(8, POWER_INFLUENCE_MAP), 2)); test('power 9→3', () => assertEqual(mapRollToValue(9, POWER_INFLUENCE_MAP), 3)); test('power 10→4', () => assertEqual(mapRollToValue(10, POWER_INFLUENCE_MAP), 4)); test('power 11→5', () => assertEqual(mapRollToValue(11, POWER_INFLUENCE_MAP), 5)); test('power 12→6', () => assertEqual(mapRollToValue(12, POWER_INFLUENCE_MAP), 6)); // ────────────────────────────────────── console.log('\ngetLabel'); // ────────────────────────────────────── test('finds matching affinity label', () => { assertEqual(getLabel(3, AFFINITY_LABELS).label, 'Très bienveillant'); }); test('returns first for out-of-range', () => { assertEqual(getLabel(99, AFFINITY_LABELS).label, 'Aucune'); }); test('finds inimity label', () => { assertEqual(getLabel(4, INIMITY_LABELS).label, 'Haine'); }); test('finds power label', () => { assertEqual(getLabel(5, POWER_LABELS).label, 'Très puissant'); }); test('finds influence label', () => { assertEqual(getLabel(2, INFLUENCE_LABELS).label, 'Influence modérée'); }); // ────────────────────────────────────── console.log('\nclamp'); // ────────────────────────────────────── test('within range', () => assertEqual(clamp(3, 0, 6), 3)); test('below min', () => assertEqual(clamp(-1, 0, 6), 0)); test('above max', () => assertEqual(clamp(7, 0, 6), 6)); test('edge min', () => assertEqual(clamp(0, 0, 6), 0)); test('edge max', () => assertEqual(clamp(6, 0, 6), 6)); // ────────────────────────────────────── console.log('\nRELATION_FORMULAS'); // ────────────────────────────────────── test('ally: 2d6 affinity, 0 inimity', () => { assertEqual(RELATION_FORMULAS.ally.affinity, '2d6'); assertEqual(RELATION_FORMULAS.ally.inimity, '0'); }); test('contact: 1d6+1 affinity, 1d6-1 inimity', () => { assertEqual(RELATION_FORMULAS.contact.affinity, '1d6+1'); assertEqual(RELATION_FORMULAS.contact.inimity, '1d6-1'); }); test('rival: 1d6-1 affinity, 1d6+1 inimity', () => { assertEqual(RELATION_FORMULAS.rival.affinity, '1d6-1'); assertEqual(RELATION_FORMULAS.rival.inimity, '1d6+1'); }); test('enemy: 0 affinity, 2d6 inimity', () => { assertEqual(RELATION_FORMULAS.enemy.affinity, '0'); assertEqual(RELATION_FORMULAS.enemy.inimity, '2d6'); }); // ────────────────────────────────────── console.log('\nLABELS — array lengths'); // ────────────────────────────────────── test('AFFINITY_LABELS has 7 entries', () => assertEqual(AFFINITY_LABELS.length, 7)); test('INIMITY_LABELS has 7 entries', () => assertEqual(INIMITY_LABELS.length, 7)); test('POWER_LABELS has 7 entries', () => assertEqual(POWER_LABELS.length, 7)); test('INFLUENCE_LABELS has 7 entries', () => assertEqual(INFLUENCE_LABELS.length, 7)); // ────────────────────────────────────── console.log('\nSPECIAL_CHARACTERISTICS_TABLE'); // ────────────────────────────────────── test('has 36 D66 entries', () => assertEqual(SPECIAL_CHARACTERISTICS_TABLE.length, 36)); test('all entries have valid D66 range', () => { for (const e of SPECIAL_CHARACTERISTICS_TABLE) { if (e.d66 < 11 || e.d66 > 66) throw new Error(`entry d66=${e.d66} out of range`); if (!e.text) throw new Error(`entry d66=${e.d66} missing text`); if (!e.effects) throw new Error(`entry d66=${e.d66} missing effects`); } }); test('D66 65 is extraRolls 2', () => { const e = SPECIAL_CHARACTERISTICS_TABLE.find(x => x.d66 === 65); assertEqual(e.effects.action, 'extraRolls'); assertEqual(e.effects.actionValue, 2); }); test('D66 66 is extraRolls 3', () => { const e = SPECIAL_CHARACTERISTICS_TABLE.find(x => x.d66 === 66); assertEqual(e.effects.action, 'extraRolls'); assertEqual(e.effects.actionValue, 3); }); test('D66 11 has affinityMod 1', () => { const e = SPECIAL_CHARACTERISTICS_TABLE.find(x => x.d66 === 11); assertEqual(e.effects.affinityMod, 1); }); test('D66 44 has setPowerToZero + inimityMod 1', () => { const e = SPECIAL_CHARACTERISTICS_TABLE.find(x => x.d66 === 44); assertEqual(e.effects.action, 'setPowerToZero'); assertEqual(e.effects.inimityMod, 1); }); // ────────────────────────────────────── console.log('\n'); // ────────────────────────────────────── if (failed > 0) { console.error(`\n ${failed} of ${passed + failed} tests FAILED\n`); process.exit(1); } else { console.log(` All ${passed} tests passed\n`); }