github.com/shoshinnikita/budget-manager@v0.7.1-0.20220131195411-8c46ff1c6778/internal/logger/struct_test.go (about) 1 package logger 2 3 import ( 4 "strings" 5 "testing" 6 "time" 7 8 "github.com/stretchr/testify/require" 9 ) 10 11 func TestStructToFields(t *testing.T) { 12 t.Parallel() 13 14 type testCase struct { 15 in interface{} 16 namePrefix string 17 want Fields 18 } 19 runTestCases := func(t *testing.T, testCases []testCase) { 20 for _, tt := range testCases { 21 tt := tt 22 t.Run("", func(t *testing.T) { 23 got := structToFields(tt.in, tt.namePrefix) 24 require.Equal(t, tt.want, got) 25 }) 26 } 27 } 28 29 t.Run("wrong types", func(t *testing.T) { 30 runTestCases(t, []testCase{ 31 {in: 5, want: nil}, 32 {in: 15.7, want: nil}, 33 {in: "hello", want: nil}, 34 {in: func() error { return nil }, want: nil}, 35 {in: map[string]int{"1": 2}, want: nil}, 36 }) 37 }) 38 39 t.Run("basic", func(t *testing.T) { 40 type S struct { 41 A float64 `json:"a"` 42 B string `json:"b"` 43 C map[string]float64 44 E **int `json:"e"` 45 F *float64 46 g string 47 } 48 49 var ( 50 i = 10 51 iPtr = &i 52 ) 53 runTestCases(t, []testCase{ 54 { 55 in: S{A: 0.15, B: "hello world", C: map[string]float64{"1": 2}, E: &iPtr, F: nil, g: "g"}, 56 want: Fields{"a": 0.15, "b": "hello world", "C": map[string]float64{"1": 2}, "e": 10, "F": "<nil>"}, 57 }, 58 { 59 in: S{A: 0, B: "", E: &iPtr}, 60 namePrefix: "p", 61 want: Fields{"p.a": 0.0, "p.b": "", "p.C": "<nil>", "p.e": 10, "p.F": "<nil>"}, 62 }, 63 }) 64 }) 65 66 t.Run("complex", func(t *testing.T) { 67 type Embedded struct { 68 A int `json:"a"` 69 B int `json:"b"` 70 } 71 72 type Empty struct{} 73 74 type Nested1 struct { 75 Arr []string `json:"arr"` 76 } 77 78 type Nested struct { 79 X int `json:"x"` 80 Nested Nested1 `json:"nested1"` 81 } 82 83 type S struct { 84 Embedded 85 Empty 86 87 A string `json:"a"` 88 Nested Nested `json:"nested"` 89 } 90 91 runTestCases(t, []testCase{ 92 { 93 in: S{Embedded: Embedded{A: 1, B: 2}, A: "qwerty", Nested: Nested{X: 3}}, 94 namePrefix: "req", 95 want: Fields{"req.Embedded.a": 1, "req.Embedded.b": 2, "req.a": "qwerty", "req.nested.x": 3, "req.nested.nested1.arr": "<nil>"}, 96 }, 97 }) 98 }) 99 100 t.Run("format", func(t *testing.T) { 101 type S struct { 102 T time.Time `json:"t"` 103 D time.Duration `json:"d"` 104 B *strings.Builder `json:"b"` // (*strings.Builder).String() panics if builder is nil 105 } 106 107 runTestCases(t, []testCase{ 108 { 109 in: S{ 110 T: time.Date(2021, time.August, 11, 0, 0, 0, 0, time.UTC), 111 D: 5 * time.Second, 112 }, 113 want: Fields{ 114 "t": "2021-08-11T00:00:00Z", 115 "d": "5s", 116 "b": "<nil>", 117 }, 118 }, 119 { 120 in: S{ 121 T: time.Date(2021, time.August, 11, 0, 0, 0, 0, time.UTC), 122 B: &strings.Builder{}, 123 }, 124 want: Fields{ 125 "t": "2021-08-11T00:00:00Z", 126 "d": "0s", 127 "b": "", 128 }, 129 }, 130 }) 131 }) 132 }