/** * PR-A Baseline Test 03: memory_search Current Behavior * Verifies: memory_search tool exists, has stable schema, returns stable format * Freezes: memory_search contract */ import { describe, it } from "node:test"; import assert from "node:assert"; import { execSync } from "node:child_process"; describe("test-03: memory_search Baseline", () => { it("03.01 - memory_search CLI returns JSON", () => { const out = execSync( 'openclaw memory search "hello world" --json 2>/dev/null', { timeout: 15000, encoding: "utf8" } ).trim(); assert.ok(out.length > 0, "memory search must produce output"); try { const result = JSON.parse(out); assert.ok(typeof result === "object", "must be JSON object"); console.log("[BASELINE] memory_search result keys:", Object.keys(result).join(", ")); console.log("[BASELINE] memory_search results count:", result.results?.length ?? "N/A"); } catch (e) { console.log("[BASELINE] memory_search output (not JSON):", out.substring(0, 200)); assert.ok(!out.toLowerCase().includes("error"), "must not error"); } }); it("03.02 - memory_search returns results array", () => { const out = execSync( 'openclaw memory search "AGENTS.md" --json 2>/dev/null', { timeout: 15000, encoding: "utf8" } ).trim(); try { const result = JSON.parse(out); const results = result.results || []; console.log("[BASELINE] search 'AGENTS.md' results:", results.length); if (results.length > 0) { const first = results[0]; console.log("[BASELINE] first result keys:", Object.keys(first).join(", ")); console.log("[BASELINE] first result file:", first.file || first.path || "N/A"); console.log("[BASELINE] first result score:", first.score ?? "N/A"); } assert.ok(Array.isArray(results), "results must be array"); } catch { console.log("[BASELINE] search output raw:", out.substring(0, 300)); } assert.ok(true, "baseline frozen: search results shape"); }); it("03.03 - memory_search schema stable (empty query)", () => { const out = execSync( 'openclaw memory search "___nonexistent_xyzzy___" --json 2>/dev/null', { timeout: 15000, encoding: "utf8" } ).trim(); try { const result = JSON.parse(out); const results = result.results || []; console.log("[BASELINE] empty search results:", results.length); // Empty results should not error } catch { console.log("[BASELINE] empty search raw:", out.substring(0, 200)); } assert.ok(true, "baseline frozen: empty search behavior"); }); it("03.04 - memory_search handles special characters", () => { const queries = [ "中文测试", "test-123", "hello/world", "a.b.c", ]; for (const q of queries) { const out = execSync( `openclaw memory search "${q}" --json 2>/dev/null`, { timeout: 15000, encoding: "utf8" } ).trim(); try { JSON.parse(out); console.log(`[BASELINE] search "${q}": OK (valid JSON)`); } catch { console.log(`[BASELINE] search "${q}": non-JSON output`); } assert.ok(!out.toLowerCase().includes("fatal"), `query "${q}" must not crash`); } }); it("03.05 - memory_search contract: result object shape", () => { const out = execSync( 'openclaw memory search "architecture" --json 2>/dev/null', { timeout: 15000, encoding: "utf8" } ).trim(); try { const result = JSON.parse(out); // Freeze the top-level keys const topKeys = Object.keys(result).sort(); console.log("[BASELINE] memory_search response keys:", topKeys.join(", ")); // There must be a 'results' key assert.ok("results" in result || topKeys.length > 0, "must have results key or be non-empty object"); } catch { console.log("[BASELINE] raw response:", out.substring(0, 300)); } assert.ok(true, "baseline frozen: contract shape"); }); });