test(FN-1893): add comprehensive QMD test coverage
- Add QMD route success tests in dashboard routes - Expand QMD prompt completeness tests in executor - Add QMD bootstrap and instruction completeness tests in triage - Add QMD convenience function integration tests in memory-backend and project-memory
This commit is contained in:
@@ -701,6 +701,70 @@ describe("memory-backend", () => {
|
||||
expect(writeResult.success).toBe(true);
|
||||
expect(writeResult.backend).toBe("test-backend");
|
||||
});
|
||||
|
||||
it("should handle QMD write-then-read round-trip via convenience functions", async () => {
|
||||
const qmdSettings = { [MEMORY_BACKEND_SETTINGS_KEYS.MEMORY_BACKEND_TYPE]: "qmd" };
|
||||
const testContent = "QMD test content for round-trip verification";
|
||||
|
||||
// Write using QMD convenience function
|
||||
const writeResult = await writeMemory(tempDir, testContent, qmdSettings);
|
||||
expect(writeResult.success).toBe(true);
|
||||
expect(writeResult.backend).toBe("qmd");
|
||||
|
||||
// Read using QMD convenience function
|
||||
const readResult = await readMemory(tempDir, qmdSettings);
|
||||
expect(readResult.content).toBe(testContent);
|
||||
expect(readResult.exists).toBe(true);
|
||||
expect(readResult.backend).toBe("qmd");
|
||||
});
|
||||
|
||||
it("should handle QMD persistence cross-verification (QMD write, FileMemoryBackend read)", async () => {
|
||||
const qmdSettings = { [MEMORY_BACKEND_SETTINGS_KEYS.MEMORY_BACKEND_TYPE]: "qmd" };
|
||||
const testContent = "QMD persistence cross-verification content";
|
||||
|
||||
// Write via QMD convenience function
|
||||
await writeMemory(tempDir, testContent, qmdSettings);
|
||||
|
||||
// Read via direct FileMemoryBackend instance to verify filesystem delegation
|
||||
const fileBackend = new FileMemoryBackend();
|
||||
const fileResult = await fileBackend.read(tempDir);
|
||||
expect(fileResult.content).toBe(testContent);
|
||||
expect(fileResult.exists).toBe(true);
|
||||
expect(fileResult.backend).toBe("file"); // FileBackend reports "file"
|
||||
});
|
||||
|
||||
it("should preserve content across backend switching (file to QMD)", async () => {
|
||||
const fileSettings = { [MEMORY_BACKEND_SETTINGS_KEYS.MEMORY_BACKEND_TYPE]: "file" };
|
||||
const qmdSettings = { [MEMORY_BACKEND_SETTINGS_KEYS.MEMORY_BACKEND_TYPE]: "qmd" };
|
||||
const testContent = "Shared storage content across backends";
|
||||
|
||||
// Write via file backend
|
||||
await writeMemory(tempDir, testContent, fileSettings);
|
||||
|
||||
// Read via QMD backend
|
||||
const qmdReadResult = await readMemory(tempDir, qmdSettings);
|
||||
expect(qmdReadResult.content).toBe(testContent);
|
||||
expect(qmdReadResult.backend).toBe("qmd");
|
||||
|
||||
// Read back via file backend to verify consistency
|
||||
const fileReadResult = await readMemory(tempDir, fileSettings);
|
||||
expect(fileReadResult.content).toBe(testContent);
|
||||
});
|
||||
|
||||
it("should correctly report memoryExists for QMD backend", async () => {
|
||||
const qmdSettings = { [MEMORY_BACKEND_SETTINGS_KEYS.MEMORY_BACKEND_TYPE]: "qmd" };
|
||||
|
||||
// Initially should not exist
|
||||
const existsBefore = await memoryExists(tempDir, qmdSettings);
|
||||
expect(existsBefore).toBe(false);
|
||||
|
||||
// Write via QMD
|
||||
await writeMemory(tempDir, "QMD exists test content", qmdSettings);
|
||||
|
||||
// Now should exist
|
||||
const existsAfter = await memoryExists(tempDir, qmdSettings);
|
||||
expect(existsAfter).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
// ── Edge Cases ────────────────────────────────────────────────────
|
||||
|
||||
@@ -275,6 +275,43 @@ describe("project-memory", () => {
|
||||
// Should return false since readonly can't write
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
|
||||
it("creates memory file with QMD backend when memory does not exist", async () => {
|
||||
// Ensure clean state
|
||||
await mkdir(join(testDir, ".fusion"), { recursive: true });
|
||||
if (existsSync(memoryPath)) await unlink(memoryPath);
|
||||
expect(existsSync(memoryPath)).toBe(false);
|
||||
|
||||
const settings = { memoryBackendType: "qmd" };
|
||||
const created = await ensureMemoryFileWithBackend(testDir, settings);
|
||||
|
||||
expect(created).toBe(true);
|
||||
expect(existsSync(memoryPath)).toBe(true);
|
||||
const content = readFileSync(memoryPath, "utf-8");
|
||||
expect(content).toBe(getDefaultMemoryScaffold());
|
||||
});
|
||||
|
||||
it("QMD ensureMemoryFileWithBackend is idempotent and does not overwrite", async () => {
|
||||
// Create memory via QMD backend
|
||||
await mkdir(join(testDir, ".fusion"), { recursive: true });
|
||||
if (existsSync(memoryPath)) await unlink(memoryPath);
|
||||
|
||||
const settings = { memoryBackendType: "qmd" };
|
||||
const firstCreated = await ensureMemoryFileWithBackend(testDir, settings);
|
||||
expect(firstCreated).toBe(true);
|
||||
|
||||
// Manually edit the content
|
||||
const customContent = "# Custom Memory\n\nI edited this content";
|
||||
await writeFile(memoryPath, customContent, "utf-8");
|
||||
|
||||
// Call ensure again - should NOT overwrite
|
||||
const secondCreated = await ensureMemoryFileWithBackend(testDir, settings);
|
||||
expect(secondCreated).toBe(false);
|
||||
|
||||
// Content should still be the custom content
|
||||
const content = readFileSync(memoryPath, "utf-8");
|
||||
expect(content).toBe(customContent);
|
||||
});
|
||||
});
|
||||
|
||||
// ── readProjectMemoryWithBackend ─────────────────────────────────────
|
||||
@@ -333,6 +370,16 @@ describe("project-memory", () => {
|
||||
const content = await readProjectMemoryWithBackend(testDir, settings);
|
||||
expect(content).toBe("");
|
||||
});
|
||||
|
||||
it("returns memory content when using QMD backend", async () => {
|
||||
// Create the memory file directly (simulating prior creation)
|
||||
await mkdir(join(testDir, ".fusion"), { recursive: true });
|
||||
await writeFile(memoryPath, "# QMD Memory\n\nSome content", "utf-8");
|
||||
|
||||
const settings = { memoryBackendType: "qmd" };
|
||||
const content = await readProjectMemoryWithBackend(testDir, settings);
|
||||
expect(content).toBe("# QMD Memory\n\nSome content");
|
||||
});
|
||||
});
|
||||
|
||||
// ── Backend-aware bootstrap integration ─────────────────────────────
|
||||
@@ -445,6 +492,15 @@ describe("project-memory", () => {
|
||||
expect(instructions).toMatch(/consult.*project memory/i);
|
||||
});
|
||||
|
||||
it("QMD triage instructions completeness - contains consult guidance", () => {
|
||||
const settings = { memoryBackendType: "qmd" };
|
||||
const instructions = buildTriageMemoryInstructions(testDir, settings);
|
||||
expect(instructions).toContain("## Project Memory");
|
||||
expect(instructions).not.toContain(".fusion/memory.md");
|
||||
// Should contain consult guidance
|
||||
expect(instructions).toMatch(/consult.*memory/i);
|
||||
});
|
||||
|
||||
it("does not include .fusion/memory.md for non-file backends without instructionPathHint", () => {
|
||||
const settings = { memoryBackendType: "some-custom-backend" };
|
||||
const instructions = buildTriageMemoryInstructions(testDir, settings);
|
||||
@@ -494,6 +550,21 @@ describe("project-memory", () => {
|
||||
expect(instructions).toMatch(/consult.*project memory/i);
|
||||
});
|
||||
|
||||
it("QMD execution instructions completeness", () => {
|
||||
const settings = { memoryBackendType: "qmd" };
|
||||
const instructions = buildExecutionMemoryInstructions(testDir, settings);
|
||||
expect(instructions).toContain("## Project Memory");
|
||||
expect(instructions).not.toContain(".fusion/memory.md");
|
||||
// Contains consult guidance at start of execution
|
||||
expect(instructions).toMatch(/consult.*memory/i);
|
||||
// Contains "end of execution" write guidance
|
||||
expect(instructions).toMatch(/end of execution/i);
|
||||
// Contains "skip" wording for when nothing durable learned
|
||||
expect(instructions).toMatch(/skip.*memory.*update|nothing durable/i);
|
||||
// Contains "avoid" / "trivia" guidance
|
||||
expect(instructions).toMatch(/trivia|avoid/i);
|
||||
});
|
||||
|
||||
it("maintains backward compatibility when settings omitted (file behavior)", () => {
|
||||
const instructions = buildExecutionMemoryInstructions(testDir);
|
||||
expect(instructions).toContain(".fusion/memory.md");
|
||||
|
||||
Reference in New Issue
Block a user