package config import ( "os" "path/filepath" "testing" "time" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "gopkg.in/yaml.v3" ) func TestDefaultConfig(t *testing.T) { cfg := DefaultConfig() require.NotNil(t, cfg) assert.Equal(t, 9826, cfg.Server.Port) assert.Equal(t, 30*time.Second, cfg.Server.ReadTimeout) assert.Equal(t, 30*time.Second, cfg.Server.WriteTimeout) assert.Equal(t, 10, cfg.Database.MaxIdleConns) assert.Equal(t, 100, cfg.Database.MaxOpenConns) assert.Equal(t, 1*time.Hour, cfg.Database.ConnMaxLifetime) assert.Equal(t, "info", cfg.Log.Level) assert.Equal(t, 100, cfg.Log.MaxSize) assert.Equal(t, 10, cfg.Log.MaxBackups) assert.Equal(t, 30, cfg.Log.MaxAge) assert.Equal(t, true, cfg.Log.Compress) } func TestConfig_Validate(t *testing.T) { tests := []struct { name string modify func(*Config) wantErr bool errMsg string }{ { name: "默认配置有效", modify: func(c *Config) {}, wantErr: false, }, { name: "端口号为0无效", modify: func(c *Config) { c.Server.Port = 0 }, wantErr: true, errMsg: "配置验证失败", }, { name: "端口号超出范围无效", modify: func(c *Config) { c.Server.Port = 70000 }, wantErr: true, errMsg: "配置验证失败", }, { name: "端口号为1有效", modify: func(c *Config) { c.Server.Port = 1 }, wantErr: false, }, { name: "端口号为65535有效", modify: func(c *Config) { c.Server.Port = 65535 }, wantErr: false, }, { name: "无效日志级别", modify: func(c *Config) { c.Log.Level = "invalid" }, wantErr: true, errMsg: "配置验证失败", }, { name: "debug级别有效", modify: func(c *Config) { c.Log.Level = "debug" }, wantErr: false, }, { name: "warn级别有效", modify: func(c *Config) { c.Log.Level = "warn" }, wantErr: false, }, { name: "error级别有效", modify: func(c *Config) { c.Log.Level = "error" }, wantErr: false, }, { name: "数据库路径为空无效", modify: func(c *Config) { c.Database.Path = "" }, wantErr: true, errMsg: "配置验证失败", }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { cfg := DefaultConfig() tt.modify(cfg) err := cfg.Validate() if tt.wantErr { assert.Error(t, err) assert.Contains(t, err.Error(), tt.errMsg) } else { assert.NoError(t, err) } }) } } func TestGetConfigDir(t *testing.T) { dir, err := GetConfigDir() require.NoError(t, err) assert.NotEmpty(t, dir) assert.Contains(t, dir, ".nex") } func TestGetDBPath(t *testing.T) { path, err := GetDBPath() require.NoError(t, err) assert.NotEmpty(t, path) assert.Contains(t, path, "config.db") } func TestGetConfigPath(t *testing.T) { path, err := GetConfigPath() require.NoError(t, err) assert.NotEmpty(t, path) assert.Contains(t, path, "config.yaml") } func TestSaveAndLoadConfig(t *testing.T) { // 使用临时目录覆盖配置路径 dir := t.TempDir() cfg := &Config{ Server: ServerConfig{ Port: 9999, ReadTimeout: 10 * time.Second, WriteTimeout: 20 * time.Second, }, Database: DatabaseConfig{ Path: filepath.Join(dir, "test.db"), MaxIdleConns: 5, MaxOpenConns: 50, ConnMaxLifetime: 30 * time.Minute, }, Log: LogConfig{ Level: "debug", Path: filepath.Join(dir, "log"), MaxSize: 50, MaxBackups: 5, MaxAge: 7, Compress: false, }, } // 保存配置 configPath := filepath.Join(dir, "config.yaml") data, err := yaml.Marshal(cfg) require.NoError(t, err) err = os.WriteFile(configPath, data, 0644) require.NoError(t, err) // 加载配置 data, err = os.ReadFile(configPath) require.NoError(t, err) loaded := &Config{} err = yaml.Unmarshal(data, loaded) require.NoError(t, err) assert.Equal(t, cfg.Server.Port, loaded.Server.Port) assert.Equal(t, cfg.Log.Level, loaded.Log.Level) assert.Equal(t, cfg.Database.MaxIdleConns, loaded.Database.MaxIdleConns) assert.Equal(t, cfg.Log.Compress, loaded.Log.Compress) } func TestCLIConfig(t *testing.T) { // 测试 CLI 参数配置(简化版本) // 注意:由于 flag.Parse 只能调用一次,这里只测试配置加载流程 t.Run("配置加载流程", func(t *testing.T) { // 使用默认配置路径测试 cfg := DefaultConfig() require.NotNil(t, cfg) // 验证默认值正确 assert.Equal(t, 9826, cfg.Server.Port) assert.Equal(t, "info", cfg.Log.Level) }) } func TestEnvConfig(t *testing.T) { // 测试环境变量配置(简化版本) t.Run("环境变量前缀", func(t *testing.T) { // 验证环境变量前缀设置正确 // 实际的环境变量测试需要独立的进程,这里只验证配置结构 cfg := DefaultConfig() require.NotNil(t, cfg) assert.Equal(t, 9826, cfg.Server.Port) }) } func TestConfigPriority(t *testing.T) { // 测试配置优先级(简化版本) t.Run("默认值设置", func(t *testing.T) { cfg := DefaultConfig() require.NotNil(t, cfg) // 验证所有默认值 assert.Equal(t, 9826, cfg.Server.Port) assert.Equal(t, 30*time.Second, cfg.Server.ReadTimeout) assert.Equal(t, 30*time.Second, cfg.Server.WriteTimeout) assert.Equal(t, 10, cfg.Database.MaxIdleConns) assert.Equal(t, 100, cfg.Database.MaxOpenConns) assert.Equal(t, 1*time.Hour, cfg.Database.ConnMaxLifetime) assert.Equal(t, "info", cfg.Log.Level) assert.Equal(t, 100, cfg.Log.MaxSize) assert.Equal(t, 10, cfg.Log.MaxBackups) assert.Equal(t, 30, cfg.Log.MaxAge) assert.Equal(t, true, cfg.Log.Compress) }) } func TestPrintSummary(t *testing.T) { // 测试配置摘要输出 t.Run("打印配置摘要", func(t *testing.T) { cfg := DefaultConfig() // PrintSummary 只是打印,不会返回错误 // 这里主要验证不会 panic assert.NotPanics(t, func() { cfg.PrintSummary() }) }) }