Files
portifolio-evandrodevbr/lib/jogo/regulador.test.ts
T
evandro 67b32fcab3
CI / audit (push) Successful in 10m48s
CI / verify (push) Successful in 19m2s
CI / deploy (push) Successful in 2m14s
CI / e2e (push) Failing after 36m15s
feat(jogo): expediente dos mortos, jogo de zumbis em primeira pessoa
Etapa 1 inteira (logica com 100% de cobertura, cena 3D, toque, sons, bancada de desempenho, e2e) e a base da etapa 2 (mapa novo no Tiled, texturas, imagens dos itens, sons conferidos, golpe recortado e medido). Pagina /jogo fora do menu e do sitemap ate a medicao no celular.
2026-11-10 19:37:10 -03:00

158 lines
4.8 KiB
TypeScript

import {
amostrar,
criarRegulador,
nivelAtual,
type Regulador,
} from "./regulador";
import { NIVEIS } from "./valores";
const ULTIMO = NIVEIS.length - 1;
const HZ_60 = 1000 / 60;
const HZ_30 = 1000 / 30;
/** Alimenta `n` janelas inteiras (2 s cada) de quadros iguais; para antes se o regulador travar. */
function janelas(
r: Regulador,
intervalo: number,
trabalho: number,
n: number,
): number {
for (let i = 0; i < n && !r.travado; i++) {
do amostrar(r, intervalo, trabalho);
while (r.somaDaJanela > 0);
}
return r.nivel;
}
/** Regulador com o topo no nível 0 (tela de pixelRatio 2), já no nível `nivel`. */
function reguladorEm(nivel: number): Regulador {
const r = criarRegulador(2);
r.nivel = nivel;
return r;
}
describe("regulador", () => {
it("começa no primeiro nível cujo pixelRatio cabe no do aparelho", () => {
expect(criarRegulador(3).nivel).toBe(0);
expect(criarRegulador(2).nivel).toBe(0);
expect(criarRegulador(1.5).nivel).toBe(1);
expect(criarRegulador(1.25).nivel).toBe(2);
expect(criarRegulador(1).nivel).toBe(2);
// zoom de afastar: abaixo de 1 vale o primeiro degrau de pixelRatio 1
expect(criarRegulador(0.8).nivel).toBe(2);
});
it("nunca sobe acima do nível inicial do aparelho", () => {
const r = criarRegulador(1);
expect(janelas(r, 8, 2, 20)).toBe(2);
r.nivel = 4;
expect(janelas(r, 8, 2, 20)).toBe(2);
});
it("nivelAtual devolve o degrau de NIVEIS", () => {
expect(nivelAtual(reguladorEm(2))).toBe(NIVEIS[2]);
});
it("60 Hz com folga nunca muda o nível 0", () => {
expect(janelas(criarRegulador(2), HZ_60, 3, 30)).toBe(0);
});
it("60 Hz saudável sobe depois de cair", () => {
const r = criarRegulador(2);
expect(janelas(r, 30, 25, 1)).toBe(1);
// a janela depois da descida já ganhou e conta como folga: 5 janelas (10 s) sobem
expect(janelas(r, HZ_60, 3, 4)).toBe(1);
expect(janelas(r, HZ_60, 3, 1)).toBe(0);
expect(r.travado).toBe(false);
});
it("60 Hz com trabalho pesado não conta folga", () => {
const r = reguladorEm(2);
expect(janelas(r, HZ_60, 8, 10)).toBe(2);
});
it("tela limitada a 30 Hz desce 2, volta 2 e trava", () => {
const r = criarRegulador(2);
expect(janelas(r, HZ_30, 3, 1)).toBe(1);
expect(janelas(r, HZ_30, 3, 1)).toBe(2);
expect(janelas(r, HZ_30, 3, 1)).toBe(0);
expect(r.travado).toBe(true);
expect(janelas(r, HZ_30, 3, 1)).toBe(0);
expect(amostrar(r, HZ_30, 3)).toBe(0);
expect(r.intervalos).toHaveLength(0);
});
it("carga real desce e fica", () => {
const r = criarRegulador(2);
expect(janelas(r, 30, 25, 1)).toBe(1);
// cada descida melhora o intervalo em mais de 10%
expect(janelas(r, 24, 20, 1)).toBe(2);
expect(janelas(r, 18, 15, 15)).toBe(2);
expect(r.travado).toBe(false);
});
it("descida com ganho zera a conta de descidas sem ganho", () => {
const r = criarRegulador(2);
janelas(r, 30, 25, 1);
janelas(r, 30, 25, 1);
expect(r.descidasSemGanho).toBe(1);
expect(janelas(r, 25, 20, 1)).toBe(3);
expect(r.descidasSemGanho).toBe(0);
});
it("descida sem ganho que não desce de novo não trava, e a volta não passa do topo", () => {
const r = criarRegulador(2);
janelas(r, 21, 3, 1);
// 20 ms: sem ganho, mas dentro do limite; sobe de volta depois da folga
expect(janelas(r, 20, 3, 5)).toBe(0);
expect(r.descidasSemGanho).toBe(1);
janelas(r, 21, 3, 1);
expect(janelas(r, 21, 3, 1)).toBe(0);
expect(r.travado).toBe(true);
});
it("não passa do último degrau", () => {
const r = reguladorEm(ULTIMO);
expect(janelas(r, 30, 25, 5)).toBe(ULTIMO);
});
it("janela mediana zera a folga acumulada", () => {
const r = reguladorEm(1);
janelas(r, 8, 2, 4);
janelas(r, 16, 8, 1);
expect(janelas(r, 8, 2, 4)).toBe(1);
});
it("descer logo depois de subir trava a subida: depois disso 20 s de folga não sobem", () => {
const r = reguladorEm(2);
expect(janelas(r, 8, 2, 5)).toBe(1);
expect(janelas(r, 30, 25, 1)).toBe(2);
expect(janelas(r, 8, 2, 10)).toBe(2);
expect(r.subidaTravada).toBe(true);
});
it("descer muito depois de subir não trava", () => {
const r = reguladorEm(2);
expect(janelas(r, 8, 2, 5)).toBe(1);
janelas(r, 16, 8, 15);
expect(janelas(r, 30, 25, 1)).toBe(2);
expect(janelas(r, 8, 2, 5)).toBe(1);
});
it("quadro de 300 ms é ignorado", () => {
const r = reguladorEm(1);
for (let i = 0; i < 20; i++) expect(amostrar(r, 300, 3)).toBe(1);
expect(r.intervalos).toHaveLength(0);
});
it("o p95 decide, não a média", () => {
const r = criarRegulador(2);
let nivel = 0;
for (let g = 0; g < 16; g++) {
for (let i = 0; i < 9; i++) nivel = amostrar(r, 10, 2);
nivel = amostrar(r, 40, 2);
}
expect(nivel).toBe(1);
});
});