package question import ( "os" "path/filepath" "strings" "testing" "github.com/stretchr/testify/require" "github.com/tamakyi/TamaBox/internal/conf" ) // TestFontCandidatesOrder 锁住候选字体的优先级。 // // 顺序错了不会报错,只会让线上多花几秒去解析一个注定失败的 19 MB CFF 字体 // (Noto Sans CJK 是 OTTO 轮廓,freetype 不支持),甚至在缺字体时把排障引向 // 「配了 font_path 却仍失败」的错误方向。 func TestFontCandidatesOrder(t *testing.T) { old := conf.App.FontPath t.Cleanup(func() { conf.App.FontPath = old }) conf.App.FontPath = "/opt/fonts/mine.ttf" got := fontCandidates() require.NotEmpty(t, got) require.Equal(t, "/opt/fonts/mine.ttf", got[0], "配置项必须排在最前") idxWQY, idxNoto := -1, -1 for i, p := range got { if strings.Contains(p, "wqy-zenhei") { idxWQY = i } if strings.Contains(p, "NotoSansCJK") && idxNoto < 0 { idxNoto = i } } require.NotEqual(t, -1, idxWQY, "系统 glyf 候选(文泉驿)应保留") require.NotEqual(t, -1, idxNoto, "CFF 兜底候选应保留") require.Less(t, idxWQY, idxNoto, "glyf 轮廓的系统字体必须排在 Noto(CFF) 之前") } // TestStaticFontDirs 校验两条不变式:返回的目录一定真实存在、且不重复。 // 存在性很重要 —— 把不存在的目录交给 Glob 不会报错,只会静默返回空, // 于是「字体明明放在 static/fonts 却找不到」这种问题查起来毫无线索。 func TestStaticFontDirs(t *testing.T) { seen := make(map[string]struct{}) for _, d := range staticFontDirs() { st, err := os.Stat(d) require.NoError(t, err, "候选目录必须存在:%s", d) require.True(t, st.IsDir(), "候选必须是目录:%s", d) _, dup := seen[d] require.False(t, dup, "目录重复:%s", d) seen[d] = struct{}{} } } // TestLoadFontWithPathReportsTried 确认失败信息里列出实际尝试过的路径 —— // 缺字体时这条文案就是唯一线索(分享卡是公开端点,没人看得到 console)。 func TestLoadFontWithPathReportsTried(t *testing.T) { old := conf.App.FontPath t.Cleanup(func() { conf.App.FontPath = old }) conf.App.FontPath = filepath.Join(t.TempDir(), "definitely-missing.ttf") // 环境里可能偏偏装着可用系统字体,那就只能跳过(不断言失败)。 if _, path, err := loadFontWithPath(); err == nil { t.Skipf("本机存在可用系统字体 %q,跳过失败路径断言", path) } else { require.Contains(t, err.Error(), "definitely-missing.ttf", "错误信息必须列出尝试过的路径") require.Contains(t, err.Error(), "TrueType 轮廓", "错误信息必须点明需要 glyf 轮廓") } }