Keep CHOAM's own poverty claim bank-funded. Prototype full other-faction claims using available CHOAM cash and an explicitly provisional bank residual; retain original eligibility, cancellation, Homeworld portions and claim limits. Connect persistent controls and genuine public setup/bribe evidence. Complete rules and deployed acceptance remain open.
41 lines
2.4 KiB
TypeScript
41 lines
2.4 KiB
TypeScript
import test from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import { CharityFundingError, quoteCharityFunding, charityPayer } from '../game/charity';
|
|
import { createGame, newPlayer } from '../game/engine';
|
|
|
|
void test('the full ordinary claim uses available CHOAM first, with a provisional bank remainder', () => {
|
|
for (const [cash, choam, bank] of [[0, 0, 2], [1, 1, 1], [2, 2, 0], [8, 2, 0]]) {
|
|
const amounts = { ordinary: 2, homeworld: 0 }, before = structuredClone(amounts);
|
|
assert.deepEqual(quoteCharityFunding(amounts, cash), { choam, bank });
|
|
assert.deepEqual(amounts, before);
|
|
}
|
|
});
|
|
void test('Homeworld additions stay bank-funded with doubled, partial and absent CHOAM funding', () => {
|
|
assert.deepEqual(quoteCharityFunding({ ordinary: 4, homeworld: 2 }, 3), { choam: 3, bank: 3 });
|
|
assert.deepEqual(quoteCharityFunding({ ordinary: 2, homeworld: 1 }, 8), { choam: 2, bank: 1 });
|
|
assert.deepEqual(quoteCharityFunding({ ordinary: 1, homeworld: 1 }, null), { choam: 0, bank: 2 });
|
|
assert.deepEqual(quoteCharityFunding({ ordinary: 0, homeworld: 0 }, 0), { choam: 0, bank: 0 });
|
|
});
|
|
void test('invalid balances or claim amounts reject before any private funding calculation', () => {
|
|
for (const invalid of [-1, 0.5, NaN, Infinity, Number.MAX_SAFE_INTEGER + 1]) {
|
|
assert.throws(() => quoteCharityFunding({ ordinary: invalid, homeworld: 0 }, 2), CharityFundingError);
|
|
assert.throws(() => quoteCharityFunding({ ordinary: 2, homeworld: invalid }, 2), CharityFundingError);
|
|
assert.throws(() => quoteCharityFunding({ ordinary: 2, homeworld: 0 }, invalid), CharityFundingError);
|
|
}
|
|
assert.throws(() => quoteCharityFunding({ ordinary: Number.MAX_SAFE_INTEGER, homeworld: 1 }, null), CharityFundingError);
|
|
});
|
|
void test('CHOAM pays only other factions after current allowed opening; its own poverty remains bank-funded', () => {
|
|
const g = createGame('CHARITYFUND', newPlayer('c', 'CHOAM', 'choam'), false, ['choam']);
|
|
g.players.push(newPlayer('a', 'Atreides', 'atreides'));
|
|
assert.equal(charityPayer(g, 'a'), undefined);
|
|
g.choamCharity = { turn: g.turn, canceled: false };
|
|
const before = structuredClone(g);
|
|
assert.equal(charityPayer(g, 'a')?.id, 'c');
|
|
assert.equal(charityPayer(g, 'c'), undefined);
|
|
assert.deepEqual(g, before);
|
|
g.choamCharity.canceled = true;
|
|
assert.equal(charityPayer(g, 'a'), undefined);
|
|
g.choamCharity = { turn: g.turn - 1, canceled: false };
|
|
assert.equal(charityPayer(g, 'a'), undefined);
|
|
});
|