github.com/RevenueMonster/sqlike@v1.0.6/jsonb/unmarshal_test.go (about) 1 package jsonb 2 3 import ( 4 "encoding/base64" 5 "encoding/json" 6 "io/ioutil" 7 "testing" 8 "time" 9 10 "github.com/RevenueMonster/sqlike/types" 11 "github.com/google/uuid" 12 "github.com/stretchr/testify/require" 13 "golang.org/x/text/currency" 14 "golang.org/x/text/language" 15 ) 16 17 type User struct { 18 Name string 19 Email string 20 Age int 21 UUID uuid.UUID 22 } 23 24 type ptrStruct struct { 25 PtrStr *string 26 PtrByte *[]byte 27 PtrBool *bool 28 PtrInt *int 29 PtrInt8 *int8 30 PtrInt16 *int16 31 PtrInt32 *int32 32 PtrInt64 *int64 33 PtrUint *uint 34 PtrUint8 *uint8 35 PtrUint16 *uint16 36 PtrUint32 *uint32 37 PtrUint64 *uint64 38 PtrFloat32 *float32 39 PtrFloat64 *float64 40 PtrJSONRaw *json.RawMessage 41 PtrJSONNumber *json.Number 42 PtrStrSlice *[]string 43 PtrIntSlice *[]int 44 PtrUintSlice *[]uint 45 PtrF32Slice *[]float32 46 PtrF64Slice *[]float64 47 PtrLanguageTag *language.Tag 48 PtrCurrencyUnit *currency.Unit 49 PtrUUID *uuid.UUID 50 PtrTime *time.Time 51 PtrStruct *struct { 52 Nested string 53 } 54 } 55 56 type testStruct struct { 57 Str string 58 UUID *****uuid.UUID 59 BigDecimal float64 60 SymbolStr string 61 EscapeStr string 62 StrSlice []string 63 Users []User 64 Nested struct { 65 NilKey *types.Key 66 MultiNilPtrKey ******types.Key 67 Key *types.Key 68 MultiPtr ***string 69 Security struct { 70 PrivateKey []byte 71 } 72 Test string 73 Test2 string 74 Nested struct { 75 Deep struct { 76 Value float64 `sqlike:"value"` 77 } `sqlike:"deep1"` 78 YOLO string `sqlike:"deep2"` 79 } `sqlike:"nested"` 80 } 81 EmptyStruct struct{} 82 Integer int 83 Bool bool 84 } 85 86 type customKey struct { 87 value string 88 } 89 90 func (c *customKey) UnmarshalText(b []byte) error { 91 *c = customKey{value: string(b)} 92 return nil 93 } 94 95 func TestUnmarshal(t *testing.T) { 96 var ( 97 strval = `hello world !!!!!!` 98 symbolstrval = `\n\t\t\t<html>\n\t\t\t\t<div>Hello World</div>\n\t\t\t</html>\n\t\t\ttesting with !@#$%^&*(_)()()_()_((*??D|}A||||\\\\))\n\t\t` 99 byteval = []byte(`LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlDWFFJQkFBS0JnUUMrYUlTemtOdXFiZmdxWW9IYW1iS0dyaEF6UnV0dWYydWFzOUJIeXllUFJUdUk5ZVdwCnJHY3lRZlhPVlh2OGJBZVMxK2tIS0MvK1ZDTk9EbGZBTFlQWVVZa053eHVvRnFMbU1SR3E1MzMwSEVLSUpySDcKSUU5aUs0QUVZL3h5WjBTUEp5ZkNnQ2ZaeGtJTmpacWFoSS8rVWxrL1BmdWwyaEQ0ZTNUZVpGTm5HUUlEQVFBQgpBb0dBSHpOYlExMWlVV3dSdFVoTkJQZ1lnKzh6NG1NbG93YW9LRUo4eDdibmRaZWZxTks2WG5KTXVyU0tSZFJHCks5ZTc2ZmtOUzBudmkxcFlLcXM0LzltMWQ4Mk9XdmtDeXZvR3pmRXdyNGJ6bVBBZjdkczVkWElhb29wbWV4WWwKbFpsSmtuMDhWNFJmOWc4RFEyNFRsb3BpZ3RrSzY5UktRSzFHaHVyV1A4UjVxeTBDUVFEZ3dxcGVKZFF5RUdaYgpQUElJN2ZsSUVDRjlQNnNVc1ovNW40cEhNNmg2N0dOdGU1cEx4bDkzOXYybVhaN09aSUZHQU1rUmNDL1ZIK3c4Cm5oaytaNE9yQWtFQTJOK01oOWRpN1YreldaNUNIWXBWTHM5Qi9xOVl3YjFCNjN0UnZUbG9QSnFqTHc1NDUzZUUKbEs0ZnJSaVhXbEhLaUpLYlBOTU1ZUVkyTVRrcEQ2dDhTd0pCQUlkU2JRVFdQZFlPcmJITkZlUnVjeUlDSkVlbQpwN2lENFUrSDBOZGhzTlNoc3BOZVVkM0JpQVZRZmhOR1ZyRHBMalFaa1BXZzJBdTNkcUpnaGM1ZXdKVUNRQUVFCkV4RnoxZGZNMGZkQ2dZYkg1aHhCQmtzZUlTbFBMS2JndmdKSDZaQVhIVnFVRThicHpXb3c0cDhaOVdPTDdJbjEKUGRyc0ZpdkNMckRPVnIzbkRMOENRUURKSENwSEVFNTc0ckpzblJNYk5rR0F5dmZheW9MeElhVUF5WXovaGxrMgpzQ0wzb3BsdDNYM0tjYzV1MkRISVFsZTdGM1M4Wmp4REZMSVRrbnJ4QS9UVgotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQ==`) 100 nullval = []byte(`null`) 101 ) 102 103 var ( 104 pk []byte 105 b []byte 106 err error 107 ) 108 109 t.Run("Unmarshal RawMessage", func(it *testing.T) { 110 var ( 111 b = []byte(`{ 112 "Raw": { 113 "Title": "Header", 114 "Body": {} 115 }, 116 "Nested" : { 117 "DeepNested" : { 118 "RawObject" : { 119 "Name" : "john", 120 "Email" : "john@hotmail.com", 121 "Emoji": " π π π ", 122 "Age" : 28 123 }, 124 "RawStr" : "hello world!", 125 "RawNumber": 189202.882 126 } 127 } 128 }`) 129 o struct { 130 Raw json.RawMessage 131 Nested struct { 132 DeepNested struct { 133 RawObject json.RawMessage 134 RawStr json.RawMessage 135 RawNumber json.RawMessage 136 } 137 } 138 } 139 ) 140 141 err = Unmarshal(b, &o) 142 require.NoError(it, err) 143 require.Equal(it, json.RawMessage(`{"Title":"Header","Body":{}}`), o.Raw) 144 require.Equal(it, json.RawMessage(`{"Name":"john","Email":"john@hotmail.com","Emoji":" π π π ","Age":28}`), o.Nested.DeepNested.RawObject) 145 require.Equal(it, json.RawMessage(`"hello world!"`), o.Nested.DeepNested.RawStr) 146 require.Equal(it, json.RawMessage(`189202.882`), o.Nested.DeepNested.RawNumber) 147 require.Equal(it, json.RawMessage(`"hello world!"`), o.Nested.DeepNested.RawStr) 148 }) 149 150 { 151 pk, err = ioutil.ReadFile("./../examples/pk.pem") 152 require.NoError(t, err) 153 b, err = base64.StdEncoding.DecodeString(string(byteval)) 154 require.NoError(t, err) 155 require.Equal(t, b, pk) 156 } 157 158 t.Run("Unmarshal UUID", func(it *testing.T) { 159 var uid uuid.UUID 160 err = Unmarshal([]byte(`"4c03d1de-645b-40d2-9ed5-12bb537a602e"`), &uid) 161 require.NoError(t, err) 162 require.Equal(t, uuid.MustParse("4c03d1de-645b-40d2-9ed5-12bb537a602e"), uid) 163 164 var ptruid *****uuid.UUID 165 err = Unmarshal([]byte(`"4c03d1de-645b-40d2-9ed5-12bb537a602e"`), &ptruid) 166 require.NoError(t, err) 167 require.NotNil(t, ptruid) 168 require.Equal(t, uuid.MustParse("4c03d1de-645b-40d2-9ed5-12bb537a602e"), *****ptruid) 169 170 var nilUUID *uuid.UUID 171 err = Unmarshal([]byte(`null`), &nilUUID) 172 require.NoError(t, err) 173 require.Nil(t, nilUUID) 174 }) 175 176 t.Run("Unmarshal String", func(it *testing.T) { 177 var ( 178 addrptr *string 179 nilptr *string 180 ) 181 182 err = Unmarshal([]byte(`null`), &addrptr) 183 require.NoError(t, err) 184 require.Equal(t, nilptr, addrptr) 185 186 var str string 187 err = Unmarshal([]byte(`"`+strval+`"`), &str) 188 require.Equal(it, strval, str) 189 require.NoError(t, err) 190 191 output := ` 192 <html> 193 <div>Hello World</div> 194 </html> 195 testing with !@#$%^&*(_)()()_()_((*??D|}A||||\\)) 196 ` 197 198 var symbolstr string 199 err = Unmarshal([]byte(`"`+symbolstrval+`"`), &symbolstr) 200 require.NoError(t, err) 201 require.Equal(it, output, symbolstr) 202 203 err = Unmarshal(nullval, &str) 204 require.NoError(t, err) 205 require.Equal(it, "", str) 206 207 var uinitstr *string 208 err = Unmarshal([]byte(`null`), uinitstr) 209 require.Error(t, err) 210 211 err = Unmarshal([]byte(`null`), nil) 212 require.Error(t, err) 213 }) 214 215 t.Run("Unmarshal Boolean", func(it *testing.T) { 216 var flag bool 217 err = Unmarshal([]byte(`true`), &flag) 218 require.NoError(t, err) 219 require.Equal(it, true, flag) 220 221 err = Unmarshal([]byte(`false`), &flag) 222 require.NoError(t, err) 223 require.Equal(it, false, flag) 224 225 err = Unmarshal(nullval, &flag) 226 require.NoError(it, err) 227 require.Equal(it, false, flag) 228 }) 229 230 t.Run("Unmarshal Integer", func(it *testing.T) { 231 var ( 232 i8 int8 233 i16 int16 234 i32 int32 235 i64 int64 236 i int 237 ) 238 239 err = Unmarshal([]byte(`10`), &i8) 240 require.NoError(t, err) 241 require.Equal(it, int8(10), i8) 242 243 err = Unmarshal([]byte(`-10`), &i8) 244 require.NoError(t, err) 245 require.Equal(it, int8(-10), i8) 246 247 err = Unmarshal(nullval, &i8) 248 require.NoError(t, err) 249 require.Equal(it, int8(0), i8) 250 251 err = Unmarshal([]byte(`128`), &i16) 252 require.NoError(t, err) 253 require.Equal(it, int16(128), i16) 254 255 err = Unmarshal([]byte(`-128`), &i16) 256 require.NoError(t, err) 257 require.Equal(it, int16(-128), i16) 258 259 err = Unmarshal(nullval, &i16) 260 require.NoError(t, err) 261 require.Equal(it, int16(0), i16) 262 263 err = Unmarshal([]byte(`1354677198`), &i32) 264 require.NoError(t, err) 265 require.Equal(it, int32(1354677198), i32) 266 267 err = Unmarshal([]byte(`-1354677198`), &i32) 268 require.NoError(t, err) 269 require.Equal(it, int32(-1354677198), i32) 270 271 err = Unmarshal(nullval, &i32) 272 require.NoError(t, err) 273 require.Equal(it, int32(0), i32) 274 275 err = Unmarshal([]byte(`7354673213123121983`), &i64) 276 require.NoError(t, err) 277 require.Equal(it, int64(7354673213123121983), i64) 278 279 err = Unmarshal([]byte(`-7354673213123121983`), &i64) 280 require.NoError(t, err) 281 require.Equal(it, int64(-7354673213123121983), i64) 282 283 err = Unmarshal(nullval, &i64) 284 require.NoError(t, err) 285 require.Equal(it, int64(0), i64) 286 287 err = Unmarshal([]byte(`1354677198`), &i) 288 require.NoError(t, err) 289 require.Equal(it, int(1354677198), i) 290 291 err = Unmarshal([]byte(`-1354677198`), &i) 292 require.NoError(t, err) 293 require.Equal(it, int(-1354677198), i) 294 295 err = Unmarshal(nullval, &i) 296 require.NoError(t, err) 297 require.Equal(it, int(0), i) 298 }) 299 300 t.Run("Unmarshal Unsigned Integer", func(it *testing.T) { 301 var ( 302 ui8 uint8 303 ui16 uint16 304 ui32 uint32 305 ui64 uint64 306 ui uint 307 ) 308 309 err = Unmarshal([]byte(`10`), &ui8) 310 require.NoError(t, err) 311 require.Equal(it, uint8(10), ui8) 312 313 err = Unmarshal([]byte(`-10`), &ui8) 314 require.Error(t, err) 315 316 err = Unmarshal(nullval, &ui8) 317 require.NoError(t, err) 318 require.Equal(it, uint8(0), ui8) 319 320 err = Unmarshal([]byte(`128`), &ui16) 321 require.NoError(t, err) 322 require.Equal(it, uint16(128), ui16) 323 324 err = Unmarshal([]byte(`-128`), &ui16) 325 require.Error(t, err) 326 327 err = Unmarshal(nullval, &ui16) 328 require.NoError(t, err) 329 require.Equal(it, uint16(0), ui16) 330 331 err = Unmarshal([]byte(`1354677198`), &ui32) 332 require.NoError(t, err) 333 require.Equal(it, uint32(1354677198), ui32) 334 335 err = Unmarshal([]byte(`-1354677198`), &ui32) 336 require.Error(t, err) 337 338 err = Unmarshal(nullval, &ui32) 339 require.NoError(t, err) 340 require.Equal(it, uint32(0), ui32) 341 342 err = Unmarshal([]byte(`7354673213123121983`), &ui64) 343 require.NoError(t, err) 344 require.Equal(it, uint64(7354673213123121983), ui64) 345 346 err = Unmarshal([]byte(`-7354673213123121983`), &ui64) 347 require.Error(t, err) 348 349 err = Unmarshal(nullval, &ui64) 350 require.NoError(t, err) 351 require.Equal(it, uint64(0), ui64) 352 353 err = Unmarshal([]byte(`1354677198`), &ui) 354 require.NoError(t, err) 355 require.Equal(it, uint(1354677198), ui) 356 357 err = Unmarshal([]byte(`-1354677198`), &ui) 358 require.Error(t, err) 359 360 err = Unmarshal(nullval, &ui) 361 require.NoError(t, err) 362 require.Equal(it, uint(0), ui) 363 }) 364 365 t.Run("Unmarshal Float", func(it *testing.T) { 366 var ( 367 f32 float32 368 f64 float64 369 ) 370 371 err = Unmarshal([]byte(`10`), &f32) 372 require.NoError(t, err) 373 require.Equal(it, float32(10), f32) 374 375 err = Unmarshal([]byte(`10.32`), &f32) 376 require.NoError(t, err) 377 require.Equal(it, float32(10.32), f32) 378 379 err = Unmarshal([]byte(`-882.3261239`), &f32) 380 require.NoError(t, err) 381 require.Equal(it, float32(-882.3261239), f32) 382 383 err = Unmarshal([]byte(`-128.32128392`), &f64) 384 require.NoError(t, err) 385 require.Equal(it, float64(-128.32128392), f64) 386 387 err = Unmarshal([]byte(`10.32128392`), &f64) 388 require.NoError(t, err) 389 require.Equal(it, float64(10.32128392), f64) 390 }) 391 392 t.Run("Unmarshal Byte", func(it *testing.T) { 393 b = []byte(`"` + string(byteval) + `"`) 394 var bytea []byte 395 err = Unmarshal(b, &bytea) 396 require.NoError(t, err) 397 require.Equal(t, pk, bytea) 398 399 bytea = []byte(nil) 400 err = Unmarshal(nullval, &bytea) 401 require.NoError(t, err) 402 require.Equal(t, []byte(nil), bytea) 403 }) 404 405 t.Run("Unmarshal Time", func(it *testing.T) { 406 var dt time.Time 407 date := `2018-01-02T15:04:33Z` 408 b = []byte(`"` + date + `"`) 409 410 err = Unmarshal(b, &dt) 411 require.NoError(t, err) 412 require.Equal(t, date, dt.UTC().Format(time.RFC3339)) 413 414 err = Unmarshal(nullval, &dt) 415 require.NoError(t, err) 416 require.Equal(t, `0001-01-01T00:00:00Z`, dt.UTC().Format(time.RFC3339)) 417 }) 418 419 t.Run("Unmarshal Array", func(it *testing.T) { 420 var ( 421 nullArr []string 422 initArr []int 423 strArr []string 424 intArr []int 425 twoDArr [][]int 426 threeDArr [][][]string 427 ) 428 429 nullArr = []string{"xyz"} 430 err = Unmarshal(nullval, &nullArr) 431 require.NoError(t, err) 432 require.Equal(t, []string(nil), nullArr) 433 434 err = Unmarshal([]byte(`null`), &nullArr) 435 require.NoError(t, err) 436 require.Equal(t, []string(nil), nullArr) 437 438 err = Unmarshal([]byte("[]"), &initArr) 439 require.NoError(t, err) 440 require.NotNil(t, initArr) 441 require.Equal(t, make([]int, 0), initArr) 442 443 err = Unmarshal([]byte(`["a", "b", "c"]`), &strArr) 444 require.NoError(t, err) 445 require.ElementsMatch(t, []string{"a", "b", "c"}, strArr) 446 447 err = Unmarshal([]byte(`[2, 8, 32, 64, 128]`), &intArr) 448 require.NoError(t, err) 449 require.ElementsMatch(t, []int{2, 8, 32, 64, 128}, intArr) 450 451 err = Unmarshal([]byte(`[ 452 [2, 8, 32, 64, 128], 453 [1, 3, 5, 7], 454 [0, 100, 1000, 10000, 100000] 455 ]`), &twoDArr) 456 require.ElementsMatch(t, [][]int{ 457 {2, 8, 32, 64, 128}, 458 {1, 3, 5, 7}, 459 {0, 100, 1000, 10000, 100000}, 460 }, twoDArr) 461 require.NoError(t, err) 462 463 err = Unmarshal([]byte(`[ 464 [ 465 ["a", "b", "c", "d", "e"], 466 ["η²", "δΉ", "δΈ", "δΈ"], 467 ["π", "π ", "π", "π", "π"] 468 ], 469 [ 470 ["a", "b", "c", "d", "e"], 471 ["f", "g", "h", "i", "j"] 472 ], 473 [ 474 ["Java", "JavaScript", "TypeScript"], 475 ["Rust", "GoLang"] 476 ] 477 ]`), &threeDArr) 478 require.NoError(t, err) 479 require.ElementsMatch(t, [][][]string{{ 480 []string{"a", "b", "c", "d", "e"}, 481 []string{"η²", "δΉ", "δΈ", "δΈ"}, 482 []string{"π", "π ", "π", "π", "π"}, 483 }, { 484 []string{"a", "b", "c", "d", "e"}, 485 []string{"f", "g", "h", "i", "j"}, 486 }, { 487 []string{"Java", "JavaScript", "TypeScript"}, 488 []string{"Rust", "GoLang"}, 489 }}, threeDArr) 490 491 b := []byte(`[{"Name": "John", 492 "Email": "john@hotmail.com" , 493 "Age" : 20, 494 }, {"Name": " π π π π π π π π π", 495 "Email": "test@hotmail.com" , 496 "Age" : 88, 497 "UUID": "daa68da0-8890-11ea-bc55-0242ac130003" 498 }]`) 499 500 users := []User{} 501 err = Unmarshal(b, &users) 502 require.NoError(t, err) 503 id := uuid.MustParse("daa68da0-8890-11ea-bc55-0242ac130003") 504 require.ElementsMatch(t, []User{ 505 {Name: "John", Email: "john@hotmail.com", Age: 20}, 506 {Name: " π π π π π π π π π", Email: "test@hotmail.com", Age: 88, UUID: id}, 507 }, users) 508 509 type recursiveNestedStruct struct { 510 Unicode string 511 String string 512 Boolean bool 513 Integer int 514 Level uint 515 Recursive *recursiveNestedStruct 516 Float float64 517 Time time.Time 518 Nested *struct { 519 Name string 520 No int 521 StrSlice []string 522 } 523 } 524 525 b = []byte(` 526 [{ 527 "Unicode" : "δΈε½β ", 528 "String": "hello world", 529 "Level" : 1, 530 "Time": "2017-02-05T03:46:15Z", 531 "Recursive": {}, 532 "Nested": { 533 "No" : 2, 534 "StrSlice": ["a", "b", "c"], 535 } 536 }] 537 `) 538 539 structs := []recursiveNestedStruct{} 540 err = Unmarshal(b, &structs) 541 require.NoError(t, err) 542 543 f := structs[0] 544 require.NotNil(t, f.Nested) 545 require.Equal(t, "δΈε½β ", f.Unicode) 546 require.Equal(t, uint(1), f.Level) 547 require.Equal(t, "hello world", f.String) 548 require.Equal(t, 2, f.Nested.No) 549 require.ElementsMatch(t, []string{"a", "b", "c"}, f.Nested.StrSlice) 550 }) 551 552 t.Run("Unmarshal Map", func(it *testing.T) { 553 data := make(map[customKey]string) 554 555 err = Unmarshal([]byte(`{"test":"hello" , "test2": "world"}`), &data) 556 require.NoError(t, err) 557 558 k1 := customKey{value: "test"} 559 k2 := customKey{value: "test2"} 560 561 require.Contains(t, data, k1) 562 require.Contains(t, data, k2) 563 564 require.Equal(t, data[k1], "hello") 565 require.Equal(t, data[k2], "world") 566 }) 567 568 t.Run("Unmarshal Struct", func(it *testing.T) { 569 { 570 // unmarshal with empty object {} 571 b = []byte(` { } `) 572 var a struct{} 573 err = Unmarshal(b, &a) 574 require.NoError(it, err) 575 require.Equal(t, struct{}{}, a) 576 } 577 578 { 579 b = []byte(` 580 { 581 "Str" :"hello world!!" , 582 "UUID": "4c03d1de-645b-40d2-9ed5-12bb537a602e", 583 "SymbolStr" : "x1#$%^\t!\n\t\t@#$%^&*())))?\\<>.,/:\":;'{}[]-=+_~", 584 "EscapeStr" : "<html><div>hello world!</div></html>", 585 "StrSlice" : ["a", "b", "c", "d"], 586 "Users" : [ 587 {"Name":"SianLoong", "Age": 18} , 588 { "Name":"Junkai"}], 589 "Nested": { 590 "NilKey": null, 591 "MultiNilPtrKey": null, 592 "MultiPtr": "testing \"multiple\" pointer", 593 "Security" : { 594 "PrivateKey": "LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlDWFFJQkFBS0JnUUMrYUlTemtOdXFiZmdxWW9IYW1iS0dyaEF6UnV0dWYydWFzOUJIeXllUFJUdUk5ZVdwCnJHY3lRZlhPVlh2OGJBZVMxK2tIS0MvK1ZDTk9EbGZBTFlQWVVZa053eHVvRnFMbU1SR3E1MzMwSEVLSUpySDcKSUU5aUs0QUVZL3h5WjBTUEp5ZkNnQ2ZaeGtJTmpacWFoSS8rVWxrL1BmdWwyaEQ0ZTNUZVpGTm5HUUlEQVFBQgpBb0dBSHpOYlExMWlVV3dSdFVoTkJQZ1lnKzh6NG1NbG93YW9LRUo4eDdibmRaZWZxTks2WG5KTXVyU0tSZFJHCks5ZTc2ZmtOUzBudmkxcFlLcXM0LzltMWQ4Mk9XdmtDeXZvR3pmRXdyNGJ6bVBBZjdkczVkWElhb29wbWV4WWwKbFpsSmtuMDhWNFJmOWc4RFEyNFRsb3BpZ3RrSzY5UktRSzFHaHVyV1A4UjVxeTBDUVFEZ3dxcGVKZFF5RUdaYgpQUElJN2ZsSUVDRjlQNnNVc1ovNW40cEhNNmg2N0dOdGU1cEx4bDkzOXYybVhaN09aSUZHQU1rUmNDL1ZIK3c4Cm5oaytaNE9yQWtFQTJOK01oOWRpN1YreldaNUNIWXBWTHM5Qi9xOVl3YjFCNjN0UnZUbG9QSnFqTHc1NDUzZUUKbEs0ZnJSaVhXbEhLaUpLYlBOTU1ZUVkyTVRrcEQ2dDhTd0pCQUlkU2JRVFdQZFlPcmJITkZlUnVjeUlDSkVlbQpwN2lENFUrSDBOZGhzTlNoc3BOZVVkM0JpQVZRZmhOR1ZyRHBMalFaa1BXZzJBdTNkcUpnaGM1ZXdKVUNRQUVFCkV4RnoxZGZNMGZkQ2dZYkg1aHhCQmtzZUlTbFBMS2JndmdKSDZaQVhIVnFVRThicHpXb3c0cDhaOVdPTDdJbjEKUGRyc0ZpdkNMckRPVnIzbkRMOENRUURKSENwSEVFNTc0ckpzblJNYk5rR0F5dmZheW9MeElhVUF5WXovaGxrMgpzQ0wzb3BsdDNYM0tjYzV1MkRISVFsZTdGM1M4Wmp4REZMSVRrbnJ4QS9UVgotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQ==" 595 }, 596 "Test" :"hello world!!" , 597 "Test2" :"hello world!!" , 598 "Testxx" :"hello world!!" , 599 "empty" : {}, 600 "nested" : { 601 "deep0" : 100, 602 "deep1" : { 603 "value" : 199303.00 604 }, 605 "deep2": "YOLO" 606 } 607 }, 608 "BigDecimal": 100.111, 609 "Integer": 6000, 610 "Bool": true 611 }`) 612 613 cp := make([]byte, len(b)) 614 copy(cp, b) 615 616 var ( 617 o testStruct 618 nilKey *types.Key 619 multiNilKey ******types.Key 620 ) 621 622 o.Nested.Key = types.IDKey("XX", 100, nil) 623 624 err = Unmarshal(cp, &o) 625 require.NoError(t, err) 626 627 require.Nil(t, o.Nested.Key) 628 require.Equal(t, nilKey, o.Nested.Key) 629 630 require.Nil(t, o.Nested.NilKey) 631 require.Equal(t, nilKey, o.Nested.NilKey) 632 633 require.Nil(t, o.Nested.MultiNilPtrKey) 634 require.Equal(t, multiNilKey, o.Nested.MultiNilPtrKey) 635 636 // after unmarshal, the input should be the same (input shouldn't modified) 637 require.Equal(t, uuid.MustParse(`4c03d1de-645b-40d2-9ed5-12bb537a602e`), *****o.UUID) 638 require.Equal(t, `testing "multiple" pointer`, ***o.Nested.MultiPtr) 639 require.Equal(t, b, cp) 640 require.Equal(t, `hello world!!`, o.Str) 641 require.Equal(t, `x1#$%^ ! 642 @#$%^&*())))?\<>.,/:":;'{}[]-=+_~`, o.SymbolStr) 643 require.Equal(t, pk, o.Nested.Security.PrivateKey) 644 require.Equal(t, true, o.Bool) 645 require.Equal(t, int(6000), o.Integer) 646 require.Equal(t, float64(100.111), o.BigDecimal) 647 require.ElementsMatch(t, []User{ 648 {Name: "SianLoong", Age: 18}, 649 {Name: "Junkai"}, 650 }, o.Users) 651 require.ElementsMatch(t, []string{"a", "b", "c", "d"}, o.StrSlice) 652 } 653 654 { 655 var i User 656 i.Name = "testing" 657 i.Email = "sianloong90@gmail.com" 658 i.Age = 100 659 err = Unmarshal(nullval, &i) 660 require.NoError(t, err) 661 require.Equal(t, User{}, i) 662 } 663 664 { 665 u := new(User) 666 u.Name = "testing" 667 err = Unmarshal([]byte(`{"Name": "lol", "Email":"test@hotmail.com", "Age": 18}`), u) 668 require.NoError(t, err) 669 require.Equal(t, "lol", u.Name) 670 require.Equal(t, "test@hotmail.com", u.Email) 671 require.Equal(t, int(18), u.Age) 672 } 673 }) 674 675 t.Run("Unmarshal Pointer Struct", func(it *testing.T) { 676 var ptr *ptrStruct 677 err = Unmarshal([]byte(`null`), &ptr) 678 require.NoError(t, err) 679 680 var nilptr *ptrStruct 681 require.Equal(t, nilptr, ptr) 682 683 initPtr := new(ptrStruct) 684 err = Unmarshal([]byte(`{ 685 "PtrStr": "testing {}!@#$%^&*(\\", 686 "PtrBool": true, 687 "PtrInt": -100, 688 "PtrInt8": -88, 689 "PtrInt16": 8814, 690 "PtrInt64": -88818111321351212, 691 "PtrUint": 718222455, 692 "PtrUint8": 173, 693 "PtrUint16": 8814, 694 "PtrUint32": 2031273814, 695 "PtrUint64": 88818111321351212, 696 "PtrStrSlice" : ["a", "b", "c", "d"], 697 "PtrJSONRaw": { "k1" : "value" , "k2" : " value 1312$%^&*"}, 698 "PtrJSONNumber" : 183939.778, 699 "PtrUintSlice" : [7, 88, 199, 200], 700 "PtrF32Slice" : [10.88, 728.99, 722.00], 701 "PtrCurrencyUnit" : "MYR", 702 "PtrLanguageTag" : "en", 703 "PtrTime": "2008-01-26T00:00:58Z" 704 }`), initPtr) 705 require.NoError(t, err) 706 707 { 708 str := `testing {}!@#$%^&*(\` 709 require.Equal(t, &str, initPtr.PtrStr) 710 flag := true 711 require.Equal(t, &flag, initPtr.PtrBool) 712 } 713 714 { 715 i := int(-100) 716 require.Equal(t, &i, initPtr.PtrInt) 717 i8 := int8(-88) 718 require.Equal(t, &i8, initPtr.PtrInt8) 719 i16 := int16(8814) 720 require.Equal(t, &i16, initPtr.PtrInt16) 721 i64 := int64(-88818111321351212) 722 require.Equal(t, &i64, initPtr.PtrInt64) 723 } 724 725 { 726 ui := uint(718222455) 727 require.Equal(t, &ui, initPtr.PtrUint) 728 ui8 := uint8(173) 729 require.Equal(t, &ui8, initPtr.PtrUint8) 730 ui16 := uint16(8814) 731 require.Equal(t, &ui16, initPtr.PtrUint16) 732 ui32 := uint32(2031273814) 733 require.Equal(t, &ui32, initPtr.PtrUint32) 734 ui64 := uint64(88818111321351212) 735 require.Equal(t, &ui64, initPtr.PtrUint64) 736 } 737 738 { 739 var nilByte *[]byte 740 require.Equal(t, nilByte, initPtr.PtrByte) 741 } 742 743 { 744 raw := json.RawMessage(`{"k1":"value","k2":" value 1312$%^&*"}`) 745 require.Equal(t, &raw, initPtr.PtrJSONRaw) 746 } 747 748 { 749 num := json.Number("183939.778") 750 require.Equal(t, &num, initPtr.PtrJSONNumber) 751 f64, _ := initPtr.PtrJSONNumber.Float64() 752 require.Equal(t, float64(183939.778), f64) 753 i64, _ := initPtr.PtrJSONNumber.Int64() 754 require.Equal(t, int64(0), i64) 755 } 756 757 { 758 slice := []string{"a", "b", "c", "d"} 759 require.Equal(t, &slice, initPtr.PtrStrSlice) 760 } 761 762 { 763 require.Nil(it, initPtr.PtrUUID) 764 require.Nil(it, initPtr.PtrIntSlice) 765 } 766 767 { 768 slice := []uint{7, 88, 199, 200} 769 require.Equal(t, &slice, initPtr.PtrUintSlice) 770 } 771 772 { 773 slice := []float32{10.88, 728.99, 722.00} 774 require.Equal(t, &slice, initPtr.PtrF32Slice) 775 } 776 777 { 778 lang := language.English 779 require.Equal(t, &lang, initPtr.PtrLanguageTag) 780 } 781 782 { 783 unit, _ := currency.ParseISO("MYR") 784 require.Equal(t, &unit, initPtr.PtrCurrencyUnit) 785 } 786 787 { 788 dt, _ := time.Parse(time.RFC3339, "2008-01-26T00:00:58Z") 789 require.Equal(t, &dt, initPtr.PtrTime) 790 } 791 }) 792 } 793 794 func BenchmarkJSONUnmarshal(b *testing.B) { 795 data := []byte(` 796 { 797 "Test" :"hello world!!" , 798 "Test2" : "x1#$%^&*xx", 799 "Test4": { 800 "Test" :"hello world!!" , 801 "Test2" :"hello world!!" , 802 "Testxx" :"hello world!!" , 803 "empty" : {}, 804 "nested" : { 805 "deep0" : 100, 806 "deep1" : { 807 "value" : 199303.00 808 }, 809 "deep2": "YOLO" 810 } 811 }, 812 "Test0": 100.111, 813 "Test99": 6000, 814 "Bool": true 815 } 816 817 `) 818 var ( 819 o testStruct 820 err error 821 ) 822 823 for n := 0; n < b.N; n++ { 824 err = json.Unmarshal(data, &o) 825 require.NoError(b, err) 826 } 827 } 828 829 func BenchmarkJSONBUnmarshal(b *testing.B) { 830 // data := []byte(` 831 // { 832 // "Test" :"hello world!!" , 833 // "Test2" : "x1#$%^&*xx", 834 // "Test4": { 835 // "Test" :"hello world!!" , 836 // "Test2" :"hello world!!" , 837 // "Testxx" :"hello world!!" , 838 // "empty" : {}, 839 // "nested" : { 840 // "deep0" : 100, 841 // "deep1" : { 842 // "value" : 199303.00 843 // }, 844 // "deep2": "YOLO" 845 // } 846 // }, 847 // "Test0": 100.111, 848 // "Test99": 6000, 849 // "Bool": true 850 // } 851 852 // `) 853 // var ( 854 // o testStruct 855 // err error 856 // ) 857 // for n := 0; n < b.N; n++ { 858 // err = Unmarshal(data, &o) 859 // require.NoError(b, err) 860 // } 861 }