Files
Dune/tests/choam-charity-funding-engine.test.ts
T
Quintine d63efccb55 Settle CHOAM charity claims after depleted funding
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.
2026-10-24 18:03:08 +11:00

56 lines
2.8 KiB
TypeScript

import test from 'node:test';
import assert from 'node:assert/strict';
import { viewGame } from '../game/engine';
import {
createChoamCharityFundingFixture as fixture,
actChoamCharityFunding as act,
choamCharityFundingPlayer as player,
choamCharityFundingInventory as inventory,
} from './fixture-choam-charity-funding';
for (const advanced of [false, true]) {
void test(`${advanced ? 'Advanced' : 'Basic'} native CHOAM poverty claim draws from Bank after actual earned-income bribes`, () => {
for (const choamSpice of [0, 1] as const) {
const f = fixture({ advanced, choamSpice }), before = structuredClone(f.game);
const g = act(f.game, f.choam, f.selfClaim);
assert.equal(player(g, f.choam).spice, 2);
assert.equal(player(g, f.guild).spice, 0);
assert.equal(player(g, f.recipient).bribes, 13 - choamSpice);
assert.equal(viewGame(g, f.choam).charity.payer, null);
assert.equal(viewGame(g, f.choam).players.find(p => p.id === f.choam)!.charityClaimed, true);
assert.deepEqual(inventory(g), f.originalInventory);
assert.deepEqual(f.game, before);
assert.throws(() => act(g, f.choam, f.selfClaim), /once per turn|fewer than/);
}
});
void test(`${advanced ? 'Advanced' : 'Basic'} native other-faction full claim uses provisional shortfall funding`, () => {
for (const choamSpice of [0, 1] as const) {
const f = fixture({ advanced, choamSpice }), before = structuredClone(f.game);
const g = act(f.game, f.guild, f.otherClaim);
assert.equal(player(g, f.choam).spice, 0);
assert.equal(player(g, f.guild).spice, 2);
assert.equal(player(g, f.recipient).bribes, 13 - choamSpice);
assert.deepEqual(g.choamCharity, f.game.choamCharity);
assert.deepEqual(g.players.map(p => p.forces), f.game.players.map(p => p.forces));
assert.deepEqual(inventory(g), f.originalInventory);
assert.deepEqual(f.game, before);
assert.throws(() => act(g, f.guild, f.otherClaim), /once per turn|fewer than/);
}
});
void test(`${advanced ? 'Advanced' : 'Basic'} each low faction keeps exactly one independent claim in either order`, () => {
const f = fixture({ advanced, choamSpice: 1, guildSpice: 1 });
for (const order of [[f.choam, f.guild], [f.guild, f.choam]]) {
let g = structuredClone(f.game);
for (const actor of order) g = act(g, actor, { type: 'charity' });
assert.equal(player(g, f.guild).spice, 2);
assert.equal(player(g, f.choam).spice, order[0] === f.choam ? 1 : 2);
assert.equal(player(g, f.recipient).bribes, 11);
for (const actor of order) {
assert.equal(viewGame(g, actor).players.find(p => p.id === actor)!.charityClaimed, true);
assert.throws(() => act(g, actor, { type: 'charity' }), /once per turn|fewer than/);
}
assert.deepEqual(inventory(g), f.originalInventory);
}
});
}