Files
OmniRoute/tests/unit/combo/combo-attempt-loop.test.ts
Bob.Hou ce49d969ca refactor(combo): move handleRoundRobinCombo into roundRobinCombo.ts (#12811)
Validado numa worktree combinada com as 16 PRs desta leva sobre `release/v3.8.51`: typecheck:core limpo, check-file-size e check-changelog-integrity OK, complexity 2788/3218 e cognitive 1261/1437, ESLint 0 erros nos 152 arquivos alterados, 771 testes unitários focados, 49 de integração e a suíte vitest:ui completa (2149) verdes.

**Sobre a reconstrução da branch.** Esta PR continha os 7 commits do #12746 mais os 3 do round-robin. O dono escolheu mergear os dois em sequência em vez de fechar um como subsumido, então depois que o squash do #12746 entrou eu reconstruí esta branch: cherry-pick de `05059880`, `54168238` e `ddd6bcbf` sobre o tip novo, e force-push. Autoria preservada — os três commits continuam seus (`Minxi Hou <houminxi@gmail.com>`), verificado com `git log --format=%an` antes do push. A PR foi de +4167/−3187 em 14 arquivos para +1281/−1182 em 5, que é o delta real do round-robin.

O `05059880` ("guard round-robin extract before the lift") é o commit que faz esse tipo de extract ser revisável: sem um teste que fixe o contrato antes do movimento, mover 1198 linhas é indistinguível de reescrever 1198 linhas.

Revalidei sobre o tip reconstruído: `round-robin-combo`, `combo-attempt-loop`, `execute-target-attempt`, `execute-target-gates` e `combo-loop-safety-timer-leak-11804` — 24/24 — com typecheck:core limpo e o cap de arquivo OK.
2026-09-07 09:09:51 -03:00

66 lines
2.8 KiB
TypeScript

/**
* Characterization for comboAttemptLoop.ts (#11804 finally + gates/attempt wiring).
* Plan Task 4. RED until that module exists.
*/
import test from "node:test";
import assert from "node:assert/strict";
import { readFileSync } from "node:fs";
import { fileURLToPath } from "node:url";
import { dirname, resolve } from "node:path";
const here = dirname(fileURLToPath(import.meta.url));
test("dispatchWithCooldownRetry clears activeLoopSafetyTimer in finally", async () => {
const src = readFileSync(
resolve(here, "../../../open-sse/services/combo/comboAttemptLoop.ts"),
"utf8"
);
assert.match(src, /finally\s*\{[^}]*clearTimeout\(activeLoopSafetyTimer\)/s);
assert.match(src, /activeLoopSafetyTimer = loopSafetyTimer/);
});
test("dispatchWithCooldownRetry calls evaluateGates then executeAttempt, not inline executeTarget", async () => {
const src = readFileSync(
resolve(here, "../../../open-sse/services/combo/comboAttemptLoop.ts"),
"utf8"
);
assert.match(src, /extra\.evaluateGates/);
assert.match(src, /extra\.executeAttempt/);
// Thin wrapper may keep the local name; the old inline retry/gate body must not.
assert.doesNotMatch(src, /getCircuitBreaker\(provider\)/);
assert.doesNotMatch(src, /for \(let retry = 0; retry <= deps\.maxRetries/);
});
test("attempt budget lives on state.globalAttempts, not extra.globalAttempts box", async () => {
const loopSrc = readFileSync(
resolve(here, "../../../open-sse/services/combo/comboAttemptLoop.ts"),
"utf8"
);
const comboSrc = readFileSync(resolve(here, "../../../open-sse/services/combo.ts"), "utf8");
const attemptSrc = readFileSync(
resolve(here, "../../../open-sse/services/combo/executeTargetAttempt.ts"),
"utf8"
);
assert.match(attemptSrc, /state\.globalAttempts\+\+/);
assert.doesNotMatch(loopSrc, /globalAttempts:\s*\{\s*current:\s*number\s*\}/);
assert.doesNotMatch(comboSrc, /globalAttempts:\s*\{\s*current:\s*0\s*\}/);
});
test("handleComboChatInner does not leave unused delay locals or unused failureTracker import", async () => {
const comboSrc = readFileSync(resolve(here, "../../../open-sse/services/combo.ts"), "utf8");
const innerStart = comboSrc.indexOf("async function handleComboChatInner");
const rrStart = comboSrc.indexOf("async function handleRoundRobinCombo");
const inner = comboSrc.slice(innerStart, rrStart === -1 ? comboSrc.length : rrStart);
assert.doesNotMatch(inner, /const retryDelayMs = resolveDelayMs/);
assert.doesNotMatch(inner, /const fallbackDelayMs = resolveDelayMs/);
assert.doesNotMatch(comboSrc, /clearComboFailureTracking/);
});
test("hedge delay does not declare unused timeoutResolve", async () => {
const loopSrc = readFileSync(
resolve(here, "../../../open-sse/services/combo/comboAttemptLoop.ts"),
"utf8"
);
assert.doesNotMatch(loopSrc, /let timeoutResolve/);
});