test(memory): dedupe temp-dir lifecycle hooks and cover overlapping path dedupe

This commit is contained in:
Peter Steinberger
2026-02-21 19:39:12 +00:00
parent 6051dc10ff
commit 2000dcdcd0

View File

@@ -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);