github.com/cloudwego/dynamicgo@v0.2.6-0.20240519101509-707f41b6b834/thrift/generic/path_test.go (about) 1 /** 2 * Copyright 2023 CloudWeGo Authors. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package generic 18 19 import ( 20 "encoding/hex" 21 "reflect" 22 "strconv" 23 "testing" 24 25 "github.com/cloudwego/dynamicgo/testdata/kitex_gen/base" 26 "github.com/cloudwego/dynamicgo/testdata/kitex_gen/example2" 27 "github.com/cloudwego/dynamicgo/testdata/sample" 28 "github.com/cloudwego/dynamicgo/thrift" 29 "github.com/davecgh/go-spew/spew" 30 "github.com/stretchr/testify/require" 31 ) 32 33 func TestChildren(t *testing.T) { 34 desc := getExampleDesc() 35 data := getExampleData() 36 v := NewValue(desc, data) 37 38 // t.Run("skip", func(t *testing.T) { 39 // opts := Options{} 40 // children := make([]PathNode, 0) 41 // err := v.Children(&children, false, &opts) 42 // require.Nil(t, err) 43 // checkHelper2(t, getExampleValue(v), children, true) 44 // }) 45 46 t.Run("recurse", func(t *testing.T) { 47 children := make([]PathNode, 0) 48 opts := Options{} 49 err := v.Children(&children, true, &opts) 50 require.NoError(t, err) 51 require.Equal(t, 4, len(children)) 52 exp := toInterface2(sample.Example2Obj, false, b2s) 53 act := PathNodeToInterface(PathNode{ 54 Node: v.Node, 55 Next: children, 56 }, &opts, false) 57 // require.Equal(t, exp, act) 58 require.True(t, DeepEqual(exp, act)) 59 require.True(t, DeepEqual(act, exp)) 60 }) 61 62 t.Run("NotScanParentNode", func(t *testing.T) { 63 children := make([]PathNode, 0) 64 opts := Options{} 65 opts.NotScanParentNode = true 66 err := v.Children(&children, true, &opts) 67 require.NoError(t, err) 68 require.Equal(t, 4, len(children)) 69 exp := toInterface2(sample.Example2Obj, false, b2s) 70 act := PathNodeToInterface(PathNode{ 71 Node: v.Node, 72 Next: children, 73 }, &opts, false) 74 require.True(t, DeepEqual(exp, act)) 75 require.True(t, DeepEqual(act, exp)) 76 }) 77 78 t.Run("StoreChildrenById", func(t *testing.T) { 79 children := make([]PathNode, 0) 80 opts := Options{} 81 opts.StoreChildrenById = true 82 err := v.Children(&children, true, &opts) 83 require.NoError(t, err) 84 require.Equal(t, 257, len(children)) 85 // get 86 require.Equal(t, thrift.STRING, children[desc.Struct().Fields()[0].ID()].Node.Type()) 87 base := children[desc.Struct().Fields()[2].ID()] 88 require.Equal(t, thrift.STRUCT, base.Node.Type()) 89 require.Equal(t, thrift.STRUCT, base.Field(thrift.FieldID(255), &opts).Node.Type()) 90 // set 91 var testByte byte = 123 92 exist, err := base.SetField(2, NewNodeByte(testByte), &opts) 93 require.NoError(t, err) 94 require.True(t, exist) 95 exist, err = base.SetField(299, NewNodeByte(testByte), &opts) 96 require.NoError(t, err) 97 require.False(t, exist) 98 // get again 99 require.Equal(t, thrift.STRUCT, base.Field(thrift.FieldID(255), &opts).Node.Type()) 100 101 // marshal 102 out, err := base.Marshal(&opts) 103 require.NoError(t, err) 104 act := example2.NewInnerBase() 105 _, err = act.FastRead(out) 106 require.NoError(t, err) 107 require.Equal(t, testByte, byte(act.Byte)) 108 }) 109 110 t.Run("StoreChildrenByHash", func(t *testing.T) { 111 opts := Options{} 112 exp := example2.NewExampleReq() 113 exp.Base = base.NewBase() 114 exp.Base.Extra = map[string]string{} 115 for i := 0; i < 100; i++ { 116 exp.Base.Extra[strconv.Itoa(i)] = strconv.Itoa(i) 117 } 118 exp.InnerBase = example2.NewInnerBase() 119 exp.InnerBase.MapInt32String = map[int32]string{} 120 for i := 0; i < 100; i++ { 121 exp.InnerBase.MapInt32String[int32(i)] = strconv.Itoa(i) 122 } 123 in := make([]byte, exp.BLength()) 124 exp.FastWriteNocopy(in, nil) 125 x := NewValue(getExampleDesc(), in) 126 127 // load 128 children := make([]PathNode, 0) 129 opts.StoreChildrenByHash = true 130 opts.StoreChildrenById = true 131 err := x.Children(&children, true, &opts) 132 require.NoError(t, err) 133 134 // get str key 135 con := &children[255].Next[6] 136 require.Nil(t, con.GetByStr("c", &opts)) 137 pv := con.GetByStr("0", &opts) 138 require.NotNil(t, pv) 139 v, err := pv.Interface(&opts) 140 require.NoError(t, err) 141 require.Equal(t, "0", v) 142 143 // set str key 144 exist, err := con.SetByStr("0", NewNodeString("123"), &opts) 145 require.NoError(t, err) 146 require.True(t, exist) 147 exist, err = con.SetByStr("299", NewNodeString("123"), &opts) 148 require.NoError(t, err) 149 require.False(t, exist) 150 151 // get str key again 152 pv = con.GetByStr("0", &opts) 153 require.NotNil(t, pv) 154 v, err = pv.Interface(&opts) 155 require.NoError(t, err) 156 require.Equal(t, "123", v) 157 158 // get int key 159 con2 := &children[3].Next[12] 160 require.Nil(t, con2.GetByInt(299, &opts)) 161 pv = con2.GetByInt(0, &opts) 162 require.NotNil(t, pv) 163 v, err = pv.Interface(&opts) 164 require.NoError(t, err) 165 require.Equal(t, "0", v) 166 167 // set int key 168 exist, err = con2.SetByInt(0, NewNodeString("123"), &opts) 169 require.NoError(t, err) 170 require.True(t, exist) 171 exist, err = con2.SetByInt(299, NewNodeString("123"), &opts) 172 require.NoError(t, err) 173 require.False(t, exist) 174 175 // get int key again 176 pv = con2.GetByInt(0, &opts) 177 require.NotNil(t, pv) 178 v, err = pv.Interface(&opts) 179 require.NoError(t, err) 180 require.Equal(t, "123", v) 181 182 // marshal 183 r := PathNode{ 184 Node: x.Node, 185 Next: children, 186 } 187 out, err := r.Marshal(&opts) 188 require.NoError(t, err) 189 act := example2.NewExampleReq() 190 _, err = act.FastRead(out) 191 require.NoError(t, err) 192 require.Equal(t, "123", act.Base.Extra["0"]) 193 require.Equal(t, "123", act.Base.Extra["299"]) 194 require.Equal(t, "123", act.InnerBase.MapInt32String[0]) 195 require.Equal(t, "123", act.InnerBase.MapInt32String[299]) 196 }) 197 } 198 199 var ( 200 BasePathNode = PathNode{ 201 Path: NewPathFieldId(255), 202 Next: []PathNode{ 203 { 204 Path: NewPathFieldId(1), 205 }, 206 { 207 Path: NewPathFieldId(2), 208 }, 209 { 210 Path: NewPathFieldId(3), 211 }, 212 { 213 Path: NewPathFieldId(4), 214 }, 215 { 216 Path: NewPathFieldId(5), 217 Next: []PathNode{ 218 { 219 Path: NewPathFieldId(1), 220 }, 221 { 222 Path: NewPathFieldId(2), 223 }, 224 }, 225 }, 226 { 227 Path: NewPathFieldId(6), 228 }, 229 }, 230 } 231 InnerBasePathNode = PathNode{ 232 Path: NewPathFieldId(3), 233 Next: []PathNode{ 234 { 235 Path: NewPathFieldId(1), 236 }, 237 { 238 Path: NewPathFieldId(2), 239 }, 240 { 241 Path: NewPathFieldId(3), 242 }, 243 { 244 Path: NewPathFieldId(4), 245 }, 246 { 247 Path: NewPathFieldId(5), 248 }, 249 { 250 Path: NewPathFieldId(6), 251 }, 252 { 253 Path: NewPathFieldId(7), 254 }, 255 { 256 Path: NewPathFieldId(8), 257 }, 258 { 259 Path: NewPathFieldId(9), 260 }, 261 { 262 Path: NewPathFieldId(10), 263 }, 264 { 265 Path: NewPathFieldId(11), 266 }, 267 { 268 Path: NewPathFieldId(12), 269 }, 270 { 271 Path: NewPathFieldId(13), 272 }, 273 { 274 Path: NewPathFieldId(14), 275 }, 276 { 277 Path: NewPathFieldId(15), 278 }, 279 { 280 Path: NewPathFieldId(16), 281 }, 282 BasePathNode, 283 }, 284 } 285 ExamplePathNode = PathNode{ 286 Path: NewPathFieldName("root"), 287 Next: []PathNode{ 288 { 289 Path: NewPathFieldId(1), 290 }, 291 { 292 Path: NewPathFieldId(2), 293 }, 294 InnerBasePathNode, 295 BasePathNode, 296 { 297 Path: NewPathFieldId(32767), 298 }, 299 }, 300 } 301 ) 302 303 func TestPathCast(t *testing.T) { 304 t.Run("field id", func(t *testing.T) { 305 exp := thrift.FieldID(1) 306 path := NewPathFieldId(exp) 307 require.Equal(t, exp, path.Id()) 308 require.Equal(t, exp, path.Value()) 309 }) 310 t.Run("field name", func(t *testing.T) { 311 exp := "name" 312 path := NewPathFieldName(exp) 313 require.Equal(t, exp, path.Str()) 314 require.Equal(t, exp, path.Value()) 315 }) 316 t.Run("index", func(t *testing.T) { 317 exp := 1 318 path := NewPathIndex(exp) 319 require.Equal(t, exp, path.Int()) 320 require.Equal(t, exp, path.Value()) 321 }) 322 t.Run("key", func(t *testing.T) { 323 exp := "key" 324 path := NewPathStrKey(exp) 325 require.Equal(t, exp, path.Str()) 326 require.Equal(t, exp, path.Value()) 327 }) 328 // t.Run("obj key", func(t *testing.T) { 329 // exp := struct{ A int }{1} 330 // path := NewPathObjKey(exp) 331 // require.Equal(t, exp, path.Value()) 332 // }) 333 } 334 335 // func TestDescriptorToPN(t *testing.T) { 336 // desc := getExampleDesc() 337 338 // t.Run("field id", func(t *testing.T) { 339 // var opts = &Options{ 340 // // OnlyScanStruct: true, 341 // } 342 // var exp = ExamplePathNode 343 344 // act := PathNode{ 345 // Path: NewPathFieldName("root"), 346 // } 347 // require.Nil(t, DescriptorToPathNode(desc, &act, opts)) 348 // require.Equal(t, exp, act) 349 // }) 350 // } 351 352 func TestPathReuse(t *testing.T) { 353 desc := getExampleDesc() 354 data := getExampleData() 355 root := NewValue(desc, data) 356 357 obj := ExamplePathNode.Fork() 358 require.Equal(t, ExamplePathNode, obj) 359 360 obj.Node = root.Node 361 opts := &Options{} 362 require.Nil(t, obj.Assgin(true, opts)) 363 out1, err := obj.Marshal(opts) 364 require.Nil(t, err) 365 366 obj.ResetValue() 367 require.Equal(t, ExamplePathNode, obj) 368 369 obj.Node = root.Node 370 require.Nil(t, obj.Assgin(true, opts)) 371 out2, err := obj.Marshal(opts) 372 require.Nil(t, err) 373 374 require.Equal(t, out1, out2) 375 } 376 377 func TestPathEmpty(t *testing.T) { 378 desc := getExampleDesc() 379 data := getExampleData() 380 root := NewValue(desc, data) 381 opts := &Options{} 382 383 ori := PathNode{ 384 Path: NewPathFieldName("root"), 385 Node: root.Node, 386 } 387 root.Children(&ori.Next, true, opts) 388 389 obj := ori.Fork() 390 obj.Next = append(obj.Next, PathNode{Path: NewPathFieldName("empty")}) 391 obj.Next[2].Next = append(obj.Next[2].Next, PathNode{Path: NewPathFieldName("empty")}) 392 obj.Next[2].Next[7].Next = append(obj.Next[2].Next[7].Next, PathNode{Path: NewPathIndex(1024)}) 393 obj.Next[2].Next[8].Next = append(obj.Next[2].Next[8].Next, PathNode{Path: NewPathStrKey("empty")}) 394 obj.Node = root.Node 395 396 require.Nil(t, obj.Assgin(true, opts)) 397 out1, err := obj.Marshal(opts) 398 require.Nil(t, err) 399 400 obj = ori.Fork() 401 obj.Node = root.Node 402 require.Nil(t, obj.Assgin(true, opts)) 403 out2, err := obj.Marshal(opts) 404 require.Nil(t, err) 405 406 require.Equal(t, out1, out2) 407 } 408 409 func TestTreeGet(t *testing.T) { 410 desc := getExampleDesc() 411 data := getExampleData() 412 413 exp := example2.NewExampleReq() 414 v := NewValue(desc, data) 415 tree := PathNode{ 416 Node: v.Node, 417 Next: []PathNode{ 418 { 419 Path: NewPathFieldId(1), 420 }, 421 { 422 Path: NewPathFieldId(3), 423 Next: []PathNode{ 424 { 425 Path: NewPathFieldId(1), 426 }, 427 { 428 Path: NewPathFieldId(8), 429 Next: []PathNode{ 430 { 431 Path: NewPathIndex(1), 432 }, 433 }, 434 }, 435 { 436 Path: NewPathFieldId(9), 437 Next: []PathNode{ 438 { 439 Path: NewPathStrKey("b"), 440 }, 441 }, 442 }, 443 { 444 Path: NewPathFieldId(12), 445 Next: []PathNode{ 446 { 447 Path: NewPathIntKey(2), 448 }, 449 }, 450 }, 451 }, 452 }, 453 { 454 Path: NewPathFieldId(255), 455 Next: []PathNode{ 456 { 457 Path: NewPathFieldId(2), 458 }, 459 }, 460 }, 461 }, 462 } 463 opts := Options{} 464 err := tree.Assgin(true, &opts) 465 require.NoError(t, err) 466 467 _, err = exp.FastRead(data) 468 require.Nil(t, err) 469 470 expM2 := map[int]interface{}{} 471 for k, v := range exp.InnerBase.MapInt32String { 472 expM2[int(k)] = v 473 } 474 checkHelper(t, *exp.Msg, tree.Next[0].Node, "String") 475 checkHelper(t, exp.InnerBase.Bool, tree.Next[1].Next[0].Node, "Bool") 476 checkHelper(t, exp.InnerBase.ListInt32, tree.Next[1].Next[1].Node, "List") 477 checkHelper(t, exp.InnerBase.MapStringString, tree.Next[1].Next[2].Node, "StrMap") 478 checkHelper(t, expM2, tree.Next[1].Next[3].Node, "IntMap") 479 checkHelper(t, exp.Base.Client, tree.Next[2].Next[0].Node, "String") 480 481 out, err := tree.Marshal(&opts) 482 require.Nil(t, err) 483 println(hex.Dump(out)) 484 } 485 486 func TestTreeMarshal(t *testing.T) { 487 desc := getExampleDesc() 488 data := getExampleData() 489 490 v := NewValue(desc, data) 491 tree := PathNode{ 492 Node: v.Node, 493 Next: []PathNode{ 494 { 495 Path: NewPathFieldId(1), 496 }, 497 { 498 Path: NewPathFieldId(3), 499 Next: []PathNode{ 500 { 501 Path: NewPathFieldId(1), 502 }, 503 { 504 Path: NewPathFieldId(8), 505 Next: []PathNode{ 506 { 507 Path: NewPathIndex(1), 508 }, 509 }, 510 }, 511 { 512 Path: NewPathFieldId(9), 513 Next: []PathNode{ 514 { 515 Path: NewPathStrKey("b"), 516 }, 517 }, 518 }, 519 { 520 Path: NewPathFieldId(12), 521 Next: []PathNode{ 522 { 523 Path: NewPathIntKey(2), 524 }, 525 }, 526 }, 527 }, 528 }, 529 { 530 Path: NewPathFieldId(255), 531 Next: []PathNode{ 532 { 533 Path: NewPathFieldId(2), 534 }, 535 }, 536 }, 537 }, 538 } 539 opts := Options{} 540 err := tree.Assgin(true, &opts) 541 require.NoError(t, err) 542 543 out, err := tree.Marshal(&opts) 544 require.Nil(t, err) 545 // spew.Dump(out) 546 exp := example2.NewExampleReq() 547 _, err = exp.FastRead(out) 548 require.Nil(t, err) 549 550 x := v.GetByPath(PathExampleByte...) 551 tt := PathNode{ 552 Path: NewPathFieldName("Msg"), 553 Node: x.Node, 554 Next: []PathNode{ 555 tree, 556 }, 557 } 558 out, err = tt.Marshal(&opts) 559 require.Nil(t, err) 560 require.Equal(t, x.Raw(), out) 561 } 562 563 func getExampleValue(v Value) []PathNode { 564 return []PathNode{ 565 { 566 Path: NewPathFieldId(1), 567 Node: v.GetByPath(NewPathFieldName("Msg")).Node, 568 }, 569 { 570 Path: NewPathFieldId(3), 571 Node: v.GetByPath(NewPathFieldName("InnerBase")).Node, 572 }, 573 { 574 Path: NewPathFieldId(255), 575 Node: v.GetByPath(NewPathFieldName("Base")).Node, 576 }, 577 { 578 Path: NewPathFieldId(32767), 579 Node: v.GetByPath(NewPathFieldName("Subfix")).Node, 580 }, 581 } 582 } 583 584 func getInnerBase(v Value) []PathNode { 585 return []PathNode{ 586 { 587 Path: NewPathFieldId(1), 588 Node: v.GetByPath(NewPathFieldName("Base"), NewPathFieldName("LogID")).Node, 589 }, 590 { 591 Path: NewPathFieldId(2), 592 Node: v.GetByPath(NewPathFieldName("Base"), NewPathFieldName("Caller")).Node, 593 }, 594 { 595 Path: NewPathFieldId(3), 596 Node: v.GetByPath(NewPathFieldName("Base"), NewPathFieldName("Addr")).Node, 597 }, 598 { 599 Path: NewPathFieldId(4), 600 Node: v.GetByPath(NewPathFieldName("Base"), NewPathFieldName("Client")).Node, 601 }, 602 { 603 Path: NewPathFieldId(5), 604 Node: v.GetByPath(NewPathFieldName("Base"), NewPathFieldName("TrafficEnv")).Node, 605 Next: []PathNode{ 606 { 607 Path: NewPathFieldId(1), 608 Node: v.GetByPath(NewPathFieldName("Base"), NewPathFieldName("TrafficEnv"), NewPathFieldName("Open")).Node, 609 }, 610 { 611 Path: NewPathFieldId(2), 612 Node: v.GetByPath(NewPathFieldName("Base"), NewPathFieldName("TrafficEnv"), NewPathFieldName("Env")).Node, 613 }, 614 }, 615 }, 616 { 617 Path: NewPathFieldId(6), 618 Node: v.GetByPath(NewPathFieldName("Base"), NewPathFieldName("Extra")).Node, 619 Next: []PathNode{ 620 { 621 Path: NewPathStrKey("a"), 622 Node: v.GetByPath(NewPathFieldName("Base"), NewPathFieldName("Extra"), NewPathStrKey("a")).Node, 623 }, 624 { 625 Path: NewPathStrKey("b"), 626 Node: v.GetByPath(NewPathFieldName("Base"), NewPathFieldName("Extra"), NewPathStrKey("b")).Node, 627 }, 628 { 629 Path: NewPathStrKey("c"), 630 Node: v.GetByPath(NewPathFieldName("Base"), NewPathFieldName("Extra"), NewPathStrKey("c")).Node, 631 }, 632 }, 633 }, 634 } 635 } 636 637 func checkHelper2(t *testing.T, exp []PathNode, act []PathNode, checkNode bool) { 638 require.Equal(t, len(exp), len(act)) 639 for i := range exp { 640 t.Logf("Path: %s\n", exp[i].Path) 641 found := false 642 for j := range act { 643 if exp[i].Path.String() == act[j].Path.String() { 644 if checkNode { 645 require.Equal(t, exp[i].Node, act[j].Node) 646 } 647 checkHelper2(t, exp[i].Next, act[j].Next, checkNode) 648 found = true 649 break 650 } 651 } 652 require.True(t, found) 653 } 654 } 655 656 // func toPathNode(v interface{}, ret *PathNode) { 657 // vt := reflect.ValueOf(v) 658 // if vt.Kind() == reflect.Ptr { 659 // if vt.IsNil() { 660 // return 661 // } 662 // vt = vt.Elem() 663 // } 664 665 // if k := vt.Kind(); k == reflect.Slice || k == reflect.Array { 666 // if vt.Type() == bytesType || vt.Len() == 0 { 667 // return 668 // } 669 // if len(ret.Next) < vt.Len() { 670 // ret.Next = make([]PathNode, vt.Len()) 671 // } 672 // var r *PathNode 673 // for i := 0; i < vt.Len(); i++ { 674 // r = &r.Next[i] 675 // r.Path = NewPathIndex(i) 676 // toPathNode(vt.Index(i).Interface(), r) 677 // } 678 // return 679 // } else if k == reflect.Map { 680 // if vt.Len() == 0 { 681 // return 682 // } 683 // if len(ret.Next) < vt.Len() { 684 // ret.Next = make([]PathNode, vt.Len()) 685 // } 686 // if kt := vt.Type().Key().Kind(); kt == reflect.String { 687 // var r *PathNode 688 // for i, k := range vt.MapKeys() { 689 // r = &r.Next[i] 690 // r.Path = NewPathStrKey(k.String()) 691 // toPathNode(vt.MapIndex(k).Interface(), r) 692 // } 693 // return 694 // } else if kt == reflect.Int || kt == reflect.Int8 || kt == reflect.Int16 || kt == reflect.Int32 || kt == reflect.Int64 { 695 // var r *PathNode 696 // for i, k := range vt.MapKeys() { 697 // r = &r.Next[i] 698 // r.Path = NewPathIntKey(int(k.Int())) 699 // toPathNode(vt.MapIndex(k).Interface(), r) 700 // } 701 // return 702 // } 703 // } else if k == reflect.Struct { 704 // var r *PathNode 705 // if vt.NumField() == 0 { 706 // return 707 // } 708 // if len(ret.Next) < vt.NumField() { 709 // ret.Next = make([]PathNode, vt.NumField()) 710 // } 711 // for i := 0; i < vt.NumField(); i++ { 712 // r = &r.Next[i] 713 // field := vt.Type().Field(i) 714 // tag := field.Tag.Get("thrift") 715 // ts := strings.Split(tag, ",") 716 // id := i 717 // if len(ts) > 1 { 718 // id, _ = strconv.Atoi(ts[1]) 719 // } 720 // r.Path = NewPathFieldId(thrift.FieldID(id)) 721 // toPathNode(vt.Field(i).Interface(), r) 722 // } 723 // return 724 // } else { 725 // ret.Node = NewNodeAny(vt.Interface()) 726 // return 727 // } 728 // } 729 730 func DeepEqual(exp interface{}, act interface{}) bool { 731 switch ev := exp.(type) { 732 case map[int]interface{}: 733 av, ok := act.(map[int]interface{}) 734 if !ok { 735 return false 736 } 737 for k, v := range ev { 738 vv, ok := av[k] 739 if !ok { 740 return false 741 } 742 if !DeepEqual(v, vv) { 743 return false 744 } 745 } 746 return true 747 case map[string]interface{}: 748 av, ok := act.(map[string]interface{}) 749 if !ok { 750 return false 751 } 752 for k, v := range ev { 753 vv, ok := av[k] 754 if !ok { 755 return false 756 } 757 if !DeepEqual(v, vv) { 758 return false 759 } 760 } 761 return true 762 case map[interface{}]interface{}: 763 av, ok := act.(map[interface{}]interface{}) 764 if !ok { 765 return false 766 } 767 if len(ev) == 0 { 768 return true 769 } 770 erv := reflect.ValueOf(ev) 771 arv := reflect.ValueOf(av) 772 eks := erv.MapKeys() 773 aks := arv.MapKeys() 774 isPointer := eks[0].Elem().Kind() == reflect.Ptr 775 if !isPointer { 776 for k, v := range ev { 777 vv, ok := av[k] 778 if !ok { 779 return false 780 } 781 if !DeepEqual(v, vv) { 782 return false 783 } 784 } 785 } else { 786 for _, ek := range eks { 787 found := false 788 for _, ak := range aks { 789 if DeepEqual(ek.Elem().Elem().Interface(), ak.Elem().Elem().Interface()) { 790 found = true 791 evv := erv.MapIndex(ek) 792 avv := arv.MapIndex(ak) 793 if !DeepEqual(evv.Interface(), avv.Interface()) { 794 return false 795 } 796 } 797 if !found { 798 return false 799 } 800 } 801 } 802 } 803 return true 804 case []interface{}: 805 av, ok := act.([]interface{}) 806 if !ok { 807 return false 808 } 809 for i, v := range ev { 810 vv := av[i] 811 if !DeepEqual(v, vv) { 812 return false 813 } 814 } 815 return true 816 default: 817 return reflect.DeepEqual(exp, act) 818 } 819 } 820 821 func TestDeepEqual(t *testing.T) { 822 a := map[interface{}]interface{}{ 823 float64(0.1): "A", 824 float64(0.2): "B", 825 float64(0.3): "C", 826 float64(0.4): "D", 827 float64(0.5): "E", 828 float64(0.6): "F", 829 float64(0.7): "G", 830 float64(0.8): "H", 831 float64(0.9): "I", 832 } 833 b := map[interface{}]interface{}{ 834 float64(0.4): "D", 835 float64(0.8): "H", 836 float64(0.7): "G", 837 float64(0.5): "E", 838 float64(0.6): "F", 839 float64(0.9): "I", 840 float64(0.2): "B", 841 float64(0.1): "A", 842 float64(0.3): "C", 843 } 844 for i := 0; i < 10; i++ { 845 require.Equal(t, a, b) 846 } 847 require.True(t, DeepEqual(a, b)) 848 } 849 850 func TestUnknownFields(t *testing.T) { 851 desc := getExampleDesc() 852 data := getExampleSuperData() 853 v := NewValue(desc, data) 854 855 t.Run("Children()", func(t *testing.T) { 856 // t.Run("allow", func(t *testing.T) { 857 children := make([]PathNode, 0) 858 opts := Options{} 859 err := v.Children(&children, true, &opts) 860 require.Nil(t, err) 861 act := PathNodeToInterface(PathNode{Node: v.Node, Next: children}, &opts, false) 862 exp := toInterface2(sample.Example2Super, false, b2s) 863 if !DeepEqual(exp, act) { 864 t.Fatal() 865 } 866 if !DeepEqual(act, exp) { 867 t.Fatal() 868 } 869 // require.Equal(t, exp, act) 870 // }) 871 872 // t.Run("disallow", func(t *testing.T) { 873 // children := make([]PathNode, 0) 874 // opts := Options{ 875 // DisallowUnknow: true, 876 // } 877 // err := v.Children(&children, false, &opts) 878 // require.NotNil(t, err) 879 // require.Equal(t, meta.ErrUnknownField, err.(meta.Error).Code.Behavior()) 880 // }) 881 }) 882 883 t.Run("Assgin(true, )", func(t *testing.T) { 884 // t.Run("allow", func(t *testing.T) { 885 opts := Options{ 886 DescriptorToPathNodeWriteDefualt: true, 887 DescriptorToPathNodeWriteOptional: true, 888 } 889 path := PathNode{ 890 Node: v.Node, 891 } 892 err := DescriptorToPathNode(desc, &path, &opts) 893 if err != nil { 894 t.Fatal(err) 895 } 896 err = path.Assgin(true, &opts) 897 require.NoError(t, err) 898 act := PathNodeToInterface(path, &opts, true) 899 exp := toInterface2(sample.Example2Obj, false, b2s) 900 // require.Equal(t, exp, act) 901 if !DeepEqual(exp, act) { 902 spew.Dump(exp, act) 903 t.Fatal() 904 } 905 906 // }) 907 // t.Run("disallow", func(t *testing.T) { 908 // opts := Options{ 909 // DisallowUnknow: true, 910 // } 911 // path := PathNode{ 912 // Node: v.Node, 913 // } 914 // err := DescriptorToPathNode(desc, &path, &opts) 915 // if err != nil { 916 // t.Fatal(err) 917 // } 918 // err = path.Assgin(true, &opts) 919 // require.Error(t, err) 920 // require.Equal(t, meta.ErrUnknownField, err.(Value).ErrCode()) 921 // }) 922 }) 923 924 // t.Run("Interface()/ByName", func(t *testing.T) { 925 // // t.Run("allow", func(t *testing.T) { 926 // opts := Options{ 927 // DisallowUnknow: false, 928 // StructByName: true, 929 // } 930 // ret, err := v.Interface(&opts) 931 // require.NoError(t, err) 932 // rv := toInterface2(sample.Example2Obj, false, true) 933 // require.Equal(t, rv, ret) 934 // }) 935 // t.Run("disallow", func(t *testing.T) { 936 // opts := Options{ 937 // DisallowUnknow: true, 938 // StructByName: true, 939 // } 940 // _, err := v.Interface(&opts) 941 // require.Error(t, err) 942 // require.Equal(t, meta.ErrUnknownField, err.(Value).ErrCode()) 943 // }) 944 // }) 945 946 t.Run("Interface()", func(t *testing.T) { 947 // t.Run("allow", func(t *testing.T) { 948 opts := Options{ 949 // DisallowUnknow: false, 950 // StructByName: false, 951 } 952 ret, err := v.Interface(&opts) 953 require.NoError(t, err) 954 rv := toInterface2(sample.Example2Super, false, b2s) 955 if !DeepEqual(rv, ret) { 956 t.Fatal() 957 } 958 if !DeepEqual(ret, rv) { 959 t.Fatal() 960 } 961 // }) 962 // t.Run("disallow", func(t *testing.T) { 963 // opts := Options{ 964 // DisallowUnknow: true, 965 // StructByName: false, 966 // } 967 // _, err := v.Interface(&opts) 968 // require.Error(t, err) 969 // require.Equal(t, meta.ErrUnknownField, err.(Value).ErrCode()) 970 // }) 971 }) 972 973 t.Run("Marshal()", func(t *testing.T) { 974 children := make([]PathNode, 0) 975 opts := Options{} 976 err := v.Children(&children, true, &opts) 977 require.Nil(t, err) 978 tree := PathNode{ 979 Node: v.Node, 980 Next: children, 981 } 982 out, err := tree.Marshal(&opts) 983 require.NoError(t, err) 984 985 act := example2.NewExampleSuper() 986 _, err = act.FastRead(out) 987 require.NoError(t, err) 988 989 // require.Equal(t, sample.Example2Super, act) 990 }) 991 } 992 993 func TestDescriptorToPathNode(t *testing.T) { 994 type args struct { 995 desc *thrift.TypeDescriptor 996 root *PathNode 997 opts *Options 998 } 999 tests := []struct { 1000 name string 1001 args args 1002 wantErr bool 1003 }{ 1004 {name: "defualt", args: args{ 1005 desc: getExampleDesc(), 1006 root: new(PathNode), 1007 opts: &Options{}, 1008 }, wantErr: false}, 1009 {name: "array size 1", args: args{ 1010 desc: getExampleDesc(), 1011 root: new(PathNode), 1012 opts: &Options{ 1013 DescriptorToPathNodeArraySize: 1, 1014 DescriptorToPathNodeMaxDepth: 256, 1015 }, 1016 }, wantErr: false}, 1017 {name: "map size 1", args: args{ 1018 desc: getExampleDesc(), 1019 root: new(PathNode), 1020 opts: &Options{ 1021 DescriptorToPathNodeMapSize: 1, 1022 DescriptorToPathNodeMaxDepth: 256, 1023 }, 1024 }, wantErr: false}, 1025 } 1026 for _, tt := range tests { 1027 t.Run(tt.name, func(t *testing.T) { 1028 if err := DescriptorToPathNode(tt.args.desc, tt.args.root, tt.args.opts); (err != nil) != tt.wantErr { 1029 t.Errorf("DescriptorToPathNode() error = %v, wantErr %v", err, tt.wantErr) 1030 } 1031 println(tt.name) 1032 spew.Dump(PathNodeToInterface(*tt.args.root, tt.args.opts, false)) 1033 }) 1034 1035 } 1036 }