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); }); });