Files
miti99bot/tests/modules/twentyq/seeds.test.js
T
tiennm99 f6ab94ffb0 feat(twentyq): LLM-generated category + initial hint from bare keyword seeds
Previously seeds carried hand-curated {category, target, initialHint}.
Now SEEDS is a flat string[] of keywords — at round-start, the model
generates {category, initialHint} on the fly. Benefits:
- adding a seed is trivial (just append a word)
- every round gets a fresh cryptic opener (varies across plays of the
  same word)
- HINT STYLE rules apply to the opening hint too, so the initial clue
  isn't a definitional giveaway

Implementation:
- prompts.buildStartRoundPrompt(target) — with good/bad examples
- ai-client.generateRoundStart(env, target) — same JSON-in-content
  approach as judge(), with defensive fallbacks + redactSecret
- handlers.startFreshGame now async; surfaces roundstart errors via the
  existing UPSTREAM_FAIL path

Tests: 449 pass (5 new for generateRoundStart, 1 for roundstart error path).
2026-04-24 16:26:55 +07:00

34 lines
971 B
JavaScript

import { describe, expect, it } from "vitest";
import { SEEDS, getRandomSeed } from "../../../src/modules/twentyq/seeds.js";
describe("twentyq/seeds", () => {
it("every seed is a non-empty lowercase string", () => {
for (const s of SEEDS) {
expect(typeof s).toBe("string");
expect(s.length).toBeGreaterThan(0);
expect(s).toBe(s.toLowerCase());
}
});
it("no duplicate seeds", () => {
expect(new Set(SEEDS).size).toBe(SEEDS.length);
});
it("getRandomSeed returns a member of SEEDS", () => {
const s = getRandomSeed(() => 0.5);
expect(SEEDS).toContain(s);
});
it("getRandomSeed deterministic with stub rng", () => {
const a = getRandomSeed(() => 0);
const b = getRandomSeed(() => 0);
expect(a).toBe(b);
expect(a).toBe(SEEDS[0]);
});
it("rng returning 0.999... still indexes within bounds", () => {
const s = getRandomSeed(() => 0.99999);
expect(s).toBe(SEEDS[SEEDS.length - 1]);
});
});