diff --git a/tests/helpers/translator-budget.ts b/tests/helpers/translator-budget.ts index 7245729752e..0c4e5f565dd 100644 --- a/tests/helpers/translator-budget.ts +++ b/tests/helpers/translator-budget.ts @@ -1,4 +1,4 @@ -import { afterEach } from "bun:test"; +import { afterEach, onTestFinished } from "bun:test"; import type { IncomingMeta, ProviderAdapter } from "../../src/adapters/base"; import { createTranslatorBudget, @@ -8,17 +8,29 @@ import { const liveTestBudgets = new Set(); +function disposeTestTranslatorBudgets(): void { + for (const budget of liveTestBudgets) budget.dispose(); + liveTestBudgets.clear(); + resetTranslatorAggregateForTests(); +} + export function createTestTranslatorBudget(options?: Parameters[0]): TranslatorBudget { const budget = createTranslatorBudget(options); liveTestBudgets.add(budget); + // The `afterEach` below only runs for the first test file that imports this module: a + // shared Bun process evaluates it once, so every later importer keeps its budgets and the + // aggregate for the rest of the run. `onTestFinished` belongs to the running test, whatever + // file it is in. Outside a test (module scope, `beforeAll`) it throws, and the `afterEach` + // stays the only cleanup. + try { + onTestFinished(disposeTestTranslatorBudgets); + } catch { + // Not inside a running test. + } return budget; } -afterEach(() => { - for (const budget of liveTestBudgets) budget.dispose(); - liveTestBudgets.clear(); - resetTranslatorAggregateForTests(); -}); +afterEach(disposeTestTranslatorBudgets); type TestAdapter = Omit & { buildRequest(