mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 19:10:58 +00:00
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", () => {
|
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>) {
|
function expectCliSync(sync: ReturnType<typeof vi.fn>) {
|
||||||
expect(sync).toHaveBeenCalledWith(
|
expect(sync).toHaveBeenCalledWith(
|
||||||
expect.objectContaining({ reason: "cli", force: false, progress: expect.any(Function) }),
|
expect.objectContaining({ reason: "cli", force: false, progress: expect.any(Function) }),
|
||||||
@@ -92,7 +104,7 @@ describe("memory cli", () => {
|
|||||||
});
|
});
|
||||||
mockManager({ ...params.manager, close });
|
mockManager({ ...params.manager, close });
|
||||||
|
|
||||||
const error = vi.spyOn(defaultRuntime, "error").mockImplementation(() => {});
|
const error = spyRuntimeErrors();
|
||||||
await runMemoryCli(params.args);
|
await runMemoryCli(params.args);
|
||||||
|
|
||||||
params.beforeExpect?.();
|
params.beforeExpect?.();
|
||||||
@@ -123,7 +135,7 @@ describe("memory cli", () => {
|
|||||||
close,
|
close,
|
||||||
});
|
});
|
||||||
|
|
||||||
const log = vi.spyOn(defaultRuntime, "log").mockImplementation(() => {});
|
const log = spyRuntimeLogs();
|
||||||
await runMemoryCli(["status"]);
|
await runMemoryCli(["status"]);
|
||||||
|
|
||||||
expect(log).toHaveBeenCalledWith(expect.stringContaining("Vector: ready"));
|
expect(log).toHaveBeenCalledWith(expect.stringContaining("Vector: ready"));
|
||||||
@@ -152,7 +164,7 @@ describe("memory cli", () => {
|
|||||||
close,
|
close,
|
||||||
});
|
});
|
||||||
|
|
||||||
const log = vi.spyOn(defaultRuntime, "log").mockImplementation(() => {});
|
const log = spyRuntimeLogs();
|
||||||
await runMemoryCli(["status", "--agent", "main"]);
|
await runMemoryCli(["status", "--agent", "main"]);
|
||||||
|
|
||||||
expect(log).toHaveBeenCalledWith(expect.stringContaining("Vector: unavailable"));
|
expect(log).toHaveBeenCalledWith(expect.stringContaining("Vector: unavailable"));
|
||||||
@@ -170,7 +182,7 @@ describe("memory cli", () => {
|
|||||||
close,
|
close,
|
||||||
});
|
});
|
||||||
|
|
||||||
const log = vi.spyOn(defaultRuntime, "log").mockImplementation(() => {});
|
const log = spyRuntimeLogs();
|
||||||
await runMemoryCli(["status", "--deep"]);
|
await runMemoryCli(["status", "--deep"]);
|
||||||
|
|
||||||
expect(probeEmbeddingAvailability).toHaveBeenCalled();
|
expect(probeEmbeddingAvailability).toHaveBeenCalled();
|
||||||
@@ -213,7 +225,7 @@ describe("memory cli", () => {
|
|||||||
close,
|
close,
|
||||||
});
|
});
|
||||||
|
|
||||||
vi.spyOn(defaultRuntime, "log").mockImplementation(() => {});
|
spyRuntimeLogs();
|
||||||
await runMemoryCli(["status", "--index"]);
|
await runMemoryCli(["status", "--index"]);
|
||||||
|
|
||||||
expectCliSync(sync);
|
expectCliSync(sync);
|
||||||
@@ -226,7 +238,7 @@ describe("memory cli", () => {
|
|||||||
const sync = vi.fn(async () => {});
|
const sync = vi.fn(async () => {});
|
||||||
mockManager({ sync, close });
|
mockManager({ sync, close });
|
||||||
|
|
||||||
const log = vi.spyOn(defaultRuntime, "log").mockImplementation(() => {});
|
const log = spyRuntimeLogs();
|
||||||
await runMemoryCli(["index"]);
|
await runMemoryCli(["index"]);
|
||||||
|
|
||||||
expectCliSync(sync);
|
expectCliSync(sync);
|
||||||
@@ -240,7 +252,7 @@ describe("memory cli", () => {
|
|||||||
await withQmdIndexDb("sqlite-bytes", async (dbPath) => {
|
await withQmdIndexDb("sqlite-bytes", async (dbPath) => {
|
||||||
mockManager({ sync, status: () => ({ backend: "qmd", dbPath }), close });
|
mockManager({ sync, status: () => ({ backend: "qmd", dbPath }), close });
|
||||||
|
|
||||||
const log = vi.spyOn(defaultRuntime, "log").mockImplementation(() => {});
|
const log = spyRuntimeLogs();
|
||||||
await runMemoryCli(["index"]);
|
await runMemoryCli(["index"]);
|
||||||
|
|
||||||
expectCliSync(sync);
|
expectCliSync(sync);
|
||||||
@@ -256,7 +268,7 @@ describe("memory cli", () => {
|
|||||||
await withQmdIndexDb("", async (dbPath) => {
|
await withQmdIndexDb("", async (dbPath) => {
|
||||||
mockManager({ sync, status: () => ({ backend: "qmd", dbPath }), close });
|
mockManager({ sync, status: () => ({ backend: "qmd", dbPath }), close });
|
||||||
|
|
||||||
const error = vi.spyOn(defaultRuntime, "error").mockImplementation(() => {});
|
const error = spyRuntimeErrors();
|
||||||
await runMemoryCli(["index"]);
|
await runMemoryCli(["index"]);
|
||||||
|
|
||||||
expectCliSync(sync);
|
expectCliSync(sync);
|
||||||
@@ -305,7 +317,7 @@ describe("memory cli", () => {
|
|||||||
});
|
});
|
||||||
mockManager({ search, close });
|
mockManager({ search, close });
|
||||||
|
|
||||||
const error = vi.spyOn(defaultRuntime, "error").mockImplementation(() => {});
|
const error = spyRuntimeErrors();
|
||||||
await runMemoryCli(["search", "oops"]);
|
await runMemoryCli(["search", "oops"]);
|
||||||
|
|
||||||
expect(search).toHaveBeenCalled();
|
expect(search).toHaveBeenCalled();
|
||||||
@@ -313,4 +325,82 @@ describe("memory cli", () => {
|
|||||||
expect(error).toHaveBeenCalledWith(expect.stringContaining("Memory search failed: boom"));
|
expect(error).toHaveBeenCalledWith(expect.stringContaining("Memory search failed: boom"));
|
||||||
expect(process.exitCode).toBe(1);
|
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