package logging import ( "testing" "github.com/konduktor/konduktor/internal/config" ) func TestNew(t *testing.T) { logger, err := New(Config{Level: "INFO"}) if err != nil { t.Errorf("Unexpected error: %v", err) } if logger == nil { t.Fatal("Expected logger, got nil") } if logger.name != "konduktor" { t.Errorf("Expected name konduktor, got %s", logger.name) } } func TestNew_DefaultTimestampFormat(t *testing.T) { logger, err := New(Config{Level: "DEBUG"}) if err != nil { t.Fatalf("Unexpected error: %v", err) } // Logger should be created successfully if logger == nil { t.Fatal("Expected logger, got nil") } } func TestNew_CustomTimestampFormat(t *testing.T) { logger, err := New(Config{ Level: "DEBUG", TimestampFormat: "15:04:05", }) if err != nil { t.Fatalf("Unexpected error: %v", err) } if logger == nil { t.Fatal("Expected logger, got nil") } } func TestNewFromConfig(t *testing.T) { cfg := config.LoggingConfig{ Level: "DEBUG", ConsoleOutput: true, Format: config.LogFormatConfig{ Type: "standard", UseColors: true, ShowModule: true, TimestampFormat: "2006-01-02 15:04:05", }, } logger, err := NewFromConfig(cfg) if err != nil { t.Fatalf("Unexpected error: %v", err) } if logger == nil { t.Fatal("Expected logger, got nil") } } func TestNewFromConfig_WithConsole(t *testing.T) { cfg := config.LoggingConfig{ Level: "INFO", ConsoleOutput: true, Format: config.LogFormatConfig{ Type: "standard", UseColors: true, }, Console: &config.ConsoleLogConfig{ Level: "DEBUG", Format: config.LogFormatConfig{ Type: "standard", UseColors: false, }, }, } logger, err := NewFromConfig(cfg) if err != nil { t.Fatalf("Unexpected error: %v", err) } if logger == nil { t.Fatal("Expected logger, got nil") } } func TestLogger_Debug(t *testing.T) { logger, _ := New(Config{Level: "DEBUG"}) // Should not panic logger.Debug("test message", "key", "value") } func TestLogger_Info(t *testing.T) { logger, _ := New(Config{Level: "INFO"}) // Should not panic logger.Info("test message", "key", "value") } func TestLogger_Warn(t *testing.T) { logger, _ := New(Config{Level: "WARN"}) // Should not panic logger.Warn("test message", "key", "value") } func TestLogger_Error(t *testing.T) { logger, _ := New(Config{Level: "ERROR"}) // Should not panic logger.Error("test message", "key", "value") } func TestLogger_Named(t *testing.T) { logger, _ := New(Config{Level: "INFO"}) named := logger.Named("test.module") if named == nil { t.Fatal("Expected named logger, got nil") } if named.name != "test.module" { t.Errorf("Expected name 'test.module', got %s", named.name) } // Should not panic named.Info("test from named logger") } func TestLogger_With(t *testing.T) { logger, _ := New(Config{Level: "INFO"}) withFields := logger.With("service", "test") if withFields == nil { t.Fatal("Expected logger with fields, got nil") } // Should not panic withFields.Info("test with fields") } func TestLogger_Sync(t *testing.T) { logger, _ := New(Config{Level: "INFO"}) // Should not panic err := logger.Sync() // Sync may return an error for stdout on some systems, ignore it _ = err } func TestParseLevel(t *testing.T) { tests := []struct { input string expected string }{ {"DEBUG", "debug"}, {"INFO", "info"}, {"WARN", "warn"}, {"WARNING", "warn"}, {"ERROR", "error"}, {"CRITICAL", "fatal"}, {"FATAL", "fatal"}, {"invalid", "info"}, // defaults to INFO } for _, tt := range tests { t.Run(tt.input, func(t *testing.T) { level := parseLevel(tt.input) if level.String() != tt.expected { t.Errorf("parseLevel(%s) = %s, want %s", tt.input, level.String(), tt.expected) } }) } } // ============== Benchmarks ============== func BenchmarkLogger_Info(b *testing.B) { logger, _ := New(Config{Level: "INFO"}) b.ResetTimer() for i := 0; i < b.N; i++ { logger.Info("test message", "key", "value") } } func BenchmarkLogger_Debug_Filtered(b *testing.B) { logger, _ := New(Config{Level: "ERROR"}) b.ResetTimer() for i := 0; i < b.N; i++ { logger.Debug("test message", "key", "value") } }