import { test } from 'node:test' import assert from 'node:assert/strict' import { bucketize, BUCKETS } from '../src/data/regionBuckets.js' // Unit-test the presence.online region roll-up for the "Players Online" widget. // The load-bearing invariant: the bucket counts ALWAYS reconcile to the true // total — anything unmatched lands in Wilderness — so the widget can never show // a sum that disagrees with the headline online count. test('bucketize groups named regions into their buckets', () => { const { rows, total } = bucketize({ 'Britain': 4, 'Moonglow': 2, 'Despise': 3, 'Green Acres House 12': 1, // not a town/dungeon name → Housing }) const byId = Object.fromEntries(rows.map((r) => [r.id, r.count])) assert.equal(byId.britain, 4) assert.equal(byId.towns, 2) assert.equal(byId.dungeons, 3) assert.equal(byId.housing, 1) assert.equal(total, 10) }) test('first match wins by BUCKETS order: a town-named house region counts as Towns, not Housing', () => { // The towns regex is ^-anchored and towns is checked BEFORE housing, so a house // region whose name starts with a town name is bucketed as Towns. Pinning this // documents the ordering dependency for anyone retuning BUCKETS. const { rows } = bucketize({ 'Trinsic House 12': 1 }) const byId = Object.fromEntries(rows.map((r) => [r.id, r.count])) assert.equal(byId.towns, 1) assert.equal(byId.housing, undefined) // empty bucket dropped }) test('an unmatched region falls through to Wilderness so counts always reconcile', () => { const { rows, total } = bucketize({ 'Some Unnamed Field': 5, 'Wilderness': 2 }) const wilderness = rows.find((r) => r.id === 'wilderness') assert.equal(wilderness.count, 7) assert.equal(total, 7) // The reconciliation guarantee: the buckets sum to the total, exactly. assert.equal(rows.reduce((s, r) => s + r.count, 0), total) }) test('bucketize returns rows in BUCKETS order and drops empty buckets', () => { const { rows } = bucketize({ 'Despise': 1, 'Britain': 1 }) assert.deepEqual(rows.map((r) => r.id), ['britain', 'dungeons']) // BUCKETS order, no empty towns/housing/wilderness }) test('bucketize coerces non-numeric counts and tolerates empty/nullish input', () => { assert.deepEqual(bucketize({}), { rows: [], total: 0 }) assert.deepEqual(bucketize(), { rows: [], total: 0 }) const { total } = bucketize({ 'Britain': '3', 'Minoc': 'oops' }) assert.equal(total, 3) // '3' → 3, 'oops' → 0 }) test('the last bucket is the catch-all (its match accepts anything)', () => { const last = BUCKETS[BUCKETS.length - 1] assert.equal(last.id, 'wilderness') assert.equal(last.match('literally anything'), true) })