test: speed up cli and command suites

This commit is contained in:
Peter Steinberger
2026-03-31 02:12:23 +01:00
parent 6b6ddcd2a6
commit 3f1d6fe147
83 changed files with 1161 additions and 1054 deletions

View File

@@ -1,8 +1,9 @@
import { Command } from "commander";
import { beforeEach, describe, expect, it, vi } from "vitest";
import { reparseProgramFromActionArgs } from "./action-reparse.js";
const buildParseArgvMock = vi.fn();
const resolveActionArgsMock = vi.fn();
const buildParseArgvMock = vi.hoisted(() => vi.fn());
const resolveActionArgsMock = vi.hoisted(() => vi.fn());
vi.mock("../argv.js", () => ({
buildParseArgv: buildParseArgvMock,
@@ -12,8 +13,6 @@ vi.mock("./helpers.js", () => ({
resolveActionArgs: resolveActionArgsMock,
}));
const { reparseProgramFromActionArgs } = await import("./action-reparse.js");
describe("reparseProgramFromActionArgs", () => {
beforeEach(() => {
vi.clearAllMocks();

View File

@@ -1,13 +1,14 @@
import process from "node:process";
import { Command } from "commander";
import { beforeEach, describe, expect, it, vi } from "vitest";
import { buildProgram } from "./build-program.js";
import type { ProgramContext } from "./context.js";
const registerProgramCommandsMock = vi.fn();
const createProgramContextMock = vi.fn();
const configureProgramHelpMock = vi.fn();
const registerPreActionHooksMock = vi.fn();
const setProgramContextMock = vi.fn();
const registerProgramCommandsMock = vi.hoisted(() => vi.fn());
const createProgramContextMock = vi.hoisted(() => vi.fn());
const configureProgramHelpMock = vi.hoisted(() => vi.fn());
const registerPreActionHooksMock = vi.hoisted(() => vi.fn());
const setProgramContextMock = vi.hoisted(() => vi.fn());
vi.mock("./command-registry.js", () => ({
registerProgramCommands: registerProgramCommandsMock,
@@ -29,8 +30,6 @@ vi.mock("./program-context.js", () => ({
setProgramContext: setProgramContextMock,
}));
const { buildProgram } = await import("./build-program.js");
describe("buildProgram", () => {
beforeEach(() => {
vi.clearAllMocks();

View File

@@ -1,7 +1,6 @@
import process from "node:process";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
const { buildProgram } = await import("./build-program.js");
import { buildProgram } from "./build-program.js";
describe("buildProgram version alias handling", () => {
let originalArgv: string[];

View File

@@ -27,13 +27,6 @@ vi.mock("./register.maintenance.js", () => ({
},
}));
const {
getCoreCliCommandNames,
getCoreCliCommandsWithSubcommands,
registerCoreCliByName,
registerCoreCliCommands,
} = await import("./command-registry.js");
vi.mock("./register.status-health-sessions.js", () => ({
registerStatusHealthSessionsCommands: (program: Command) => {
program.command("status");
@@ -44,6 +37,13 @@ vi.mock("./register.status-health-sessions.js", () => ({
},
}));
import {
getCoreCliCommandNames,
getCoreCliCommandsWithSubcommands,
registerCoreCliByName,
registerCoreCliCommands,
} from "./command-registry.js";
const testProgramContext: ProgramContext = {
programVersion: "0.0.0-test",
channelOptions: [],

View File

@@ -1,5 +1,5 @@
import { afterAll, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
import type { RuntimeEnv } from "../../runtime.js";
import { beforeEach, describe, expect, it, vi } from "vitest";
import { ensureConfigReady, __test__ } from "./config-guard.js";
const loadAndMaybeMigrateDoctorConfigMock = vi.hoisted(() => vi.fn());
const readConfigFileSnapshotMock = vi.hoisted(() => vi.fn());
@@ -12,8 +12,6 @@ vi.mock("../../config/config.js", () => ({
readConfigFileSnapshot: readConfigFileSnapshotMock,
}));
const mockedModuleIds = ["../../commands/doctor-config-preflight.js", "../../config/config.js"];
function makeSnapshot() {
return {
exists: false,
@@ -46,13 +44,7 @@ async function withCapturedStdout(run: () => Promise<void>): Promise<string> {
}
describe("ensureConfigReady", () => {
let ensureConfigReady: (params: {
runtime: RuntimeEnv;
commandPath?: string[];
suppressDoctorStdout?: boolean;
allowInvalid?: boolean;
}) => Promise<void>;
let resetConfigGuardStateForTests: () => void;
const resetConfigGuardStateForTests = __test__.resetConfigGuardStateForTests;
async function runEnsureConfigReady(commandPath: string[], suppressDoctorStdout = false) {
const runtime = makeRuntime();
@@ -75,20 +67,6 @@ describe("ensureConfigReady", () => {
});
}
beforeAll(async () => {
({
ensureConfigReady,
__test__: { resetConfigGuardStateForTests },
} = await import("./config-guard.js"));
});
afterAll(() => {
for (const id of mockedModuleIds) {
vi.doUnmock(id);
}
vi.resetModules();
});
beforeEach(() => {
vi.clearAllMocks();
resetConfigGuardStateForTests();

View File

@@ -1,6 +1,7 @@
import { describe, expect, it, vi } from "vitest";
import { createProgramContext } from "./context.js";
const resolveCliChannelOptionsMock = vi.fn(() => ["telegram", "whatsapp"]);
const resolveCliChannelOptionsMock = vi.hoisted(() => vi.fn(() => ["telegram", "whatsapp"]));
vi.mock("../../version.js", () => ({
VERSION: "9.9.9-test",
@@ -10,8 +11,6 @@ vi.mock("../channel-options.js", () => ({
resolveCliChannelOptions: resolveCliChannelOptionsMock,
}));
const { createProgramContext } = await import("./context.js");
describe("createProgramContext", () => {
it("builds program context from version and resolved channel options", () => {
resolveCliChannelOptionsMock.mockClear().mockReturnValue(["telegram", "whatsapp"]);

View File

@@ -1,11 +1,14 @@
import { Command } from "commander";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import type { ProgramContext } from "./context.js";
import { configureProgramHelp } from "./help.js";
const hasEmittedCliBannerMock = vi.fn(() => false);
const formatCliBannerLineMock = vi.fn(() => "BANNER-LINE");
const formatDocsLinkMock = vi.fn((_path: string, full: string) => `https://${full}`);
const resolveCommitHashMock = vi.fn<() => string | null>(() => "abc1234");
const hasEmittedCliBannerMock = vi.hoisted(() => vi.fn(() => false));
const formatCliBannerLineMock = vi.hoisted(() => vi.fn(() => "BANNER-LINE"));
const formatDocsLinkMock = vi.hoisted(() =>
vi.fn((_path: string, full: string) => `https://${full}`),
);
const resolveCommitHashMock = vi.hoisted(() => vi.fn<() => string | null>(() => "abc1234"));
vi.mock("../../terminal/links.js", () => ({
formatDocsLink: formatDocsLinkMock,
@@ -44,8 +47,6 @@ vi.mock("./register.subclis.js", () => ({
getSubCliCommandsWithSubcommands: () => ["gateway"],
}));
const { configureProgramHelp } = await import("./help.js");
const testProgramContext: ProgramContext = {
programVersion: "9.9.9-test",
channelOptions: ["telegram"],

View File

@@ -1,5 +1,5 @@
import { Command } from "commander";
import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
import { repoInstallSpec } from "../../../test/helpers/bundled-plugin-paths.js";
import { loggingState } from "../../logging/state.js";
import { setCommandJsonMode } from "./json-mode.js";
@@ -48,15 +48,6 @@ vi.mock("../plugin-registry.js", () => ({
ensurePluginRegistryLoaded: ensurePluginRegistryLoadedMock,
}));
const mockedModuleIds = [
"../../globals.js",
"../../runtime.js",
"../banner.js",
"../cli-name.js",
"./config-guard.js",
"../plugin-registry.js",
];
let registerPreActionHooks: typeof import("./preaction.js").registerPreActionHooks;
let originalProcessArgv: string[];
let originalProcessTitle: string;
@@ -70,13 +61,6 @@ beforeAll(async () => {
({ registerPreActionHooks } = await import("./preaction.js"));
});
afterAll(() => {
for (const id of mockedModuleIds) {
vi.doUnmock(id);
}
vi.resetModules();
});
beforeEach(() => {
vi.clearAllMocks();
originalProcessArgv = [...process.argv];

View File

@@ -1,67 +1,63 @@
import { Command } from "commander";
import { afterAll, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
import { createCliRuntimeCapture } from "../test-runtime-capture.js";
import { beforeEach, describe, expect, it, vi } from "vitest";
import { registerAgentCommands } from "./register.agent.js";
const agentCliCommandMock = vi.fn();
const agentsAddCommandMock = vi.fn();
const agentsBindingsCommandMock = vi.fn();
const agentsBindCommandMock = vi.fn();
const agentsDeleteCommandMock = vi.fn();
const agentsListCommandMock = vi.fn();
const agentsSetIdentityCommandMock = vi.fn();
const agentsUnbindCommandMock = vi.fn();
const setVerboseMock = vi.fn();
const createDefaultDepsMock = vi.fn(() => ({ deps: true }));
const mocks = vi.hoisted(() => ({
agentCliCommandMock: vi.fn(),
agentsAddCommandMock: vi.fn(),
agentsBindingsCommandMock: vi.fn(),
agentsBindCommandMock: vi.fn(),
agentsDeleteCommandMock: vi.fn(),
agentsListCommandMock: vi.fn(),
agentsSetIdentityCommandMock: vi.fn(),
agentsUnbindCommandMock: vi.fn(),
setVerboseMock: vi.fn(),
createDefaultDepsMock: vi.fn(() => ({ deps: true })),
runtime: {
log: vi.fn(),
error: vi.fn(),
exit: vi.fn(),
},
}));
const { defaultRuntime: runtime, resetRuntimeCapture } = createCliRuntimeCapture();
const agentCliCommandMock = mocks.agentCliCommandMock;
const agentsAddCommandMock = mocks.agentsAddCommandMock;
const agentsBindingsCommandMock = mocks.agentsBindingsCommandMock;
const agentsBindCommandMock = mocks.agentsBindCommandMock;
const agentsDeleteCommandMock = mocks.agentsDeleteCommandMock;
const agentsListCommandMock = mocks.agentsListCommandMock;
const agentsSetIdentityCommandMock = mocks.agentsSetIdentityCommandMock;
const agentsUnbindCommandMock = mocks.agentsUnbindCommandMock;
const setVerboseMock = mocks.setVerboseMock;
const createDefaultDepsMock = mocks.createDefaultDepsMock;
const runtime = mocks.runtime;
vi.mock("../../commands/agent-via-gateway.js", () => ({
agentCliCommand: agentCliCommandMock,
agentCliCommand: mocks.agentCliCommandMock,
}));
vi.mock("../../commands/agents.js", () => ({
agentsAddCommand: agentsAddCommandMock,
agentsBindingsCommand: agentsBindingsCommandMock,
agentsBindCommand: agentsBindCommandMock,
agentsDeleteCommand: agentsDeleteCommandMock,
agentsListCommand: agentsListCommandMock,
agentsSetIdentityCommand: agentsSetIdentityCommandMock,
agentsUnbindCommand: agentsUnbindCommandMock,
agentsAddCommand: mocks.agentsAddCommandMock,
agentsBindingsCommand: mocks.agentsBindingsCommandMock,
agentsBindCommand: mocks.agentsBindCommandMock,
agentsDeleteCommand: mocks.agentsDeleteCommandMock,
agentsListCommand: mocks.agentsListCommandMock,
agentsSetIdentityCommand: mocks.agentsSetIdentityCommandMock,
agentsUnbindCommand: mocks.agentsUnbindCommandMock,
}));
vi.mock("../../globals.js", () => ({
setVerbose: setVerboseMock,
setVerbose: mocks.setVerboseMock,
}));
vi.mock("../deps.js", () => ({
createDefaultDeps: createDefaultDepsMock,
createDefaultDeps: mocks.createDefaultDepsMock,
}));
vi.mock("../../runtime.js", () => ({
defaultRuntime: runtime,
defaultRuntime: mocks.runtime,
}));
const mockedModuleIds = [
"../../commands/agent-via-gateway.js",
"../../commands/agents.js",
"../../globals.js",
"../deps.js",
"../../runtime.js",
];
let registerAgentCommands: typeof import("./register.agent.js").registerAgentCommands;
beforeAll(async () => {
({ registerAgentCommands } = await import("./register.agent.js"));
});
afterAll(() => {
for (const id of mockedModuleIds) {
vi.doUnmock(id);
}
vi.resetModules();
});
describe("registerAgentCommands", () => {
async function runCli(args: string[]) {
const program = new Command();
@@ -71,7 +67,6 @@ describe("registerAgentCommands", () => {
beforeEach(() => {
vi.clearAllMocks();
resetRuntimeCapture();
runtime.exit.mockImplementation(() => {});
agentCliCommandMock.mockResolvedValue(undefined);
agentsAddCommandMock.mockResolvedValue(undefined);

View File

@@ -1,43 +1,33 @@
import { Command } from "commander";
import { afterAll, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
import { createCliRuntimeCapture } from "../test-runtime-capture.js";
import { beforeEach, describe, expect, it, vi } from "vitest";
import { registerBackupCommand } from "./register.backup.js";
const backupCreateCommand = vi.fn();
const backupVerifyCommand = vi.fn();
const mocks = vi.hoisted(() => ({
backupCreateCommand: vi.fn(),
backupVerifyCommand: vi.fn(),
runtime: {
log: vi.fn(),
error: vi.fn(),
exit: vi.fn(),
},
}));
const { defaultRuntime: runtime, resetRuntimeCapture } = createCliRuntimeCapture();
const backupCreateCommand = mocks.backupCreateCommand;
const backupVerifyCommand = mocks.backupVerifyCommand;
const runtime = mocks.runtime;
vi.mock("../../commands/backup.js", () => ({
backupCreateCommand,
backupCreateCommand: mocks.backupCreateCommand,
}));
vi.mock("../../commands/backup-verify.js", () => ({
backupVerifyCommand,
backupVerifyCommand: mocks.backupVerifyCommand,
}));
vi.mock("../../runtime.js", () => ({
defaultRuntime: runtime,
defaultRuntime: mocks.runtime,
}));
const mockedModuleIds = [
"../../commands/backup.js",
"../../commands/backup-verify.js",
"../../runtime.js",
];
let registerBackupCommand: typeof import("./register.backup.js").registerBackupCommand;
beforeAll(async () => {
({ registerBackupCommand } = await import("./register.backup.js"));
});
afterAll(() => {
for (const id of mockedModuleIds) {
vi.doUnmock(id);
}
vi.resetModules();
});
describe("registerBackupCommand", () => {
async function runCli(args: string[]) {
const program = new Command();
@@ -47,7 +37,6 @@ describe("registerBackupCommand", () => {
beforeEach(() => {
vi.clearAllMocks();
resetRuntimeCapture();
backupCreateCommand.mockResolvedValue(undefined);
backupVerifyCommand.mockResolvedValue(undefined);
});

View File

@@ -1,37 +1,27 @@
import { Command } from "commander";
import { afterAll, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
import { beforeEach, describe, expect, it, vi } from "vitest";
import { registerConfigureCommand } from "./register.configure.js";
const configureCommandFromSectionsArgMock = vi.fn();
const runtime = {
log: vi.fn(),
error: vi.fn(),
exit: vi.fn(),
};
const mocks = vi.hoisted(() => ({
configureCommandFromSectionsArgMock: vi.fn(),
runtime: {
log: vi.fn(),
error: vi.fn(),
exit: vi.fn(),
},
}));
const { configureCommandFromSectionsArgMock, runtime } = mocks;
vi.mock("../../commands/configure.js", () => ({
CONFIGURE_WIZARD_SECTIONS: ["auth", "channels", "gateway", "agent"],
configureCommandFromSectionsArg: configureCommandFromSectionsArgMock,
configureCommandFromSectionsArg: mocks.configureCommandFromSectionsArgMock,
}));
vi.mock("../../runtime.js", () => ({
defaultRuntime: runtime,
defaultRuntime: mocks.runtime,
}));
const mockedModuleIds = ["../../commands/configure.js", "../../runtime.js"];
let registerConfigureCommand: typeof import("./register.configure.js").registerConfigureCommand;
beforeAll(async () => {
({ registerConfigureCommand } = await import("./register.configure.js"));
});
afterAll(() => {
for (const id of mockedModuleIds) {
vi.doUnmock(id);
}
vi.resetModules();
});
describe("registerConfigureCommand", () => {
async function runCli(args: string[]) {
const program = new Command();

View File

@@ -1,58 +1,41 @@
import { Command } from "commander";
import { afterAll, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
import { beforeEach, describe, expect, it, vi } from "vitest";
import { registerMaintenanceCommands } from "./register.maintenance.js";
const doctorCommand = vi.fn();
const dashboardCommand = vi.fn();
const resetCommand = vi.fn();
const uninstallCommand = vi.fn();
const mocks = vi.hoisted(() => ({
doctorCommand: vi.fn(),
dashboardCommand: vi.fn(),
resetCommand: vi.fn(),
uninstallCommand: vi.fn(),
runtime: {
log: vi.fn(),
error: vi.fn(),
exit: vi.fn(),
},
}));
const runtime = {
log: vi.fn(),
error: vi.fn(),
exit: vi.fn(),
};
const { doctorCommand, dashboardCommand, resetCommand, uninstallCommand, runtime } = mocks;
vi.mock("../../commands/doctor.js", () => ({
doctorCommand,
doctorCommand: mocks.doctorCommand,
}));
vi.mock("../../commands/dashboard.js", () => ({
dashboardCommand,
dashboardCommand: mocks.dashboardCommand,
}));
vi.mock("../../commands/reset.js", () => ({
resetCommand,
resetCommand: mocks.resetCommand,
}));
vi.mock("../../commands/uninstall.js", () => ({
uninstallCommand,
uninstallCommand: mocks.uninstallCommand,
}));
vi.mock("../../runtime.js", () => ({
defaultRuntime: runtime,
defaultRuntime: mocks.runtime,
}));
const mockedModuleIds = [
"../../commands/doctor.js",
"../../commands/dashboard.js",
"../../commands/reset.js",
"../../commands/uninstall.js",
"../../runtime.js",
];
let registerMaintenanceCommands: typeof import("./register.maintenance.js").registerMaintenanceCommands;
beforeAll(async () => {
({ registerMaintenanceCommands } = await import("./register.maintenance.js"));
});
afterAll(() => {
for (const id of mockedModuleIds) {
vi.doUnmock(id);
}
vi.resetModules();
});
describe("registerMaintenanceCommands doctor action", () => {
async function runMaintenanceCli(args: string[]) {
const program = new Command();

View File

@@ -1,94 +1,84 @@
import { Command } from "commander";
import { afterAll, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
import { beforeEach, describe, expect, it, vi } from "vitest";
import type { ProgramContext } from "./context.js";
import { registerMessageCommands } from "./register.message.js";
const createMessageCliHelpersMock = vi.fn(() => ({ helper: true }));
const registerMessageSendCommandMock = vi.fn();
const registerMessageBroadcastCommandMock = vi.fn();
const registerMessagePollCommandMock = vi.fn();
const registerMessageReactionsCommandsMock = vi.fn();
const registerMessageReadEditDeleteCommandsMock = vi.fn();
const registerMessagePinCommandsMock = vi.fn();
const registerMessagePermissionsCommandMock = vi.fn();
const registerMessageSearchCommandMock = vi.fn();
const registerMessageThreadCommandsMock = vi.fn();
const registerMessageEmojiCommandsMock = vi.fn();
const registerMessageStickerCommandsMock = vi.fn();
const registerMessageDiscordAdminCommandsMock = vi.fn();
const mocks = vi.hoisted(() => ({
createMessageCliHelpersMock: vi.fn(() => ({ helper: true })),
registerMessageSendCommandMock: vi.fn(),
registerMessageBroadcastCommandMock: vi.fn(),
registerMessagePollCommandMock: vi.fn(),
registerMessageReactionsCommandsMock: vi.fn(),
registerMessageReadEditDeleteCommandsMock: vi.fn(),
registerMessagePinCommandsMock: vi.fn(),
registerMessagePermissionsCommandMock: vi.fn(),
registerMessageSearchCommandMock: vi.fn(),
registerMessageThreadCommandsMock: vi.fn(),
registerMessageEmojiCommandsMock: vi.fn(),
registerMessageStickerCommandsMock: vi.fn(),
registerMessageDiscordAdminCommandsMock: vi.fn(),
}));
const createMessageCliHelpersMock = mocks.createMessageCliHelpersMock;
const registerMessageSendCommandMock = mocks.registerMessageSendCommandMock;
const registerMessageBroadcastCommandMock = mocks.registerMessageBroadcastCommandMock;
const registerMessagePollCommandMock = mocks.registerMessagePollCommandMock;
const registerMessageReactionsCommandsMock = mocks.registerMessageReactionsCommandsMock;
const registerMessageReadEditDeleteCommandsMock = mocks.registerMessageReadEditDeleteCommandsMock;
const registerMessagePinCommandsMock = mocks.registerMessagePinCommandsMock;
const registerMessagePermissionsCommandMock = mocks.registerMessagePermissionsCommandMock;
const registerMessageSearchCommandMock = mocks.registerMessageSearchCommandMock;
const registerMessageThreadCommandsMock = mocks.registerMessageThreadCommandsMock;
const registerMessageEmojiCommandsMock = mocks.registerMessageEmojiCommandsMock;
const registerMessageStickerCommandsMock = mocks.registerMessageStickerCommandsMock;
const registerMessageDiscordAdminCommandsMock = mocks.registerMessageDiscordAdminCommandsMock;
vi.mock("./message/helpers.js", () => ({
createMessageCliHelpers: createMessageCliHelpersMock,
createMessageCliHelpers: mocks.createMessageCliHelpersMock,
}));
vi.mock("./message/register.send.js", () => ({
registerMessageSendCommand: registerMessageSendCommandMock,
registerMessageSendCommand: mocks.registerMessageSendCommandMock,
}));
vi.mock("./message/register.broadcast.js", () => ({
registerMessageBroadcastCommand: registerMessageBroadcastCommandMock,
registerMessageBroadcastCommand: mocks.registerMessageBroadcastCommandMock,
}));
vi.mock("./message/register.poll.js", () => ({
registerMessagePollCommand: registerMessagePollCommandMock,
registerMessagePollCommand: mocks.registerMessagePollCommandMock,
}));
vi.mock("./message/register.reactions.js", () => ({
registerMessageReactionsCommands: registerMessageReactionsCommandsMock,
registerMessageReactionsCommands: mocks.registerMessageReactionsCommandsMock,
}));
vi.mock("./message/register.read-edit-delete.js", () => ({
registerMessageReadEditDeleteCommands: registerMessageReadEditDeleteCommandsMock,
registerMessageReadEditDeleteCommands: mocks.registerMessageReadEditDeleteCommandsMock,
}));
vi.mock("./message/register.pins.js", () => ({
registerMessagePinCommands: registerMessagePinCommandsMock,
registerMessagePinCommands: mocks.registerMessagePinCommandsMock,
}));
vi.mock("./message/register.permissions-search.js", () => ({
registerMessagePermissionsCommand: registerMessagePermissionsCommandMock,
registerMessageSearchCommand: registerMessageSearchCommandMock,
registerMessagePermissionsCommand: mocks.registerMessagePermissionsCommandMock,
registerMessageSearchCommand: mocks.registerMessageSearchCommandMock,
}));
vi.mock("./message/register.thread.js", () => ({
registerMessageThreadCommands: registerMessageThreadCommandsMock,
registerMessageThreadCommands: mocks.registerMessageThreadCommandsMock,
}));
vi.mock("./message/register.emoji-sticker.js", () => ({
registerMessageEmojiCommands: registerMessageEmojiCommandsMock,
registerMessageStickerCommands: registerMessageStickerCommandsMock,
registerMessageEmojiCommands: mocks.registerMessageEmojiCommandsMock,
registerMessageStickerCommands: mocks.registerMessageStickerCommandsMock,
}));
vi.mock("./message/register.discord-admin.js", () => ({
registerMessageDiscordAdminCommands: registerMessageDiscordAdminCommandsMock,
registerMessageDiscordAdminCommands: mocks.registerMessageDiscordAdminCommandsMock,
}));
const mockedModuleIds = [
"./message/helpers.js",
"./message/register.send.js",
"./message/register.broadcast.js",
"./message/register.poll.js",
"./message/register.reactions.js",
"./message/register.read-edit-delete.js",
"./message/register.pins.js",
"./message/register.permissions-search.js",
"./message/register.thread.js",
"./message/register.emoji-sticker.js",
"./message/register.discord-admin.js",
];
let registerMessageCommands: typeof import("./register.message.js").registerMessageCommands;
beforeAll(async () => {
({ registerMessageCommands } = await import("./register.message.js"));
});
afterAll(() => {
for (const id of mockedModuleIds) {
vi.doUnmock(id);
}
vi.resetModules();
});
describe("registerMessageCommands", () => {
const ctx: ProgramContext = {
programVersion: "9.9.9-test",

View File

@@ -1,13 +1,18 @@
import { Command } from "commander";
import { afterAll, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
import { beforeEach, describe, expect, it, vi } from "vitest";
import { registerOnboardCommand } from "./register.onboard.js";
const setupWizardCommandMock = vi.fn();
const mocks = vi.hoisted(() => ({
setupWizardCommandMock: vi.fn(),
runtime: {
log: vi.fn(),
error: vi.fn(),
exit: vi.fn(),
},
}));
const runtime = {
log: vi.fn(),
error: vi.fn(),
exit: vi.fn(),
};
const setupWizardCommandMock = mocks.setupWizardCommandMock;
const runtime = mocks.runtime;
vi.mock("../../commands/auth-choice-options.static.js", () => ({
formatStaticAuthChoiceChoicesForCli: () => "token|oauth",
@@ -38,35 +43,13 @@ vi.mock("../../plugins/provider-auth-choices.js", () => ({
}));
vi.mock("../../commands/onboard.js", () => ({
setupWizardCommand: setupWizardCommandMock,
setupWizardCommand: mocks.setupWizardCommandMock,
}));
vi.mock("../../runtime.js", () => ({
defaultRuntime: runtime,
defaultRuntime: mocks.runtime,
}));
const mockedModuleIds = [
"../../commands/auth-choice-options.static.js",
"../../commands/auth-choice-options.js",
"../../commands/onboard-core-auth-flags.js",
"../../plugins/provider-auth-choices.js",
"../../commands/onboard.js",
"../../runtime.js",
];
let registerOnboardCommand: typeof import("./register.onboard.js").registerOnboardCommand;
beforeAll(async () => {
({ registerOnboardCommand } = await import("./register.onboard.js"));
});
afterAll(() => {
for (const id of mockedModuleIds) {
vi.doUnmock(id);
}
vi.resetModules();
});
describe("registerOnboardCommand", () => {
async function runCli(args: string[]) {
const program = new Command();

View File

@@ -1,45 +1,33 @@
import { Command } from "commander";
import { afterAll, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
import { beforeEach, describe, expect, it, vi } from "vitest";
import { registerSetupCommand } from "./register.setup.js";
const setupCommandMock = vi.fn();
const setupWizardCommandMock = vi.fn();
const runtime = {
log: vi.fn(),
error: vi.fn(),
exit: vi.fn(),
};
const mocks = vi.hoisted(() => ({
setupCommandMock: vi.fn(),
setupWizardCommandMock: vi.fn(),
runtime: {
log: vi.fn(),
error: vi.fn(),
exit: vi.fn(),
},
}));
const setupCommandMock = mocks.setupCommandMock;
const setupWizardCommandMock = mocks.setupWizardCommandMock;
const runtime = mocks.runtime;
vi.mock("../../commands/setup.js", () => ({
setupCommand: setupCommandMock,
setupCommand: mocks.setupCommandMock,
}));
vi.mock("../../commands/onboard.js", () => ({
setupWizardCommand: setupWizardCommandMock,
setupWizardCommand: mocks.setupWizardCommandMock,
}));
vi.mock("../../runtime.js", () => ({
defaultRuntime: runtime,
defaultRuntime: mocks.runtime,
}));
const mockedModuleIds = [
"../../commands/setup.js",
"../../commands/onboard.js",
"../../runtime.js",
];
let registerSetupCommand: typeof import("./register.setup.js").registerSetupCommand;
beforeAll(async () => {
({ registerSetupCommand } = await import("./register.setup.js"));
});
afterAll(() => {
for (const id of mockedModuleIds) {
vi.doUnmock(id);
}
vi.resetModules();
});
describe("registerSetupCommand", () => {
async function runCli(args: string[]) {
const program = new Command();

View File

@@ -1,60 +1,72 @@
import { Command } from "commander";
import { beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
import { createCliRuntimeCapture } from "../test-runtime-capture.js";
import { beforeEach, describe, expect, it, vi } from "vitest";
import { registerStatusHealthSessionsCommands } from "./register.status-health-sessions.js";
const statusCommand = vi.fn();
const healthCommand = vi.fn();
const sessionsCommand = vi.fn();
const sessionsCleanupCommand = vi.fn();
const tasksListCommand = vi.fn();
const tasksAuditCommand = vi.fn();
const tasksMaintenanceCommand = vi.fn();
const tasksShowCommand = vi.fn();
const tasksNotifyCommand = vi.fn();
const tasksCancelCommand = vi.fn();
const setVerbose = vi.fn();
const mocks = vi.hoisted(() => ({
statusCommand: vi.fn(),
healthCommand: vi.fn(),
sessionsCommand: vi.fn(),
sessionsCleanupCommand: vi.fn(),
tasksListCommand: vi.fn(),
tasksAuditCommand: vi.fn(),
tasksMaintenanceCommand: vi.fn(),
tasksShowCommand: vi.fn(),
tasksNotifyCommand: vi.fn(),
tasksCancelCommand: vi.fn(),
setVerbose: vi.fn(),
runtime: {
log: vi.fn(),
error: vi.fn(),
exit: vi.fn(),
},
}));
const { defaultRuntime: runtime, resetRuntimeCapture } = createCliRuntimeCapture();
const statusCommand = mocks.statusCommand;
const healthCommand = mocks.healthCommand;
const sessionsCommand = mocks.sessionsCommand;
const sessionsCleanupCommand = mocks.sessionsCleanupCommand;
const tasksListCommand = mocks.tasksListCommand;
const tasksAuditCommand = mocks.tasksAuditCommand;
const tasksMaintenanceCommand = mocks.tasksMaintenanceCommand;
const tasksShowCommand = mocks.tasksShowCommand;
const tasksNotifyCommand = mocks.tasksNotifyCommand;
const tasksCancelCommand = mocks.tasksCancelCommand;
const setVerbose = mocks.setVerbose;
const runtime = mocks.runtime;
vi.mock("../../commands/status.js", () => ({
statusCommand,
statusCommand: mocks.statusCommand,
}));
vi.mock("../../commands/health.js", () => ({
healthCommand,
healthCommand: mocks.healthCommand,
}));
vi.mock("../../commands/sessions.js", () => ({
sessionsCommand,
sessionsCommand: mocks.sessionsCommand,
}));
vi.mock("../../commands/sessions-cleanup.js", () => ({
sessionsCleanupCommand,
sessionsCleanupCommand: mocks.sessionsCleanupCommand,
}));
vi.mock("../../commands/tasks.js", () => ({
tasksListCommand,
tasksAuditCommand,
tasksMaintenanceCommand,
tasksShowCommand,
tasksNotifyCommand,
tasksCancelCommand,
tasksListCommand: mocks.tasksListCommand,
tasksAuditCommand: mocks.tasksAuditCommand,
tasksMaintenanceCommand: mocks.tasksMaintenanceCommand,
tasksShowCommand: mocks.tasksShowCommand,
tasksNotifyCommand: mocks.tasksNotifyCommand,
tasksCancelCommand: mocks.tasksCancelCommand,
}));
vi.mock("../../globals.js", () => ({
setVerbose,
setVerbose: mocks.setVerbose,
}));
vi.mock("../../runtime.js", () => ({
defaultRuntime: runtime,
defaultRuntime: mocks.runtime,
}));
let registerStatusHealthSessionsCommands: typeof import("./register.status-health-sessions.js").registerStatusHealthSessionsCommands;
beforeAll(async () => {
({ registerStatusHealthSessionsCommands } = await import("./register.status-health-sessions.js"));
});
describe("registerStatusHealthSessionsCommands", () => {
async function runCli(args: string[]) {
const program = new Command();
@@ -64,7 +76,6 @@ describe("registerStatusHealthSessionsCommands", () => {
beforeEach(() => {
vi.clearAllMocks();
resetRuntimeCapture();
runtime.exit.mockImplementation(() => {});
statusCommand.mockResolvedValue(undefined);
healthCommand.mockResolvedValue(undefined);

View File

@@ -1,5 +1,10 @@
import { Command } from "commander";
import { afterAll, afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import {
loadValidatedConfigForPluginRegistration,
registerSubCliByName,
registerSubCliCommands,
} from "./register.subclis.js";
const { acpAction, registerAcpCli } = vi.hoisted(() => {
const action = vi.fn();
@@ -27,18 +32,6 @@ vi.mock("../acp-cli.js", () => ({ registerAcpCli }));
vi.mock("../nodes-cli.js", () => ({ registerNodesCli }));
vi.mock("../../config/config.js", () => configModule);
const mockedModuleIds = ["../acp-cli.js", "../nodes-cli.js", "../../config/config.js"];
const { loadValidatedConfigForPluginRegistration, registerSubCliByName, registerSubCliCommands } =
await import("./register.subclis.js");
afterAll(() => {
for (const id of mockedModuleIds) {
vi.doUnmock(id);
}
vi.resetModules();
});
describe("registerSubCliCommands", () => {
const originalArgv = process.argv;
const originalDisableLazySubcommands = process.env.OPENCLAW_DISABLE_LAZY_SUBCOMMANDS;

View File

@@ -1,4 +1,5 @@
import { describe, expect, it, vi } from "vitest";
import { renderRootHelpText } from "./root-help.js";
vi.mock("./core-command-descriptors.js", () => ({
getCoreCliCommandDescriptors: () => [
@@ -32,8 +33,6 @@ vi.mock("../../plugins/cli.js", () => ({
],
}));
const { renderRootHelpText } = await import("./root-help.js");
describe("root help", () => {
it("includes plugin CLI descriptors alongside core and sub-CLI commands", async () => {
const text = await renderRootHelpText();