package zapx import ( "bytes" "testing" "time" "go.uber.org/zap" "go.uber.org/zap/zapcore" ) var ( eventTime = time.Date(2006, 1, 2, 15, 4, 5, 0, time.UTC) caller = func(zapcore.EntryCaller) string { return "" } ) func TestEncodeNestedObject(t *testing.T) { entry := zapcore.Entry{ Level: zapcore.InfoLevel, Time: eventTime, LoggerName: "", Message: "msg", Caller: zapcore.EntryCaller{}, Stack: "", } fields := []zapcore.Field{ zap.Object("a", zapcore.ObjectMarshalerFunc(func(oe zapcore.ObjectEncoder) error { oe.AddString("a1", "v1") oe.AddArray("b", zapcore.ArrayMarshalerFunc(func(ae zapcore.ArrayEncoder) error { ae.AppendString("b1") ae.AppendObject(zapcore.ObjectMarshalerFunc(func(oe zapcore.ObjectEncoder) error { oe.AddString("c1", "v2") return nil })) return nil })) return nil })), } encoder := NewEncoder("category", caller) buf, err := encoder.EncodeEntry(entry, fields) if err != nil { t.Fatal(err) } s := buf.String() want := `{"eventTime":"2006-01-02T15:04:05Z","category":"category","level":"info","caller":"","message":"msg","stringEntries":[{"key":"a.a1","value":"v1"},{"key":"a.b[0]","value":"b1"},{"key":"a.b[1].c1","value":"v2"}],"floatEntries":[],"intEntries":[],"boolEntries":[]}` if s != want { t.Errorf("log mismatch\n got %s\nwant %s", s, want) } } func TestEncodeInt(t *testing.T) { entry := zapcore.Entry{ Level: zapcore.InfoLevel, Time: eventTime, LoggerName: "", Message: "msg", Caller: zapcore.EntryCaller{}, Stack: "", } fields := []zapcore.Field{ zap.Int64("a1", 1), zap.Int64("b1", 2147483648), // 1 << 33 = max int32 + 1 zap.Int64("c1", 9007199254740993), // 1<<53+1 zap.Uint64("a2", 1), zap.Uint64("b2", 2147483648), // 1 << 33 = max int32 + 1 zap.Uint64("c2", 9007199254740993), // 1<<53+1 } encoder := NewEncoder("category", caller) buf, err := encoder.EncodeEntry(entry, fields) if err != nil { t.Fatal(err) } s := buf.String() want := `{"eventTime":"2006-01-02T15:04:05Z","category":"category","level":"info","caller":"","message":"msg","stringEntries":[{"key":"c1","value":"9007199254740993"},{"key":"c2","value":"9007199254740993"}],"floatEntries":[{"key":"b1","value":2147483648},{"key":"b2","value":2147483648}],"intEntries":[{"key":"a1","value":1},{"key":"a2","value":1}],"boolEntries":[]}` if s != want { t.Errorf("log mismatch\n got %s\nwant %s", s, want) } } func TestWith(t *testing.T) { var buf bytes.Buffer var clock mockClock encoder := NewEncoder("category", caller) core := zapcore.NewCore(encoder, zapcore.AddSync(&buf), zapcore.InfoLevel) logger := zap.New(core, zap.WithClock(clock)) logger = logger.With(zap.String("a", "b")) logger.Info("hello", zap.String("name", "world")) want := `{"eventTime":"2006-01-02T15:04:05Z","category":"category","level":"info","caller":"","message":"hello","stringEntries":[{"key":"a","value":"b"},{"key":"name","value":"world"}],"floatEntries":[],"intEntries":[],"boolEntries":[]}` s := buf.String() if s != want { t.Errorf("log mismatch\n got %s\nwant %s", s, want) } } func TestNameSpace(t *testing.T) { var buf bytes.Buffer var clock mockClock encoder := NewEncoder("category", caller) core := zapcore.NewCore(encoder, zapcore.AddSync(&buf), zapcore.InfoLevel) logger := zap.New(core, zap.WithClock(clock)) logger = logger.With(zap.Namespace("a"), zap.String("b", "c")) logger.Info("msg", zap.String("d", "e")) want := `{"eventTime":"2006-01-02T15:04:05Z","category":"category","level":"info","caller":"","message":"msg","stringEntries":[{"key":"a.b","value":"c"},{"key":"a.d","value":"e"}],"floatEntries":[],"intEntries":[],"boolEntries":[]}` s := buf.String() if s != want { t.Errorf("log mismatch\n got %s\nwant %s", s, want) } } type mockClock struct{} func (c mockClock) Now() time.Time { return eventTime } func (c mockClock) NewTicker(time.Duration) *time.Ticker { panic("not implemented") }