Files
2026-10-18 19:49:49 +08:00

170 lines
5.0 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package config
import (
"os"
"path/filepath"
"strings"
"testing"
)
func writeFile(t *testing.T, dir, name, body string) string {
t.Helper()
p := filepath.Join(dir, name)
if err := os.WriteFile(p, []byte(body), 0o644); err != nil {
t.Fatalf("写测试配置失败: %v", err)
}
return p
}
func TestLoadCreatesDefaultFile(t *testing.T) {
dir := t.TempDir()
path := filepath.Join(dir, FileName)
cfg, err := Load(path, dir)
if err != nil {
t.Fatalf("Load 失败: %v", err)
}
if !cfg.Created {
t.Fatal("首次加载应标记为已生成")
}
if cfg.ListenIP != "0.0.0.0" || cfg.ListenPort != 17777 {
t.Fatalf("默认监听地址不对: %s:%d", cfg.ListenIP, cfg.ListenPort)
}
if cfg.BackupKeep != 14 || !cfg.BackupEnabled || !cfg.ScreenPublic || !cfg.LogEnabled {
t.Fatalf("默认值不对: %+v", cfg)
}
// 相对路径应解析到 exe 目录
if cfg.DatabasePath != filepath.Join(dir, "daili.db") {
t.Fatalf("数据库路径=%s", cfg.DatabasePath)
}
if cfg.BackupDir != filepath.Join(dir, "backup") || cfg.LogDir != filepath.Join(dir, "logs") {
t.Fatalf("备份/日志目录=%s %s", cfg.BackupDir, cfg.LogDir)
}
data, err := os.ReadFile(path)
if err != nil {
t.Fatalf("默认配置文件未生成: %v", err)
}
text := string(data)
for _, want := range []string{"listen_ip = 0.0.0.0", "listen_port = 17777", "代打台 配置文件(daili.ini)", "timezone ="} {
if !strings.Contains(text, want) {
t.Errorf("默认配置缺少 %q", want)
}
}
// 再读一次不应重新生成
cfg2, err := Load(path, dir)
if err != nil {
t.Fatal(err)
}
if cfg2.Created {
t.Fatal("第二次加载不应标记为已生成")
}
}
func TestLoadParsesValues(t *testing.T) {
dir := t.TempDir()
absLogDir := t.TempDir() // 各平台都是绝对路径,避免把 Windows 盘符写进用例
body := "\ufeff# 注释\n" +
"listen_ip = 127.0.0.1\r\n" +
"\r\n" +
"listen_port = 19000\r\n" +
" database_path = data/mydb.db \r\n" +
"backup_enabled = no\r\n" +
"backup_keep = 30\r\n" +
"timezone = Asia/Shanghai\r\n" +
"open_browser = 0\r\n" +
"screen_public = false\r\n" +
"log_enabled = on\r\n" +
"log_dir = " + absLogDir + "\r\n"
path := writeFile(t, dir, FileName, body)
cfg, err := Load(path, dir)
if err != nil {
t.Fatalf("Load 失败: %v", err)
}
if cfg.ListenIP != "127.0.0.1" || cfg.ListenPort != 19000 {
t.Fatalf("监听=%s:%d", cfg.ListenIP, cfg.ListenPort)
}
if !cfg.LoopbackOnly() || cfg.PublicBind() {
t.Fatal("127.0.0.1 应判定为仅本机")
}
if cfg.DatabasePath != filepath.Join(dir, "data", "mydb.db") {
t.Fatalf("相对路径未按 exe 目录解析: %s", cfg.DatabasePath)
}
if cfg.BackupEnabled || cfg.BackupKeep != 30 {
t.Fatalf("备份配置=%v/%d", cfg.BackupEnabled, cfg.BackupKeep)
}
if cfg.Timezone != "Asia/Shanghai" || cfg.OpenBrowser || cfg.ScreenPublic || !cfg.LogEnabled {
t.Fatalf("其余配置不对: %+v", cfg)
}
if cfg.LogDir != absLogDir {
t.Fatalf("绝对路径被改写: %s", cfg.LogDir)
}
if cfg.Addr() != "127.0.0.1:19000" {
t.Fatalf("Addr=%s", cfg.Addr())
}
}
func TestLoadRejectsBadInput(t *testing.T) {
cases := []struct {
name string
body string
want string
}{
{"未知配置项", "listen_port = 1\nlisten_prt = 2\n", "未知配置项 listen_prt"},
{"端口非数字", "\nlisten_port = abc\n", "listen_port 必须是数字"},
{"端口越界", "listen_port = 70000\n", "必须在 1-65535 之间"},
{"非法IP", "listen_ip = 300.1.1.1\n", "不是合法 IP"},
{"布尔值非法", "open_browser = maybe\n", "必须是 true/false"},
{"保留份数越界", "backup_keep = 0\n", "backup_keep 必须在 1-365 之间"},
{"时区非法", "timezone = Mars/Base\n", "timezone"},
{"重复配置", "listen_port = 1\nlisten_port = 2\n", "重复"},
{"缺少等号", "listen_port 1\n", "缺少等号"},
{"不支持分节", "[net]\nlisten_port = 1\n", "不支持分节"},
}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
dir := t.TempDir()
path := writeFile(t, dir, FileName, c.body)
before, _ := os.ReadFile(path)
_, err := Load(path, dir)
if err == nil {
t.Fatalf("期望报错,实际通过")
}
if !strings.Contains(err.Error(), c.want) {
t.Fatalf("错误信息 %q 不含 %q", err.Error(), c.want)
}
after, _ := os.ReadFile(path)
if string(before) != string(after) {
t.Fatal("出错时不应修改原文件")
}
})
}
}
func TestErrorHasLineNumber(t *testing.T) {
dir := t.TempDir()
path := writeFile(t, dir, FileName, "# 注释\nlisten_ip = 0.0.0.0\nlisten_port = 99999\n")
_, err := Load(path, dir)
if err == nil {
t.Fatal("期望报错")
}
if !strings.Contains(err.Error(), "第 3 行") {
t.Fatalf("错误信息应带行号: %v", err)
}
}
func TestValidateAfterOverride(t *testing.T) {
dir := t.TempDir()
path := writeFile(t, dir, FileName, "listen_port = 18080\n")
cfg, err := Load(path, dir)
if err != nil {
t.Fatal(err)
}
cfg.ListenPort = 0
if err := cfg.Validate(); err == nil {
t.Fatal("覆盖后的非法端口应被拦截")
}
}