import { escolherHordas, montarFila, tamanhoDaHorda } from "./hordas"; import { problemaPorId, problemasDaArea } from "./problemas"; import { sortearInteiro } from "./rng"; import type { Dificuldade } from "./tipos"; describe("tamanhoDaHorda", () => { it.each([ [0, "facil", 8], [1, "facil", 11], [2, "facil", 14], [0, "normal", 12], [1, "normal", 16], [2, "normal", 20], [0, "dificil", 16], [1, "dificil", 21], [2, "dificil", 26], ] as const)("horda %i no %s tem %i", (indice, dificuldade, esperado) => { expect(tamanhoDaHorda(indice, dificuldade)).toBe(esperado); }); it("lança erro para índice fora de 0 a 2", () => { expect(() => tamanhoDaHorda(3, "normal")).toThrow(Error); expect(() => tamanhoDaHorda(-1, "normal")).toThrow(Error); }); }); describe("escolherHordas", () => { const id = "site-lento"; const area = problemaPorId(id)?.area ?? "vender"; it("devolve 3 outros problemas da área, sem repetir, e o próprio id por último", () => { for (let rng = 1; rng <= 30; rng++) { const ids = escolherHordas({ rng }, id); expect(ids).toHaveLength(4); expect(ids[3]).toBe(id); expect(new Set(ids).size).toBe(4); for (const outro of ids) { expect(problemaPorId(outro)?.area).toBe(area); } } }); it("usa sortearInteiro sobre os candidatos restantes", () => { const p = { rng: 7 }; const copia = { rng: 7 }; const outros = problemasDaArea(area) .map((problema) => problema.id) .filter((outro) => outro !== id); const esperado: string[] = []; for (let i = 0; i < 3; i++) { const [escolhido] = outros.splice( sortearInteiro(copia, outros.length), 1, ); esperado.push(escolhido); } expect(escolherHordas(p, id)).toEqual([...esperado, id]); }); it("lança erro para id inexistente", () => { expect(() => escolherHordas({ rng: 1 }, "nao-existe")).toThrow(Error); }); }); describe("montarFila", () => { const tipos = (indice: number, dificuldade: Dificuldade = "normal") => montarFila(indice, "x", dificuldade).map((n) => n.tipo); it("horda 0: todos comuns", () => { expect(tipos(0)).toEqual(Array(12).fill("comum")); }); it("horda 1: alterna comum e rápido", () => { const t = tipos(1); expect(t).toHaveLength(16); expect(t.slice(0, 4)).toEqual(["comum", "rapido", "comum", "rapido"]); expect(t.filter((x) => x === "comum")).toHaveLength(8); expect(t.filter((x) => x === "rapido")).toHaveLength(8); }); it("horda 2: posição módulo 5", () => { const t = tipos(2); expect(t).toHaveLength(20); expect(t.slice(0, 5)).toEqual([ "comum", "comum", "rapido", "rapido", "blindado", ]); expect(t.slice(15)).toEqual(t.slice(0, 5)); }); it("chefão: um chefão e a escolta fixa, sem mudar com a dificuldade", () => { const esperado = ["chefao", ...Array(6).fill("comum")]; expect(tipos(3)).toEqual(esperado); expect(tipos(3, "dificil")).toEqual(esperado); }); it("o tamanho segue a dificuldade e todos levam o problemaId", () => { const fila = montarFila(0, "abc", "facil"); expect(fila).toHaveLength(8); expect(fila.every((n) => n.problemaId === "abc")).toBe(true); expect( montarFila(3, "abc", "facil").every((n) => n.problemaId === "abc"), ).toBe(true); }); it("lança erro para índice fora de 0 a 3", () => { expect(() => montarFila(4, "x", "normal")).toThrow(Error); expect(() => montarFila(-1, "x", "normal")).toThrow(Error); }); });