diff --git a/src/game/words.test.ts b/src/game/words.test.ts new file mode 100644 index 0000000..e4327fc --- /dev/null +++ b/src/game/words.test.ts @@ -0,0 +1,74 @@ +import { describe, it, expect } from "vitest"; +import { wordsByLevel, getWordsForLevel } from "./words"; +import { getKeysUpToLevel } from "./levels"; + +describe("wordsByLevel", () => { + it("has entries for levels 1-6", () => { + for (let level = 1; level <= 6; level++) { + expect(wordsByLevel[level]).toBeDefined(); + expect(Array.isArray(wordsByLevel[level])).toBe(true); + } + }); + + it("each level has at least 8 words", () => { + for (let level = 1; level <= 6; level++) { + expect(wordsByLevel[level]!.length).toBeGreaterThanOrEqual(8); + } + }); + + it("every word in level N uses only characters from that level's allKeys (no spaces)", () => { + for (let level = 1; level <= 6; level++) { + const allowedKeys = getKeysUpToLevel(level).filter((k) => k !== " "); + const words = wordsByLevel[level]!; + for (const word of words) { + for (const char of word) { + expect( + allowedKeys.includes(char), + `Word "${word}" in level ${level} contains "${char}" which is not in allowed keys [${allowedKeys.join(", ")}]`, + ).toBe(true); + } + } + } + }); + + it("no word exceeds 5 characters", () => { + for (let level = 1; level <= 6; level++) { + const words = wordsByLevel[level]!; + for (const word of words) { + expect( + word.length, + `Word "${word}" in level ${level} has ${word.length} chars (max 5)`, + ).toBeLessThanOrEqual(5); + } + } + }); +}); + +describe("getWordsForLevel", () => { + it("returns the requested count of random words from that level", () => { + const words = getWordsForLevel(3, 5); + expect(words).toHaveLength(5); + for (const word of words) { + expect(wordsByLevel[3]).toContain(word); + } + }); + + it("returns empty array for non-existent level", () => { + expect(getWordsForLevel(99, 5)).toEqual([]); + expect(getWordsForLevel(0, 5)).toEqual([]); + }); + + it("can return more words than list length (with replacement)", () => { + const words = getWordsForLevel(1, 20); + expect(words).toHaveLength(20); + for (const word of words) { + expect(wordsByLevel[1]).toContain(word); + } + }); + + it("returns unique words when count <= list length (without replacement)", () => { + const words = getWordsForLevel(3, 5); + const unique = new Set(words); + expect(unique.size).toBe(5); + }); +});