package logging_test import ( "errors" "log/slog" "testing" "go.sudomsg.com/kit/logging" "go.sudomsg.com/kit/logging/test" ) func TestWithLogger_And_FromContext(t *testing.T) { ctx := t.Context() mock := test.NewMockLogHandler(t) logger := slog.New(mock) ctx = logging.WithLogger(ctx, logger) got := logging.FromContext(ctx) if got != logger { t.Errorf("expected logger from context to match original logger") } } func TestFromContext_DefaultFallback(t *testing.T) { ctx := t.Context() got := logging.FromContext(ctx) if got != slog.Default() { t.Errorf("expected default logger when no logger is in context") } } func TestRecoverAndLog(t *testing.T) { ctx := t.Context() mock := test.NewMockLogHandler(t) logger := slog.New(mock) ctx = logging.WithLogger(ctx, logger) err := errors.New("something broke") logging.RecoverAndLog(ctx, "panic recovered", err) records := mock.Records() if len(records) != 1 { t.Fatalf("expected 1 log record, got %d", len(records)) } record := records[0] if record.Message != "panic recovered" { t.Errorf("expected message 'panic recAvered', got %q", record.Message) } foundStack := false record.Attrs(func(a slog.Attr) bool { if a.Key == "stack" { foundStack = true } return true }) if !foundStack { t.Errorf("expected 'stack' attribute in log") } } func TestWith(t *testing.T) { ctx := t.Context() mock := test.NewMockLogHandler(t) logger := slog.New(mock) ctx = logging.WithLogger(ctx, logger) user := "user" id := "1234" logger2, newCtx := logging.With(ctx, "user", user, "id", id) logger2.InfoContext(ctx, "test message") records := mock.Records() if len(records) != 1 { t.Fatalf("expected 1 record, got %d", len(records)) } record := records[0] foundUser := false foundID := false record.Attrs(func(attr slog.Attr) bool { switch attr.Key { case "user": foundUser = attr.Value.String() == user case "id": foundID = attr.Value.String() == id } return true }) if !foundUser || !foundID { t.Errorf("expected 'user' and 'id' attributes in log record, %v", records) } // Test context carries logger with same attributes logFromCtx := logging.FromContext(newCtx) logFromCtx.InfoContext(ctx, "second message") if len(mock.Records()) != 2 { t.Errorf("expected 2 log records, got %d", len(mock.Records())) } } func TestWithGroup(t *testing.T) { ctx := t.Context() mock := test.NewMockLogHandler(t) logger := slog.New(mock) ctx = logging.WithLogger(ctx, logger) logger2, _ := logging.WithGroup(ctx, "foo") logger2.InfoContext(ctx, "test message", "key", "value") records := mock.Records() if len(records) != 1 { t.Fatalf("expected 1 record, got %d", len(records)) } record := records[0] var foundGroup bool record.Attrs(func(attr slog.Attr) bool { foundGroup = attr.Value.Kind() == slog.KindGroup return false }) if !foundGroup { t.Errorf("expected 'user' and 'id' attributes in log record, %v", records) } }