/* * Vencord, a Discord client mod * Copyright (c) 2026 Evandro * SPDX-License-Identifier: GPL-3.0-or-later */ // Caminhos-base (McCabe): um caso por caminho independente de cada função de logic.ts. import assert from "node:assert/strict"; import { describe, test } from "node:test"; import { EN, ES_419, ES_ES, pickCopy, PT } from "./copy"; import { adjustOptions, createDispatcher, ECHO_MS, FIRST_PROBE_MS, fixPortalState, normalizeTrigger, planRegistration, PROBE_WINDOW_MS } from "./logic"; function recorder() { const calls: boolean[] = []; return { calls, callback: (isDown: boolean) => { calls.push(isDown); } }; } describe("planRegistration (V(G)=7)", () => { test("P1 portal ativo, representável, segurar → hold", () => { assert.equal(planRegistration({ keydown: true, keyup: true }, true, true), "hold"); }); test("P2 portal inativo → passthrough", () => { assert.equal(planRegistration({ keydown: true, keyup: true }, false, true), "passthrough"); }); test("P3 combinação não representável → passthrough", () => { assert.equal(planRegistration({ keydown: true, keyup: true }, true, false), "passthrough"); }); test("P4 ação com portal:false (SOUNDBOARD_HOLD no Linux) → passthrough", () => { assert.equal(planRegistration({ keydown: true, keyup: true, portal: false }, true, true), "passthrough"); }); test("P5 só soltar (TOGGLE_MUTE) → pressAsRelease", () => { assert.equal(planRegistration({ keydown: false, keyup: true }, true, true), "pressAsRelease"); }); test("P6 só pressionar (SAVE_CLIP) → passthrough", () => { assert.equal(planRegistration({ keydown: true, keyup: false }, true, true), "passthrough"); }); test("P7 nenhum evento → passthrough", () => { assert.equal(planRegistration({}, true, true), "passthrough"); }); }); describe("adjustOptions (V(G)=2)", () => { test("P1 pressAsRelease → pede pressionar e soltar ao nativo e preserva o resto", () => { const options = { focused: true, blurred: true, keydown: false, keyup: true, shortcutId: "toggle-mute" }; assert.deepEqual(adjustOptions(options, "pressAsRelease"), { focused: true, blurred: true, keydown: true, keyup: true, shortcutId: "toggle-mute" }); assert.equal(options.keydown, false, "não muta o objeto original"); }); test("P2 outros modos → mesmo objeto", () => { const options = { keydown: true, keyup: true }; assert.equal(adjustOptions(options, "hold"), options); assert.equal(adjustOptions(options, "passthrough"), options); }); }); // Relógio falso: timers só disparam quando o teste avança o tempo. function fakeScheduler() { let now = 0, seq = 0; const timers = new Map void; }>(); return { now: () => now, setTimeout: (fn: () => void, ms: number) => { timers.set(++seq, { at: now + ms, fn }); return seq; }, clearTimeout: (id: unknown) => { timers.delete(id as number); }, pending: () => timers.size, advance(ms: number) { const target = now + ms; for (;;) { const next = [...timers.entries()].filter(([, t]) => t.at <= target).sort((a, b) => a[1].at - b[1].at)[0]; if (!next) break; timers.delete(next[0]); now = next[1].at; next[1].fn(); } now = target; } }; } function rig(mode: "pressAsRelease" | "hold") { const clock = fakeScheduler(); const calls: boolean[] = []; let rearms = 0; const { dispatch, cancel } = createDispatcher(d => { calls.push(d); }, mode, () => { rearms++; }, clock); return { clock, calls, dispatch, cancel, rearms: () => rearms }; } describe("createDispatcher (V(G)=2) e o despachante (V(G)=6)", () => { test("P1 passthrough → devolve o próprio callback e cancel inofensivo", () => { const { callback } = recorder(); const d = createDispatcher(callback, "passthrough", () => { throw new Error("não deve re-registrar"); }, fakeScheduler()); assert.equal(d.dispatch, callback); d.cancel(); }); test("D1 ocioso + soltar avulso → ignorado, nada agendado", () => { const r = rig("hold"); r.dispatch(false); assert.deepEqual(r.calls, []); assert.equal(r.clock.pending(), 0); }); test("D2 ocioso + pressionar → alternar dispara como soltura (false) e agenda a 1ª sondagem", () => { const r = rig("pressAsRelease"); r.dispatch(true); assert.deepEqual(r.calls, [false]); r.clock.advance(FIRST_PROBE_MS - 1); assert.equal(r.rearms(), 0); r.clock.advance(1); assert.equal(r.rearms(), 1); }); test("D2 ocioso + pressionar → segurar começa (true)", () => { const r = rig("hold"); r.dispatch(true); assert.deepEqual(r.calls, [true]); }); test("D3 segurado + repetição logo após o re-registro → continua segurado e sonda de novo", () => { const r = rig("hold"); r.dispatch(true); r.clock.advance(FIRST_PROBE_MS); r.clock.advance(20); r.dispatch(true); r.clock.advance(PROBE_WINDOW_MS - 20); assert.deepEqual(r.calls, [true]); assert.equal(r.rearms(), 2); }); test("veredito sem repetição → segurar termina (false) e para de sondar", () => { const r = rig("hold"); r.dispatch(true); r.clock.advance(FIRST_PROBE_MS + PROBE_WINDOW_MS); assert.deepEqual(r.calls, [true, false]); assert.equal(r.clock.pending(), 0); assert.equal(r.rearms(), 1); }); test("veredito sem repetição → alternar não chama nada a mais", () => { const r = rig("pressAsRelease"); r.dispatch(true); r.clock.advance(FIRST_PROBE_MS + PROBE_WINDOW_MS); assert.deepEqual(r.calls, [false]); assert.equal(r.clock.pending(), 0); }); test("D4 segurado + pressionar fora do eco (soltura perdida, novo gesto) → alternar dispara de novo", () => { const r = rig("pressAsRelease"); r.dispatch(true); r.clock.advance(FIRST_PROBE_MS + ECHO_MS); r.dispatch(true); assert.deepEqual(r.calls, [false, false]); }); test("D5 segurado + soltar dentro do eco do re-registro → ignorado (soltura sintética)", () => { const r = rig("hold"); r.dispatch(true); r.clock.advance(FIRST_PROBE_MS + 1); r.dispatch(false); assert.deepEqual(r.calls, [true]); }); test("D6 segurado + soltar real → segurar termina na hora e cancela a sondagem", () => { const r = rig("hold"); r.dispatch(true); r.clock.advance(400); r.dispatch(false); assert.deepEqual(r.calls, [true, false]); assert.equal(r.clock.pending(), 0); r.clock.advance(5000); assert.equal(r.rearms(), 0); }); test("D6 alternar + soltar real → sem chamada extra, próximo toque dispara (toque duplo)", () => { const r = rig("pressAsRelease"); r.dispatch(true); r.clock.advance(80); r.dispatch(false); r.clock.advance(200); r.dispatch(true); assert.deepEqual(r.calls, [false, false]); }); test("cancel → para a sondagem e nada mais é re-registrado", () => { const r = rig("hold"); r.dispatch(true); r.cancel(); r.clock.advance(5000); assert.equal(r.rearms(), 0); assert.equal(r.clock.pending(), 0); }); test("cenário medido: segurar 1,8 s soltando modificadores antes, depois novo toque", () => { const r = rig("pressAsRelease"); r.dispatch(true); // Activated r.clock.advance(FIRST_PROBE_MS); r.dispatch(true); // repetição logo após o 1º re-registro r.clock.advance(PROBE_WINDOW_MS); r.dispatch(true); // ainda segurado no 2º re-registro r.clock.advance(PROBE_WINDOW_MS); // soltou (sem Deactivated): veredito encerra r.clock.advance(1500); r.dispatch(true); // gesto seguinte não é engolido assert.deepEqual(r.calls, [false, false]); assert.equal(r.clock.pending(), 1); }); }); describe("normalizeTrigger (V(G)=2 + apelidos)", () => { test("P1 formato do portal (sem <>) → MODS|tecla", () => { assert.equal(normalizeTrigger("CTRL+SHIFT+F12"), "CTRL+SHIFT|f12"); }); test("P2 descrição do GNOME (com <>) → mesma forma canônica", () => { assert.equal(normalizeTrigger("Press F12"), "CTRL+SHIFT|f12"); }); test("tecla sem modificador, descrição localizada do GNOME", () => { assert.equal(normalizeTrigger("Pressione F12"), "|f12"); assert.equal(normalizeTrigger("m"), "|m"); }); test("apelidos de modificador e modificador desconhecido", () => { assert.equal(normalizeTrigger("Press m"), "ALT+CTRL+LOGO|m"); assert.equal(normalizeTrigger("NUM+a"), "NUM|a"); }); }); describe("fixPortalState (V(G)=5)", () => { const gnome = { eventId: 7, bound: true, triggerDescription: "Press F12", matchesTrigger: false }; test("P1 vinculado, divergente só no formato → matchesTrigger true (cópia)", () => { const fixed = fixPortalState(gnome, "CTRL+SHIFT+F12"); assert.deepEqual(fixed, { ...gnome, matchesTrigger: true }); assert.equal(gnome.matchesTrigger, false, "não muta o estado original"); }); test("P2 não vinculado → igual", () => { const s = { ...gnome, bound: false }; assert.equal(fixPortalState(s, "CTRL+SHIFT+F12"), s); }); test("P3 já casa → igual", () => { const s = { ...gnome, matchesTrigger: true }; assert.equal(fixPortalState(s, "CTRL+SHIFT+F12"), s); }); test("P4 sem gatilho esperado → igual", () => { assert.equal(fixPortalState(gnome, undefined), gnome); }); test("P5 atalho realmente diferente no sistema → igual", () => { assert.equal(fixPortalState(gnome, "CTRL+ALT+F12"), gnome); }); }); describe("pickCopy (V(G)=4)", () => { test("P1 português → PT", () => { assert.equal(pickCopy("pt-BR"), PT); }); test("P2 espanhol da América Latina → ES_419", () => { assert.equal(pickCopy("es-419"), ES_419); }); test("P3 espanhol da Espanha → ES_ES", () => { assert.equal(pickCopy("es-ES"), ES_ES); }); test("P4 inglês → EN", () => { assert.equal(pickCopy("en-US"), EN); }); test("borda: idioma fora dos três → EN", () => { assert.equal(pickCopy("fr"), EN); assert.equal(pickCopy("ja"), EN); }); test("borda: idioma vazio → EN", () => { assert.equal(pickCopy(""), EN); }); test("borda: maiúsculas e minúsculas não importam", () => { assert.equal(pickCopy("PT-br"), PT); assert.equal(pickCopy("ES-419"), ES_419); }); }); describe("textos do painel", () => { test("botão citado no passo 2 é o rótulo oficial do Discord em cada idioma", () => { assert.equal(EN.steps[1][1], "Add a Keybind"); assert.equal(PT.steps[1][1], "Adicionar atalho"); assert.equal(ES_ES.steps[1][1], "Añadir un atajo de teclado"); assert.equal(ES_419.steps[1][1], "Añadir un atajo de teclado"); }); test("as variantes de espanhol usam os nomes de ação de cada região", () => { assert.match(ES_ES.steps[1][2], /Alternar silencio, Alternar ensordecimiento/); assert.match(ES_419.steps[1][2], /Activar o desactivar silencio, Activar o desactivar ensordecer/); }); test("plural do status", () => { for (const copy of [EN, PT, ES_ES]) { assert.notEqual(copy.active(0), copy.active(1)); assert.notEqual(copy.active(1).replace("1", "2"), copy.active(2)); } assert.equal(ES_ES.active(1), "Activo en este sistema · 1 atajo registrado"); assert.equal(ES_ES.active(2), "Activo en este sistema · 2 atajos registrados"); }); });