// The chips to actually push, for an amount. const test = require("node:test"); const assert = require("node:assert"); const { Money } = require("./load"); // A standard house set. const LEGEND = [ { value: 1, color: "#fff" }, { value: 5, color: "#c0392b" }, { value: 25, color: "#27ae60" }, { value: 100, color: "#2c3e50" }, { value: 500, color: "#8e44ad" }, ]; const say = (amount, legend = LEGEND) => Money.formatChipBreakdown(amount, legend); test("a payout comes back as chips, largest first", () => { assert.equal(say(132), "1×$100, 1×$25, 1×$5, 2×$1"); }); test("it uses the fewest chips on a normal set", () => { const { chips } = Money.chipBreakdown(500, LEGEND); assert.deepEqual(chips.map(c => `${c.count}×${c.value}`), ["1×500"]); }); test("a denomination that doesn't fit is skipped rather than listed as none", () => { assert.equal(say(7), "1×$5, 2×$1"); }); test("nothing to pay is nothing to say", () => { assert.equal(say(0), ""); assert.equal(say(-5), ""); }); test("no legend means no advice, not a wrong answer", () => { // A table that never set chip colours up gets the amount on its own. assert.equal(say(132, []), ""); assert.equal(say(132, null), ""); }); test("a legend with no values in it yet is the same as none", () => { assert.equal(say(132, [{ value: "", color: "#fff" }, { value: 0, color: "#000" }]), ""); }); test("what the smallest chip can't make is reported, not rounded away", () => { // 50c in a game whose smallest chip is a dollar is the dealer's problem to solve, // and they can only solve it if they're told. const { chips, remainder } = Money.chipBreakdown(10.5, LEGEND); assert.deepEqual(chips.map(c => `${c.count}×${c.value}`), ["2×5"]); assert.equal(remainder, 0.5); assert.equal(say(10.5), "2×$5, $0.50 no chip covers"); }); test("cent chips make cent amounts exactly", () => { const cents = [{ value: 0.25 }, { value: 0.05 }, { value: 0.01 }]; assert.equal(say(0.41, cents), "1×$0.25, 3×$0.05, 1×$0.01"); assert.equal(Money.chipBreakdown(0.41, cents).remainder, 0); }); test("the chips add up to the amount", () => { for (const amount of [1, 7, 33, 132, 499, 500, 1234, 9999]) { const { chips, remainder } = Money.chipBreakdown(amount, LEGEND); const total = chips.reduce((sum, c) => sum + c.count * c.value, 0) + remainder; assert.equal(Money.round(total), amount, `${amount} should be accounted for`); } }); test("a legend in any order still pays largest first", () => { const jumbled = [{ value: 25 }, { value: 1 }, { value: 500 }, { value: 5 }, { value: 100 }]; assert.equal(say(631, jumbled), "1×$500, 1×$100, 1×$25, 1×$5, 1×$1"); }); test("the colour comes along, so the felt can say it in chips", () => { const { chips } = Money.chipBreakdown(25, LEGEND); assert.equal(chips[0].color, "#27ae60"); }); test("a legend that exists but can't reach the amount does say so", () => { // Different from having no legend at all: this table has told us its chips, and // the answer is that they don't go that low. assert.equal(say(3, [{ value: 5 }, { value: 25 }]), "$3 no chip covers"); });