import { afterEach, describe, expect, it, vi } from "vitest"; import { startLazyPluginServiceModule } from "./lazy-service-module.js"; function createAsyncHookMock() { return vi.fn(async () => {}); } function createLazyModuleLifecycle() { const start = createAsyncHookMock(); const stop = createAsyncHookMock(); return { start, stop, module: { startDefault: start, stopDefault: stop, }, }; } async function expectLifecycleStarted(params: { overrideEnvVar?: string; loadDefaultModule?: () => Promise>; loadOverrideModule?: (spec: string) => Promise>; startExportNames: string[]; stopExportNames?: string[]; }) { return startLazyPluginServiceModule({ ...(params.overrideEnvVar ? { overrideEnvVar: params.overrideEnvVar } : {}), loadDefaultModule: params.loadDefaultModule ?? (async () => createLazyModuleLifecycle().module), ...(params.loadOverrideModule ? { loadOverrideModule: params.loadOverrideModule } : {}), startExportNames: params.startExportNames, ...(params.stopExportNames ? { stopExportNames: params.stopExportNames } : {}), }); } describe("startLazyPluginServiceModule", () => { afterEach(() => { delete process.env.OPENCLAW_LAZY_SERVICE_SKIP; delete process.env.OPENCLAW_LAZY_SERVICE_OVERRIDE; }); it("starts the default module and returns its stop hook", async () => { const lifecycle = createLazyModuleLifecycle(); const handle = await expectLifecycleStarted({ loadDefaultModule: async () => lifecycle.module, startExportNames: ["startDefault"], stopExportNames: ["stopDefault"], }); expect(lifecycle.start).toHaveBeenCalledTimes(1); expect(handle).not.toBeNull(); await handle?.stop(); expect(lifecycle.stop).toHaveBeenCalledTimes(1); }); it("honors skip env before loading the module", async () => { process.env.OPENCLAW_LAZY_SERVICE_SKIP = "1"; const loadDefaultModule = vi.fn(async () => createLazyModuleLifecycle().module); const handle = await startLazyPluginServiceModule({ skipEnvVar: "OPENCLAW_LAZY_SERVICE_SKIP", loadDefaultModule, startExportNames: ["startDefault"], }); expect(handle).toBeNull(); expect(loadDefaultModule).not.toHaveBeenCalled(); }); it("uses the override module when configured", async () => { process.env.OPENCLAW_LAZY_SERVICE_OVERRIDE = "virtual:service"; const start = createAsyncHookMock(); const loadOverrideModule = vi.fn(async () => ({ startOverride: start })); await expectLifecycleStarted({ overrideEnvVar: "OPENCLAW_LAZY_SERVICE_OVERRIDE", loadDefaultModule: async () => ({ startDefault: createAsyncHookMock() }), loadOverrideModule, startExportNames: ["startOverride", "startDefault"], }); expect(loadOverrideModule).toHaveBeenCalledWith("virtual:service"); expect(start).toHaveBeenCalledTimes(1); }); });