// scanner_test.go -- 记忆目录扫描器的单元测试. // // 覆盖场景: // - ScanMemoryDir 正常扫描 // - 目录不存在返回空 // - 排除 MEMORY.md 索引文件 // - 按 mtime 排序 // - 跳过无效 frontmatter 的文件 package memory import ( "os" "path/filepath" "testing" "time" ) // TestScanMemoryDir_Normal 测试正常扫描 func TestScanMemoryDir_Normal(t *testing.T) { dir := t.TempDir() // 创建测试记忆文件 files := []struct { name string content string }{ {"mem1.md", "---\nname: mem1\ndescription: first\ntype: user\n---\nContent 1"}, {"mem2.md", "---\nname: mem2\ndescription: second\ntype: project\n---\nContent 2"}, } for _, f := range files { os.WriteFile(filepath.Join(dir, f.name), []byte(f.content), 0644) time.Sleep(10 * time.Millisecond) // 确保 mtime 不同 } headers, err := ScanMemoryDir(dir) if err != nil { t.Fatalf("扫描失败: %v", err) } if len(headers) != 2 { t.Fatalf("期望 2 个文件, 实际 %d", len(headers)) } // 应按 mtime 倒序(最新的在前) if headers[0].Frontmatter.Name != "mem2" { t.Errorf("最新的应在前, 第一个: %q", headers[0].Frontmatter.Name) } } // TestScanMemoryDir_NotExist 测试目录不存在 func TestScanMemoryDir_NotExist(t *testing.T) { headers, err := ScanMemoryDir("/nonexistent/dir") if err != nil { t.Fatalf("不应返回错误: %v", err) } if len(headers) != 0 { t.Errorf("目录不存在应返回空, 实际 %d 个", len(headers)) } } // TestScanMemoryDir_ExcludeMemoryMD 测试排除 MEMORY.md func TestScanMemoryDir_ExcludeMemoryMD(t *testing.T) { dir := t.TempDir() os.WriteFile(filepath.Join(dir, "MEMORY.md"), []byte("# Index\n"), 0644) os.WriteFile(filepath.Join(dir, "real.md"), []byte("---\nname: real\ndescription: d\ntype: user\n---\nContent"), 0644) headers, err := ScanMemoryDir(dir) if err != nil { t.Fatalf("扫描失败: %v", err) } if len(headers) != 1 { t.Fatalf("期望 1 个文件(排除 MEMORY.md), 实际 %d", len(headers)) } if headers[0].Frontmatter.Name != "real" { t.Errorf("应为 'real', 实际: %q", headers[0].Frontmatter.Name) } } // TestScanMemoryDir_SkipInvalidFrontmatter 测试跳过无效文件 func TestScanMemoryDir_SkipInvalidFrontmatter(t *testing.T) { dir := t.TempDir() os.WriteFile(filepath.Join(dir, "valid.md"), []byte("---\nname: valid\ndescription: d\ntype: user\n---\nContent"), 0644) os.WriteFile(filepath.Join(dir, "invalid.md"), []byte("No frontmatter here"), 0644) os.WriteFile(filepath.Join(dir, "noname.md"), []byte("---\ndescription: d\ntype: user\n---\nContent"), 0644) headers, err := ScanMemoryDir(dir) if err != nil { t.Fatalf("扫描失败: %v", err) } if len(headers) != 1 { t.Fatalf("应只有 1 个有效文件, 实际 %d", len(headers)) } } // TestScanMemoryDir_SkipNonMD 测试跳过非 .md 文件 func TestScanMemoryDir_SkipNonMD(t *testing.T) { dir := t.TempDir() os.WriteFile(filepath.Join(dir, "valid.md"), []byte("---\nname: valid\ndescription: d\ntype: user\n---\nContent"), 0644) os.WriteFile(filepath.Join(dir, "other.txt"), []byte("not a memory"), 0644) os.WriteFile(filepath.Join(dir, "data.json"), []byte(`{"key":"value"}`), 0644) headers, err := ScanMemoryDir(dir) if err != nil { t.Fatalf("扫描失败: %v", err) } if len(headers) != 1 { t.Fatalf("应只扫描 .md 文件, 实际 %d", len(headers)) } }