// The people standing behind the chairs. // // A full home game always has a couple of them, and the list lives on a napkin or in // the dealer's head — which is where the argument comes from an hour later about who // said they were next. Order of arrival, because it is the only ordering anybody has // ever agreed to. const test = require("node:test"); const { describe } = require("node:test"); const assert = require("node:assert"); const { HoldemState } = require("./load"); const table = (seated = 2, seats = 4) => { const state = HoldemState.createDefault(); HoldemState.resizeSeats(state, seats); ["Ann", "Ben", "Cal", "Dee"].slice(0, seated).forEach((name, i) => { state.seats[i].name = name; state.seats[i].stack = 200; state.seats[i].buyIns = 200; }); return state; }; describe("keeping the list", () => { test("names go on in the order they arrive", () => { const state = table(); HoldemState.addToWaitingList(state, "Priya"); HoldemState.addToWaitingList(state, "Sam"); assert.deepEqual(state.waitingList.map(row => row.name), ["Priya", "Sam"]); }); test("whitespace is trimmed and nothing empty gets on", () => { const state = table(); assert.ok(HoldemState.addToWaitingList(state, " Priya ")); assert.equal(HoldemState.addToWaitingList(state, " "), null); assert.equal(HoldemState.addToWaitingList(state, ""), null); assert.deepEqual(state.waitingList.map(row => row.name), ["Priya"]); }); test("two people with the same name are two people", () => { // Home games have two Mikes. The list is keyed by id, not by name. const state = table(); HoldemState.addToWaitingList(state, "Mike"); HoldemState.addToWaitingList(state, "Mike"); assert.equal(state.waitingList.length, 2); assert.notEqual(state.waitingList[0].id, state.waitingList[1].id); HoldemState.removeFromWaitingList(state, state.waitingList[0].id); assert.equal(state.waitingList.length, 1, "only one of them leaves"); }); test("taking somebody off gives them back, so the toast can name them", () => { const state = table(); HoldemState.addToWaitingList(state, "Priya"); const gone = HoldemState.removeFromWaitingList(state, state.waitingList[0].id); assert.equal(gone.name, "Priya"); assert.deepEqual(state.waitingList, []); assert.equal(HoldemState.removeFromWaitingList(state, "not-a-real-id"), null); }); }); describe("which chairs are open", () => { test("the ones with nobody in them, in seat order", () => { assert.deepEqual(HoldemState.openSeats(table(2, 4)), [2, 3]); assert.deepEqual(HoldemState.openSeats(table(4, 4)), []); }); test("a chair with chips or a buy-in on it is not open", () => { // Somebody who has stepped away from the table still owns their seat. const state = table(2, 4); state.seats[2].stack = 120; state.seats[3].buyIns = 100; assert.deepEqual(HoldemState.openSeats(state), []); }); }); describe("sitting somebody down", () => { test("their name goes on the chair and they come off the list", () => { const state = table(); HoldemState.addToWaitingList(state, "Priya"); HoldemState.addToWaitingList(state, "Sam"); const result = HoldemState.seatFromWaitingList(state, state.waitingList[0].id, 2); assert.equal(result.ok, true); assert.equal(state.seats[2].name, "Priya"); assert.deepEqual(state.waitingList.map(row => row.name), ["Sam"]); }); test("with nothing in front of them, because they haven't bought in yet", () => { // Guessing a stack would put chips on the table nobody has paid for, which is // the one thing the bank check exists to catch. const state = table(); HoldemState.addToWaitingList(state, "Priya"); HoldemState.seatFromWaitingList(state, state.waitingList[0].id, 2); assert.equal(state.seats[2].stack, null); assert.equal(state.seats[2].buyIns, 0); assert.equal(state.seats[2].inHand, false, "they're in the next hand, not this one"); assert.equal(HoldemState.bankReconciliation(state).balanced, true); }); test("never into a chair somebody is already in", () => { const state = table(); HoldemState.addToWaitingList(state, "Priya"); const result = HoldemState.seatFromWaitingList(state, state.waitingList[0].id, 0); assert.equal(result.ok, false); assert.match(result.reason, /Ann is already/); assert.equal(state.waitingList.length, 1, "and they keep their place in the queue"); }); test("nor from a name that has already been seated", () => { const state = table(); HoldemState.addToWaitingList(state, "Priya"); const id = state.waitingList[0].id; HoldemState.seatFromWaitingList(state, id, 2); const again = HoldemState.seatFromWaitingList(state, id, 3); assert.equal(again.ok, false); assert.equal(state.seats[3].name, "", "the second chair is untouched"); }); test("a seat that doesn't exist is refused rather than invented", () => { const state = table(); HoldemState.addToWaitingList(state, "Priya"); assert.equal(HoldemState.seatFromWaitingList(state, state.waitingList[0].id, 99).ok, false); assert.equal(state.waitingList.length, 1); }); }); describe("a seat opening up", () => { test("cashing somebody out is what makes room for the next one", () => { const state = table(4, 4); HoldemState.addToWaitingList(state, "Priya"); assert.deepEqual(HoldemState.openSeats(state), [], "the table is full"); HoldemState.cashOut(state, 1); assert.deepEqual(HoldemState.openSeats(state), [1]); const seated = HoldemState.seatFromWaitingList(state, state.waitingList[0].id, 1); assert.equal(seated.ok, true); assert.equal(state.seats[1].name, "Priya"); // Ben's night is still on the record, and the money still adds up. assert.equal(state.cashedOut.length, 1); assert.equal(HoldemState.bankReconciliation(state).balanced, true); }); }); describe("what a saved table remembers", () => { test("the list survives a reload", () => { const state = table(); HoldemState.addToWaitingList(state, "Priya"); const migrated = HoldemState.migrate(JSON.parse(JSON.stringify(state))); assert.deepEqual(migrated.waitingList.map(row => row.name), ["Priya"]); }); test("a table saved before the list existed has nobody waiting", () => { const parsed = JSON.parse(JSON.stringify(table())); delete parsed.waitingList; assert.deepEqual(HoldemState.migrate(parsed).waitingList, []); }); test("junk in a saved list is cleaned up rather than trusted", () => { const parsed = JSON.parse(JSON.stringify(table())); parsed.waitingList = [{ name: " Priya " }, { name: "" }, null, "Sam"]; const migrated = HoldemState.migrate(parsed); assert.deepEqual(migrated.waitingList.map(row => row.name), ["Priya", "Sam"]); assert.ok(migrated.waitingList.every(row => row.id), "and everybody gets an id"); }); });