Files
u-tabs/internal/rename_persist_test.go
lxy cc58de4661 修复: 重命名时缓存缺条目补建防标题丢失
- 缓存缺 entry(缓存损坏或新会话未入缓存)时补建,标题才能落盘
- 补缓存补建测试,顺带补齐测试文件缺失的换行
2026-10-03 10:13:40 +08:00

76 lines
2.3 KiB
Go

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)
}
}
// TestSetUserTitleBackfillCacheEntry 验证缓存缺 entry 时(缓存文件损坏/
// 新会话未入缓存)重命名会补建 entry,保证标题落盘而非只改内存
func TestSetUserTitleBackfillCacheEntry(t *testing.T) {
m := NewModel()
m.history.Cache = map[string]*cacheEntry{}
m.setUserTitle("missing-session", "新标题")
e, ok := m.history.Cache["missing-session"]
if !ok {
t.Fatal("缓存缺 entry 时应补建")
}
if e.UserTitle != "新标题" {
t.Fatalf("补建 entry 应写入标题, got %q", e.UserTitle)
}
if !m.cacheDirty {
t.Fatal("应置 cacheDirty 调度落盘")
}
}