package config import ( "os" "path/filepath" "testing" "time" "skillmgr/internal/types" ) func setupInstallTestEnv(t *testing.T) (string, func()) { t.Helper() tmpDir, err := os.MkdirTemp("", "skillmgr-install-test-*") if err != nil { t.Fatalf("创建临时目录失败: %v", err) } os.Setenv("SKILLMGR_TEST_ROOT", tmpDir) cleanup := func() { os.Unsetenv("SKILLMGR_TEST_ROOT") os.RemoveAll(tmpDir) } return tmpDir, cleanup } func TestLoadInstallConfig_Empty(t *testing.T) { _, cleanup := setupInstallTestEnv(t) defer cleanup() cfg, err := LoadInstallConfig() if err != nil { t.Fatalf("LoadInstallConfig 失败: %v", err) } if len(cfg.Installations) != 0 { t.Errorf("期望空安装列表,得到 %d 个", len(cfg.Installations)) } } func TestAddInstallRecord_Success(t *testing.T) { _, cleanup := setupInstallTestEnv(t) defer cleanup() record := types.InstallRecord{ Type: types.ItemTypeSkill, Name: "test-skill", SourceRepo: "test-repo", Platform: types.PlatformClaude, Scope: types.ScopeGlobal, InstallPath: "/path/to/skill", InstalledAt: time.Now(), UpdatedAt: time.Now(), } if err := AddInstallRecord(record); err != nil { t.Fatalf("AddInstallRecord 失败: %v", err) } cfg, _ := LoadInstallConfig() if len(cfg.Installations) != 1 { t.Errorf("期望 1 条记录,得到 %d 条", len(cfg.Installations)) } } func TestFindInstallRecord_Found(t *testing.T) { _, cleanup := setupInstallTestEnv(t) defer cleanup() record := types.InstallRecord{ Type: types.ItemTypeSkill, Name: "test-skill", Platform: types.PlatformClaude, Scope: types.ScopeGlobal, InstalledAt: time.Now(), UpdatedAt: time.Now(), } AddInstallRecord(record) found, err := FindInstallRecord(types.ItemTypeSkill, "test-skill", types.PlatformClaude, types.ScopeGlobal) if err != nil { t.Fatalf("FindInstallRecord 失败: %v", err) } if found.Name != "test-skill" { t.Errorf("期望名称 'test-skill',得到 '%s'", found.Name) } } func TestRemoveInstallRecord_Success(t *testing.T) { _, cleanup := setupInstallTestEnv(t) defer cleanup() record := types.InstallRecord{ Type: types.ItemTypeSkill, Name: "test-skill", Platform: types.PlatformClaude, Scope: types.ScopeGlobal, InstalledAt: time.Now(), UpdatedAt: time.Now(), } AddInstallRecord(record) if err := RemoveInstallRecord(types.ItemTypeSkill, "test-skill", types.PlatformClaude, types.ScopeGlobal); err != nil { t.Fatalf("RemoveInstallRecord 失败: %v", err) } cfg, _ := LoadInstallConfig() if len(cfg.Installations) != 0 { t.Errorf("期望 0 条记录,得到 %d 条", len(cfg.Installations)) } } func TestCleanOrphanRecords(t *testing.T) { tmpDir, cleanup := setupInstallTestEnv(t) defer cleanup() // 创建一个存在的路径 existingPath := filepath.Join(tmpDir, "existing-skill") os.MkdirAll(existingPath, 0755) // 添加两条记录:一条存在,一条不存在 record1 := types.InstallRecord{ Type: types.ItemTypeSkill, Name: "existing-skill", Platform: types.PlatformClaude, Scope: types.ScopeGlobal, InstallPath: existingPath, InstalledAt: time.Now(), UpdatedAt: time.Now(), } record2 := types.InstallRecord{ Type: types.ItemTypeSkill, Name: "orphan-skill", Platform: types.PlatformClaude, Scope: types.ScopeGlobal, InstallPath: "/nonexistent/path", InstalledAt: time.Now(), UpdatedAt: time.Now(), } AddInstallRecord(record1) AddInstallRecord(record2) cleaned, err := CleanOrphanRecords() if err != nil { t.Fatalf("CleanOrphanRecords 失败: %v", err) } if len(cleaned) != 1 { t.Errorf("期望清理 1 条记录,清理了 %d 条", len(cleaned)) } if len(cleaned) > 0 && cleaned[0].Name != "orphan-skill" { t.Errorf("期望清理 'orphan-skill',清理了 '%s'", cleaned[0].Name) } // 验证只剩下存在的记录 cfg, _ := LoadInstallConfig() if len(cfg.Installations) != 1 { t.Errorf("期望剩余 1 条记录,剩余 %d 条", len(cfg.Installations)) } }