package helper import ( "bytes" "errors" "log" "os" "strings" "testing" ) func TestLogInfo(t *testing.T) { tests := []struct { name string goEnv string message string wantLog bool }{ { name: "Development environment", goEnv: "development", message: "Test info message", wantLog: true, }, { name: "Debug environment", goEnv: "debug", message: "Test info message", wantLog: true, }, { name: "Production environment", goEnv: "production", message: "Test info message", wantLog: true, }, { name: "Canary environment", goEnv: "canary", message: "Test info message", wantLog: true, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { // Setup os.Setenv("GO_ENV", tt.goEnv) defer os.Unsetenv("GO_ENV") // Capture log output var buf bytes.Buffer log.SetOutput(&buf) defer log.SetOutput(os.Stderr) // Execute LogInfo(tt.message) // Assert logOutput := buf.String() if tt.wantLog && !strings.Contains(logOutput, "INFO:") { t.Errorf("Expected log output to contain 'INFO:', got: %s", logOutput) } if tt.wantLog && !strings.Contains(logOutput, tt.message) { t.Errorf("Expected log output to contain '%s', got: %s", tt.message, logOutput) } }) } } func TestLogInfoNoEnvironment(t *testing.T) { // Setup os.Unsetenv("GO_ENV") // Capture log output and expect panic/fatal defer func() { if r := recover(); r == nil { // log.Fatal will exit the program, so we can't really test it directly // But we can ensure it would be called by testing the condition } }() // This will call log.Fatal which exits, so we need to test it differently // For now, we'll just ensure the function exists } func TestLogWarn(t *testing.T) { tests := []struct { name string goEnv string message string wantLog bool }{ { name: "Development environment", goEnv: "development", message: "Test warning message", wantLog: true, }, { name: "Debug environment", goEnv: "debug", message: "Test warning message", wantLog: true, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { // Setup os.Setenv("GO_ENV", tt.goEnv) defer os.Unsetenv("GO_ENV") // Capture log output var buf bytes.Buffer log.SetOutput(&buf) defer log.SetOutput(os.Stderr) // Execute LogWarn(tt.message) // Assert logOutput := buf.String() if tt.wantLog && !strings.Contains(logOutput, "WARNING:") { t.Errorf("Expected log output to contain 'WARNING:', got: %s", logOutput) } if tt.wantLog && !strings.Contains(logOutput, tt.message) { t.Errorf("Expected log output to contain '%s', got: %s", tt.message, logOutput) } }) } } func TestLogError(t *testing.T) { tests := []struct { name string goEnv string err error message string wantLog bool }{ { name: "Development with error", goEnv: "development", err: errors.New("test error"), message: "Test error message", wantLog: true, }, { name: "Development without error", goEnv: "development", err: nil, message: "Test error message", wantLog: true, }, { name: "Debug with error", goEnv: "debug", err: errors.New("test error"), message: "Test error message", wantLog: true, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { // Setup os.Setenv("GO_ENV", tt.goEnv) defer os.Unsetenv("GO_ENV") // Capture log output var buf bytes.Buffer log.SetOutput(&buf) defer log.SetOutput(os.Stderr) // Execute LogError(tt.err, tt.message) // Assert logOutput := buf.String() if tt.wantLog && !strings.Contains(logOutput, "ERROR:") { t.Errorf("Expected log output to contain 'ERROR:', got: %s", logOutput) } if tt.wantLog && !strings.Contains(logOutput, tt.message) { t.Errorf("Expected log output to contain '%s', got: %s", tt.message, logOutput) } }) } } func TestLogErrorWithNilError(t *testing.T) { // Setup os.Setenv("GO_ENV", "development") defer os.Unsetenv("GO_ENV") // Capture log output var buf bytes.Buffer log.SetOutput(&buf) defer log.SetOutput(os.Stderr) // Execute LogError(nil, "Message without error") // Assert logOutput := buf.String() if !strings.Contains(logOutput, "ERROR:") { t.Errorf("Expected log output to contain 'ERROR:', got: %s", logOutput) } } func TestLogFatal(t *testing.T) { // Note: We cannot properly test log.Fatal as it calls os.Exit // This test just ensures the function signature is correct // In a real scenario, you'd use a testing framework that can capture os.Exit t.Run("Function exists", func(t *testing.T) { // Just verify the function exists and is callable // We won't actually call it to avoid exiting the test // Verify the function signature is correct var _ func(error, string) = LogFatal // If this compiles, the function signature is correct t.Log("LogFatal function signature is correct") }) } func TestLoggingEnvironmentCheck(t *testing.T) { // Test that all logging functions check for GO_ENV originalEnv := os.Getenv("GO_ENV") defer func() { if originalEnv != "" { os.Setenv("GO_ENV", originalEnv) } }() tests := []struct { name string testFunc func() }{ { name: "LogInfo", testFunc: func() { os.Setenv("GO_ENV", "development") var buf bytes.Buffer log.SetOutput(&buf) defer log.SetOutput(os.Stderr) LogInfo("test") }, }, { name: "LogWarn", testFunc: func() { os.Setenv("GO_ENV", "development") var buf bytes.Buffer log.SetOutput(&buf) defer log.SetOutput(os.Stderr) LogWarn("test") }, }, { name: "LogError", testFunc: func() { os.Setenv("GO_ENV", "development") var buf bytes.Buffer log.SetOutput(&buf) defer log.SetOutput(os.Stderr) LogError(nil, "test") }, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { // This should not panic when GO_ENV is set tt.testFunc() }) } }