github.com/mundipagg/tracer-splunk-writer@v1.0.6/json/encoder/struct_test.go (about) 1 package encoder 2 3 import ( 4 "bytes" 5 "errors" 6 "reflect" 7 "strings" 8 "testing" 9 "unsafe" 10 11 jsoniter "github.com/json-iterator/go" 12 "github.com/stretchr/testify/assert" 13 ) 14 15 func TestStruct_IsEmpty(t *testing.T) { 16 t.Parallel() 17 is := assert.New(t) 18 subject := &Struct{} 19 input := struct{}{} 20 pointer := reflect.ValueOf(&input).Pointer() 21 is.False(subject.IsEmpty(unsafe.Pointer(pointer))) 22 } 23 24 type V struct { 25 A int 26 } 27 28 func (V) MarshalJSON() ([]byte, error) { 29 return jsoniter.Marshal("custom") 30 } 31 32 func TestStruct_Encode(t *testing.T) { 33 t.Parallel() 34 t.Run("when the value implements the json.Marshaller interface", func(t *testing.T) { 35 t.Parallel() 36 is := assert.New(t) 37 input := V{15} 38 called := 0 39 subject := &Struct{ 40 Strategy: func(s string) string { 41 called++ 42 return strings.ToLower(s) 43 }, 44 Type: reflect.TypeOf(input), 45 } 46 buf := &bytes.Buffer{} 47 stream := jsoniter.NewStream(jsoniter.ConfigFastest, buf, 100) 48 subject.Encode(unsafe.Pointer(reflect.ValueOf(&input).Pointer()), stream) 49 stream.Flush() 50 is.Equal(`"custom"`, buf.String(), "it should change the name of the field") 51 is.Equal(0, called, "it should not call the strategy ") 52 }) 53 t.Run("when the value implements the error interface", func(t *testing.T) { 54 t.Parallel() 55 is := assert.New(t) 56 input := errors.New("error") 57 called := 0 58 subject := &Struct{ 59 Strategy: func(s string) string { 60 called++ 61 return strings.ToLower(s) 62 }, 63 Type: reflect.TypeOf(input), 64 } 65 buf := &bytes.Buffer{} 66 67 stream := jsoniter.NewStream(jsoniter.ConfigFastest, buf, 100) 68 ptr := reflect.New(reflect.TypeOf(input)) 69 ptr.Elem().Set(reflect.ValueOf(input)) 70 subject.Encode(unsafe.Pointer(ptr.Pointer()), stream) 71 stream.Flush() 72 is.Equal(`"error"`, buf.String(), "it should change the name of the field") 73 is.Equal(0, called, "it should not call the strategy ") 74 }) 75 t.Run("when the field does not have a json tag", func(t *testing.T) { 76 t.Parallel() 77 is := assert.New(t) 78 input := struct { 79 A int 80 b int 81 }{ 82 A: 15, 83 b: 15, 84 } 85 called := 0 86 subject := &Struct{ 87 Strategy: func(s string) string { 88 called++ 89 return strings.ToLower(s) 90 }, 91 Type: reflect.TypeOf(input), 92 } 93 buf := &bytes.Buffer{} 94 stream := jsoniter.NewStream(jsoniter.ConfigFastest, buf, 100) 95 subject.Encode(unsafe.Pointer(reflect.ValueOf(&input).Pointer()), stream) 96 stream.Flush() 97 is.Equal(`{"a":15}`, buf.String(), "it should change the name of the field") 98 is.Equal(1, called, "it should call the strategy exactly one time") 99 }) 100 t.Run("when the field does not have omitempty on it's tag", func(t *testing.T) { 101 t.Parallel() 102 is := assert.New(t) 103 input := struct { 104 A int `json:"SuperParameter"` 105 }{ 106 A: 15, 107 } 108 called := 0 109 subject := &Struct{ 110 Strategy: func(s string) string { 111 called++ 112 return strings.ToUpper(s) 113 }, 114 Type: reflect.TypeOf(input), 115 } 116 buf := &bytes.Buffer{} 117 stream := jsoniter.NewStream(jsoniter.ConfigFastest, buf, 100) 118 subject.Encode(unsafe.Pointer(reflect.ValueOf(&input).Pointer()), stream) 119 stream.Flush() 120 is.Equal(`{"SUPERPARAMETER":15}`, buf.String(), "it should change the name of the field") 121 is.Equal(1, called, "it should call the strategy exactly one time") 122 }) 123 t.Run("when the field does have omitempty on it's tag", func(t *testing.T) { 124 t.Parallel() 125 t.Run("but the field is not empty", func(t *testing.T) { 126 t.Parallel() 127 is := assert.New(t) 128 v := 16 129 input := struct { 130 A int `json:"SuperParameterA"` 131 B *int `json:"SuperParameterB,omitempty"` 132 C int `json:"SuperParameterC,omitempty"` 133 D *int `json:"SuperParameterD,omitempty"` 134 E int `json:"SuperParameterE"` 135 }{ 136 A: 15, 137 D: &v, 138 E: 17, 139 } 140 called := 0 141 subject := &Struct{ 142 Strategy: func(s string) string { 143 called++ 144 return strings.ToUpper(s) 145 }, 146 Type: reflect.TypeOf(input), 147 } 148 buf := &bytes.Buffer{} 149 stream := jsoniter.NewStream(jsoniter.ConfigFastest, buf, 100) 150 subject.Encode(unsafe.Pointer(reflect.ValueOf(&input).Pointer()), stream) 151 stream.Flush() 152 is.Equal(`{"SUPERPARAMETERA":15,"SUPERPARAMETERD":16,"SUPERPARAMETERE":17}`, buf.String(), "it should change the name of the field") 153 is.Equal(3, called, "it should call the strategy exactly three times") 154 }) 155 t.Run("and the field is empty", func(t *testing.T) { 156 t.Parallel() 157 is := assert.New(t) 158 input := struct { 159 A *int `json:"SuperParameter,omitempty"` 160 }{ 161 A: nil, 162 } 163 called := 0 164 subject := &Struct{ 165 Strategy: func(s string) string { 166 called++ 167 return strings.ToUpper(s) 168 }, 169 Type: reflect.TypeOf(input), 170 } 171 buf := &bytes.Buffer{} 172 stream := jsoniter.NewStream(jsoniter.ConfigFastest, buf, 100) 173 subject.Encode(unsafe.Pointer(reflect.ValueOf(&input).Pointer()), stream) 174 stream.Flush() 175 is.Equal(`{}`, buf.String(), "it should change the name of the field") 176 is.Equal(0, called, "it should not call the strategy") 177 }) 178 }) 179 }