package internal import ( "testing" tea "charm.land/bubbletea/v2" ) // TestRenameSurvivesStaleScan 验证改名持久化竞态: // 改名后内存缓存已设 UserTitle 但尚未落盘(3s 延迟), // 此时若触发扫描(切 tab/刷新),ScanCompleteMsg 会用磁盘旧缓存 // (不含新标题)覆盖内存,导致改名丢失。 func TestRenameSurvivesStaleScan(t *testing.T) { m := NewModel() m.history.Projects = []*ProjectDir{ {DirShort: "test", Sessions: []*Session{ {ID: "s1", AISummary: "原标题", UserTitle: "我的新名"}, }}, } // 内存缓存:改名已写入但尚未落盘 m.history.Cache = map[string]*cacheEntry{ "s1": {UserTitle: "我的新名"}, } m.history.Favorites = map[string]bool{} // 跳过 loadFavorites 文件读取 m.cacheDirty = true // 现在用户改名后 3 秒内按了 "2"/"r" 触发扫描: // 扫描从磁盘读到旧缓存(不含 UserTitle),返回的 msg 也无 UserTitle staleProjects := []*ProjectDir{ {DirShort: "test", Sessions: []*Session{ {ID: "s1", AISummary: "原标题"}, }}, } staleCache := map[string]*cacheEntry{ "s1": {UserTitle: ""}, } var cmd tea.Cmd model, _ := m.Update(ScanCompleteMsg{ Projects: staleProjects, Cache: staleCache, }) _ = model _ = cmd // 改名应存活:内存缓存的 UserTitle 不应被磁盘旧缓存清掉 got := m.history.Cache["s1"].UserTitle if got != "我的新名" { t.Fatalf("扫描后改名丢失: cache UserTitle = %q, 期望 \"我的新名\"", got) } // session 的 UserTitle 也应保留 s := m.history.Projects[0].Sessions[0] if s.UserTitle != "我的新名" { t.Fatalf("扫描后 session UserTitle 丢失: = %q, 期望 \"我的新名\"", s.UserTitle) } }