github.com/zerosnake0/jzon@v0.0.9-0.20230801092939-1b135cb83f7f/val_encoder_native_map_test.go (about) 1 package jzon 2 3 import ( 4 "encoding/json" 5 "errors" 6 "math" 7 "strconv" 8 "testing" 9 10 "github.com/stretchr/testify/require" 11 ) 12 13 func TestValEncoder_Map_Error(t *testing.T) { 14 t.Run("chain error", func(t *testing.T) { 15 testStreamerChainError(t, func(s *Streamer) { 16 (*directMapEncoder)(nil).Encode(nil, s, nil) 17 }) 18 }) 19 t.Run("element error", func(t *testing.T) { 20 e := errors.New("test") 21 checkEncodeValueWithStandard(t, map[string]json.Marshaler{ 22 "key": testJSONMarshaler{ 23 err: e, 24 }, 25 }, e) 26 }) 27 } 28 29 func TestValEncoder_Map(t *testing.T) { 30 t.Run("nil", func(t *testing.T) { 31 var m map[string]int 32 checkEncodeValueWithStandard(t, m, nil) 33 }) 34 t.Run("nil pointer", func(t *testing.T) { 35 var m map[string]int 36 checkEncodeValueWithStandard(t, &m, nil) 37 }) 38 t.Run("simple", func(t *testing.T) { 39 m := map[string]int{"1": 2} 40 checkEncodeValueWithStandard(t, m, nil) 41 }) 42 t.Run("pointer elem", func(t *testing.T) { 43 i := 3 44 m := map[string]*int{ 45 "1": (*int)(nil), 46 "2": &i, 47 } 48 checkEncodeValueWithStandard(t, m, nil) 49 }) 50 } 51 52 type testMapIntKey2 int 53 54 func (i testMapIntKey2) MarshalText() ([]byte, error) { 55 return []byte(strconv.Itoa(int(i * 2))), nil 56 } 57 58 type testMapIntKey2Ptr int 59 60 func (i *testMapIntKey2Ptr) MarshalText() ([]byte, error) { 61 return []byte(strconv.Itoa(int(*i * 2))), nil 62 } 63 64 type testMapStringKey2 string 65 66 func (s testMapStringKey2) MarshalText() ([]byte, error) { 67 return []byte(strconv.Itoa(len(s))), nil 68 } 69 70 type testMapStringKey2Ptr string 71 72 func (s *testMapStringKey2Ptr) MarshalText() ([]byte, error) { 73 return []byte(strconv.Itoa(len(*s))), nil 74 } 75 76 func TestValEncoder_Native_Map_KeyEncoder_TextMarshaler(t *testing.T) { 77 t.Run("not supported", func(t *testing.T) { 78 type key testTextMarshaler 79 m := map[key]int{{ 80 data: "a", 81 }: 1} 82 checkEncodeValueWithStandard(t, m, TypeNotSupportedError("")) 83 }) 84 t.Run("marshaler 1-non pointer", func(t *testing.T) { 85 t.Run("no error", func(t *testing.T) { 86 type key = testTextMarshaler 87 m := map[key]int{{ 88 data: "a", 89 }: 1} 90 checkEncodeValueWithStandard(t, m, nil) 91 }) 92 t.Run("no error 2", func(t *testing.T) { 93 type key = testTextMarshaler 94 m := map[key]int{{ 95 data: "a", 96 }: 1} 97 checkEncodeValueWithStandard(t, &m, nil) 98 }) 99 t.Run("error", func(t *testing.T) { 100 type key = testTextMarshaler 101 e := errors.New("test") 102 m := map[key]int{{ 103 data: "a", 104 err: e, 105 }: 1} 106 checkEncodeValueWithStandard(t, m, e) 107 }) 108 }) 109 t.Run("marshaler 1-pointer", func(t *testing.T) { 110 t.Run("no error", func(t *testing.T) { 111 type key = *testTextMarshaler 112 m := map[key]int{{ 113 data: "a", 114 }: 1} 115 checkEncodeValueWithStandard(t, m, nil) 116 }) 117 t.Run("no error 2", func(t *testing.T) { 118 type key = *testTextMarshaler 119 m := map[key]int{{ 120 data: "a", 121 }: 1} 122 checkEncodeValueWithStandard(t, &m, nil) 123 }) 124 t.Run("error", func(t *testing.T) { 125 e := errors.New("test") 126 type key = *testTextMarshaler 127 m := map[key]int{{ 128 data: "a", 129 err: e, 130 }: 1} 131 checkEncodeValueWithStandard(t, m, e) 132 }) 133 t.Run("nil", func(t *testing.T) { 134 type key = *testTextMarshaler 135 m := map[key]int{nil: 1} 136 v := "go1.13.15" 137 if goVersion.LessEqual(v) { 138 b, err := Marshal(m) 139 require.NoError(t, err) 140 require.Equal(t, `{"":1}`, string(b)) 141 } else { 142 checkEncodeValueWithStandard(t, m, nil) 143 } 144 }) 145 }) 146 t.Run("marshaler 2-non pointer", func(t *testing.T) { 147 type key = testTextMarshaler2 148 m := map[key]int{{ 149 data: "a", 150 }: 1} 151 checkEncodeValueWithStandard(t, m, TypeNotSupportedError("")) 152 }) 153 t.Run("marshaler 2-pointer", func(t *testing.T) { 154 t.Run("no error", func(t *testing.T) { 155 type key = *testTextMarshaler2 156 m := map[key]int{{ 157 data: "a", 158 }: 1} 159 checkEncodeValueWithStandard(t, m, nil) 160 }) 161 t.Run("error", func(t *testing.T) { 162 e := errors.New("test") 163 type key = *testTextMarshaler2 164 m := map[key]int{{ 165 data: "a", 166 err: e, 167 }: 1} 168 checkEncodeValueWithStandard(t, m, e) 169 }) 170 t.Run("nil", func(t *testing.T) { 171 type key = *testTextMarshaler2 172 m := map[key]int{nil: 1} 173 v := "go1.13.15" 174 if goVersion.LessEqual(v) { 175 b, err := Marshal(m) 176 require.NoError(t, err) 177 require.Equal(t, `{"":1}`, string(b)) 178 } else { 179 checkEncodeValueWithStandard(t, m, nil) 180 } 181 }) 182 }) 183 t.Run("int key", func(t *testing.T) { 184 t.Run("value", func(t *testing.T) { 185 m := map[testMapIntKey2]testMapIntKey2{ 186 1: 2, 187 } 188 checkEncodeValueWithStandard(t, m, nil) 189 }) 190 t.Run("ptr", func(t *testing.T) { 191 m := map[testMapIntKey2Ptr]testMapIntKey2Ptr{ 192 1: 2, 193 } 194 checkEncodeValueWithStandard(t, m, nil) 195 }) 196 }) 197 t.Run("string key", func(t *testing.T) { 198 t.Run("value", func(t *testing.T) { 199 // the MarshalText of the key is ignored 200 m := map[testMapStringKey2]testMapStringKey2{ 201 "key": "value", 202 } 203 checkEncodeValueWithStandard(t, m, nil) 204 }) 205 t.Run("ptr", func(t *testing.T) { 206 // the MarshalText of the key is ignored 207 m := map[testMapStringKey2Ptr]testMapStringKey2Ptr{ 208 "key": "value", 209 } 210 checkEncodeValueWithStandard(t, m, nil) 211 }) 212 }) 213 } 214 215 func TestValEncoder_Native_Map_KeyEncoder_String(t *testing.T) { 216 t.Run("string", func(t *testing.T) { 217 type key string 218 m := map[key]int{"a": 1} 219 checkEncodeValueWithStandard(t, m, nil) 220 }) 221 } 222 223 func TestValEncoder_Native_Map_KeyEncoder_Int(t *testing.T) { 224 t.Run("int8", func(t *testing.T) { 225 type key int8 226 m := map[key]key{ 227 math.MaxInt8: math.MaxInt8, 228 math.MinInt8: math.MinInt8, 229 } 230 checkEncodeValueWithStandard(t, m, nil) 231 }) 232 t.Run("int16", func(t *testing.T) { 233 type key int16 234 m := map[key]key{ 235 math.MaxInt16: math.MaxInt16, 236 math.MinInt16: math.MinInt16, 237 } 238 checkEncodeValueWithStandard(t, m, nil) 239 }) 240 t.Run("int32", func(t *testing.T) { 241 type key int32 242 m := map[key]key{ 243 math.MaxInt32: math.MaxInt32, 244 math.MinInt32: math.MinInt32, 245 } 246 checkEncodeValueWithStandard(t, m, nil) 247 }) 248 t.Run("int64", func(t *testing.T) { 249 type key int64 250 m := map[key]key{ 251 math.MaxInt64: math.MaxInt64, 252 math.MinInt64: math.MinInt64, 253 } 254 checkEncodeValueWithStandard(t, m, nil) 255 }) 256 } 257 258 func TestValEncoder_Native_Map_KeyEncoder_Uint(t *testing.T) { 259 t.Run("uint8", func(t *testing.T) { 260 type key uint8 261 m := map[key]key{ 262 math.MaxUint8: math.MaxUint8, 263 } 264 checkEncodeValueWithStandard(t, m, nil) 265 }) 266 t.Run("uint16", func(t *testing.T) { 267 type key uint16 268 m := map[key]key{ 269 math.MaxUint16: math.MaxUint16, 270 } 271 checkEncodeValueWithStandard(t, m, nil) 272 }) 273 t.Run("uint32", func(t *testing.T) { 274 type key uint32 275 m := map[key]key{ 276 math.MaxUint32: math.MaxUint32, 277 } 278 checkEncodeValueWithStandard(t, m, nil) 279 }) 280 t.Run("uint64", func(t *testing.T) { 281 type key uint64 282 m := map[key]key{ 283 math.MaxUint64: math.MaxUint64, 284 } 285 checkEncodeValueWithStandard(t, m, nil) 286 }) 287 } 288 289 func TestValEncoder_Map_OmitEmpty(t *testing.T) { 290 t.Run("normal", func(t *testing.T) { 291 type M map[int]int 292 type st struct { 293 M M `json:",omitempty"` 294 } 295 t.Run("nil", func(t *testing.T) { 296 checkEncodeValueWithStandard(t, st{}, nil) 297 }) 298 t.Run("empty", func(t *testing.T) { 299 checkEncodeValueWithStandard(t, st{ 300 M: M{}, 301 }, nil) 302 }) 303 t.Run("non empty", func(t *testing.T) { 304 checkEncodeValueWithStandard(t, st{ 305 M: M{1: 2}, 306 }, nil) 307 }) 308 }) 309 }