package ezconf import ( "os" "path/filepath" "testing" ) func TestParseEnvComment(t *testing.T) { tests := []struct { name string comment string wantEnvVar *EnvVar expectError bool }{ { name: "simple env variable", comment: "ENV LOG_LEVEL: 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", comment: "ENV LOG_LEVEL: 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", comment: "ENV DATABASE_URL: Database connection string (required)", wantEnvVar: &EnvVar{ Name: "DATABASE_URL", Description: "Database connection string", Required: true, Default: "", }, expectError: false, }, { name: "required with condition and default", comment: "ENV LOG_DIR: Directory for log files (required when LOG_OUTPUT is file) (default: /var/log)", wantEnvVar: &EnvVar{ Name: "LOG_DIR", Description: "Directory for log files", Required: true, Default: "/var/log", }, expectError: false, }, { name: "missing colon", comment: "ENV LOG_LEVEL Log level", wantEnvVar: nil, expectError: true, }, { name: "not an ENV comment", comment: "This is a regular comment", wantEnvVar: nil, expectError: true, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { envVar, err := parseEnvComment(tt.comment) 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 TestParseConfigFile(t *testing.T) { // Create a temporary test file tempDir := t.TempDir() testFile := filepath.Join(tempDir, "config.go") content := `package testpkg type Config struct { // ENV LOG_LEVEL: Log level for the application (default: info) LogLevel string // ENV LOG_OUTPUT: Output destination (default: console) LogOutput string // ENV DATABASE_URL: Database connection string (required) DatabaseURL string } ` if err := os.WriteFile(testFile, []byte(content), 0644); err != nil { t.Fatalf("failed to create test file: %v", err) } envVars, err := ParseConfigFile(testFile) if err != nil { t.Fatalf("ParseConfigFile 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 TestParseConfigPackage(t *testing.T) { // Test with actual hlog package hlogPath := filepath.Join("..", "hlog") if _, err := os.Stat(hlogPath); os.IsNotExist(err) { t.Skip("hlog package not found, skipping integration test") } envVars, err := ParseConfigPackage(hlogPath) if err != nil { t.Fatalf("ParseConfigPackage failed: %v", err) } if len(envVars) == 0 { t.Error("expected at least one env var from hlog package") } // Check for known hlog variables foundLogLevel := false for _, envVar := range envVars { if envVar.Name == "LOG_LEVEL" { foundLogLevel = true t.Logf("Found LOG_LEVEL: %s", envVar.Description) } } if !foundLogLevel { t.Error("expected to find LOG_LEVEL in hlog package") } } func TestParseConfigFile_InvalidFile(t *testing.T) { _, err := ParseConfigFile("/nonexistent/file.go") if err == nil { t.Error("expected error for nonexistent file") } } func TestParseConfigPackage_InvalidPath(t *testing.T) { envVars, err := ParseConfigPackage("/nonexistent/package") if err != nil { t.Fatalf("ParseConfigPackage should not error on invalid path: %v", err) } // Should return empty slice for invalid path if len(envVars) != 0 { t.Errorf("expected 0 env vars for invalid path, got %d", len(envVars)) } }