|
|
|
@ -7,6 +7,7 @@ import (
|
|
|
|
|
"io/ioutil"
|
|
|
|
|
"log"
|
|
|
|
|
"os"
|
|
|
|
|
"reflect"
|
|
|
|
|
"runtime"
|
|
|
|
|
"strings"
|
|
|
|
|
"sync"
|
|
|
|
@ -92,6 +93,86 @@ func (mw *mockWriter) String() string {
|
|
|
|
|
return mw.builder.String()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestField(t *testing.T) {
|
|
|
|
|
tests := []struct {
|
|
|
|
|
name string
|
|
|
|
|
f LogField
|
|
|
|
|
want map[string]interface{}
|
|
|
|
|
}{
|
|
|
|
|
{
|
|
|
|
|
name: "error",
|
|
|
|
|
f: Field("foo", errors.New("bar")),
|
|
|
|
|
want: map[string]interface{}{
|
|
|
|
|
"foo": "bar",
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "errors",
|
|
|
|
|
f: Field("foo", []error{errors.New("bar"), errors.New("baz")}),
|
|
|
|
|
want: map[string]interface{}{
|
|
|
|
|
"foo": []interface{}{"bar", "baz"},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "strings",
|
|
|
|
|
f: Field("foo", []string{"bar", "baz"}),
|
|
|
|
|
want: map[string]interface{}{
|
|
|
|
|
"foo": []interface{}{"bar", "baz"},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "duration",
|
|
|
|
|
f: Field("foo", time.Second),
|
|
|
|
|
want: map[string]interface{}{
|
|
|
|
|
"foo": "1s",
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "durations",
|
|
|
|
|
f: Field("foo", []time.Duration{time.Second, 2 * time.Second}),
|
|
|
|
|
want: map[string]interface{}{
|
|
|
|
|
"foo": []interface{}{"1s", "2s"},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "times",
|
|
|
|
|
f: Field("foo", []time.Time{
|
|
|
|
|
time.Date(2020, time.January, 1, 0, 0, 0, 0, time.UTC),
|
|
|
|
|
time.Date(2020, time.January, 2, 0, 0, 0, 0, time.UTC),
|
|
|
|
|
}),
|
|
|
|
|
want: map[string]interface{}{
|
|
|
|
|
"foo": []interface{}{"2020-01-01 00:00:00 +0000 UTC", "2020-01-02 00:00:00 +0000 UTC"},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "stringer",
|
|
|
|
|
f: Field("foo", ValStringer{val: "bar"}),
|
|
|
|
|
want: map[string]interface{}{
|
|
|
|
|
"foo": "bar",
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "stringers",
|
|
|
|
|
f: Field("foo", []fmt.Stringer{ValStringer{val: "bar"}, ValStringer{val: "baz"}}),
|
|
|
|
|
want: map[string]interface{}{
|
|
|
|
|
"foo": []interface{}{"bar", "baz"},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for _, test := range tests {
|
|
|
|
|
test := test
|
|
|
|
|
t.Run(test.name, func(t *testing.T) {
|
|
|
|
|
w := new(mockWriter)
|
|
|
|
|
old := writer.Swap(w)
|
|
|
|
|
defer writer.Store(old)
|
|
|
|
|
|
|
|
|
|
Infow("foo", test.f)
|
|
|
|
|
validateFields(t, w.String(), test.want)
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestFileLineFileMode(t *testing.T) {
|
|
|
|
|
w := new(mockWriter)
|
|
|
|
|
old := writer.Swap(w)
|
|
|
|
@ -675,3 +756,18 @@ type ValStringer struct {
|
|
|
|
|
func (v ValStringer) String() string {
|
|
|
|
|
return v.val
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func validateFields(t *testing.T, content string, fields map[string]interface{}) {
|
|
|
|
|
var m map[string]interface{}
|
|
|
|
|
if err := json.Unmarshal([]byte(content), &m); err != nil {
|
|
|
|
|
t.Error(err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for k, v := range fields {
|
|
|
|
|
if reflect.TypeOf(v).Kind() == reflect.Slice {
|
|
|
|
|
assert.EqualValues(t, v, m[k])
|
|
|
|
|
} else {
|
|
|
|
|
assert.Equal(t, v, m[k], content)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|