package ezconf import ( "testing" ) func TestParseEzconfTag(t *testing.T) { tests := []struct { name string tag string wantEnvVar *EnvVar expectError bool }{ { name: "simple env variable", tag: "LOG_LEVEL,description:Log level for the application", wantEnvVar: &EnvVar{ Name: "LOG_LEVEL", Description: "Log level for the application", Required: false, Default: "", }, expectError: false, }, { name: "env variable with default", tag: "LOG_LEVEL,description:Log level for the application,default:info", wantEnvVar: &EnvVar{ Name: "LOG_LEVEL", Description: "Log level for the application", Required: false, Default: "info", }, expectError: false, }, { name: "required env variable", tag: "DATABASE_URL,description:Database connection string,required", wantEnvVar: &EnvVar{ Name: "DATABASE_URL", Description: "Database connection string", Required: true, Default: "", }, expectError: false, }, { name: "required with condition and default", tag: "LOG_DIR,description:Directory for log files,required:when LOG_OUTPUT is file,default:/var/log", wantEnvVar: &EnvVar{ Name: "LOG_DIR", Description: "Directory for log files (required when LOG_OUTPUT is file)", Required: true, Default: "/var/log", }, expectError: false, }, { name: "name only", tag: "SIMPLE_VAR", wantEnvVar: &EnvVar{ Name: "SIMPLE_VAR", Description: "", Required: false, Default: "", }, expectError: false, }, { name: "empty tag", tag: "", wantEnvVar: nil, expectError: true, }, { name: "empty name", tag: ",description:some desc", wantEnvVar: nil, expectError: true, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { envVar, err := parseEzconfTag(tt.tag) if tt.expectError { if err == nil { t.Errorf("expected error but got none") } return } if err != nil { t.Errorf("unexpected error: %v", err) return } if envVar.Name != tt.wantEnvVar.Name { t.Errorf("Name = %v, want %v", envVar.Name, tt.wantEnvVar.Name) } if envVar.Description != tt.wantEnvVar.Description { t.Errorf("Description = %v, want %v", envVar.Description, tt.wantEnvVar.Description) } if envVar.Required != tt.wantEnvVar.Required { t.Errorf("Required = %v, want %v", envVar.Required, tt.wantEnvVar.Required) } if envVar.Default != tt.wantEnvVar.Default { t.Errorf("Default = %v, want %v", envVar.Default, tt.wantEnvVar.Default) } }) } } func TestParseConfigStruct(t *testing.T) { type TestConfig struct { LogLevel string `ezconf:"LOG_LEVEL,description:Log level for the application,default:info"` LogOutput string `ezconf:"LOG_OUTPUT,description:Output destination,default:console"` DatabaseURL string `ezconf:"DATABASE_URL,description:Database connection string,required"` NoTag string } envVars, err := ParseConfigStruct(&TestConfig{}) if err != nil { t.Fatalf("ParseConfigStruct failed: %v", err) } if len(envVars) != 3 { t.Errorf("expected 3 env vars, got %d", len(envVars)) } // Check first variable if envVars[0].Name != "LOG_LEVEL" { t.Errorf("expected LOG_LEVEL, got %s", envVars[0].Name) } if envVars[0].Default != "info" { t.Errorf("expected default 'info', got %s", envVars[0].Default) } // Check required variable if envVars[2].Name != "DATABASE_URL" { t.Errorf("expected DATABASE_URL, got %s", envVars[2].Name) } if !envVars[2].Required { t.Error("expected DATABASE_URL to be required") } } func TestParseConfigStruct_NilPointer(t *testing.T) { _, err := ParseConfigStruct(nil) if err == nil { t.Error("expected error for nil pointer") } } func TestParseConfigStruct_NotPointer(t *testing.T) { type TestConfig struct { Foo string `ezconf:"FOO,description:test"` } _, err := ParseConfigStruct(TestConfig{}) if err == nil { t.Error("expected error for non-pointer") } } func TestParseConfigStruct_NotStruct(t *testing.T) { str := "not a struct" _, err := ParseConfigStruct(&str) if err == nil { t.Error("expected error for non-struct pointer") } } func TestParseConfigStruct_NoTags(t *testing.T) { type EmptyConfig struct { Foo string Bar int } envVars, err := ParseConfigStruct(&EmptyConfig{}) if err != nil { t.Fatalf("ParseConfigStruct failed: %v", err) } if len(envVars) != 0 { t.Errorf("expected 0 env vars for struct with no tags, got %d", len(envVars)) } } func TestParseConfigStruct_UnexportedFields(t *testing.T) { type TestConfig struct { exported string `ezconf:"EXPORTED,description:An exported field"` unexported string `ezconf:"UNEXPORTED,description:An unexported field"` } envVars, err := ParseConfigStruct(&TestConfig{}) if err != nil { t.Fatalf("ParseConfigStruct failed: %v", err) } if len(envVars) != 2 { t.Errorf("expected 2 env vars (both exported and unexported), got %d", len(envVars)) } } func TestParseConfigStruct_InvalidTag(t *testing.T) { type TestConfig struct { Bad string `ezconf:",description:missing name"` } _, err := ParseConfigStruct(&TestConfig{}) if err == nil { t.Error("expected error for invalid tag") } }