From 723e314e2bf272c49d458dbc69a3071b5931a443 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sun, 15 Feb 2026 14:52:31 +0000 Subject: [PATCH] fix(ci): avoid vitest TDZ in shared mocks --- ...nt-runner.heartbeat-typing.test-harness.ts | 24 +++---- .../agent-runner.memory-flush.test-harness.ts | 24 +++---- .../monitor/slash.command-arg-menus.test.ts | 40 +++++++++++- src/slack/monitor/slash.policy.test.ts | 40 +++++++++++- src/slack/monitor/slash.test-mocks.ts | 62 ------------------- 5 files changed, 98 insertions(+), 92 deletions(-) delete mode 100644 src/slack/monitor/slash.test-mocks.ts diff --git a/src/auto-reply/reply/agent-runner.heartbeat-typing.test-harness.ts b/src/auto-reply/reply/agent-runner.heartbeat-typing.test-harness.ts index b88c004f6..d1c176d49 100644 --- a/src/auto-reply/reply/agent-runner.heartbeat-typing.test-harness.ts +++ b/src/auto-reply/reply/agent-runner.heartbeat-typing.test-harness.ts @@ -4,11 +4,6 @@ import type { TypingMode } from "../../config/types.js"; import type { TemplateContext } from "../templating.js"; import type { GetReplyOptions } from "../types.js"; import type { FollowupRun, QueueSettings } from "./queue.js"; -import { - embeddedPiMockFactory, - modelFallbackMockFactory, - queueMockFactory, -} from "./agent-runner.test-harness.mocks.js"; import { createMockTypingController } from "./test-helpers.js"; // Avoid exporting vitest mock types (TS2742 under pnpm + d.ts emit). @@ -44,15 +39,20 @@ export function installRunReplyAgentTypingHeartbeatTestHooks() { }); } -vi.mock("../../agents/model-fallback.js", () => ({ - ...modelFallbackMockFactory(), -})); +vi.mock("../../agents/model-fallback.js", async () => { + const { modelFallbackMockFactory } = await import("./agent-runner.test-harness.mocks.js"); + return modelFallbackMockFactory(); +}); -vi.mock("../../agents/pi-embedded.js", () => ({ - ...embeddedPiMockFactory(state), -})); +vi.mock("../../agents/pi-embedded.js", async () => { + const { embeddedPiMockFactory } = await import("./agent-runner.test-harness.mocks.js"); + return embeddedPiMockFactory(state); +}); -vi.mock("./queue.js", queueMockFactory); +vi.mock("./queue.js", async () => { + const { queueMockFactory } = await import("./agent-runner.test-harness.mocks.js"); + return await queueMockFactory(); +}); export function createMinimalRun(params?: { opts?: GetReplyOptions; diff --git a/src/auto-reply/reply/agent-runner.memory-flush.test-harness.ts b/src/auto-reply/reply/agent-runner.memory-flush.test-harness.ts index 820b096fd..131da7c52 100644 --- a/src/auto-reply/reply/agent-runner.memory-flush.test-harness.ts +++ b/src/auto-reply/reply/agent-runner.memory-flush.test-harness.ts @@ -3,11 +3,6 @@ import path from "node:path"; import { vi } from "vitest"; import type { TemplateContext } from "../templating.js"; import type { FollowupRun, QueueSettings } from "./queue.js"; -import { - embeddedPiMockFactory, - modelFallbackMockFactory, - queueMockFactory, -} from "./agent-runner.test-harness.mocks.js"; import { createMockTypingController } from "./test-helpers.js"; // Avoid exporting vitest mock types (TS2742 under pnpm + d.ts emit). @@ -35,19 +30,24 @@ export function getRunCliAgentMock(): AnyMock { export type { EmbeddedRunParams }; -vi.mock("../../agents/model-fallback.js", () => ({ - ...modelFallbackMockFactory(), -})); +vi.mock("../../agents/model-fallback.js", async () => { + const { modelFallbackMockFactory } = await import("./agent-runner.test-harness.mocks.js"); + return modelFallbackMockFactory(); +}); vi.mock("../../agents/cli-runner.js", () => ({ runCliAgent: (params: unknown) => state.runCliAgentMock(params), })); -vi.mock("../../agents/pi-embedded.js", () => ({ - ...embeddedPiMockFactory(state), -})); +vi.mock("../../agents/pi-embedded.js", async () => { + const { embeddedPiMockFactory } = await import("./agent-runner.test-harness.mocks.js"); + return embeddedPiMockFactory(state); +}); -vi.mock("./queue.js", queueMockFactory); +vi.mock("./queue.js", async () => { + const { queueMockFactory } = await import("./agent-runner.test-harness.mocks.js"); + return await queueMockFactory(); +}); export async function seedSessionStore(params: { storePath: string; diff --git a/src/slack/monitor/slash.command-arg-menus.test.ts b/src/slack/monitor/slash.command-arg-menus.test.ts index d9a2b27fc..600102b98 100644 --- a/src/slack/monitor/slash.command-arg-menus.test.ts +++ b/src/slack/monitor/slash.command-arg-menus.test.ts @@ -1,8 +1,42 @@ -import { describe, expect, it, vi } from "vitest"; +import { beforeEach, describe, expect, it, vi } from "vitest"; import { registerSlackMonitorSlashCommands } from "./slash.js"; -import { getDispatchMock } from "./slash.test-mocks.js"; -const dispatchMock = getDispatchMock(); +const dispatchMock = vi.fn(); +const readAllowFromStoreMock = vi.fn(); +const upsertPairingRequestMock = vi.fn(); +const resolveAgentRouteMock = vi.fn(); + +vi.mock("../../auto-reply/reply/provider-dispatcher.js", () => ({ + dispatchReplyWithDispatcher: (...args: unknown[]) => dispatchMock(...args), +})); + +vi.mock("../../pairing/pairing-store.js", () => ({ + readChannelAllowFromStore: (...args: unknown[]) => readAllowFromStoreMock(...args), + upsertChannelPairingRequest: (...args: unknown[]) => upsertPairingRequestMock(...args), +})); + +vi.mock("../../routing/resolve-route.js", () => ({ + resolveAgentRoute: (...args: unknown[]) => resolveAgentRouteMock(...args), +})); + +vi.mock("../../agents/identity.js", async (importOriginal) => { + const actual = await importOriginal(); + return { + ...actual, + resolveEffectiveMessagesConfig: () => ({ responsePrefix: "" }), + }; +}); + +beforeEach(() => { + dispatchMock.mockReset().mockResolvedValue({ counts: { final: 1, tool: 0, block: 0 } }); + readAllowFromStoreMock.mockReset().mockResolvedValue([]); + upsertPairingRequestMock.mockReset().mockResolvedValue({ code: "PAIRCODE", created: true }); + resolveAgentRouteMock.mockReset().mockReturnValue({ + agentId: "main", + sessionKey: "session:1", + accountId: "acct", + }); +}); function encodeValue(parts: { command: string; arg: string; value: string; userId: string }) { return [ diff --git a/src/slack/monitor/slash.policy.test.ts b/src/slack/monitor/slash.policy.test.ts index c4bf40b7f..48e48bdf8 100644 --- a/src/slack/monitor/slash.policy.test.ts +++ b/src/slack/monitor/slash.policy.test.ts @@ -1,8 +1,42 @@ -import { describe, expect, it, vi } from "vitest"; +import { beforeEach, describe, expect, it, vi } from "vitest"; import { registerSlackMonitorSlashCommands } from "./slash.js"; -import { getDispatchMock } from "./slash.test-mocks.js"; -const dispatchMock = getDispatchMock(); +const dispatchMock = vi.fn(); +const readAllowFromStoreMock = vi.fn(); +const upsertPairingRequestMock = vi.fn(); +const resolveAgentRouteMock = vi.fn(); + +vi.mock("../../auto-reply/reply/provider-dispatcher.js", () => ({ + dispatchReplyWithDispatcher: (...args: unknown[]) => dispatchMock(...args), +})); + +vi.mock("../../pairing/pairing-store.js", () => ({ + readChannelAllowFromStore: (...args: unknown[]) => readAllowFromStoreMock(...args), + upsertChannelPairingRequest: (...args: unknown[]) => upsertPairingRequestMock(...args), +})); + +vi.mock("../../routing/resolve-route.js", () => ({ + resolveAgentRoute: (...args: unknown[]) => resolveAgentRouteMock(...args), +})); + +vi.mock("../../agents/identity.js", async (importOriginal) => { + const actual = await importOriginal(); + return { + ...actual, + resolveEffectiveMessagesConfig: () => ({ responsePrefix: "" }), + }; +}); + +beforeEach(() => { + dispatchMock.mockReset().mockResolvedValue({ counts: { final: 1, tool: 0, block: 0 } }); + readAllowFromStoreMock.mockReset().mockResolvedValue([]); + upsertPairingRequestMock.mockReset().mockResolvedValue({ code: "PAIRCODE", created: true }); + resolveAgentRouteMock.mockReset().mockReturnValue({ + agentId: "main", + sessionKey: "session:1", + accountId: "acct", + }); +}); function createHarness(overrides?: { groupPolicy?: "open" | "allowlist"; diff --git a/src/slack/monitor/slash.test-mocks.ts b/src/slack/monitor/slash.test-mocks.ts deleted file mode 100644 index 690e594de..000000000 --- a/src/slack/monitor/slash.test-mocks.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { beforeEach, vi } from "vitest"; - -// Avoid exporting vitest mock types (TS2742 under pnpm + d.ts emit). -// oxlint-disable-next-line typescript/no-explicit-any -type AnyMock = any; - -const hoisted = vi.hoisted(() => ({ - dispatchMock: vi.fn(), - readAllowFromStoreMock: vi.fn(), - upsertPairingRequestMock: vi.fn(), - resolveAgentRouteMock: vi.fn(), -})); - -export function getDispatchMock(): AnyMock { - return hoisted.dispatchMock; -} - -export function getReadAllowFromStoreMock(): AnyMock { - return hoisted.readAllowFromStoreMock; -} - -export function getUpsertPairingRequestMock(): AnyMock { - return hoisted.upsertPairingRequestMock; -} - -export function getResolveAgentRouteMock(): AnyMock { - return hoisted.resolveAgentRouteMock; -} - -vi.mock("../../auto-reply/reply/provider-dispatcher.js", () => ({ - dispatchReplyWithDispatcher: (...args: unknown[]) => hoisted.dispatchMock(...args), -})); - -vi.mock("../../pairing/pairing-store.js", () => ({ - readChannelAllowFromStore: (...args: unknown[]) => hoisted.readAllowFromStoreMock(...args), - upsertChannelPairingRequest: (...args: unknown[]) => hoisted.upsertPairingRequestMock(...args), -})); - -vi.mock("../../routing/resolve-route.js", () => ({ - resolveAgentRoute: (...args: unknown[]) => hoisted.resolveAgentRouteMock(...args), -})); - -vi.mock("../../agents/identity.js", async (importOriginal) => { - const actual = await importOriginal(); - return { - ...actual, - resolveEffectiveMessagesConfig: () => ({ responsePrefix: "" }), - }; -}); - -beforeEach(() => { - hoisted.dispatchMock.mockReset().mockResolvedValue({ counts: { final: 1, tool: 0, block: 0 } }); - hoisted.readAllowFromStoreMock.mockReset().mockResolvedValue([]); - hoisted.upsertPairingRequestMock - .mockReset() - .mockResolvedValue({ code: "PAIRCODE", created: true }); - hoisted.resolveAgentRouteMock.mockReset().mockReturnValue({ - agentId: "main", - sessionKey: "session:1", - accountId: "acct", - }); -});