'use strict'; // node --test で実行(ACCESS_KEY はテスト用のダミー、統計の保存先は一時ディレクトリ) const fs = require('fs'); const os = require('os'); const path = require('path'); process.env.ACCESS_KEY = process.env.ACCESS_KEY || '000000'; process.env.STATS_DIR = fs.mkdtempSync(path.join(os.tmpdir(), 'holdem-stats-')); const test = require('node:test'); const assert = require('node:assert/strict'); const { Table } = require('../server/tables'); const T = (n) => 'q'.repeat(31) + n; // 32文字のトークン function makeTable(n) { const t = new Table({ id: 'x', name: 'test', startingStack: 1000, smallBlind: 10, bigBlind: 20, blindTimerEnabled: false, blindIntervalMin: 10, hostToken: T(0), mode: 'friends', }); for (let i = 0; i < n; i++) t.join(T(i), 'p' + i); return t; } // 席の並び(名前) const names = (t) => t.seats.filter(Boolean).map((s) => s.name); test('席順: 開始前はすぐに並べ替え、ホスト以外や着席者と合わない指定は受け付けない', () => { const t = makeTable(4); assert.equal(t.setSeating(T(1), [3, 2, 1, 0]), 'ホストのみ操作できます'); assert.match(t.setSeating(T(0), [3, 2, 1]), /もう一度/); assert.match(t.setSeating(T(0), [3, 3, 1, 0]), /もう一度/); assert.match(t.setSeating(T(0), [3, 2, 1, 5]), /もう一度/); assert.equal(t.setSeating(T(0), [0, 3, 1, 2]), null); assert.deepEqual(names(t), ['p0', 'p3', 'p1', 'p2']); assert.equal(t.pendingSeating, null); // 席は詰めて座らせ、新しく座った人は空いている次の席(並びの最後)に入る t.leave(T(1)); t.join(T(9), 'p9'); assert.deepEqual(names(t), ['p0', 'p3', 'p9', 'p2']); }); test('席順: ハンド中は次のハンドの始めに並べ替え、ボタンは同じ人に付いたまま次へ回る', () => { const t = makeTable(4); t.start(T(0), 0); const h = t.hand; const buttonName = t.seats[h.button].name; const order = [0, 2, 1, 3]; // p0 → p2 → p1 → p3 assert.equal(t.setSeating(T(0), order), null); assert.deepEqual(names(t), ['p0', 'p1', 'p2', 'p3']); // まだ変わらない assert.deepEqual(t.publicState(T(0), new Set()).pendingSeating, order); assert.equal(t.publicState(T(1), new Set()).pendingSeating, null); // ホスト以外には送らない // 全員降りてハンドを終わらせ、次のハンドへ for (let i = 0; i < 10 && !h.finished; i++) t.act(t.seats[h.toAct].token, 'fold', 0); assert.ok(h.finished); t.tick(10 ** 6); t.tick(10 ** 7); assert.equal(t.hand.number, 2); assert.deepEqual(names(t), ['p0', 'p2', 'p1', 'p3']); assert.equal(t.pendingSeating, null); // 前のハンドのボタンの人の、新しい並びでの次の人がボタン const after = ['p0', 'p2', 'p1', 'p3']; const next = after[(after.indexOf(buttonName) + 1) % 4]; assert.equal(t.seats[t.hand.button].name, next); // 参加者の順もボタンの次から新しい並びどおり const seq = t.hand.order.map((s) => t.seats[s].name); const k = after.indexOf(next); assert.deepEqual(seq, [1, 2, 3, 4].map((d) => after[(k + d) % 4])); }); test('席順: 決めた後に座った人は最後に加え、いなくなった人は外す', () => { const t = makeTable(3); t.start(T(0), 0); const h = t.hand; assert.equal(t.setSeating(T(0), [2, 1, 0]), null); t.join(T(5), 'p5'); // ハンド中に新しく座る t.leave(T(1)); // ハンド中に退席 for (let i = 0; i < 10 && !h.finished; i++) t.act(t.seats[h.toAct].token, 'fold', 0); t.tick(10 ** 6); t.tick(10 ** 7); assert.deepEqual(names(t), ['p2', 'p0', 'p5']); });