package logging import ( "bytes" "os" "path/filepath" "strings" "testing" ) func TestSetupStdout(t *testing.T) { file, err := Setup("stdout") if err != nil { t.Fatalf("Setup(stdout) failed: %v", err) } if file != nil { t.Error("Expected nil file for stdout") } } func TestSetupStderr(t *testing.T) { file, err := Setup("stderr") if err != nil { t.Fatalf("Setup(stderr) failed: %v", err) } if file != nil { t.Error("Expected nil file for stderr") } } func TestSetupEmpty(t *testing.T) { file, err := Setup("") if err != nil { t.Fatalf("Setup('') failed: %v", err) } if file != nil { t.Error("Expected nil file for empty string") } } func TestSetupFilePath(t *testing.T) { tmpDir := t.TempDir() logPath := filepath.Join(tmpDir, "test.log") file, err := Setup(logPath) if err != nil { t.Fatalf("Setup(file) failed: %v", err) } if file == nil { t.Fatal("Expected non-nil file for file path") } defer file.Close() // Verify file was created if _, err := os.Stat(logPath); os.IsNotExist(err) { t.Error("Expected log file to be created") } } func TestSetupInvalidPath(t *testing.T) { _, err := Setup("/nonexistent/directory/path/test.log") if err == nil { t.Error("Expected error for invalid path") } } func TestNewLoggerDefaultLevel(t *testing.T) { var buf bytes.Buffer logger := NewLogger("", &buf) if logger.level != LevelInfo { t.Errorf("Expected default level Info, got %d", logger.level) } } func TestNewLoggerInvalidLevel(t *testing.T) { var buf bytes.Buffer logger := NewLogger("invalid", &buf) if logger.level != LevelInfo { t.Errorf("Expected default level Info for invalid input, got %d", logger.level) } } func TestNewLoggerDebugLevel(t *testing.T) { var buf bytes.Buffer logger := NewLogger("debug", &buf) if logger.level != LevelDebug { t.Errorf("Expected level Debug, got %d", logger.level) } } func TestNewLoggerWarnLevel(t *testing.T) { var buf bytes.Buffer logger := NewLogger("warn", &buf) if logger.level != LevelWarn { t.Errorf("Expected level Warn, got %d", logger.level) } } func TestNewLoggerErrorLevel(t *testing.T) { var buf bytes.Buffer logger := NewLogger("error", &buf) if logger.level != LevelError { t.Errorf("Expected level Error, got %d", logger.level) } } func TestLoggerDebugOutputAtDebugLevel(t *testing.T) { var buf bytes.Buffer logger := NewLogger("debug", &buf) logger.Debug("test message") output := buf.String() if !strings.Contains(output, "[DEBUG]") { t.Errorf("Expected [DEBUG] prefix, got: %s", output) } if !strings.Contains(output, "test message") { t.Errorf("Expected 'test message' in output, got: %s", output) } } func TestLoggerDebugSuppressedAtInfoLevel(t *testing.T) { var buf bytes.Buffer logger := NewLogger("info", &buf) logger.Debug("should not appear") output := buf.String() if output != "" { t.Errorf("Expected no output for debug at info level, got: %s", output) } } func TestLoggerInfoOutputAtInfoLevel(t *testing.T) { var buf bytes.Buffer logger := NewLogger("info", &buf) logger.Info("info message") output := buf.String() if !strings.Contains(output, "[INFO]") { t.Errorf("Expected [INFO] prefix, got: %s", output) } if !strings.Contains(output, "info message") { t.Errorf("Expected 'info message' in output, got: %s", output) } } func TestLoggerInfoSuppressedAtWarnLevel(t *testing.T) { var buf bytes.Buffer logger := NewLogger("warn", &buf) logger.Info("should not appear") output := buf.String() if output != "" { t.Errorf("Expected no output for info at warn level, got: %s", output) } } func TestLoggerWarnOutputAtWarnLevel(t *testing.T) { var buf bytes.Buffer logger := NewLogger("warn", &buf) logger.Warn("warn message") output := buf.String() if !strings.Contains(output, "[WARN]") { t.Errorf("Expected [WARN] prefix, got: %s", output) } if !strings.Contains(output, "warn message") { t.Errorf("Expected 'warn message' in output, got: %s", output) } } func TestLoggerWarnSuppressedAtErrorLevel(t *testing.T) { var buf bytes.Buffer logger := NewLogger("error", &buf) logger.Warn("should not appear") output := buf.String() if output != "" { t.Errorf("Expected no output for warn at error level, got: %s", output) } } func TestLoggerErrorOutputAtErrorLevel(t *testing.T) { var buf bytes.Buffer logger := NewLogger("error", &buf) logger.Error("error message") output := buf.String() if !strings.Contains(output, "[ERROR]") { t.Errorf("Expected [ERROR] prefix, got: %s", output) } if !strings.Contains(output, "error message") { t.Errorf("Expected 'error message' in output, got: %s", output) } } func TestLoggerErrorAlwaysOutputs(t *testing.T) { var buf bytes.Buffer logger := NewLogger("error", &buf) logger.Error("critical failure") output := buf.String() if !strings.Contains(output, "critical failure") { t.Errorf("Expected error message in output, got: %s", output) } } func TestLoggerDebugLevelAllMessages(t *testing.T) { var buf bytes.Buffer logger := NewLogger("debug", &buf) logger.Debug("d") logger.Info("i") logger.Warn("w") logger.Error("e") output := buf.String() if !strings.Contains(output, "[DEBUG]") { t.Error("Expected [DEBUG] in output") } if !strings.Contains(output, "[INFO]") { t.Error("Expected [INFO] in output") } if !strings.Contains(output, "[WARN]") { t.Error("Expected [WARN] in output") } if !strings.Contains(output, "[ERROR]") { t.Error("Expected [ERROR] in output") } } func TestLoggerFormatf(t *testing.T) { var buf bytes.Buffer logger := NewLogger("info", &buf) logger.Infof("count: %d", 42) output := buf.String() if !strings.Contains(output, "count: 42") { t.Errorf("Expected formatted output 'count: 42', got: %s", output) } } func TestLoggerLevelCaseInsensitive(t *testing.T) { var buf bytes.Buffer logger := NewLogger("DEBUG", &buf) if logger.level != LevelDebug { t.Errorf("Expected level Debug for 'DEBUG', got %d", logger.level) } logger = NewLogger("Info", &buf) if logger.level != LevelInfo { t.Errorf("Expected level Info for 'Info', got %d", logger.level) } logger = NewLogger("WARN", &buf) if logger.level != LevelWarn { t.Errorf("Expected level Warn for 'WARN', got %d", logger.level) } logger = NewLogger("ERROR", &buf) if logger.level != LevelError { t.Errorf("Expected level Error for 'ERROR', got %d", logger.level) } }