From 2000dcdcd0a0627d638d6ac175e6dd5c5f5ee470 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sat, 21 Feb 2026 19:39:12 +0000 Subject: [PATCH] test(memory): dedupe temp-dir lifecycle hooks and cover overlapping path dedupe --- src/memory/internal.test.ts | 46 ++++++++++++++++++++++--------------- 1 file changed, 28 insertions(+), 18 deletions(-) diff --git a/src/memory/internal.test.ts b/src/memory/internal.test.ts index 0c3b199ca..0f17843a8 100644 --- a/src/memory/internal.test.ts +++ b/src/memory/internal.test.ts @@ -10,6 +10,17 @@ import { remapChunkLines, } from "./internal.js"; +function setupTempDirLifecycle(prefix: string): () => string { + let tmpDir = ""; + beforeEach(async () => { + tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), prefix)); + }); + afterEach(async () => { + await fs.rm(tmpDir, { recursive: true, force: true }); + }); + return () => tmpDir; +} + describe("normalizeExtraMemoryPaths", () => { it("trims, resolves, and dedupes paths", () => { const workspaceDir = path.join(os.tmpdir(), "memory-test-workspace"); @@ -26,17 +37,10 @@ describe("normalizeExtraMemoryPaths", () => { }); describe("listMemoryFiles", () => { - let tmpDir: string; - - beforeEach(async () => { - tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), "memory-test-")); - }); - - afterEach(async () => { - await fs.rm(tmpDir, { recursive: true, force: true }); - }); + const getTmpDir = setupTempDirLifecycle("memory-test-"); it("includes files from additional paths (directory)", async () => { + const tmpDir = getTmpDir(); await fs.writeFile(path.join(tmpDir, "MEMORY.md"), "# Default memory"); const extraDir = path.join(tmpDir, "extra-notes"); await fs.mkdir(extraDir, { recursive: true }); @@ -53,6 +57,7 @@ describe("listMemoryFiles", () => { }); it("includes files from additional paths (single file)", async () => { + const tmpDir = getTmpDir(); await fs.writeFile(path.join(tmpDir, "MEMORY.md"), "# Default memory"); const singleFile = path.join(tmpDir, "standalone.md"); await fs.writeFile(singleFile, "# Standalone"); @@ -63,6 +68,7 @@ describe("listMemoryFiles", () => { }); it("handles relative paths in additional paths", async () => { + const tmpDir = getTmpDir(); await fs.writeFile(path.join(tmpDir, "MEMORY.md"), "# Default memory"); const extraDir = path.join(tmpDir, "subdir"); await fs.mkdir(extraDir, { recursive: true }); @@ -74,6 +80,7 @@ describe("listMemoryFiles", () => { }); it("ignores non-existent additional paths", async () => { + const tmpDir = getTmpDir(); await fs.writeFile(path.join(tmpDir, "MEMORY.md"), "# Default memory"); const files = await listMemoryFiles(tmpDir, ["/does/not/exist"]); @@ -81,6 +88,7 @@ describe("listMemoryFiles", () => { }); it("ignores symlinked files and directories", async () => { + const tmpDir = getTmpDir(); await fs.writeFile(path.join(tmpDir, "MEMORY.md"), "# Default memory"); const extraDir = path.join(tmpDir, "extra"); await fs.mkdir(extraDir, { recursive: true }); @@ -115,20 +123,21 @@ describe("listMemoryFiles", () => { expect(files.some((file) => file.endsWith("nested.md"))).toBe(false); } }); + + it("dedupes overlapping extra paths that resolve to the same file", async () => { + const tmpDir = getTmpDir(); + await fs.writeFile(path.join(tmpDir, "MEMORY.md"), "# Default memory"); + const files = await listMemoryFiles(tmpDir, [tmpDir, ".", path.join(tmpDir, "MEMORY.md")]); + const memoryMatches = files.filter((file) => file.endsWith("MEMORY.md")); + expect(memoryMatches).toHaveLength(1); + }); }); describe("buildFileEntry", () => { - let tmpDir: string; - - beforeEach(async () => { - tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), "memory-build-entry-")); - }); - - afterEach(async () => { - await fs.rm(tmpDir, { recursive: true, force: true }); - }); + const getTmpDir = setupTempDirLifecycle("memory-build-entry-"); it("returns null when the file disappears before reading", async () => { + const tmpDir = getTmpDir(); const target = path.join(tmpDir, "ghost.md"); await fs.writeFile(target, "ghost", "utf-8"); await fs.rm(target); @@ -137,6 +146,7 @@ describe("buildFileEntry", () => { }); it("returns metadata when the file exists", async () => { + const tmpDir = getTmpDir(); const target = path.join(tmpDir, "note.md"); await fs.writeFile(target, "hello", "utf-8"); const entry = await buildFileEntry(target, tmpDir);