diff --git a/ctx_test.go b/ctx_test.go new file mode 100644 index 0000000..e4edf68 --- /dev/null +++ b/ctx_test.go @@ -0,0 +1,91 @@ +package slogcontext + +import ( + "bytes" + "context" + "log/slog" + "testing" +) + +func TestCtx(t *testing.T) { + t.Parallel() + + buf := &bytes.Buffer{} + h := slog.NewJSONHandler(buf, &slog.HandlerOptions{ + AddSource: false, + Level: slog.LevelDebug, + ReplaceAttr: func(groups []string, a slog.Attr) slog.Attr { + // fmt.Printf("ReplaceAttr: key:%s valueKind:%s value:%s nilGroups:%t groups:%#+v\n", a.Key, a.Value.Kind().String(), a.Value.String(), groups == nil, groups) + if groups == nil && a.Key == slog.TimeKey { + return slog.Time(slog.TimeKey, defaultTime) + } + return a + }, + }) + + ctx := ToCtx(context.Background(), slog.New(h)) + + ctx = With(ctx, "with1", "arg1", "with1", "arg2") + ctx = With(ctx, "with2", "arg1", "with2", "arg2") + With(ctx, "with3", "arg1", "with3", "arg2") // Ensure we aren't overwriting the parent context + + WithGroup(ctx, "group0") // Ensure we aren't overwriting the parent context + ctx = WithGroup(ctx, "group1") + WithGroup(ctx, "group2") // Ensure we aren't overwriting the parent context + + ctx = With(ctx, "with4", "arg1", "with4", "arg2") + ctx = With(ctx, "with5", "arg1", "with5", "arg2") + With(ctx, "with6", "arg1", "with6", "arg2") // Ensure we aren't overwriting the parent context + + // Test with getting logger back out + l := Logger(ctx) + l.InfoContext(ctx, "main message", "main1", "arg1", "main1", "arg2") + expectedInfo := `{"time":"2023-09-29T13:00:59Z","level":"INFO","msg":"main message","with1":"arg1","with1":"arg2","with2":"arg1","with2":"arg2","group1":{"with4":"arg1","with4":"arg2","with5":"arg1","with5":"arg2","main1":"arg1","main1":"arg2"}} +` + if buf.String() != expectedInfo { + t.Errorf("Expected:\n%s\nGot:\n%s\n", expectedInfo, buf.String()) + } + + // Test with wrappers + buf.Reset() + Debug(ctx, "main message", "main1", "arg1", "main1", "arg2") + expectedDebug := `{"time":"2023-09-29T13:00:59Z","level":"DEBUG","msg":"main message","with1":"arg1","with1":"arg2","with2":"arg1","with2":"arg2","group1":{"with4":"arg1","with4":"arg2","with5":"arg1","with5":"arg2","main1":"arg1","main1":"arg2"}} +` + if buf.String() != expectedDebug { + t.Errorf("Expected:\n%s\nGot:\n%s\n", expectedDebug, buf.String()) + } + + buf.Reset() + Info(ctx, "main message", "main1", "arg1", "main1", "arg2") + if buf.String() != expectedInfo { + t.Errorf("Expected:\n%s\nGot:\n%s\n", expectedInfo, buf.String()) + } + + buf.Reset() + Warn(ctx, "main message", "main1", "arg1", "main1", "arg2") + expectedWarn := `{"time":"2023-09-29T13:00:59Z","level":"WARN","msg":"main message","with1":"arg1","with1":"arg2","with2":"arg1","with2":"arg2","group1":{"with4":"arg1","with4":"arg2","with5":"arg1","with5":"arg2","main1":"arg1","main1":"arg2"}} +` + if buf.String() != expectedWarn { + t.Errorf("Expected:\n%s\nGot:\n%s\n", expectedWarn, buf.String()) + } + + buf.Reset() + Error(ctx, "main message", "main1", "arg1", "main1", "arg2") + expectedError := `{"time":"2023-09-29T13:00:59Z","level":"ERROR","msg":"main message","with1":"arg1","with1":"arg2","with2":"arg1","with2":"arg2","group1":{"with4":"arg1","with4":"arg2","with5":"arg1","with5":"arg2","main1":"arg1","main1":"arg2"}} +` + if buf.String() != expectedError { + t.Errorf("Expected:\n%s\nGot:\n%s\n", expectedError, buf.String()) + } + + buf.Reset() + Log(ctx, slog.LevelWarn, "main message", "main1", "arg1", "main1", "arg2") + if buf.String() != expectedWarn { + t.Errorf("Expected:\n%s\nGot:\n%s\n", expectedWarn, buf.String()) + } + + buf.Reset() + LogAttrs(ctx, slog.LevelInfo, "main message", slog.String("main1", "arg1"), slog.String("main1", "arg2")) + if buf.String() != expectedInfo { + t.Errorf("Expected:\n%s\nGot:\n%s\n", expectedInfo, buf.String()) + } +} diff --git a/handler_test.go b/handler_test.go index 26ccf78..dc3a8b8 100644 --- a/handler_test.go +++ b/handler_test.go @@ -15,24 +15,33 @@ func TestHandler(t *testing.T) { ctx := context.Background() ctx = Prepend(ctx, "prepend1", "arg1", "prepend1", "arg2") ctx = Prepend(ctx, "prepend2", "arg1", "prepend2", "arg2") + Prepend(ctx, "prepend3", "arg1", "prepend3", "arg2") // Ensure we aren't overwriting the parent context ctx = Append(ctx, "append1", "arg1", "append1", "arg2") ctx = Append(ctx, "append2", "arg1", "append2", "arg2") + Append(ctx, "append3", "arg1", "append3", "arg2") // Ensure we aren't overwriting the parent context - log := slog.New(h) + l := slog.New(h) - log = log.With("with1", "arg1", "with1", "arg2") - log = log.WithGroup("group1") - log = log.With("with2", "arg1", "with2", "arg2") + l = l.With("with1", "arg1", "with1", "arg2") + l = l.WithGroup("group1") + l = l.With("with2", "arg1", "with2", "arg2") - log.InfoContext(ctx, "main message", "main1", "arg1", "main1", "arg2") + l.InfoContext(ctx, "main message", "main1", "arg1", "main1", "arg2") - t.Log(tester.String()) - // time=2023-09-29T13:00:59.000Z level=INFO msg="main message" prepend1=arg1 prepend1=arg2 prepend2=arg1 prepend2=arg2 with1=arg1 with1=arg2 group1.with2=arg1 group1.with2=arg2 group1.main1=arg1 group1.main1=arg2 group1.append1=arg1 group1.append1=arg2 group1.append2=arg1 group1.append2=arg2 + expectedText := `time=2023-09-29T13:00:59.000Z level=INFO msg="main message" prepend1=arg1 prepend1=arg2 prepend2=arg1 prepend2=arg2 with1=arg1 with1=arg2 group1.with2=arg1 group1.with2=arg2 group1.main1=arg1 group1.main1=arg2 group1.append1=arg1 group1.append1=arg2 group1.append2=arg1 group1.append2=arg2 +` + if s := tester.String(); s != expectedText { + t.Errorf("Expected:\n%s\nGot:\n%s\n", expectedText, s) + } b, err := tester.MarshalJSON() if err != nil { t.Fatal(err) } - t.Log(string(b)) - // {"time":"2023-09-29T13:00:59Z","level":"INFO","msg":"main message","prepend1":"arg1","prepend1":"arg2","prepend2":"arg1","prepend2":"arg2","with1":"arg1","with1":"arg2","group1":{"with2":"arg1","with2":"arg2","main1":"arg1","main1":"arg2","append1":"arg1","append1":"arg2","append2":"arg1","append2":"arg2"}} + + expectedJSON := `{"time":"2023-09-29T13:00:59Z","level":"INFO","msg":"main message","prepend1":"arg1","prepend1":"arg2","prepend2":"arg1","prepend2":"arg2","with1":"arg1","with1":"arg2","group1":{"with2":"arg1","with2":"arg2","main1":"arg1","main1":"arg2","append1":"arg1","append1":"arg2","append2":"arg1","append2":"arg2"}} +` + if string(b) != expectedJSON { + t.Errorf("Expected:\n%s\nGot:\n%s\n", expectedText, string(b)) + } } diff --git a/helpers_test.go b/helpers_test.go index 5ebfdad..28b6a05 100644 --- a/helpers_test.go +++ b/helpers_test.go @@ -7,6 +7,8 @@ import ( "time" ) +var defaultTime = time.Date(2023, 9, 29, 13, 0, 59, 0, time.UTC) + type testHandler struct { Ctx context.Context Record slog.Record @@ -19,7 +21,7 @@ func (h *testHandler) Enabled(context.Context, slog.Level) bool { func (h *testHandler) Handle(ctx context.Context, r slog.Record) error { h.Ctx = ctx h.Record = r - h.Record.Time = time.Date(2023, 9, 29, 13, 0, 59, 0, time.UTC) + h.Record.Time = defaultTime return nil }