...

Source file src/github.com/rs/zerolog/log_test.go

Documentation: github.com/rs/zerolog

     1  package zerolog
     2  
     3  import (
     4  	"bytes"
     5  	"errors"
     6  	"fmt"
     7  	"net"
     8  	"reflect"
     9  	"runtime"
    10  	"strconv"
    11  	"strings"
    12  	"testing"
    13  	"time"
    14  )
    15  
    16  func TestLog(t *testing.T) {
    17  	t.Run("empty", func(t *testing.T) {
    18  		out := &bytes.Buffer{}
    19  		log := New(out)
    20  		log.Log().Msg("")
    21  		if got, want := decodeIfBinaryToString(out.Bytes()), "{}\n"; got != want {
    22  			t.Errorf("invalid log output:\ngot:  %v\nwant: %v", got, want)
    23  		}
    24  	})
    25  
    26  	t.Run("one-field", func(t *testing.T) {
    27  		out := &bytes.Buffer{}
    28  		log := New(out)
    29  		log.Log().Str("foo", "bar").Msg("")
    30  		if got, want := decodeIfBinaryToString(out.Bytes()), `{"foo":"bar"}`+"\n"; got != want {
    31  			t.Errorf("invalid log output:\ngot:  %v\nwant: %v", got, want)
    32  		}
    33  	})
    34  
    35  	t.Run("two-field", func(t *testing.T) {
    36  		out := &bytes.Buffer{}
    37  		log := New(out)
    38  		log.Log().
    39  			Str("foo", "bar").
    40  			Int("n", 123).
    41  			Msg("")
    42  		if got, want := decodeIfBinaryToString(out.Bytes()), `{"foo":"bar","n":123}`+"\n"; got != want {
    43  			t.Errorf("invalid log output:\ngot:  %v\nwant: %v", got, want)
    44  		}
    45  	})
    46  }
    47  
    48  func TestInfo(t *testing.T) {
    49  	t.Run("empty", func(t *testing.T) {
    50  		out := &bytes.Buffer{}
    51  		log := New(out)
    52  		log.Info().Msg("")
    53  		if got, want := decodeIfBinaryToString(out.Bytes()), `{"level":"info"}`+"\n"; got != want {
    54  			t.Errorf("invalid log output:\ngot:  %v\nwant: %v", got, want)
    55  		}
    56  	})
    57  
    58  	t.Run("one-field", func(t *testing.T) {
    59  		out := &bytes.Buffer{}
    60  		log := New(out)
    61  		log.Info().Str("foo", "bar").Msg("")
    62  		if got, want := decodeIfBinaryToString(out.Bytes()), `{"level":"info","foo":"bar"}`+"\n"; got != want {
    63  			t.Errorf("invalid log output:\ngot:  %v\nwant: %v", got, want)
    64  		}
    65  	})
    66  
    67  	t.Run("two-field", func(t *testing.T) {
    68  		out := &bytes.Buffer{}
    69  		log := New(out)
    70  		log.Info().
    71  			Str("foo", "bar").
    72  			Int("n", 123).
    73  			Msg("")
    74  		if got, want := decodeIfBinaryToString(out.Bytes()), `{"level":"info","foo":"bar","n":123}`+"\n"; got != want {
    75  			t.Errorf("invalid log output:\ngot:  %v\nwant: %v", got, want)
    76  		}
    77  	})
    78  }
    79  
    80  func TestEmptyLevelFieldName(t *testing.T) {
    81  	fieldName := LevelFieldName
    82  	LevelFieldName = ""
    83  
    84  	t.Run("empty setting", func(t *testing.T) {
    85  		out := &bytes.Buffer{}
    86  		log := New(out)
    87  		log.Info().
    88  			Str("foo", "bar").
    89  			Int("n", 123).
    90  			Msg("")
    91  		if got, want := decodeIfBinaryToString(out.Bytes()), `{"foo":"bar","n":123}`+"\n"; got != want {
    92  			t.Errorf("invalid log output:\ngot:  %v\nwant: %v", got, want)
    93  		}
    94  	})
    95  	LevelFieldName = fieldName
    96  }
    97  
    98  func TestWith(t *testing.T) {
    99  	out := &bytes.Buffer{}
   100  	ctx := New(out).With().
   101  		Str("string", "foo").
   102  		Stringer("stringer", net.IP{127, 0, 0, 1}).
   103  		Stringer("stringer_nil", nil).
   104  		Bytes("bytes", []byte("bar")).
   105  		Hex("hex", []byte{0x12, 0xef}).
   106  		RawJSON("json", []byte(`{"some":"json"}`)).
   107  		AnErr("some_err", nil).
   108  		Err(errors.New("some error")).
   109  		Bool("bool", true).
   110  		Int("int", 1).
   111  		Int8("int8", 2).
   112  		Int16("int16", 3).
   113  		Int32("int32", 4).
   114  		Int64("int64", 5).
   115  		Uint("uint", 6).
   116  		Uint8("uint8", 7).
   117  		Uint16("uint16", 8).
   118  		Uint32("uint32", 9).
   119  		Uint64("uint64", 10).
   120  		Float32("float32", 11.101).
   121  		Float64("float64", 12.30303).
   122  		Time("time", time.Time{})
   123  	_, file, line, _ := runtime.Caller(0)
   124  	caller := fmt.Sprintf("%s:%d", file, line+3)
   125  	log := ctx.Caller().Logger()
   126  	log.Log().Msg("")
   127  	if got, want := decodeIfBinaryToString(out.Bytes()), `{"string":"foo","stringer":"127.0.0.1","stringer_nil":null,"bytes":"bar","hex":"12ef","json":{"some":"json"},"error":"some error","bool":true,"int":1,"int8":2,"int16":3,"int32":4,"int64":5,"uint":6,"uint8":7,"uint16":8,"uint32":9,"uint64":10,"float32":11.101,"float64":12.30303,"time":"0001-01-01T00:00:00Z","caller":"`+caller+`"}`+"\n"; got != want {
   128  		t.Errorf("invalid log output:\ngot:  %v\nwant: %v", got, want)
   129  	}
   130  
   131  	// Validate CallerWithSkipFrameCount.
   132  	out.Reset()
   133  	_, file, line, _ = runtime.Caller(0)
   134  	caller = fmt.Sprintf("%s:%d", file, line+5)
   135  	log = ctx.CallerWithSkipFrameCount(3).Logger()
   136  	func() {
   137  		log.Log().Msg("")
   138  	}()
   139  	// The above line is a little contrived, but the line above should be the line due
   140  	// to the extra frame skip.
   141  	if got, want := decodeIfBinaryToString(out.Bytes()), `{"string":"foo","stringer":"127.0.0.1","stringer_nil":null,"bytes":"bar","hex":"12ef","json":{"some":"json"},"error":"some error","bool":true,"int":1,"int8":2,"int16":3,"int32":4,"int64":5,"uint":6,"uint8":7,"uint16":8,"uint32":9,"uint64":10,"float32":11.101,"float64":12.30303,"time":"0001-01-01T00:00:00Z","caller":"`+caller+`"}`+"\n"; got != want {
   142  		t.Errorf("invalid log output:\ngot:  %v\nwant: %v", got, want)
   143  	}
   144  }
   145  
   146  func TestFieldsMap(t *testing.T) {
   147  	out := &bytes.Buffer{}
   148  	log := New(out)
   149  	log.Log().Fields(map[string]interface{}{
   150  		"nil":     nil,
   151  		"string":  "foo",
   152  		"bytes":   []byte("bar"),
   153  		"error":   errors.New("some error"),
   154  		"bool":    true,
   155  		"int":     int(1),
   156  		"int8":    int8(2),
   157  		"int16":   int16(3),
   158  		"int32":   int32(4),
   159  		"int64":   int64(5),
   160  		"uint":    uint(6),
   161  		"uint8":   uint8(7),
   162  		"uint16":  uint16(8),
   163  		"uint32":  uint32(9),
   164  		"uint64":  uint64(10),
   165  		"float32": float32(11),
   166  		"float64": float64(12),
   167  		"ipv6":    net.IP{0x20, 0x01, 0x0d, 0xb8, 0x85, 0xa3, 0x00, 0x00, 0x00, 0x00, 0x8a, 0x2e, 0x03, 0x70, 0x73, 0x34},
   168  		"dur":     1 * time.Second,
   169  		"time":    time.Time{},
   170  		"obj":     obj{"a", "b", 1},
   171  	}).Msg("")
   172  	if got, want := decodeIfBinaryToString(out.Bytes()), `{"bool":true,"bytes":"bar","dur":1000,"error":"some error","float32":11,"float64":12,"int":1,"int16":3,"int32":4,"int64":5,"int8":2,"ipv6":"2001:db8:85a3::8a2e:370:7334","nil":null,"obj":{"Pub":"a","Tag":"b","priv":1},"string":"foo","time":"0001-01-01T00:00:00Z","uint":6,"uint16":8,"uint32":9,"uint64":10,"uint8":7}`+"\n"; got != want {
   173  		t.Errorf("invalid log output:\ngot:  %v\nwant: %v", got, want)
   174  	}
   175  }
   176  
   177  func TestFieldsMapPnt(t *testing.T) {
   178  	out := &bytes.Buffer{}
   179  	log := New(out)
   180  	log.Log().Fields(map[string]interface{}{
   181  		"string":  new(string),
   182  		"bool":    new(bool),
   183  		"int":     new(int),
   184  		"int8":    new(int8),
   185  		"int16":   new(int16),
   186  		"int32":   new(int32),
   187  		"int64":   new(int64),
   188  		"uint":    new(uint),
   189  		"uint8":   new(uint8),
   190  		"uint16":  new(uint16),
   191  		"uint32":  new(uint32),
   192  		"uint64":  new(uint64),
   193  		"float32": new(float32),
   194  		"float64": new(float64),
   195  		"dur":     new(time.Duration),
   196  		"time":    new(time.Time),
   197  	}).Msg("")
   198  	if got, want := decodeIfBinaryToString(out.Bytes()), `{"bool":false,"dur":0,"float32":0,"float64":0,"int":0,"int16":0,"int32":0,"int64":0,"int8":0,"string":"","time":"0001-01-01T00:00:00Z","uint":0,"uint16":0,"uint32":0,"uint64":0,"uint8":0}`+"\n"; got != want {
   199  		t.Errorf("invalid log output:\ngot:  %v\nwant: %v", got, want)
   200  	}
   201  }
   202  
   203  func TestFieldsMapNilPnt(t *testing.T) {
   204  	var (
   205  		stringPnt  *string
   206  		boolPnt    *bool
   207  		intPnt     *int
   208  		int8Pnt    *int8
   209  		int16Pnt   *int16
   210  		int32Pnt   *int32
   211  		int64Pnt   *int64
   212  		uintPnt    *uint
   213  		uint8Pnt   *uint8
   214  		uint16Pnt  *uint16
   215  		uint32Pnt  *uint32
   216  		uint64Pnt  *uint64
   217  		float32Pnt *float32
   218  		float64Pnt *float64
   219  		durPnt     *time.Duration
   220  		timePnt    *time.Time
   221  	)
   222  	out := &bytes.Buffer{}
   223  	log := New(out)
   224  	fields := map[string]interface{}{
   225  		"string":  stringPnt,
   226  		"bool":    boolPnt,
   227  		"int":     intPnt,
   228  		"int8":    int8Pnt,
   229  		"int16":   int16Pnt,
   230  		"int32":   int32Pnt,
   231  		"int64":   int64Pnt,
   232  		"uint":    uintPnt,
   233  		"uint8":   uint8Pnt,
   234  		"uint16":  uint16Pnt,
   235  		"uint32":  uint32Pnt,
   236  		"uint64":  uint64Pnt,
   237  		"float32": float32Pnt,
   238  		"float64": float64Pnt,
   239  		"dur":     durPnt,
   240  		"time":    timePnt,
   241  	}
   242  
   243  	log.Log().Fields(fields).Msg("")
   244  	if got, want := decodeIfBinaryToString(out.Bytes()), `{"bool":null,"dur":null,"float32":null,"float64":null,"int":null,"int16":null,"int32":null,"int64":null,"int8":null,"string":null,"time":null,"uint":null,"uint16":null,"uint32":null,"uint64":null,"uint8":null}`+"\n"; got != want {
   245  		t.Errorf("invalid log output:\ngot:  %v\nwant: %v", got, want)
   246  	}
   247  }
   248  
   249  func TestFieldsSlice(t *testing.T) {
   250  	out := &bytes.Buffer{}
   251  	log := New(out)
   252  	log.Log().Fields([]interface{}{
   253  		"nil", nil,
   254  		"string", "foo",
   255  		"bytes", []byte("bar"),
   256  		"error", errors.New("some error"),
   257  		"bool", true,
   258  		"int", int(1),
   259  		"int8", int8(2),
   260  		"int16", int16(3),
   261  		"int32", int32(4),
   262  		"int64", int64(5),
   263  		"uint", uint(6),
   264  		"uint8", uint8(7),
   265  		"uint16", uint16(8),
   266  		"uint32", uint32(9),
   267  		"uint64", uint64(10),
   268  		"float32", float32(11),
   269  		"float64", float64(12),
   270  		"ipv6", net.IP{0x20, 0x01, 0x0d, 0xb8, 0x85, 0xa3, 0x00, 0x00, 0x00, 0x00, 0x8a, 0x2e, 0x03, 0x70, 0x73, 0x34},
   271  		"dur", 1 * time.Second,
   272  		"time", time.Time{},
   273  		"obj", obj{"a", "b", 1},
   274  	}).Msg("")
   275  	if got, want := decodeIfBinaryToString(out.Bytes()), `{"nil":null,"string":"foo","bytes":"bar","error":"some error","bool":true,"int":1,"int8":2,"int16":3,"int32":4,"int64":5,"uint":6,"uint8":7,"uint16":8,"uint32":9,"uint64":10,"float32":11,"float64":12,"ipv6":"2001:db8:85a3::8a2e:370:7334","dur":1000,"time":"0001-01-01T00:00:00Z","obj":{"Pub":"a","Tag":"b","priv":1}}`+"\n"; got != want {
   276  		t.Errorf("invalid log output:\ngot:  %v\nwant: %v", got, want)
   277  	}
   278  }
   279  
   280  func TestFieldsSliceExtraneous(t *testing.T) {
   281  	out := &bytes.Buffer{}
   282  	log := New(out)
   283  	log.Log().Fields([]interface{}{
   284  		"string", "foo",
   285  		"error", errors.New("some error"),
   286  		32, "valueForNonStringKey",
   287  		"bool", true,
   288  		"int", int(1),
   289  		"keyWithoutValue",
   290  	}).Msg("")
   291  	if got, want := decodeIfBinaryToString(out.Bytes()), `{"string":"foo","error":"some error","bool":true,"int":1}`+"\n"; got != want {
   292  		t.Errorf("invalid log output:\ngot:  %v\nwant: %v", got, want)
   293  	}
   294  }
   295  
   296  func TestFieldsNotMapSlice(t *testing.T) {
   297  	out := &bytes.Buffer{}
   298  	log := New(out)
   299  	log.Log().
   300  		Fields(obj{"a", "b", 1}).
   301  		Fields("string").
   302  		Fields(1).
   303  		Msg("")
   304  	if got, want := decodeIfBinaryToString(out.Bytes()), `{}`+"\n"; got != want {
   305  		t.Errorf("invalid log output:\ngot:  %v\nwant: %v", got, want)
   306  	}
   307  }
   308  
   309  func TestFields(t *testing.T) {
   310  	out := &bytes.Buffer{}
   311  	log := New(out)
   312  	now := time.Now()
   313  	_, file, line, _ := runtime.Caller(0)
   314  	caller := fmt.Sprintf("%s:%d", file, line+3)
   315  	log.Log().
   316  		Caller().
   317  		Str("string", "foo").
   318  		Stringer("stringer", net.IP{127, 0, 0, 1}).
   319  		Stringer("stringer_nil", nil).
   320  		Bytes("bytes", []byte("bar")).
   321  		Hex("hex", []byte{0x12, 0xef}).
   322  		RawJSON("json", []byte(`{"some":"json"}`)).
   323  		Func(func(e *Event) { e.Str("func", "func_output") }).
   324  		AnErr("some_err", nil).
   325  		Err(errors.New("some error")).
   326  		Bool("bool", true).
   327  		Int("int", 1).
   328  		Int8("int8", 2).
   329  		Int16("int16", 3).
   330  		Int32("int32", 4).
   331  		Int64("int64", 5).
   332  		Uint("uint", 6).
   333  		Uint8("uint8", 7).
   334  		Uint16("uint16", 8).
   335  		Uint32("uint32", 9).
   336  		Uint64("uint64", 10).
   337  		IPAddr("IPv4", net.IP{192, 168, 0, 100}).
   338  		IPAddr("IPv6", net.IP{0x20, 0x01, 0x0d, 0xb8, 0x85, 0xa3, 0x00, 0x00, 0x00, 0x00, 0x8a, 0x2e, 0x03, 0x70, 0x73, 0x34}).
   339  		MACAddr("Mac", net.HardwareAddr{0x00, 0x14, 0x22, 0x01, 0x23, 0x45}).
   340  		IPPrefix("Prefix", net.IPNet{IP: net.IP{192, 168, 0, 100}, Mask: net.CIDRMask(24, 32)}).
   341  		Float32("float32", 11.1234).
   342  		Float64("float64", 12.321321321).
   343  		Dur("dur", 1*time.Second).
   344  		Time("time", time.Time{}).
   345  		TimeDiff("diff", now, now.Add(-10*time.Second)).
   346  		Msg("")
   347  	if got, want := decodeIfBinaryToString(out.Bytes()), `{"caller":"`+caller+`","string":"foo","stringer":"127.0.0.1","stringer_nil":null,"bytes":"bar","hex":"12ef","json":{"some":"json"},"func":"func_output","error":"some error","bool":true,"int":1,"int8":2,"int16":3,"int32":4,"int64":5,"uint":6,"uint8":7,"uint16":8,"uint32":9,"uint64":10,"IPv4":"192.168.0.100","IPv6":"2001:db8:85a3::8a2e:370:7334","Mac":"00:14:22:01:23:45","Prefix":"192.168.0.100/24","float32":11.1234,"float64":12.321321321,"dur":1000,"time":"0001-01-01T00:00:00Z","diff":10000}`+"\n"; got != want {
   348  		t.Errorf("invalid log output:\ngot:  %v\nwant: %v", got, want)
   349  	}
   350  }
   351  
   352  func TestFieldsArrayEmpty(t *testing.T) {
   353  	out := &bytes.Buffer{}
   354  	log := New(out)
   355  	log.Log().
   356  		Strs("string", []string{}).
   357  		Stringers("stringer", []fmt.Stringer{}).
   358  		Errs("err", []error{}).
   359  		Bools("bool", []bool{}).
   360  		Ints("int", []int{}).
   361  		Ints8("int8", []int8{}).
   362  		Ints16("int16", []int16{}).
   363  		Ints32("int32", []int32{}).
   364  		Ints64("int64", []int64{}).
   365  		Uints("uint", []uint{}).
   366  		Uints8("uint8", []uint8{}).
   367  		Uints16("uint16", []uint16{}).
   368  		Uints32("uint32", []uint32{}).
   369  		Uints64("uint64", []uint64{}).
   370  		Floats32("float32", []float32{}).
   371  		Floats64("float64", []float64{}).
   372  		Durs("dur", []time.Duration{}).
   373  		Times("time", []time.Time{}).
   374  		Msg("")
   375  	if got, want := decodeIfBinaryToString(out.Bytes()), `{"string":[],"stringer":[],"err":[],"bool":[],"int":[],"int8":[],"int16":[],"int32":[],"int64":[],"uint":[],"uint8":[],"uint16":[],"uint32":[],"uint64":[],"float32":[],"float64":[],"dur":[],"time":[]}`+"\n"; got != want {
   376  		t.Errorf("invalid log output:\ngot:  %v\nwant: %v", got, want)
   377  	}
   378  }
   379  
   380  func TestFieldsArraySingleElement(t *testing.T) {
   381  	out := &bytes.Buffer{}
   382  	log := New(out)
   383  	log.Log().
   384  		Strs("string", []string{"foo"}).
   385  		Stringers("stringer", []fmt.Stringer{net.IP{127, 0, 0, 1}}).
   386  		Errs("err", []error{errors.New("some error")}).
   387  		Bools("bool", []bool{true}).
   388  		Ints("int", []int{1}).
   389  		Ints8("int8", []int8{2}).
   390  		Ints16("int16", []int16{3}).
   391  		Ints32("int32", []int32{4}).
   392  		Ints64("int64", []int64{5}).
   393  		Uints("uint", []uint{6}).
   394  		Uints8("uint8", []uint8{7}).
   395  		Uints16("uint16", []uint16{8}).
   396  		Uints32("uint32", []uint32{9}).
   397  		Uints64("uint64", []uint64{10}).
   398  		Floats32("float32", []float32{11}).
   399  		Floats64("float64", []float64{12}).
   400  		Durs("dur", []time.Duration{1 * time.Second}).
   401  		Times("time", []time.Time{{}}).
   402  		Msg("")
   403  	if got, want := decodeIfBinaryToString(out.Bytes()), `{"string":["foo"],"stringer":["127.0.0.1"],"err":["some error"],"bool":[true],"int":[1],"int8":[2],"int16":[3],"int32":[4],"int64":[5],"uint":[6],"uint8":[7],"uint16":[8],"uint32":[9],"uint64":[10],"float32":[11],"float64":[12],"dur":[1000],"time":["0001-01-01T00:00:00Z"]}`+"\n"; got != want {
   404  		t.Errorf("invalid log output:\ngot:  %v\nwant: %v", got, want)
   405  	}
   406  }
   407  
   408  func TestFieldsArrayMultipleElement(t *testing.T) {
   409  	out := &bytes.Buffer{}
   410  	log := New(out)
   411  	log.Log().
   412  		Strs("string", []string{"foo", "bar"}).
   413  		Stringers("stringer", []fmt.Stringer{nil, net.IP{127, 0, 0, 1}}).
   414  		Errs("err", []error{errors.New("some error"), nil}).
   415  		Bools("bool", []bool{true, false}).
   416  		Ints("int", []int{1, 0}).
   417  		Ints8("int8", []int8{2, 0}).
   418  		Ints16("int16", []int16{3, 0}).
   419  		Ints32("int32", []int32{4, 0}).
   420  		Ints64("int64", []int64{5, 0}).
   421  		Uints("uint", []uint{6, 0}).
   422  		Uints8("uint8", []uint8{7, 0}).
   423  		Uints16("uint16", []uint16{8, 0}).
   424  		Uints32("uint32", []uint32{9, 0}).
   425  		Uints64("uint64", []uint64{10, 0}).
   426  		Floats32("float32", []float32{11, 0}).
   427  		Floats64("float64", []float64{12, 0}).
   428  		Durs("dur", []time.Duration{1 * time.Second, 0}).
   429  		Times("time", []time.Time{{}, {}}).
   430  		Msg("")
   431  	if got, want := decodeIfBinaryToString(out.Bytes()), `{"string":["foo","bar"],"stringer":[null,"127.0.0.1"],"err":["some error",null],"bool":[true,false],"int":[1,0],"int8":[2,0],"int16":[3,0],"int32":[4,0],"int64":[5,0],"uint":[6,0],"uint8":[7,0],"uint16":[8,0],"uint32":[9,0],"uint64":[10,0],"float32":[11,0],"float64":[12,0],"dur":[1000,0],"time":["0001-01-01T00:00:00Z","0001-01-01T00:00:00Z"]}`+"\n"; got != want {
   432  		t.Errorf("invalid log output:\ngot:  %v\nwant: %v", got, want)
   433  	}
   434  }
   435  
   436  func TestFieldsDisabled(t *testing.T) {
   437  	out := &bytes.Buffer{}
   438  	log := New(out).Level(InfoLevel)
   439  	now := time.Now()
   440  	log.Debug().
   441  		Str("string", "foo").
   442  		Stringer("stringer", net.IP{127, 0, 0, 1}).
   443  		Bytes("bytes", []byte("bar")).
   444  		Hex("hex", []byte{0x12, 0xef}).
   445  		AnErr("some_err", nil).
   446  		Err(errors.New("some error")).
   447  		Func(func(e *Event) { e.Str("func", "func_output") }).
   448  		Bool("bool", true).
   449  		Int("int", 1).
   450  		Int8("int8", 2).
   451  		Int16("int16", 3).
   452  		Int32("int32", 4).
   453  		Int64("int64", 5).
   454  		Uint("uint", 6).
   455  		Uint8("uint8", 7).
   456  		Uint16("uint16", 8).
   457  		Uint32("uint32", 9).
   458  		Uint64("uint64", 10).
   459  		Float32("float32", 11).
   460  		Float64("float64", 12).
   461  		Dur("dur", 1*time.Second).
   462  		Time("time", time.Time{}).
   463  		TimeDiff("diff", now, now.Add(-10*time.Second)).
   464  		Msg("")
   465  	if got, want := decodeIfBinaryToString(out.Bytes()), ""; got != want {
   466  		t.Errorf("invalid log output:\ngot:  %v\nwant: %v", got, want)
   467  	}
   468  }
   469  
   470  func TestMsgf(t *testing.T) {
   471  	out := &bytes.Buffer{}
   472  	log := New(out)
   473  	log.Log().Msgf("one %s %.1f %d %v", "two", 3.4, 5, errors.New("six"))
   474  	if got, want := decodeIfBinaryToString(out.Bytes()), `{"message":"one two 3.4 5 six"}`+"\n"; got != want {
   475  		t.Errorf("invalid log output:\ngot:  %v\nwant: %v", got, want)
   476  	}
   477  }
   478  
   479  func TestWithAndFieldsCombined(t *testing.T) {
   480  	out := &bytes.Buffer{}
   481  	log := New(out).With().Str("f1", "val").Str("f2", "val").Logger()
   482  	log.Log().Str("f3", "val").Msg("")
   483  	if got, want := decodeIfBinaryToString(out.Bytes()), `{"f1":"val","f2":"val","f3":"val"}`+"\n"; got != want {
   484  		t.Errorf("invalid log output:\ngot:  %v\nwant: %v", got, want)
   485  	}
   486  }
   487  
   488  func TestLevel(t *testing.T) {
   489  	t.Run("Disabled", func(t *testing.T) {
   490  		out := &bytes.Buffer{}
   491  		log := New(out).Level(Disabled)
   492  		log.Info().Msg("test")
   493  		if got, want := decodeIfBinaryToString(out.Bytes()), ""; got != want {
   494  			t.Errorf("invalid log output:\ngot:  %v\nwant: %v", got, want)
   495  		}
   496  	})
   497  
   498  	t.Run("NoLevel/Disabled", func(t *testing.T) {
   499  		out := &bytes.Buffer{}
   500  		log := New(out).Level(Disabled)
   501  		log.Log().Msg("test")
   502  		if got, want := decodeIfBinaryToString(out.Bytes()), ""; got != want {
   503  			t.Errorf("invalid log output:\ngot:  %v\nwant: %v", got, want)
   504  		}
   505  	})
   506  
   507  	t.Run("NoLevel/Info", func(t *testing.T) {
   508  		out := &bytes.Buffer{}
   509  		log := New(out).Level(InfoLevel)
   510  		log.Log().Msg("test")
   511  		if got, want := decodeIfBinaryToString(out.Bytes()), `{"message":"test"}`+"\n"; got != want {
   512  			t.Errorf("invalid log output:\ngot:  %v\nwant: %v", got, want)
   513  		}
   514  	})
   515  
   516  	t.Run("NoLevel/Panic", func(t *testing.T) {
   517  		out := &bytes.Buffer{}
   518  		log := New(out).Level(PanicLevel)
   519  		log.Log().Msg("test")
   520  		if got, want := decodeIfBinaryToString(out.Bytes()), `{"message":"test"}`+"\n"; got != want {
   521  			t.Errorf("invalid log output:\ngot:  %v\nwant: %v", got, want)
   522  		}
   523  	})
   524  
   525  	t.Run("NoLevel/WithLevel", func(t *testing.T) {
   526  		out := &bytes.Buffer{}
   527  		log := New(out).Level(InfoLevel)
   528  		log.WithLevel(NoLevel).Msg("test")
   529  		if got, want := decodeIfBinaryToString(out.Bytes()), `{"message":"test"}`+"\n"; got != want {
   530  			t.Errorf("invalid log output:\ngot:  %v\nwant: %v", got, want)
   531  		}
   532  	})
   533  
   534  	t.Run("Info", func(t *testing.T) {
   535  		out := &bytes.Buffer{}
   536  		log := New(out).Level(InfoLevel)
   537  		log.Info().Msg("test")
   538  		if got, want := decodeIfBinaryToString(out.Bytes()), `{"level":"info","message":"test"}`+"\n"; got != want {
   539  			t.Errorf("invalid log output:\ngot:  %v\nwant: %v", got, want)
   540  		}
   541  	})
   542  }
   543  
   544  func TestGetLevel(t *testing.T) {
   545  	levels := []Level{
   546  		DebugLevel,
   547  		InfoLevel,
   548  		WarnLevel,
   549  		ErrorLevel,
   550  		FatalLevel,
   551  		PanicLevel,
   552  		NoLevel,
   553  		Disabled,
   554  	}
   555  	for _, level := range levels {
   556  		if got, want := New(nil).Level(level).GetLevel(), level; got != want {
   557  			t.Errorf("GetLevel() = %v, want: %v", got, want)
   558  		}
   559  	}
   560  }
   561  
   562  func TestSampling(t *testing.T) {
   563  	out := &bytes.Buffer{}
   564  	log := New(out).Sample(&BasicSampler{N: 2})
   565  	log.Log().Int("i", 1).Msg("")
   566  	log.Log().Int("i", 2).Msg("")
   567  	log.Log().Int("i", 3).Msg("")
   568  	log.Log().Int("i", 4).Msg("")
   569  	if got, want := decodeIfBinaryToString(out.Bytes()), "{\"i\":1}\n{\"i\":3}\n"; got != want {
   570  		t.Errorf("invalid log output:\ngot:  %v\nwant: %v", got, want)
   571  	}
   572  }
   573  
   574  func TestDiscard(t *testing.T) {
   575  	out := &bytes.Buffer{}
   576  	log := New(out)
   577  	log.Log().Discard().Str("a", "b").Msgf("one %s %.1f %d %v", "two", 3.4, 5, errors.New("six"))
   578  	if got, want := decodeIfBinaryToString(out.Bytes()), ""; got != want {
   579  		t.Errorf("invalid log output:\ngot:  %v\nwant: %v", got, want)
   580  	}
   581  
   582  	// Double call
   583  	log.Log().Discard().Discard().Str("a", "b").Msgf("one %s %.1f %d %v", "two", 3.4, 5, errors.New("six"))
   584  	if got, want := decodeIfBinaryToString(out.Bytes()), ""; got != want {
   585  		t.Errorf("invalid log output:\ngot:  %v\nwant: %v", got, want)
   586  	}
   587  }
   588  
   589  type levelWriter struct {
   590  	ops []struct {
   591  		l Level
   592  		p string
   593  	}
   594  }
   595  
   596  func (lw *levelWriter) Write(p []byte) (int, error) {
   597  	return len(p), nil
   598  }
   599  
   600  func (lw *levelWriter) WriteLevel(lvl Level, p []byte) (int, error) {
   601  	p = decodeIfBinaryToBytes(p)
   602  	lw.ops = append(lw.ops, struct {
   603  		l Level
   604  		p string
   605  	}{lvl, string(p)})
   606  	return len(p), nil
   607  }
   608  
   609  func TestLevelWriter(t *testing.T) {
   610  	lw := &levelWriter{
   611  		ops: []struct {
   612  			l Level
   613  			p string
   614  		}{},
   615  	}
   616  
   617  	// Allow extra-verbose logs.
   618  	SetGlobalLevel(TraceLevel - 1)
   619  	log := New(lw).Level(TraceLevel - 1)
   620  
   621  	log.Trace().Msg("0")
   622  	log.Debug().Msg("1")
   623  	log.Info().Msg("2")
   624  	log.Warn().Msg("3")
   625  	log.Error().Msg("4")
   626  	log.Log().Msg("nolevel-1")
   627  	log.WithLevel(TraceLevel).Msg("5")
   628  	log.WithLevel(DebugLevel).Msg("6")
   629  	log.WithLevel(InfoLevel).Msg("7")
   630  	log.WithLevel(WarnLevel).Msg("8")
   631  	log.WithLevel(ErrorLevel).Msg("9")
   632  	log.WithLevel(NoLevel).Msg("nolevel-2")
   633  	log.WithLevel(-1).Msg("-1") // Same as TraceLevel
   634  	log.WithLevel(-2).Msg("-2") // Will log
   635  	log.WithLevel(-3).Msg("-3") // Will not log
   636  
   637  	want := []struct {
   638  		l Level
   639  		p string
   640  	}{
   641  		{TraceLevel, `{"level":"trace","message":"0"}` + "\n"},
   642  		{DebugLevel, `{"level":"debug","message":"1"}` + "\n"},
   643  		{InfoLevel, `{"level":"info","message":"2"}` + "\n"},
   644  		{WarnLevel, `{"level":"warn","message":"3"}` + "\n"},
   645  		{ErrorLevel, `{"level":"error","message":"4"}` + "\n"},
   646  		{NoLevel, `{"message":"nolevel-1"}` + "\n"},
   647  		{TraceLevel, `{"level":"trace","message":"5"}` + "\n"},
   648  		{DebugLevel, `{"level":"debug","message":"6"}` + "\n"},
   649  		{InfoLevel, `{"level":"info","message":"7"}` + "\n"},
   650  		{WarnLevel, `{"level":"warn","message":"8"}` + "\n"},
   651  		{ErrorLevel, `{"level":"error","message":"9"}` + "\n"},
   652  		{NoLevel, `{"message":"nolevel-2"}` + "\n"},
   653  		{Level(-1), `{"level":"trace","message":"-1"}` + "\n"},
   654  		{Level(-2), `{"level":"-2","message":"-2"}` + "\n"},
   655  	}
   656  	if got := lw.ops; !reflect.DeepEqual(got, want) {
   657  		t.Errorf("invalid ops:\ngot:\n%v\nwant:\n%v", got, want)
   658  	}
   659  }
   660  
   661  func TestContextTimestamp(t *testing.T) {
   662  	TimestampFunc = func() time.Time {
   663  		return time.Date(2001, time.February, 3, 4, 5, 6, 7, time.UTC)
   664  	}
   665  	defer func() {
   666  		TimestampFunc = time.Now
   667  	}()
   668  	out := &bytes.Buffer{}
   669  	log := New(out).With().Timestamp().Str("foo", "bar").Logger()
   670  	log.Log().Msg("hello world")
   671  
   672  	if got, want := decodeIfBinaryToString(out.Bytes()), `{"foo":"bar","time":"2001-02-03T04:05:06Z","message":"hello world"}`+"\n"; got != want {
   673  		t.Errorf("invalid log output:\ngot:  %v\nwant: %v", got, want)
   674  	}
   675  }
   676  
   677  func TestEventTimestamp(t *testing.T) {
   678  	TimestampFunc = func() time.Time {
   679  		return time.Date(2001, time.February, 3, 4, 5, 6, 7, time.UTC)
   680  	}
   681  	defer func() {
   682  		TimestampFunc = time.Now
   683  	}()
   684  	out := &bytes.Buffer{}
   685  	log := New(out).With().Str("foo", "bar").Logger()
   686  	log.Log().Timestamp().Msg("hello world")
   687  
   688  	if got, want := decodeIfBinaryToString(out.Bytes()), `{"foo":"bar","time":"2001-02-03T04:05:06Z","message":"hello world"}`+"\n"; got != want {
   689  		t.Errorf("invalid log output:\ngot:  %v\nwant: %v", got, want)
   690  	}
   691  }
   692  
   693  func TestOutputWithoutTimestamp(t *testing.T) {
   694  	ignoredOut := &bytes.Buffer{}
   695  	out := &bytes.Buffer{}
   696  	log := New(ignoredOut).Output(out).With().Str("foo", "bar").Logger()
   697  	log.Log().Msg("hello world")
   698  
   699  	if got, want := decodeIfBinaryToString(out.Bytes()), `{"foo":"bar","message":"hello world"}`+"\n"; got != want {
   700  		t.Errorf("invalid log output:\ngot:  %v\nwant: %v", got, want)
   701  	}
   702  }
   703  
   704  func TestOutputWithTimestamp(t *testing.T) {
   705  	TimestampFunc = func() time.Time {
   706  		return time.Date(2001, time.February, 3, 4, 5, 6, 7, time.UTC)
   707  	}
   708  	defer func() {
   709  		TimestampFunc = time.Now
   710  	}()
   711  	ignoredOut := &bytes.Buffer{}
   712  	out := &bytes.Buffer{}
   713  	log := New(ignoredOut).Output(out).With().Timestamp().Str("foo", "bar").Logger()
   714  	log.Log().Msg("hello world")
   715  
   716  	if got, want := decodeIfBinaryToString(out.Bytes()), `{"foo":"bar","time":"2001-02-03T04:05:06Z","message":"hello world"}`+"\n"; got != want {
   717  		t.Errorf("invalid log output:\ngot:  %v\nwant: %v", got, want)
   718  	}
   719  }
   720  
   721  type loggableError struct {
   722  	error
   723  }
   724  
   725  func (l loggableError) MarshalZerologObject(e *Event) {
   726  	e.Str("message", l.error.Error()+": loggableError")
   727  }
   728  
   729  func TestErrorMarshalFunc(t *testing.T) {
   730  	out := &bytes.Buffer{}
   731  	log := New(out)
   732  
   733  	// test default behaviour
   734  	log.Log().Err(errors.New("err")).Msg("msg")
   735  	if got, want := decodeIfBinaryToString(out.Bytes()), `{"error":"err","message":"msg"}`+"\n"; got != want {
   736  		t.Errorf("invalid log output:\ngot:  %v\nwant: %v", got, want)
   737  	}
   738  	out.Reset()
   739  
   740  	log.Log().Err(loggableError{errors.New("err")}).Msg("msg")
   741  	if got, want := decodeIfBinaryToString(out.Bytes()), `{"error":{"message":"err: loggableError"},"message":"msg"}`+"\n"; got != want {
   742  		t.Errorf("invalid log output:\ngot:  %v\nwant: %v", got, want)
   743  	}
   744  	out.Reset()
   745  
   746  	// test overriding the ErrorMarshalFunc
   747  	originalErrorMarshalFunc := ErrorMarshalFunc
   748  	defer func() {
   749  		ErrorMarshalFunc = originalErrorMarshalFunc
   750  	}()
   751  
   752  	ErrorMarshalFunc = func(err error) interface{} {
   753  		return err.Error() + ": marshaled string"
   754  	}
   755  	log.Log().Err(errors.New("err")).Msg("msg")
   756  	if got, want := decodeIfBinaryToString(out.Bytes()), `{"error":"err: marshaled string","message":"msg"}`+"\n"; got != want {
   757  		t.Errorf("invalid log output:\ngot:  %v\nwant: %v", got, want)
   758  	}
   759  
   760  	out.Reset()
   761  	ErrorMarshalFunc = func(err error) interface{} {
   762  		return errors.New(err.Error() + ": new error")
   763  	}
   764  	log.Log().Err(errors.New("err")).Msg("msg")
   765  	if got, want := decodeIfBinaryToString(out.Bytes()), `{"error":"err: new error","message":"msg"}`+"\n"; got != want {
   766  		t.Errorf("invalid log output:\ngot:  %v\nwant: %v", got, want)
   767  	}
   768  
   769  	out.Reset()
   770  	ErrorMarshalFunc = func(err error) interface{} {
   771  		return loggableError{err}
   772  	}
   773  	log.Log().Err(errors.New("err")).Msg("msg")
   774  	if got, want := decodeIfBinaryToString(out.Bytes()), `{"error":{"message":"err: loggableError"},"message":"msg"}`+"\n"; got != want {
   775  		t.Errorf("invalid log output:\ngot:  %v\nwant: %v", got, want)
   776  	}
   777  }
   778  
   779  func TestCallerMarshalFunc(t *testing.T) {
   780  	out := &bytes.Buffer{}
   781  	log := New(out)
   782  
   783  	// test default behaviour this is really brittle due to the line numbers
   784  	// actually mattering for validation
   785  	pc, file, line, _ := runtime.Caller(0)
   786  	caller := fmt.Sprintf("%s:%d", file, line+2)
   787  	log.Log().Caller().Msg("msg")
   788  	if got, want := decodeIfBinaryToString(out.Bytes()), `{"caller":"`+caller+`","message":"msg"}`+"\n"; got != want {
   789  		t.Errorf("invalid log output:\ngot:  %v\nwant: %v", got, want)
   790  	}
   791  	out.Reset()
   792  
   793  	// test custom behavior. In this case we'll take just the last directory
   794  	origCallerMarshalFunc := CallerMarshalFunc
   795  	defer func() { CallerMarshalFunc = origCallerMarshalFunc }()
   796  	CallerMarshalFunc = func(pc uintptr, file string, line int) string {
   797  		parts := strings.Split(file, "/")
   798  		if len(parts) > 1 {
   799  			return strings.Join(parts[len(parts)-2:], "/") + ":" + strconv.Itoa(line)
   800  		}
   801  
   802  		return runtime.FuncForPC(pc).Name() + ":" + file + ":" + strconv.Itoa(line)
   803  	}
   804  	pc, file, line, _ = runtime.Caller(0)
   805  	caller = CallerMarshalFunc(pc, file, line+2)
   806  	log.Log().Caller().Msg("msg")
   807  	if got, want := decodeIfBinaryToString(out.Bytes()), `{"caller":"`+caller+`","message":"msg"}`+"\n"; got != want {
   808  		t.Errorf("invalid log output:\ngot:  %v\nwant: %v", got, want)
   809  	}
   810  }
   811  
   812  func TestLevelFieldMarshalFunc(t *testing.T) {
   813  	origLevelFieldMarshalFunc := LevelFieldMarshalFunc
   814  	LevelFieldMarshalFunc = func(l Level) string {
   815  		return strings.ToUpper(l.String())
   816  	}
   817  	defer func() {
   818  		LevelFieldMarshalFunc = origLevelFieldMarshalFunc
   819  	}()
   820  	out := &bytes.Buffer{}
   821  	log := New(out)
   822  
   823  	log.Debug().Msg("test")
   824  	if got, want := decodeIfBinaryToString(out.Bytes()), `{"level":"DEBUG","message":"test"}`+"\n"; got != want {
   825  		t.Errorf("invalid log output:\ngot:  %v\nwant: %v", got, want)
   826  	}
   827  	out.Reset()
   828  
   829  	log.Info().Msg("test")
   830  	if got, want := decodeIfBinaryToString(out.Bytes()), `{"level":"INFO","message":"test"}`+"\n"; got != want {
   831  		t.Errorf("invalid log output:\ngot:  %v\nwant: %v", got, want)
   832  	}
   833  	out.Reset()
   834  
   835  	log.Warn().Msg("test")
   836  	if got, want := decodeIfBinaryToString(out.Bytes()), `{"level":"WARN","message":"test"}`+"\n"; got != want {
   837  		t.Errorf("invalid log output:\ngot:  %v\nwant: %v", got, want)
   838  	}
   839  	out.Reset()
   840  
   841  	log.Error().Msg("test")
   842  	if got, want := decodeIfBinaryToString(out.Bytes()), `{"level":"ERROR","message":"test"}`+"\n"; got != want {
   843  		t.Errorf("invalid log output:\ngot:  %v\nwant: %v", got, want)
   844  	}
   845  	out.Reset()
   846  }
   847  
   848  type errWriter struct {
   849  	error
   850  }
   851  
   852  func (w errWriter) Write(p []byte) (n int, err error) {
   853  	return 0, w.error
   854  }
   855  
   856  func TestErrorHandler(t *testing.T) {
   857  	var got error
   858  	want := errors.New("write error")
   859  	ErrorHandler = func(err error) {
   860  		got = err
   861  	}
   862  	log := New(errWriter{want})
   863  	log.Log().Msg("test")
   864  	if got != want {
   865  		t.Errorf("ErrorHandler err = %#v, want %#v", got, want)
   866  	}
   867  }
   868  
   869  func TestUpdateEmptyContext(t *testing.T) {
   870  	var buf bytes.Buffer
   871  	log := New(&buf)
   872  
   873  	log.UpdateContext(func(c Context) Context {
   874  		return c.Str("foo", "bar")
   875  	})
   876  	log.Info().Msg("no panic")
   877  
   878  	want := `{"level":"info","foo":"bar","message":"no panic"}` + "\n"
   879  
   880  	if got := decodeIfBinaryToString(buf.Bytes()); got != want {
   881  		t.Errorf("invalid log output:\ngot:  %q\nwant: %q", got, want)
   882  	}
   883  }
   884  
   885  func TestLevel_String(t *testing.T) {
   886  	tests := []struct {
   887  		name string
   888  		l    Level
   889  		want string
   890  	}{
   891  		{"trace", TraceLevel, "trace"},
   892  		{"debug", DebugLevel, "debug"},
   893  		{"info", InfoLevel, "info"},
   894  		{"warn", WarnLevel, "warn"},
   895  		{"error", ErrorLevel, "error"},
   896  		{"fatal", FatalLevel, "fatal"},
   897  		{"panic", PanicLevel, "panic"},
   898  		{"disabled", Disabled, "disabled"},
   899  		{"nolevel", NoLevel, ""},
   900  	}
   901  	for _, tt := range tests {
   902  		t.Run(tt.name, func(t *testing.T) {
   903  			if got := tt.l.String(); got != tt.want {
   904  				t.Errorf("String() = %v, want %v", got, tt.want)
   905  			}
   906  		})
   907  	}
   908  }
   909  
   910  func TestLevel_MarshalText(t *testing.T) {
   911  	tests := []struct {
   912  		name string
   913  		l    Level
   914  		want string
   915  	}{
   916  		{"trace", TraceLevel, "trace"},
   917  		{"debug", DebugLevel, "debug"},
   918  		{"info", InfoLevel, "info"},
   919  		{"warn", WarnLevel, "warn"},
   920  		{"error", ErrorLevel, "error"},
   921  		{"fatal", FatalLevel, "fatal"},
   922  		{"panic", PanicLevel, "panic"},
   923  		{"disabled", Disabled, "disabled"},
   924  		{"nolevel", NoLevel, ""},
   925  	}
   926  	for _, tt := range tests {
   927  		t.Run(tt.name, func(t *testing.T) {
   928  			if got, err := tt.l.MarshalText(); err != nil {
   929  				t.Errorf("MarshalText couldn't marshal: %v", tt.l)
   930  			} else if string(got) != tt.want {
   931  				t.Errorf("String() = %v, want %v", string(got), tt.want)
   932  			}
   933  		})
   934  	}
   935  }
   936  
   937  func TestParseLevel(t *testing.T) {
   938  	type args struct {
   939  		levelStr string
   940  	}
   941  	tests := []struct {
   942  		name    string
   943  		args    args
   944  		want    Level
   945  		wantErr bool
   946  	}{
   947  		{"trace", args{"trace"}, TraceLevel, false},
   948  		{"debug", args{"debug"}, DebugLevel, false},
   949  		{"info", args{"info"}, InfoLevel, false},
   950  		{"warn", args{"warn"}, WarnLevel, false},
   951  		{"error", args{"error"}, ErrorLevel, false},
   952  		{"fatal", args{"fatal"}, FatalLevel, false},
   953  		{"panic", args{"panic"}, PanicLevel, false},
   954  		{"disabled", args{"disabled"}, Disabled, false},
   955  		{"nolevel", args{""}, NoLevel, false},
   956  		{"-1", args{"-1"}, TraceLevel, false},
   957  		{"-2", args{"-2"}, Level(-2), false},
   958  		{"-3", args{"-3"}, Level(-3), false},
   959  	}
   960  	for _, tt := range tests {
   961  		t.Run(tt.name, func(t *testing.T) {
   962  			got, err := ParseLevel(tt.args.levelStr)
   963  			if (err != nil) != tt.wantErr {
   964  				t.Errorf("ParseLevel() error = %v, wantErr %v", err, tt.wantErr)
   965  				return
   966  			}
   967  			if got != tt.want {
   968  				t.Errorf("ParseLevel() got = %v, want %v", got, tt.want)
   969  			}
   970  		})
   971  	}
   972  }
   973  
   974  func TestUnmarshalTextLevel(t *testing.T) {
   975  	type args struct {
   976  		levelStr string
   977  	}
   978  	tests := []struct {
   979  		name    string
   980  		args    args
   981  		want    Level
   982  		wantErr bool
   983  	}{
   984  		{"trace", args{"trace"}, TraceLevel, false},
   985  		{"debug", args{"debug"}, DebugLevel, false},
   986  		{"info", args{"info"}, InfoLevel, false},
   987  		{"warn", args{"warn"}, WarnLevel, false},
   988  		{"error", args{"error"}, ErrorLevel, false},
   989  		{"fatal", args{"fatal"}, FatalLevel, false},
   990  		{"panic", args{"panic"}, PanicLevel, false},
   991  		{"disabled", args{"disabled"}, Disabled, false},
   992  		{"nolevel", args{""}, NoLevel, false},
   993  		{"-1", args{"-1"}, TraceLevel, false},
   994  		{"-2", args{"-2"}, Level(-2), false},
   995  		{"-3", args{"-3"}, Level(-3), false},
   996  	}
   997  	for _, tt := range tests {
   998  		t.Run(tt.name, func(t *testing.T) {
   999  			var l Level
  1000  			err := l.UnmarshalText([]byte(tt.args.levelStr))
  1001  			if (err != nil) != tt.wantErr {
  1002  				t.Errorf("UnmarshalText() error = %v, wantErr %v", err, tt.wantErr)
  1003  				return
  1004  			}
  1005  			if l != tt.want {
  1006  				t.Errorf("UnmarshalText() got = %v, want %v", l, tt.want)
  1007  			}
  1008  		})
  1009  	}
  1010  }
  1011  

View as plain text