import { beforeEach, describe, expect, it } from "vitest"; import { InMemoryStore } from "./in-memory-store.js"; import type { Tag } from "./types.js"; describe("InMemoryStore", () => { let store: InMemoryStore; beforeEach(() => { store = new InMemoryStore(); }); describe("create", () => { it("creates a memory and returns it with generated id", async () => { const memory = await store.create({ content: "Test memory content", projectId: "project-1", }); expect(memory.id).toBeDefined(); expect(memory.content).toBe("Test memory content"); expect(memory.projectId).toBe("project-1"); expect(memory.folderId).toBeNull(); expect(memory.tags).toEqual([]); expect(memory.metadata).toEqual({}); expect(memory.createdAt).toBeInstanceOf(Date); expect(memory.updatedAt).toBeInstanceOf(Date); }); it("creates a memory with optional fields", async () => { const tags: Tag[] = [{ id: "tag-1", name: "important" }]; const metadata = { source: "test" }; const memory = await store.create({ content: "Test memory content", projectId: "project-1", folderId: "folder-1", tags, metadata, }); expect(memory.folderId).toBe("folder-1"); expect(memory.tags).toEqual(tags); expect(memory.metadata).toEqual(metadata); }); }); describe("read", () => { it("returns a memory by id", async () => { const created = await store.create({ content: "Test memory content", projectId: "project-1", }); const result = await store.read(created.id); expect(result.success).toBe(true); if (result.success) { expect(result.value).toEqual(created); } }); it("returns failure when memory does not exist", async () => { const result = await store.read("non-existent-id"); expect(result.success).toBe(false); if (!result.success) { expect(result.error.type).toBe("MEMORY_NOT_FOUND"); expect(result.error.memoryId).toBe("non-existent-id"); } }); }); describe("update", () => { it("updates a memory and returns the updated version", async () => { const created = await store.create({ content: "Original content", projectId: "project-1", }); const result = await store.update(created.id, { content: "Updated content", }); expect(result.success).toBe(true); if (result.success) { expect(result.value.content).toBe("Updated content"); expect(result.value.updatedAt.getTime()).toBeGreaterThanOrEqual( created.updatedAt.getTime(), ); } }); it("updates only specified fields", async () => { const tags: Tag[] = [{ id: "tag-1", name: "important" }]; const created = await store.create({ content: "Original content", projectId: "project-1", folderId: "folder-1", tags, }); const result = await store.update(created.id, { content: "Updated content", }); expect(result.success).toBe(true); if (result.success) { expect(result.value.content).toBe("Updated content"); expect(result.value.folderId).toBe("folder-1"); expect(result.value.tags).toEqual(tags); } }); it("allows setting folderId to null", async () => { const created = await store.create({ content: "Test content", projectId: "project-1", folderId: "folder-1", }); const result = await store.update(created.id, { folderId: null, }); expect(result.success).toBe(true); if (result.success) { expect(result.value.folderId).toBeNull(); } }); it("returns failure when memory does not exist", async () => { const result = await store.update("non-existent-id", { content: "Updated content", }); expect(result.success).toBe(false); if (!result.success) { expect(result.error.type).toBe("MEMORY_NOT_FOUND"); expect(result.error.memoryId).toBe("non-existent-id"); } }); }); describe("delete", () => { it("deletes a memory", async () => { const created = await store.create({ content: "Test content", projectId: "project-1", }); const deleteResult = await store.delete(created.id); expect(deleteResult.success).toBe(true); const readResult = await store.read(created.id); expect(readResult.success).toBe(false); }); it("returns failure when memory does not exist", async () => { const result = await store.delete("non-existent-id"); expect(result.success).toBe(false); if (!result.success) { expect(result.error.type).toBe("MEMORY_NOT_FOUND"); expect(result.error.memoryId).toBe("non-existent-id"); } }); }); describe("list", () => { it("returns empty array when no memories exist", async () => { const memories = await store.list(); expect(memories).toEqual([]); }); it("returns all memories when no filter is provided", async () => { const memory1 = await store.create({ content: "Memory 1", projectId: "project-1", }); const memory2 = await store.create({ content: "Memory 2", projectId: "project-2", }); const memories = await store.list(); expect(memories).toHaveLength(2); expect(memories).toContainEqual(memory1); expect(memories).toContainEqual(memory2); }); it("filters memories by projectId", async () => { const memory1 = await store.create({ content: "Memory 1", projectId: "project-1", }); await store.create({ content: "Memory 2", projectId: "project-2", }); const memories = await store.list({ projectId: "project-1" }); expect(memories).toHaveLength(1); expect(memories[0]).toEqual(memory1); }); it("filters memories by folderId", async () => { const memory1 = await store.create({ content: "Memory 1", projectId: "project-1", folderId: "folder-1", }); await store.create({ content: "Memory 2", projectId: "project-1", folderId: "folder-2", }); await store.create({ content: "Memory 3", projectId: "project-1", }); const memories = await store.list({ folderId: "folder-1" }); expect(memories).toHaveLength(1); expect(memories[0]).toEqual(memory1); }); it("filters memories by tags", async () => { const tag1: Tag = { id: "tag-1", name: "important" }; const tag2: Tag = { id: "tag-2", name: "work" }; const memory1 = await store.create({ content: "Memory 1", projectId: "project-1", tags: [tag1, tag2], }); await store.create({ content: "Memory 2", projectId: "project-1", tags: [tag1], }); await store.create({ content: "Memory 3", projectId: "project-1", tags: [], }); const memories = await store.list({ tags: ["tag-1", "tag-2"] }); expect(memories).toHaveLength(1); expect(memories[0]).toEqual(memory1); }); it("filters memories by multiple criteria", async () => { const tag: Tag = { id: "tag-1", name: "important" }; const memory1 = await store.create({ content: "Memory 1", projectId: "project-1", folderId: "folder-1", tags: [tag], }); await store.create({ content: "Memory 2", projectId: "project-1", folderId: "folder-2", tags: [tag], }); await store.create({ content: "Memory 3", projectId: "project-2", folderId: "folder-1", tags: [tag], }); const memories = await store.list({ projectId: "project-1", folderId: "folder-1", tags: ["tag-1"], }); expect(memories).toHaveLength(1); expect(memories[0]).toEqual(memory1); }); }); });