test: dedupe and optimize test suites

This commit is contained in:
Peter Steinberger
2026-02-19 15:18:50 +00:00
parent b0e55283d5
commit a1cb700a05
80 changed files with 2627 additions and 2962 deletions

View File

@@ -2,7 +2,7 @@ import fs from "node:fs/promises";
import os from "node:os";
import path from "node:path";
import { Command } from "commander";
import { afterEach, describe, expect, it, vi } from "vitest";
import { afterEach, beforeAll, describe, expect, it, vi } from "vitest";
const getMemorySearchManager = vi.fn();
const loadConfig = vi.fn(() => ({}));
@@ -20,11 +20,21 @@ vi.mock("../agents/agent-scope.js", () => ({
resolveDefaultAgentId,
}));
afterEach(async () => {
let registerMemoryCli: typeof import("./memory-cli.js").registerMemoryCli;
let defaultRuntime: typeof import("../runtime.js").defaultRuntime;
let isVerbose: typeof import("../globals.js").isVerbose;
let setVerbose: typeof import("../globals.js").setVerbose;
beforeAll(async () => {
({ registerMemoryCli } = await import("./memory-cli.js"));
({ defaultRuntime } = await import("../runtime.js"));
({ isVerbose, setVerbose } = await import("../globals.js"));
});
afterEach(() => {
vi.restoreAllMocks();
getMemorySearchManager.mockReset();
process.exitCode = undefined;
const { setVerbose } = await import("../globals.js");
setVerbose(false);
});
@@ -55,15 +65,45 @@ describe("memory cli", () => {
}
async function runMemoryCli(args: string[]) {
const { registerMemoryCli } = await import("./memory-cli.js");
const program = new Command();
program.name("test");
registerMemoryCli(program);
await program.parseAsync(["memory", ...args], { from: "user" });
}
async function withQmdIndexDb(content: string, run: (dbPath: string) => Promise<void>) {
const tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), "memory-cli-qmd-index-"));
const dbPath = path.join(tmpDir, "index.sqlite");
try {
await fs.writeFile(dbPath, content, "utf-8");
await run(dbPath);
} finally {
await fs.rm(tmpDir, { recursive: true, force: true });
}
}
async function expectCloseFailureAfterCommand(params: {
args: string[];
manager: Record<string, unknown>;
beforeExpect?: () => void;
}) {
const close = vi.fn(async () => {
throw new Error("close boom");
});
mockManager({ ...params.manager, close });
const error = vi.spyOn(defaultRuntime, "error").mockImplementation(() => {});
await runMemoryCli(params.args);
params.beforeExpect?.();
expect(close).toHaveBeenCalled();
expect(error).toHaveBeenCalledWith(
expect.stringContaining("Memory manager close failed: close boom"),
);
expect(process.exitCode).toBeUndefined();
}
it("prints vector status when available", async () => {
const { defaultRuntime } = await import("../runtime.js");
const close = vi.fn(async () => {});
mockManager({
probeVectorAvailability: vi.fn(async () => true),
@@ -97,7 +137,6 @@ describe("memory cli", () => {
});
it("prints vector error when unavailable", async () => {
const { defaultRuntime } = await import("../runtime.js");
const close = vi.fn(async () => {});
mockManager({
probeVectorAvailability: vi.fn(async () => false),
@@ -122,7 +161,6 @@ describe("memory cli", () => {
});
it("prints embeddings status when deep", async () => {
const { defaultRuntime } = await import("../runtime.js");
const close = vi.fn(async () => {});
const probeEmbeddingAvailability = vi.fn(async () => ({ ok: true }));
mockManager({
@@ -141,7 +179,6 @@ describe("memory cli", () => {
});
it("enables verbose logging with --verbose", async () => {
const { isVerbose } = await import("../globals.js");
const close = vi.fn(async () => {});
mockManager({
probeVectorAvailability: vi.fn(async () => true),
@@ -155,28 +192,16 @@ describe("memory cli", () => {
});
it("logs close failure after status", async () => {
const { defaultRuntime } = await import("../runtime.js");
const close = vi.fn(async () => {
throw new Error("close boom");
await expectCloseFailureAfterCommand({
args: ["status"],
manager: {
probeVectorAvailability: vi.fn(async () => true),
status: () => makeMemoryStatus({ files: 1, chunks: 1 }),
},
});
mockManager({
probeVectorAvailability: vi.fn(async () => true),
status: () => makeMemoryStatus({ files: 1, chunks: 1 }),
close,
});
const error = vi.spyOn(defaultRuntime, "error").mockImplementation(() => {});
await runMemoryCli(["status"]);
expect(close).toHaveBeenCalled();
expect(error).toHaveBeenCalledWith(
expect.stringContaining("Memory manager close failed: close boom"),
);
expect(process.exitCode).toBeUndefined();
});
it("reindexes on status --index", async () => {
const { defaultRuntime } = await import("../runtime.js");
const close = vi.fn(async () => {});
const sync = vi.fn(async () => {});
const probeEmbeddingAvailability = vi.fn(async () => ({ ok: true }));
@@ -197,7 +222,6 @@ describe("memory cli", () => {
});
it("closes manager after index", async () => {
const { defaultRuntime } = await import("../runtime.js");
const close = vi.fn(async () => {});
const sync = vi.fn(async () => {});
mockManager({ sync, close });
@@ -211,69 +235,51 @@ describe("memory cli", () => {
});
it("logs qmd index file path and size after index", async () => {
const { defaultRuntime } = await import("../runtime.js");
const close = vi.fn(async () => {});
const sync = vi.fn(async () => {});
const tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), "memory-cli-qmd-index-"));
const dbPath = path.join(tmpDir, "index.sqlite");
await fs.writeFile(dbPath, "sqlite-bytes", "utf-8");
mockManager({ sync, status: () => ({ backend: "qmd", dbPath }), close });
await withQmdIndexDb("sqlite-bytes", async (dbPath) => {
mockManager({ sync, status: () => ({ backend: "qmd", dbPath }), close });
const log = vi.spyOn(defaultRuntime, "log").mockImplementation(() => {});
await runMemoryCli(["index"]);
const log = vi.spyOn(defaultRuntime, "log").mockImplementation(() => {});
await runMemoryCli(["index"]);
expectCliSync(sync);
expect(log).toHaveBeenCalledWith(expect.stringContaining("QMD index: "));
expect(log).toHaveBeenCalledWith("Memory index updated (main).");
expect(close).toHaveBeenCalled();
await fs.rm(tmpDir, { recursive: true, force: true });
expectCliSync(sync);
expect(log).toHaveBeenCalledWith(expect.stringContaining("QMD index: "));
expect(log).toHaveBeenCalledWith("Memory index updated (main).");
expect(close).toHaveBeenCalled();
});
});
it("fails index when qmd db file is empty", async () => {
const { defaultRuntime } = await import("../runtime.js");
const close = vi.fn(async () => {});
const sync = vi.fn(async () => {});
const tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), "memory-cli-qmd-index-"));
const dbPath = path.join(tmpDir, "index.sqlite");
await fs.writeFile(dbPath, "", "utf-8");
mockManager({ sync, status: () => ({ backend: "qmd", dbPath }), close });
await withQmdIndexDb("", async (dbPath) => {
mockManager({ sync, status: () => ({ backend: "qmd", dbPath }), close });
const error = vi.spyOn(defaultRuntime, "error").mockImplementation(() => {});
await runMemoryCli(["index"]);
const error = vi.spyOn(defaultRuntime, "error").mockImplementation(() => {});
await runMemoryCli(["index"]);
expectCliSync(sync);
expect(error).toHaveBeenCalledWith(
expect.stringContaining("Memory index failed (main): QMD index file is empty"),
);
expect(close).toHaveBeenCalled();
expect(process.exitCode).toBe(1);
await fs.rm(tmpDir, { recursive: true, force: true });
expectCliSync(sync);
expect(error).toHaveBeenCalledWith(
expect.stringContaining("Memory index failed (main): QMD index file is empty"),
);
expect(close).toHaveBeenCalled();
expect(process.exitCode).toBe(1);
});
});
it("logs close failures without failing the command", async () => {
const { defaultRuntime } = await import("../runtime.js");
const close = vi.fn(async () => {
throw new Error("close boom");
});
const sync = vi.fn(async () => {});
mockManager({ sync, close });
const error = vi.spyOn(defaultRuntime, "error").mockImplementation(() => {});
await runMemoryCli(["index"]);
expectCliSync(sync);
expect(close).toHaveBeenCalled();
expect(error).toHaveBeenCalledWith(
expect.stringContaining("Memory manager close failed: close boom"),
);
expect(process.exitCode).toBeUndefined();
await expectCloseFailureAfterCommand({
args: ["index"],
manager: { sync },
beforeExpect: () => {
expectCliSync(sync);
},
});
});
it("logs close failure after search", async () => {
const { defaultRuntime } = await import("../runtime.js");
const close = vi.fn(async () => {
throw new Error("close boom");
});
const search = vi.fn(async () => [
{
path: "memory/2026-01-12.md",
@@ -283,21 +289,16 @@ describe("memory cli", () => {
snippet: "Hello",
},
]);
mockManager({ search, close });
const error = vi.spyOn(defaultRuntime, "error").mockImplementation(() => {});
await runMemoryCli(["search", "hello"]);
expect(search).toHaveBeenCalled();
expect(close).toHaveBeenCalled();
expect(error).toHaveBeenCalledWith(
expect.stringContaining("Memory manager close failed: close boom"),
);
expect(process.exitCode).toBeUndefined();
await expectCloseFailureAfterCommand({
args: ["search", "hello"],
manager: { search },
beforeExpect: () => {
expect(search).toHaveBeenCalled();
},
});
});
it("closes manager after search error", async () => {
const { defaultRuntime } = await import("../runtime.js");
const close = vi.fn(async () => {});
const search = vi.fn(async () => {
throw new Error("boom");