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.
158 lines
4.8 KiB
TypeScript
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);
|
|
});
|
|
});
|