import assert from "node:assert/strict"; import test from "node:test"; import { chooseWinner, clampUnit, normalizeProbabilities, normalizeText, normalizeUniqueTextList } from "../src/domain/hand-validation.ts"; test("normalizeText trims and collapses whitespace", () => { assert.equal(normalizeText(" Friday\n dinner ", 20), "Friday dinner"); assert.equal(normalizeText(" ", 20), null); assert.equal(normalizeText("too long", 3), null); }); test("normalizeUniqueTextList rejects duplicates and invalid bounds", () => { assert.deepEqual(normalizeUniqueTextList([" Thai ", "Pizza"], 4, 20), ["Thai", "Pizza"]); assert.equal(normalizeUniqueTextList(["Thai", "thai"], 4, 20), null); assert.equal(normalizeUniqueTextList(["a", "b", "c"], 2, 20), null); assert.equal(normalizeUniqueTextList(["valid", 2], 4, 20), null); }); test("normalizeProbabilities accepts weights and normalizes only live options", () => { assert.deepEqual(normalizeProbabilities({ a: 20, b: 30, stale: 50 }, ["a", "b"]), { a: 0.4, b: 0.6 }); }); test("normalizeProbabilities rejects malformed or unusable weights", () => { assert.equal(normalizeProbabilities({ a: 1, b: -1 }, ["a", "b"]), null); assert.equal(normalizeProbabilities({ a: 0, b: 0 }, ["a", "b"]), null); assert.equal(normalizeProbabilities({ a: 1 }, ["a", "b"]), null); assert.equal(normalizeProbabilities({ a: Number.NaN, b: 1 }, ["a", "b"]), null); }); test("clampUnit makes Jev scalar metadata safe", () => { assert.equal(clampUnit(-1), 0); assert.equal(clampUnit(0.45), 0.45); assert.equal(clampUnit(3), 1); assert.equal(clampUnit("0.5"), 0); }); test("one-tap winner confirms the highest weight with option-order tie breaking", () => { assert.equal(chooseWinner(["first", "second"], { first: 0.2, second: 0.8 }, 123, true), "second"); assert.equal(chooseWinner(["first", "second"], { first: 0.5, second: 0.5 }, 123, true), "first"); }); test("seeded weighted winner is replayable", () => { const weights = { first: 0.2, second: 0.8 }; assert.equal(chooseWinner(["first", "second"], weights, 42), chooseWinner(["first", "second"], weights, 42)); });