test(cli): dedupe memory runtime spies and cover json/search fallback flows
This commit is contained in:
@@ -39,6 +39,18 @@ afterEach(() => {
|
||||
});
|
||||
|
||||
describe("memory cli", () => {
|
||||
function spyRuntimeLogs() {
|
||||
return vi.spyOn(defaultRuntime, "log").mockImplementation(() => {});
|
||||
}
|
||||
|
||||
function spyRuntimeErrors() {
|
||||
return vi.spyOn(defaultRuntime, "error").mockImplementation(() => {});
|
||||
}
|
||||
|
||||
function firstLoggedJson(log: ReturnType<typeof vi.spyOn>) {
|
||||
return JSON.parse(String(log.mock.calls[0]?.[0] ?? "null")) as Record<string, unknown>;
|
||||
}
|
||||
|
||||
function expectCliSync(sync: ReturnType<typeof vi.fn>) {
|
||||
expect(sync).toHaveBeenCalledWith(
|
||||
expect.objectContaining({ reason: "cli", force: false, progress: expect.any(Function) }),
|
||||
@@ -92,7 +104,7 @@ describe("memory cli", () => {
|
||||
});
|
||||
mockManager({ ...params.manager, close });
|
||||
|
||||
const error = vi.spyOn(defaultRuntime, "error").mockImplementation(() => {});
|
||||
const error = spyRuntimeErrors();
|
||||
await runMemoryCli(params.args);
|
||||
|
||||
params.beforeExpect?.();
|
||||
@@ -123,7 +135,7 @@ describe("memory cli", () => {
|
||||
close,
|
||||
});
|
||||
|
||||
const log = vi.spyOn(defaultRuntime, "log").mockImplementation(() => {});
|
||||
const log = spyRuntimeLogs();
|
||||
await runMemoryCli(["status"]);
|
||||
|
||||
expect(log).toHaveBeenCalledWith(expect.stringContaining("Vector: ready"));
|
||||
@@ -152,7 +164,7 @@ describe("memory cli", () => {
|
||||
close,
|
||||
});
|
||||
|
||||
const log = vi.spyOn(defaultRuntime, "log").mockImplementation(() => {});
|
||||
const log = spyRuntimeLogs();
|
||||
await runMemoryCli(["status", "--agent", "main"]);
|
||||
|
||||
expect(log).toHaveBeenCalledWith(expect.stringContaining("Vector: unavailable"));
|
||||
@@ -170,7 +182,7 @@ describe("memory cli", () => {
|
||||
close,
|
||||
});
|
||||
|
||||
const log = vi.spyOn(defaultRuntime, "log").mockImplementation(() => {});
|
||||
const log = spyRuntimeLogs();
|
||||
await runMemoryCli(["status", "--deep"]);
|
||||
|
||||
expect(probeEmbeddingAvailability).toHaveBeenCalled();
|
||||
@@ -213,7 +225,7 @@ describe("memory cli", () => {
|
||||
close,
|
||||
});
|
||||
|
||||
vi.spyOn(defaultRuntime, "log").mockImplementation(() => {});
|
||||
spyRuntimeLogs();
|
||||
await runMemoryCli(["status", "--index"]);
|
||||
|
||||
expectCliSync(sync);
|
||||
@@ -226,7 +238,7 @@ describe("memory cli", () => {
|
||||
const sync = vi.fn(async () => {});
|
||||
mockManager({ sync, close });
|
||||
|
||||
const log = vi.spyOn(defaultRuntime, "log").mockImplementation(() => {});
|
||||
const log = spyRuntimeLogs();
|
||||
await runMemoryCli(["index"]);
|
||||
|
||||
expectCliSync(sync);
|
||||
@@ -240,7 +252,7 @@ describe("memory cli", () => {
|
||||
await withQmdIndexDb("sqlite-bytes", async (dbPath) => {
|
||||
mockManager({ sync, status: () => ({ backend: "qmd", dbPath }), close });
|
||||
|
||||
const log = vi.spyOn(defaultRuntime, "log").mockImplementation(() => {});
|
||||
const log = spyRuntimeLogs();
|
||||
await runMemoryCli(["index"]);
|
||||
|
||||
expectCliSync(sync);
|
||||
@@ -256,7 +268,7 @@ describe("memory cli", () => {
|
||||
await withQmdIndexDb("", async (dbPath) => {
|
||||
mockManager({ sync, status: () => ({ backend: "qmd", dbPath }), close });
|
||||
|
||||
const error = vi.spyOn(defaultRuntime, "error").mockImplementation(() => {});
|
||||
const error = spyRuntimeErrors();
|
||||
await runMemoryCli(["index"]);
|
||||
|
||||
expectCliSync(sync);
|
||||
@@ -305,7 +317,7 @@ describe("memory cli", () => {
|
||||
});
|
||||
mockManager({ search, close });
|
||||
|
||||
const error = vi.spyOn(defaultRuntime, "error").mockImplementation(() => {});
|
||||
const error = spyRuntimeErrors();
|
||||
await runMemoryCli(["search", "oops"]);
|
||||
|
||||
expect(search).toHaveBeenCalled();
|
||||
@@ -313,4 +325,82 @@ describe("memory cli", () => {
|
||||
expect(error).toHaveBeenCalledWith(expect.stringContaining("Memory search failed: boom"));
|
||||
expect(process.exitCode).toBe(1);
|
||||
});
|
||||
|
||||
it("prints status json output when requested", async () => {
|
||||
const close = vi.fn(async () => {});
|
||||
mockManager({
|
||||
probeVectorAvailability: vi.fn(async () => true),
|
||||
status: () => makeMemoryStatus({ workspaceDir: undefined }),
|
||||
close,
|
||||
});
|
||||
|
||||
const log = spyRuntimeLogs();
|
||||
await runMemoryCli(["status", "--json"]);
|
||||
|
||||
const payload = firstLoggedJson(log);
|
||||
expect(Array.isArray(payload)).toBe(true);
|
||||
expect((payload[0] as Record<string, unknown>)?.agentId).toBe("main");
|
||||
expect(close).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("logs default message when memory manager is missing", async () => {
|
||||
getMemorySearchManager.mockResolvedValueOnce({ manager: null });
|
||||
|
||||
const log = spyRuntimeLogs();
|
||||
await runMemoryCli(["status"]);
|
||||
|
||||
expect(log).toHaveBeenCalledWith("Memory search disabled.");
|
||||
});
|
||||
|
||||
it("logs backend unsupported message when index has no sync", async () => {
|
||||
const close = vi.fn(async () => {});
|
||||
mockManager({
|
||||
status: () => makeMemoryStatus(),
|
||||
close,
|
||||
});
|
||||
|
||||
const log = spyRuntimeLogs();
|
||||
await runMemoryCli(["index"]);
|
||||
|
||||
expect(log).toHaveBeenCalledWith("Memory backend does not support manual reindex.");
|
||||
expect(close).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("prints no matches for empty search results", async () => {
|
||||
const close = vi.fn(async () => {});
|
||||
const search = vi.fn(async () => []);
|
||||
mockManager({ search, close });
|
||||
|
||||
const log = spyRuntimeLogs();
|
||||
await runMemoryCli(["search", "hello"]);
|
||||
|
||||
expect(search).toHaveBeenCalledWith("hello", {
|
||||
maxResults: undefined,
|
||||
minScore: undefined,
|
||||
});
|
||||
expect(log).toHaveBeenCalledWith("No matches.");
|
||||
expect(close).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("prints search results as json when requested", async () => {
|
||||
const close = vi.fn(async () => {});
|
||||
const search = vi.fn(async () => [
|
||||
{
|
||||
path: "memory/2026-01-12.md",
|
||||
startLine: 1,
|
||||
endLine: 2,
|
||||
score: 0.5,
|
||||
snippet: "Hello",
|
||||
},
|
||||
]);
|
||||
mockManager({ search, close });
|
||||
|
||||
const log = spyRuntimeLogs();
|
||||
await runMemoryCli(["search", "hello", "--json"]);
|
||||
|
||||
const payload = firstLoggedJson(log);
|
||||
expect(Array.isArray(payload.results)).toBe(true);
|
||||
expect(payload.results as unknown[]).toHaveLength(1);
|
||||
expect(close).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user